diff options
author | Gevorg Sahakyan <Gevorg.Sahakyan@synopsys.com> | 2018-07-27 04:26:29 -0400 |
---|---|---|
committer | Felipe Balbi <felipe.balbi@linux.intel.com> | 2018-07-30 03:39:18 -0400 |
commit | fe369e1826b3efae11012ad07d1713223c37ec5d (patch) | |
tree | 13674f57aaeb9f3650d74b5470bd698a4df89109 | |
parent | b138e23d3dff90c0494925b4c1874227b81bddf7 (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.h | 15 | ||||
-rw-r--r-- | drivers/usb/dwc2/platform.c | 19 |
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 */ |
1165 | static inline u32 dwc2_readl(struct dwc2_hsotg *hsotg, u32 offset) | 1167 | static 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 | ||
1170 | static inline void dwc2_writel(struct dwc2_hsotg *hsotg, u32 value, u32 offset) | 1178 | static 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 | */ | ||
360 | static 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; |