Message ID | 20220922033116.915635-3-judge.packham@gmail.com |
---|---|
State | Superseded |
Delegated to: | Stefan Roese |
Headers | show |
Series | arm: mvebu: Support for 98DX25xx/98DX35xx (AlleyCat5) | expand |
On 22.09.22 05:31, Chris Packham wrote: > Unlike the other 64-bit mvebu SoCs the AlleyCat5 uses the older ehci > block from the 32-bit SoCs. Adapt the ehci-marvell.c driver to cope with > the fact that the ac5 does not have the mbus infrastructure the 32-bit > SoCs have and ensure USB_EHCI_IS_TDI is selected. > > Signed-off-by: Chris Packham <judge.packham@gmail.com> > --- > > (no changes since v1) > > drivers/usb/host/Kconfig | 1 + > drivers/usb/host/ehci-marvell.c | 57 +++++++++++++++++++++++++++------ > 2 files changed, 48 insertions(+), 10 deletions(-) > > diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig > index a0f48f09a7..628078f495 100644 > --- a/drivers/usb/host/Kconfig > +++ b/drivers/usb/host/Kconfig > @@ -178,6 +178,7 @@ config USB_EHCI_MARVELL > depends on ARCH_MVEBU || ARCH_KIRKWOOD || ARCH_ORION5X > default y > select USB_EHCI_IS_TDI if !ARM64 > + select USB_EHCI_IS_TDI if ALLEYCAT_5 > ---help--- > Enables support for the on-chip EHCI controller on MVEBU SoCs. > > diff --git a/drivers/usb/host/ehci-marvell.c b/drivers/usb/host/ehci-marvell.c > index b7e60c690a..7d859b9cce 100644 > --- a/drivers/usb/host/ehci-marvell.c > +++ b/drivers/usb/host/ehci-marvell.c > @@ -48,12 +48,17 @@ struct ehci_mvebu_priv { > fdt_addr_t hcd_base; > }; > > +#define USB_TO_DRAM_TARGET_ID 0x2 > +#define USB_TO_DRAM_ATTR_ID 0x0 > +#define USB_DRAM_BASE 0x00000000 > +#define USB_DRAM_SIZE 0xfff /* don't overrun u-boot source (was 0xffff) */ > + > /* > * Once all the older Marvell SoC's (Orion, Kirkwood) are converted > * to the common mvebu archticture including the mbus setup, this > * will be the only function needed to configure the access windows > */ > -static void usb_brg_adrdec_setup(void *base) > +static void usb_brg_adrdec_setup(struct udevice *dev, void *base) > { > const struct mbus_dram_target_info *dram; > int i; > @@ -65,16 +70,34 @@ static void usb_brg_adrdec_setup(void *base) > writel(0, base + USB_WINDOW_BASE(i)); > } > > - for (i = 0; i < dram->num_cs; i++) { > - const struct mbus_dram_window *cs = dram->cs + i; > + if (device_is_compatible(dev, "marvell,ac5-ehci")) { > + /* > + * use decoding window to map dram address seen by usb to 0x0 > + */ > > /* Write size, attributes and target id to control register */ > - writel(((cs->size - 1) & 0xffff0000) | (cs->mbus_attr << 8) | > - (dram->mbus_dram_target_id << 4) | 1, > - base + USB_WINDOW_CTRL(i)); > + writel((USB_DRAM_SIZE << 16) | (USB_TO_DRAM_ATTR_ID << 8) | > + (USB_TO_DRAM_TARGET_ID << 4) | 1, > + base + USB_WINDOW_CTRL(0)); Nitpicking / coding-style comment: Not aligned with the '(' in the line above. I assume that checkpatch.pl will complain here. > > /* Write base address to base register */ > - writel(cs->base, base + USB_WINDOW_BASE(i)); > + writel(USB_DRAM_BASE, base + USB_WINDOW_BASE(0)); > + > + debug("## AC5 decoding windows, ctrl[%p]=0x%x, base[%p]=0x%x\n", > + base + USB_WINDOW_CTRL(0), readl(base + USB_WINDOW_CTRL(0)), > + base + USB_WINDOW_BASE(0), readl(base + USB_WINDOW_BASE(0))); > + } else { > + for (i = 0; i < dram->num_cs; i++) { > + const struct mbus_dram_window *cs = dram->cs + i; > + > + /* Write size, attributes and target id to control register */ > + writel(((cs->size - 1) & 0xffff0000) | (cs->mbus_attr << 8) | > + (dram->mbus_dram_target_id << 4) | 1, > + base + USB_WINDOW_CTRL(i)); > + > + /* Write base address to base register */ > + writel(cs->base, base + USB_WINDOW_BASE(i)); > + } > } > } > > @@ -126,15 +149,28 @@ static int ehci_mvebu_probe(struct udevice *dev) > if (device_is_compatible(dev, "marvell,armada-3700-ehci")) > marvell_ehci_ops.powerup_fixup = marvell_ehci_powerup_fixup; > else > - usb_brg_adrdec_setup((void *)priv->hcd_base); > + usb_brg_adrdec_setup(dev, (void *)priv->hcd_base); > > hccr = (struct ehci_hccr *)(priv->hcd_base + 0x100); > hcor = (struct ehci_hcor *) > ((uintptr_t)hccr + HC_LENGTH(ehci_readl(&hccr->cr_capbase))); > > debug("ehci-marvell: init hccr %lx and hcor %lx hc_length %ld\n", > - (uintptr_t)hccr, (uintptr_t)hcor, > - (uintptr_t)HC_LENGTH(ehci_readl(&hccr->cr_capbase))); > + (uintptr_t)hccr, (uintptr_t)hcor, > + (uintptr_t)HC_LENGTH(ehci_readl(&hccr->cr_capbase))); Unrelated change of indentation (see above). > + > +#define PHY_CALIB_OFFSET 0x808 > + /* > + * Trigger calibration during each usb start/reset: > + * BIT 13 to 0, and then to 1 > + */ > + if (device_is_compatible(dev, "marvell,ac5-ehci")) { > + void *phy_calib_reg = (void *)(priv->hcd_base + PHY_CALIB_OFFSET); > + u32 val = readl(phy_calib_reg) & (~BIT(13)); > + > + writel(val, phy_calib_reg); > + writel(val | BIT(13), phy_calib_reg); > + } > > return ehci_register(dev, hccr, hcor, &marvell_ehci_ops, 0, > USB_INIT_HOST); > @@ -143,6 +179,7 @@ static int ehci_mvebu_probe(struct udevice *dev) > static const struct udevice_id ehci_usb_ids[] = { > { .compatible = "marvell,orion-ehci", }, > { .compatible = "marvell,armada-3700-ehci", }, > + { .compatible = "marvell,ac5-ehci", }, > { } > }; > Other than this: Reviewed-by: Stefan Roese <sr@denx.de> Thanks, Stefan
On Thu, Sep 22, 2022 at 5:18 PM Stefan Roese <sr@denx.de> wrote: > > On 22.09.22 05:31, Chris Packham wrote: > > Unlike the other 64-bit mvebu SoCs the AlleyCat5 uses the older ehci > > block from the 32-bit SoCs. Adapt the ehci-marvell.c driver to cope with > > the fact that the ac5 does not have the mbus infrastructure the 32-bit > > SoCs have and ensure USB_EHCI_IS_TDI is selected. > > > > Signed-off-by: Chris Packham <judge.packham@gmail.com> > > --- > > > > (no changes since v1) > > > > drivers/usb/host/Kconfig | 1 + > > drivers/usb/host/ehci-marvell.c | 57 +++++++++++++++++++++++++++------ > > 2 files changed, 48 insertions(+), 10 deletions(-) > > > > diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig > > index a0f48f09a7..628078f495 100644 > > --- a/drivers/usb/host/Kconfig > > +++ b/drivers/usb/host/Kconfig > > @@ -178,6 +178,7 @@ config USB_EHCI_MARVELL > > depends on ARCH_MVEBU || ARCH_KIRKWOOD || ARCH_ORION5X > > default y > > select USB_EHCI_IS_TDI if !ARM64 > > + select USB_EHCI_IS_TDI if ALLEYCAT_5 > > ---help--- > > Enables support for the on-chip EHCI controller on MVEBU SoCs. > > > > diff --git a/drivers/usb/host/ehci-marvell.c b/drivers/usb/host/ehci-marvell.c > > index b7e60c690a..7d859b9cce 100644 > > --- a/drivers/usb/host/ehci-marvell.c > > +++ b/drivers/usb/host/ehci-marvell.c > > @@ -48,12 +48,17 @@ struct ehci_mvebu_priv { > > fdt_addr_t hcd_base; > > }; > > > > +#define USB_TO_DRAM_TARGET_ID 0x2 > > +#define USB_TO_DRAM_ATTR_ID 0x0 > > +#define USB_DRAM_BASE 0x00000000 > > +#define USB_DRAM_SIZE 0xfff /* don't overrun u-boot source (was 0xffff) */ > > + > > /* > > * Once all the older Marvell SoC's (Orion, Kirkwood) are converted > > * to the common mvebu archticture including the mbus setup, this > > * will be the only function needed to configure the access windows > > */ > > -static void usb_brg_adrdec_setup(void *base) > > +static void usb_brg_adrdec_setup(struct udevice *dev, void *base) > > { > > const struct mbus_dram_target_info *dram; > > int i; > > @@ -65,16 +70,34 @@ static void usb_brg_adrdec_setup(void *base) > > writel(0, base + USB_WINDOW_BASE(i)); > > } > > > > - for (i = 0; i < dram->num_cs; i++) { > > - const struct mbus_dram_window *cs = dram->cs + i; > > + if (device_is_compatible(dev, "marvell,ac5-ehci")) { > > + /* > > + * use decoding window to map dram address seen by usb to 0x0 > > + */ > > > > /* Write size, attributes and target id to control register */ > > - writel(((cs->size - 1) & 0xffff0000) | (cs->mbus_attr << 8) | > > - (dram->mbus_dram_target_id << 4) | 1, > > - base + USB_WINDOW_CTRL(i)); > > + writel((USB_DRAM_SIZE << 16) | (USB_TO_DRAM_ATTR_ID << 8) | > > + (USB_TO_DRAM_TARGET_ID << 4) | 1, > > + base + USB_WINDOW_CTRL(0)); > > Nitpicking / coding-style comment: Not aligned with the '(' in the > line above. I assume that checkpatch.pl will complain here. > Doesn't seem to complain about this (ran manually and via patman). I'll fix it regardless. > > > > /* Write base address to base register */ > > - writel(cs->base, base + USB_WINDOW_BASE(i)); > > + writel(USB_DRAM_BASE, base + USB_WINDOW_BASE(0)); > > + > > + debug("## AC5 decoding windows, ctrl[%p]=0x%x, base[%p]=0x%x\n", > > + base + USB_WINDOW_CTRL(0), readl(base + USB_WINDOW_CTRL(0)), > > + base + USB_WINDOW_BASE(0), readl(base + USB_WINDOW_BASE(0))); > > + } else { > > + for (i = 0; i < dram->num_cs; i++) { > > + const struct mbus_dram_window *cs = dram->cs + i; > > + > > + /* Write size, attributes and target id to control register */ > > + writel(((cs->size - 1) & 0xffff0000) | (cs->mbus_attr << 8) | > > + (dram->mbus_dram_target_id << 4) | 1, > > + base + USB_WINDOW_CTRL(i)); > > + > > + /* Write base address to base register */ > > + writel(cs->base, base + USB_WINDOW_BASE(i)); > > + } > > } > > } > > > > @@ -126,15 +149,28 @@ static int ehci_mvebu_probe(struct udevice *dev) > > if (device_is_compatible(dev, "marvell,armada-3700-ehci")) > > marvell_ehci_ops.powerup_fixup = marvell_ehci_powerup_fixup; > > else > > - usb_brg_adrdec_setup((void *)priv->hcd_base); > > + usb_brg_adrdec_setup(dev, (void *)priv->hcd_base); > > > > hccr = (struct ehci_hccr *)(priv->hcd_base + 0x100); > > hcor = (struct ehci_hcor *) > > ((uintptr_t)hccr + HC_LENGTH(ehci_readl(&hccr->cr_capbase))); > > > > debug("ehci-marvell: init hccr %lx and hcor %lx hc_length %ld\n", > > - (uintptr_t)hccr, (uintptr_t)hcor, > > - (uintptr_t)HC_LENGTH(ehci_readl(&hccr->cr_capbase))); > > + (uintptr_t)hccr, (uintptr_t)hcor, > > + (uintptr_t)HC_LENGTH(ehci_readl(&hccr->cr_capbase))); > > Unrelated change of indentation (see above). > Yep will remove > > + > > +#define PHY_CALIB_OFFSET 0x808 > > + /* > > + * Trigger calibration during each usb start/reset: > > + * BIT 13 to 0, and then to 1 > > + */ > > + if (device_is_compatible(dev, "marvell,ac5-ehci")) { > > + void *phy_calib_reg = (void *)(priv->hcd_base + PHY_CALIB_OFFSET); > > + u32 val = readl(phy_calib_reg) & (~BIT(13)); > > + > > + writel(val, phy_calib_reg); > > + writel(val | BIT(13), phy_calib_reg); > > + } > > > > return ehci_register(dev, hccr, hcor, &marvell_ehci_ops, 0, > > USB_INIT_HOST); > > @@ -143,6 +179,7 @@ static int ehci_mvebu_probe(struct udevice *dev) > > static const struct udevice_id ehci_usb_ids[] = { > > { .compatible = "marvell,orion-ehci", }, > > { .compatible = "marvell,armada-3700-ehci", }, > > + { .compatible = "marvell,ac5-ehci", }, > > { } > > }; > > > > Other than this: > > Reviewed-by: Stefan Roese <sr@denx.de> > > Thanks, > Stefan
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index a0f48f09a7..628078f495 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -178,6 +178,7 @@ config USB_EHCI_MARVELL depends on ARCH_MVEBU || ARCH_KIRKWOOD || ARCH_ORION5X default y select USB_EHCI_IS_TDI if !ARM64 + select USB_EHCI_IS_TDI if ALLEYCAT_5 ---help--- Enables support for the on-chip EHCI controller on MVEBU SoCs. diff --git a/drivers/usb/host/ehci-marvell.c b/drivers/usb/host/ehci-marvell.c index b7e60c690a..7d859b9cce 100644 --- a/drivers/usb/host/ehci-marvell.c +++ b/drivers/usb/host/ehci-marvell.c @@ -48,12 +48,17 @@ struct ehci_mvebu_priv { fdt_addr_t hcd_base; }; +#define USB_TO_DRAM_TARGET_ID 0x2 +#define USB_TO_DRAM_ATTR_ID 0x0 +#define USB_DRAM_BASE 0x00000000 +#define USB_DRAM_SIZE 0xfff /* don't overrun u-boot source (was 0xffff) */ + /* * Once all the older Marvell SoC's (Orion, Kirkwood) are converted * to the common mvebu archticture including the mbus setup, this * will be the only function needed to configure the access windows */ -static void usb_brg_adrdec_setup(void *base) +static void usb_brg_adrdec_setup(struct udevice *dev, void *base) { const struct mbus_dram_target_info *dram; int i; @@ -65,16 +70,34 @@ static void usb_brg_adrdec_setup(void *base) writel(0, base + USB_WINDOW_BASE(i)); } - for (i = 0; i < dram->num_cs; i++) { - const struct mbus_dram_window *cs = dram->cs + i; + if (device_is_compatible(dev, "marvell,ac5-ehci")) { + /* + * use decoding window to map dram address seen by usb to 0x0 + */ /* Write size, attributes and target id to control register */ - writel(((cs->size - 1) & 0xffff0000) | (cs->mbus_attr << 8) | - (dram->mbus_dram_target_id << 4) | 1, - base + USB_WINDOW_CTRL(i)); + writel((USB_DRAM_SIZE << 16) | (USB_TO_DRAM_ATTR_ID << 8) | + (USB_TO_DRAM_TARGET_ID << 4) | 1, + base + USB_WINDOW_CTRL(0)); /* Write base address to base register */ - writel(cs->base, base + USB_WINDOW_BASE(i)); + writel(USB_DRAM_BASE, base + USB_WINDOW_BASE(0)); + + debug("## AC5 decoding windows, ctrl[%p]=0x%x, base[%p]=0x%x\n", + base + USB_WINDOW_CTRL(0), readl(base + USB_WINDOW_CTRL(0)), + base + USB_WINDOW_BASE(0), readl(base + USB_WINDOW_BASE(0))); + } else { + for (i = 0; i < dram->num_cs; i++) { + const struct mbus_dram_window *cs = dram->cs + i; + + /* Write size, attributes and target id to control register */ + writel(((cs->size - 1) & 0xffff0000) | (cs->mbus_attr << 8) | + (dram->mbus_dram_target_id << 4) | 1, + base + USB_WINDOW_CTRL(i)); + + /* Write base address to base register */ + writel(cs->base, base + USB_WINDOW_BASE(i)); + } } } @@ -126,15 +149,28 @@ static int ehci_mvebu_probe(struct udevice *dev) if (device_is_compatible(dev, "marvell,armada-3700-ehci")) marvell_ehci_ops.powerup_fixup = marvell_ehci_powerup_fixup; else - usb_brg_adrdec_setup((void *)priv->hcd_base); + usb_brg_adrdec_setup(dev, (void *)priv->hcd_base); hccr = (struct ehci_hccr *)(priv->hcd_base + 0x100); hcor = (struct ehci_hcor *) ((uintptr_t)hccr + HC_LENGTH(ehci_readl(&hccr->cr_capbase))); debug("ehci-marvell: init hccr %lx and hcor %lx hc_length %ld\n", - (uintptr_t)hccr, (uintptr_t)hcor, - (uintptr_t)HC_LENGTH(ehci_readl(&hccr->cr_capbase))); + (uintptr_t)hccr, (uintptr_t)hcor, + (uintptr_t)HC_LENGTH(ehci_readl(&hccr->cr_capbase))); + +#define PHY_CALIB_OFFSET 0x808 + /* + * Trigger calibration during each usb start/reset: + * BIT 13 to 0, and then to 1 + */ + if (device_is_compatible(dev, "marvell,ac5-ehci")) { + void *phy_calib_reg = (void *)(priv->hcd_base + PHY_CALIB_OFFSET); + u32 val = readl(phy_calib_reg) & (~BIT(13)); + + writel(val, phy_calib_reg); + writel(val | BIT(13), phy_calib_reg); + } return ehci_register(dev, hccr, hcor, &marvell_ehci_ops, 0, USB_INIT_HOST); @@ -143,6 +179,7 @@ static int ehci_mvebu_probe(struct udevice *dev) static const struct udevice_id ehci_usb_ids[] = { { .compatible = "marvell,orion-ehci", }, { .compatible = "marvell,armada-3700-ehci", }, + { .compatible = "marvell,ac5-ehci", }, { } };
Unlike the other 64-bit mvebu SoCs the AlleyCat5 uses the older ehci block from the 32-bit SoCs. Adapt the ehci-marvell.c driver to cope with the fact that the ac5 does not have the mbus infrastructure the 32-bit SoCs have and ensure USB_EHCI_IS_TDI is selected. Signed-off-by: Chris Packham <judge.packham@gmail.com> --- (no changes since v1) drivers/usb/host/Kconfig | 1 + drivers/usb/host/ehci-marvell.c | 57 +++++++++++++++++++++++++++------ 2 files changed, 48 insertions(+), 10 deletions(-)