aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Packham2018-10-04 02:03:53 -0500
committerYork Sun2018-10-29 15:13:05 -0500
commit4eaf7f525a0874a1eff0f5666004896cc5c89fa3 (patch)
tree551c1b5d786f0f8fc0182361ad98f591c6a71481 /drivers
parent454cf76184c65426b68033a23da086e73663f2fc (diff)
downloadu-boot-4eaf7f525a0874a1eff0f5666004896cc5c89fa3.tar.gz
u-boot-4eaf7f525a0874a1eff0f5666004896cc5c89fa3.tar.xz
u-boot-4eaf7f525a0874a1eff0f5666004896cc5c89fa3.zip
fsl/usb: Workaround for USB erratum-A005275
Workaround makes FS as default mode on all affected socs. Add support to check erratum-A005275 validity for an soc. This info is required to determine whether a given soc is affected by this erratum. Add quirk for this erratum "has_fsl_erratum_a005275" . This quirk is used to enable workaround for the errata Force FS mode as default by: - making EPS as FS - setting PFSC bit to disable HS chirping This workaround can be disabled by mentioning "no_erratum_a005275" in hwconfig string Signed-off-by: Chris Packham <judge.packham@gmail.com> Reviewed-by: York Sun <york.sun@nxp.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/common/fsl-errata.c28
-rw-r--r--drivers/usb/host/ehci-fsl.c7
-rw-r--r--drivers/usb/host/ehci-hcd.c12
-rw-r--r--drivers/usb/host/ehci.h4
4 files changed, 50 insertions, 1 deletions
diff --git a/drivers/usb/common/fsl-errata.c b/drivers/usb/common/fsl-errata.c
index 386130d7a1..9eb1d23067 100644
--- a/drivers/usb/common/fsl-errata.c
+++ b/drivers/usb/common/fsl-errata.c
@@ -6,6 +6,7 @@
6 */ 6 */
7 7
8#include <common.h> 8#include <common.h>
9#include <hwconfig.h>
9#include <fsl_errata.h> 10#include <fsl_errata.h>
10#include<fsl_usb.h> 11#include<fsl_usb.h>
11#if defined(CONFIG_FSL_LSCH2) || defined(CONFIG_FSL_LSCH3) || \ 12#if defined(CONFIG_FSL_LSCH2) || defined(CONFIG_FSL_LSCH3) || \
@@ -44,6 +45,33 @@ bool has_dual_phy(void)
44 return false; 45 return false;
45} 46}
46 47
48bool has_erratum_a005275(void)
49{
50 u32 svr = get_svr();
51 u32 soc = SVR_SOC_VER(svr);
52
53 if (hwconfig("no_erratum_a005275"))
54 return false;
55
56 switch (soc) {
57#ifdef CONFIG_PPC
58 case SVR_P3041:
59 case SVR_P2041:
60 case SVR_P2040:
61 return IS_SVR_REV(svr, 1, 0) || IS_SVR_REV(svr, 1, 1);
62 case SVR_P5010:
63 case SVR_P5020:
64 case SVR_P5021:
65 return IS_SVR_REV(svr, 1, 0) || IS_SVR_REV(svr, 2, 0);
66 case SVR_P5040:
67 case SVR_P1010:
68 return IS_SVR_REV(svr, 1, 0);
69#endif
70 }
71
72 return false;
73}
74
47bool has_erratum_a006261(void) 75bool has_erratum_a006261(void)
48{ 76{
49 u32 svr = get_svr(); 77 u32 svr = get_svr();
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
index a04f6a31c8..a8fb2b8ac3 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -93,6 +93,7 @@ static int ehci_fsl_probe(struct udevice *dev)
93 struct usb_ehci *ehci = NULL; 93 struct usb_ehci *ehci = NULL;
94 struct ehci_hccr *hccr; 94 struct ehci_hccr *hccr;
95 struct ehci_hcor *hcor; 95 struct ehci_hcor *hcor;
96 struct ehci_ctrl *ehci_ctrl = &priv->ehci;
96 97
97 /* 98 /*
98 * Get the base address for EHCI controller from the device node 99 * Get the base address for EHCI controller from the device node
@@ -107,6 +108,8 @@ static int ehci_fsl_probe(struct udevice *dev)
107 hcor = (struct ehci_hcor *) 108 hcor = (struct ehci_hcor *)
108 ((void *)hccr + HC_LENGTH(ehci_readl(&hccr->cr_capbase))); 109 ((void *)hccr + HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
109 110
111 ehci_ctrl->has_fsl_erratum_a005275 = has_erratum_a005275();
112
110 if (ehci_fsl_init(priv, ehci, hccr, hcor) < 0) 113 if (ehci_fsl_init(priv, ehci, hccr, hcor) < 0)
111 return -ENXIO; 114 return -ENXIO;
112 115
@@ -145,6 +148,8 @@ U_BOOT_DRIVER(ehci_fsl) = {
145int ehci_hcd_init(int index, enum usb_init_type init, 148int ehci_hcd_init(int index, enum usb_init_type init,
146 struct ehci_hccr **hccr, struct ehci_hcor **hcor) 149 struct ehci_hccr **hccr, struct ehci_hcor **hcor)
147{ 150{
151 struct ehci_ctrl *ehci_ctrl = container_of(hccr,
152 struct ehci_ctrl, hccr);
148 struct usb_ehci *ehci = NULL; 153 struct usb_ehci *ehci = NULL;
149 154
150 switch (index) { 155 switch (index) {
@@ -163,6 +168,8 @@ int ehci_hcd_init(int index, enum usb_init_type init,
163 *hcor = (struct ehci_hcor *)((uint32_t) *hccr + 168 *hcor = (struct ehci_hcor *)((uint32_t) *hccr +
164 HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase))); 169 HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
165 170
171 ehci_ctrl->has_fsl_erratum_a005275 = has_erratum_a005275();
172
166 return ehci_fsl_init(index, ehci, *hccr, *hcor); 173 return ehci_fsl_init(index, ehci, *hccr, *hcor);
167} 174}
168 175
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 199b3a8b26..d1d8f08d98 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -409,9 +409,15 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
409 endpt = QH_ENDPT1_RL(8) | QH_ENDPT1_C(c) | 409 endpt = QH_ENDPT1_RL(8) | QH_ENDPT1_C(c) |
410 QH_ENDPT1_MAXPKTLEN(maxpacket) | QH_ENDPT1_H(0) | 410 QH_ENDPT1_MAXPKTLEN(maxpacket) | QH_ENDPT1_H(0) |
411 QH_ENDPT1_DTC(QH_ENDPT1_DTC_DT_FROM_QTD) | 411 QH_ENDPT1_DTC(QH_ENDPT1_DTC_DT_FROM_QTD) |
412 QH_ENDPT1_EPS(ehci_encode_speed(dev->speed)) |
413 QH_ENDPT1_ENDPT(usb_pipeendpoint(pipe)) | QH_ENDPT1_I(0) | 412 QH_ENDPT1_ENDPT(usb_pipeendpoint(pipe)) | QH_ENDPT1_I(0) |
414 QH_ENDPT1_DEVADDR(usb_pipedevice(pipe)); 413 QH_ENDPT1_DEVADDR(usb_pipedevice(pipe));
414
415 /* Force FS for fsl HS quirk */
416 if (!ctrl->has_fsl_erratum_a005275)
417 endpt |= QH_ENDPT1_EPS(ehci_encode_speed(dev->speed));
418 else
419 endpt |= QH_ENDPT1_EPS(ehci_encode_speed(QH_FULL_SPEED));
420
415 qh->qh_endpt1 = cpu_to_hc32(endpt); 421 qh->qh_endpt1 = cpu_to_hc32(endpt);
416 endpt = QH_ENDPT2_MULT(1) | QH_ENDPT2_UFCMASK(0) | QH_ENDPT2_UFSMASK(0); 422 endpt = QH_ENDPT2_MULT(1) | QH_ENDPT2_UFCMASK(0) | QH_ENDPT2_UFSMASK(0);
417 qh->qh_endpt2 = cpu_to_hc32(endpt); 423 qh->qh_endpt2 = cpu_to_hc32(endpt);
@@ -832,6 +838,10 @@ static int ehci_submit_root(struct usb_device *dev, unsigned long pipe,
832 } else { 838 } else {
833 int ret; 839 int ret;
834 840
841 /* Disable chirp for HS erratum */
842 if (ctrl->has_fsl_erratum_a005275)
843 reg |= PORTSC_FSL_PFSC;
844
835 reg |= EHCI_PS_PR; 845 reg |= EHCI_PS_PR;
836 reg &= ~EHCI_PS_PE; 846 reg &= ~EHCI_PS_PE;
837 ehci_writel(status_reg, reg); 847 ehci_writel(status_reg, reg);
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index 7945016624..6c359af90c 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -8,6 +8,7 @@
8#ifndef USB_EHCI_H 8#ifndef USB_EHCI_H
9#define USB_EHCI_H 9#define USB_EHCI_H
10 10
11#include <stdbool.h>
11#include <usb.h> 12#include <usb.h>
12#include <generic-phy.h> 13#include <generic-phy.h>
13 14
@@ -66,6 +67,8 @@ struct ehci_hcor {
66#define PORTSC_PSPD_FS 0x0 67#define PORTSC_PSPD_FS 0x0
67#define PORTSC_PSPD_LS 0x1 68#define PORTSC_PSPD_LS 0x1
68#define PORTSC_PSPD_HS 0x2 69#define PORTSC_PSPD_HS 0x2
70#define PORTSC_FSL_PFSC BIT(24) /* PFSC bit to disable HS chirping */
71
69 uint32_t or_systune; 72 uint32_t or_systune;
70} __attribute__ ((packed, aligned(4))); 73} __attribute__ ((packed, aligned(4)));
71 74
@@ -251,6 +254,7 @@ struct ehci_ctrl {
251 uint32_t *periodic_list; 254 uint32_t *periodic_list;
252 int periodic_schedules; 255 int periodic_schedules;
253 int ntds; 256 int ntds;
257 bool has_fsl_erratum_a005275; /* Freescale HS silicon quirk */
254 struct ehci_ops ops; 258 struct ehci_ops ops;
255 void *priv; /* client's private data */ 259 void *priv; /* client's private data */
256}; 260};