Improve RK3568 pcie phy handling codes a bit.
Move phy bifurcation code to a separate function that can be called during the attach phase. Also initialize both pcie lanes accordingly.
This commit is contained in:
parent
f698c1e99b
commit
4720afaffe
@ -56,9 +56,12 @@
|
|||||||
#define GRF_PCIE30PHY_CON4 0x10
|
#define GRF_PCIE30PHY_CON4 0x10
|
||||||
#define GRF_PCIE30PHY_CON5 0x14
|
#define GRF_PCIE30PHY_CON5 0x14
|
||||||
#define GRF_PCIE30PHY_CON6 0x18
|
#define GRF_PCIE30PHY_CON6 0x18
|
||||||
|
#define GRF_BIFURCATION_LANE_1 0
|
||||||
|
#define GRF_BIFURCATION_LANE_2 1
|
||||||
#define GRF_PCIE30PHY_WR_EN (0xf << 16)
|
#define GRF_PCIE30PHY_WR_EN (0xf << 16)
|
||||||
#define GRF_PCIE30PHY_CON9 0x24
|
#define GRF_PCIE30PHY_CON9 0x24
|
||||||
#define GRF_PCIE30PHY_DA_OCM ((1 << 15) | (1 << (15 + 16)))
|
#define GRF_PCIE30PHY_DA_OCM_MASK (1 << (15 + 16))
|
||||||
|
#define GRF_PCIE30PHY_DA_OCM ((1 << 15) | GRF_PCIE30PHY_DA_OCM_MASK)
|
||||||
#define GRF_PCIE30PHY_STATUS0 0x80
|
#define GRF_PCIE30PHY_STATUS0 0x80
|
||||||
#define SRAM_INIT_DONE (1 << 14)
|
#define SRAM_INIT_DONE (1 << 14)
|
||||||
|
|
||||||
@ -80,46 +83,42 @@ struct rk3568_pciephy_softc {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
rk3568_pciephy_bifurcate(device_t dev, int control, uint32_t lane)
|
||||||
|
{
|
||||||
|
struct rk3568_pciephy_softc *sc = device_get_softc(dev);
|
||||||
|
|
||||||
|
switch (lane) {
|
||||||
|
case 0:
|
||||||
|
SYSCON_WRITE_4(sc->phy_grf, control, GRF_PCIE30PHY_WR_EN);
|
||||||
|
return;
|
||||||
|
case 1:
|
||||||
|
SYSCON_WRITE_4(sc->phy_grf, control,
|
||||||
|
GRF_PCIE30PHY_WR_EN | GRF_BIFURCATION_LANE_1);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
SYSCON_WRITE_4(sc->phy_grf, control,
|
||||||
|
GRF_PCIE30PHY_WR_EN | GRF_BIFURCATION_LANE_2);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
device_printf(dev, "Illegal lane %d\n", lane);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (bootverbose)
|
||||||
|
device_printf(dev, "lane %d @ pcie3x%d\n", lane,
|
||||||
|
(control == GRF_PCIE30PHY_CON5) ? 1 : 2);
|
||||||
|
}
|
||||||
|
|
||||||
/* PHY class and methods */
|
/* PHY class and methods */
|
||||||
static int
|
static int
|
||||||
rk3568_pciephy_enable(struct phynode *phynode, bool enable)
|
rk3568_pciephy_enable(struct phynode *phynode, bool enable)
|
||||||
{
|
{
|
||||||
device_t dev = phynode_get_device(phynode);
|
device_t dev = phynode_get_device(phynode);
|
||||||
struct rk3568_pciephy_softc *sc = device_get_softc(dev);
|
struct rk3568_pciephy_softc *sc = device_get_softc(dev);
|
||||||
uint32_t data_lanes[2] = { 0, 0 };
|
|
||||||
int count;
|
int count;
|
||||||
|
|
||||||
if (enable) {
|
if (enable) {
|
||||||
/* Deassert PCIe PMA output clamp mode */
|
/* Pull PHY out of reset */
|
||||||
SYSCON_WRITE_4(sc->phy_grf, GRF_PCIE30PHY_CON9,
|
|
||||||
GRF_PCIE30PHY_DA_OCM);
|
|
||||||
|
|
||||||
/* Set bifurcation according to DT entry */
|
|
||||||
if (OF_hasprop(sc->node, "data-lanes")) {
|
|
||||||
OF_getencprop(sc->node, "data-lanes", data_lanes,
|
|
||||||
sizeof(data_lanes));
|
|
||||||
if (data_lanes[0] > 0) {
|
|
||||||
SYSCON_WRITE_4(sc->phy_grf, GRF_PCIE30PHY_CON5,
|
|
||||||
GRF_PCIE30PHY_WR_EN | (data_lanes[0] - 1));
|
|
||||||
device_printf(dev, "pcie3x1 1 lane\n");
|
|
||||||
}
|
|
||||||
if (data_lanes[1] > 0) {
|
|
||||||
SYSCON_WRITE_4(sc->phy_grf, GRF_PCIE30PHY_CON6,
|
|
||||||
GRF_PCIE30PHY_WR_EN | (data_lanes[1] - 1));
|
|
||||||
device_printf(dev, "pcie3x2 1 lane\n");
|
|
||||||
}
|
|
||||||
if (data_lanes[0] > 1 || data_lanes[1] > 1)
|
|
||||||
SYSCON_WRITE_4(sc->phy_grf, GRF_PCIE30PHY_CON1,
|
|
||||||
GRF_PCIE30PHY_DA_OCM);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
SYSCON_WRITE_4(sc->phy_grf, GRF_PCIE30PHY_CON5,
|
|
||||||
GRF_PCIE30PHY_WR_EN);
|
|
||||||
SYSCON_WRITE_4(sc->phy_grf, GRF_PCIE30PHY_CON6,
|
|
||||||
GRF_PCIE30PHY_WR_EN);
|
|
||||||
device_printf(dev, "pcie3 2 lanes\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
hwreset_deassert(sc->phy_reset);
|
hwreset_deassert(sc->phy_reset);
|
||||||
|
|
||||||
/* Poll for SRAM loaded and ready */
|
/* Poll for SRAM loaded and ready */
|
||||||
@ -165,6 +164,7 @@ rk3568_pciephy_attach(device_t dev)
|
|||||||
struct rk3568_pciephy_softc *sc = device_get_softc(dev);
|
struct rk3568_pciephy_softc *sc = device_get_softc(dev);
|
||||||
struct phynode_init_def phy_init;
|
struct phynode_init_def phy_init;
|
||||||
struct phynode *phynode;
|
struct phynode *phynode;
|
||||||
|
uint32_t data_lanes[2] = { 0, 0 };
|
||||||
int rid = 0;
|
int rid = 0;
|
||||||
|
|
||||||
sc->dev = dev;
|
sc->dev = dev;
|
||||||
@ -212,6 +212,29 @@ rk3568_pciephy_attach(device_t dev)
|
|||||||
|
|
||||||
/* Set RC/EP mode not implemented yet (RC mode only) */
|
/* Set RC/EP mode not implemented yet (RC mode only) */
|
||||||
|
|
||||||
|
/* Set bifurcation according to "data-lanes" entry */
|
||||||
|
if (OF_hasprop(sc->node, "data-lanes")) {
|
||||||
|
OF_getencprop(sc->node, "data-lanes", data_lanes,
|
||||||
|
sizeof(data_lanes));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (bootverbose)
|
||||||
|
device_printf(dev, "lane 1 & 2 @pcie3x2\n");
|
||||||
|
|
||||||
|
/* Deassert PCIe PMA output clamp mode */
|
||||||
|
SYSCON_WRITE_4(sc->phy_grf, GRF_PCIE30PHY_CON9, GRF_PCIE30PHY_DA_OCM);
|
||||||
|
|
||||||
|
/* Configure PHY HW accordingly */
|
||||||
|
rk3568_pciephy_bifurcate(dev, GRF_PCIE30PHY_CON5, data_lanes[0]);
|
||||||
|
rk3568_pciephy_bifurcate(dev, GRF_PCIE30PHY_CON6, data_lanes[1]);
|
||||||
|
|
||||||
|
if (data_lanes[0] || data_lanes[1])
|
||||||
|
SYSCON_WRITE_4(sc->phy_grf, GRF_PCIE30PHY_CON1,
|
||||||
|
GRF_PCIE30PHY_DA_OCM);
|
||||||
|
else
|
||||||
|
SYSCON_WRITE_4(sc->phy_grf, GRF_PCIE30PHY_CON1,
|
||||||
|
GRF_PCIE30PHY_DA_OCM_MASK);
|
||||||
|
|
||||||
bzero(&phy_init, sizeof(phy_init));
|
bzero(&phy_init, sizeof(phy_init));
|
||||||
phy_init.id = PHY_NONE;
|
phy_init.id = PHY_NONE;
|
||||||
phy_init.ofw_node = sc->node;
|
phy_init.ofw_node = sc->node;
|
||||||
|
Loading…
Reference in New Issue
Block a user