Declared dwc2_check_core_endianness() function for dynamicly check core endianness. Added needs_byte_swap flag to hsotg structure, and depending on flag swap value inside dwc2_readl/writel functions. Signed-off-by: Gevorg Sahakyan <sahakyan@xxxxxxxxxxxx> --- drivers/usb/dwc2/core.h | 22 ++++++++++++++++++++-- drivers/usb/dwc2/platform.c | 19 +++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index a32ff26386c2..7e5690e27cdd 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -96,6 +96,13 @@ static const char * const dwc2_hsotg_supply_names[] = { */ #define EP0_MPS_LIMIT 64 +#define swap32(x) (\ + {typeof(x) x_ = (x); \ + (((u32)(x_) << 24) & (u32)0xFF000000) | \ + (((u32)(x_) << 8) & (u32)0x00FF0000) | \ + (((u32)(x_) >> 8) & (u32)0x0000FF00) | \ + (((u32)(x_) >> 24) & (u32)0x000000FF); }) + struct dwc2_hsotg; struct dwc2_hsotg_req; @@ -781,6 +788,7 @@ struct dwc2_hregs_backup { * @gregs_backup: Backup of global registers during suspend * @dregs_backup: Backup of device registers during suspend * @hregs_backup: Backup of host registers during suspend + * @needs_byte_swap: Specifies whether the opposite endianness. * * These are for host mode: * @@ -928,6 +936,7 @@ struct dwc2_hsotg { struct dentry *debug_root; struct debugfs_regset32 *regset; + bool needs_byte_swap; /* DWC OTG HW Release versions */ #define DWC2_CORE_REV_2_71a 0x4f54271a @@ -1043,12 +1052,21 @@ struct dwc2_hsotg { /* Normal architectures just use readl/write */ static inline u32 dwc2_readl(struct dwc2_hsotg *hsotg, u32 offset) { - return readl(hsotg->regs + offset); + u32 val; + + val = readl(hsotg->regs + offset); + if (hsotg->needs_byte_swap) + return swap32(val); + else + return val; } static inline void dwc2_writel(struct dwc2_hsotg *hsotg, u32 value, u32 offset) { - writel(value, hsotg->regs + offset); + if (hsotg->needs_byte_swap) + writel(swap32(value), hsotg->regs + offset); + else + writel(value, hsotg->regs + offset); #ifdef DWC2_LOG_WRITES pr_info("info:: wrote %08x to %p\n", value, hsotg->regs + offset); diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 4c0819554bcd..9a53a58e676e 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -352,6 +352,23 @@ static void dwc2_driver_shutdown(struct platform_device *dev) disable_irq(hsotg->irq); } +/** + * dwc2_check_core_endianness() - Returns true if core and AHB have + * opposite endianness. + * @hsotg: Programming view of the DWC_otg controller. + */ +static bool dwc2_check_core_endianness(struct dwc2_hsotg *hsotg) +{ + u32 snpsid; + + snpsid = ioread32(hsotg->regs + GSNPSID); + if ((snpsid & GSNPSID_ID_MASK) == DWC2_OTG_ID || + (snpsid & GSNPSID_ID_MASK) == DWC2_FS_IOT_ID || + (snpsid & GSNPSID_ID_MASK) == DWC2_HS_IOT_ID) + return false; + return true; +} + /** * dwc2_driver_probe() - Called when the DWC_otg core is bound to the DWC_otg * driver @@ -395,6 +412,8 @@ static int dwc2_driver_probe(struct platform_device *dev) dev_dbg(&dev->dev, "mapped PA %08lx to VA %p\n", (unsigned long)res->start, hsotg->regs); + hsotg->needs_byte_swap = dwc2_check_core_endianness(hsotg); + retval = dwc2_lowlevel_hw_init(hsotg); if (retval) return retval; -- 2.11.0 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html