aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGevorg Sahakyan <Gevorg.Sahakyan@synopsys.com>2018-07-27 04:26:29 -0400
committerFelipe Balbi <felipe.balbi@linux.intel.com>2018-07-30 03:39:18 -0400
commitfe369e1826b3efae11012ad07d1713223c37ec5d (patch)
tree13674f57aaeb9f3650d74b5470bd698a4df89109
parentb138e23d3dff90c0494925b4c1874227b81bddf7 (diff)
usb: dwc2: Make dwc2_readl/writel functions endianness-agnostic.
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@synopsys.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
-rw-r--r--drivers/usb/dwc2/core.h15
-rw-r--r--drivers/usb/dwc2/platform.c19
2 files changed, 32 insertions, 2 deletions
diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index ae8534bed884..cc9c93affa14 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -857,6 +857,7 @@ struct dwc2_hregs_backup {
857 * @gr_backup: Backup of global registers during suspend 857 * @gr_backup: Backup of global registers during suspend
858 * @dr_backup: Backup of device registers during suspend 858 * @dr_backup: Backup of device registers during suspend
859 * @hr_backup: Backup of host registers during suspend 859 * @hr_backup: Backup of host registers during suspend
860 * @needs_byte_swap: Specifies whether the opposite endianness.
860 * 861 *
861 * These are for host mode: 862 * These are for host mode:
862 * 863 *
@@ -1046,6 +1047,7 @@ struct dwc2_hsotg {
1046 1047
1047 struct dentry *debug_root; 1048 struct dentry *debug_root;
1048 struct debugfs_regset32 *regset; 1049 struct debugfs_regset32 *regset;
1050 bool needs_byte_swap;
1049 1051
1050 /* DWC OTG HW Release versions */ 1052 /* DWC OTG HW Release versions */
1051#define DWC2_CORE_REV_2_71a 0x4f54271a 1053#define DWC2_CORE_REV_2_71a 0x4f54271a
@@ -1164,12 +1166,21 @@ struct dwc2_hsotg {
1164/* Normal architectures just use readl/write */ 1166/* Normal architectures just use readl/write */
1165static inline u32 dwc2_readl(struct dwc2_hsotg *hsotg, u32 offset) 1167static inline u32 dwc2_readl(struct dwc2_hsotg *hsotg, u32 offset)
1166{ 1168{
1167 return readl(hsotg->regs + offset); 1169 u32 val;
1170
1171 val = readl(hsotg->regs + offset);
1172 if (hsotg->needs_byte_swap)
1173 return swab32(val);
1174 else
1175 return val;
1168} 1176}
1169 1177
1170static inline void dwc2_writel(struct dwc2_hsotg *hsotg, u32 value, u32 offset) 1178static inline void dwc2_writel(struct dwc2_hsotg *hsotg, u32 value, u32 offset)
1171{ 1179{
1172 writel(value, hsotg->regs + offset); 1180 if (hsotg->needs_byte_swap)
1181 writel(swab32(value), hsotg->regs + offset);
1182 else
1183 writel(value, hsotg->regs + offset);
1173 1184
1174#ifdef DWC2_LOG_WRITES 1185#ifdef DWC2_LOG_WRITES
1175 pr_info("info:: wrote %08x to %p\n", value, hsotg->regs + offset); 1186 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
@@ -353,6 +353,23 @@ static void dwc2_driver_shutdown(struct platform_device *dev)
353} 353}
354 354
355/** 355/**
356 * dwc2_check_core_endianness() - Returns true if core and AHB have
357 * opposite endianness.
358 * @hsotg: Programming view of the DWC_otg controller.
359 */
360static bool dwc2_check_core_endianness(struct dwc2_hsotg *hsotg)
361{
362 u32 snpsid;
363
364 snpsid = ioread32(hsotg->regs + GSNPSID);
365 if ((snpsid & GSNPSID_ID_MASK) == DWC2_OTG_ID ||
366 (snpsid & GSNPSID_ID_MASK) == DWC2_FS_IOT_ID ||
367 (snpsid & GSNPSID_ID_MASK) == DWC2_HS_IOT_ID)
368 return false;
369 return true;
370}
371
372/**
356 * dwc2_driver_probe() - Called when the DWC_otg core is bound to the DWC_otg 373 * dwc2_driver_probe() - Called when the DWC_otg core is bound to the DWC_otg
357 * driver 374 * driver
358 * 375 *
@@ -395,6 +412,8 @@ static int dwc2_driver_probe(struct platform_device *dev)
395 dev_dbg(&dev->dev, "mapped PA %08lx to VA %p\n", 412 dev_dbg(&dev->dev, "mapped PA %08lx to VA %p\n",
396 (unsigned long)res->start, hsotg->regs); 413 (unsigned long)res->start, hsotg->regs);
397 414
415 hsotg->needs_byte_swap = dwc2_check_core_endianness(hsotg);
416
398 retval = dwc2_lowlevel_hw_init(hsotg); 417 retval = dwc2_lowlevel_hw_init(hsotg);
399 if (retval) 418 if (retval)
400 return retval; 419 return retval;