From 38aa420096e565fe9c98f9d9475fd168114501a9 Mon Sep 17 00:00:00 2001 From: Nikhil Badola Date: Mon, 15 Jun 2015 15:46:37 +0530 Subject: drivers:usb:fsl: Replace macros with enumerated type Replace macros with enumerated type to represent usb ip controller version Signed-off-by: Nikhil Badola Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/fsl-mph-dr-of.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/usb/host/fsl-mph-dr-of.c') diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c index 5e0d60035216..219595637cb1 100644 --- a/drivers/usb/host/fsl-mph-dr-of.c +++ b/drivers/usb/host/fsl-mph-dr-of.c @@ -119,9 +119,9 @@ error: static const struct of_device_id fsl_usb2_mph_dr_of_match[]; -static int usb_get_ver_info(struct device_node *np) +static enum fsl_usb2_controller_ver usb_get_ver_info(struct device_node *np) { - int ver = -1; + enum fsl_usb2_controller_ver ver = FSL_USB_VER_NONE; /* * returns 1 for usb controller version 1.6 @@ -142,7 +142,7 @@ static int usb_get_ver_info(struct device_node *np) else /* for previous controller versions */ ver = FSL_USB_VER_OLD; - if (ver > -1) + if (ver > FSL_USB_VER_NONE) return ver; } @@ -215,7 +215,7 @@ static int fsl_usb2_mph_dr_of_probe(struct platform_device *ofdev) pdata->controller_ver = usb_get_ver_info(np); if (pdata->have_sysif_regs) { - if (pdata->controller_ver < 0) { + if (pdata->controller_ver == FSL_USB_VER_NONE) { dev_warn(&ofdev->dev, "Could not get controller version\n"); return -ENODEV; } -- cgit v1.2.3 From 523f1dec58408b36e7683a3d61a0286eed1fc1c8 Mon Sep 17 00:00:00 2001 From: Nikhil Badola Date: Mon, 15 Jun 2015 15:47:29 +0530 Subject: drivers: usb :fsl: Implement Workaround for USB Erratum A007792 USB controller version-2.5 requires to enable internal UTMI phy and program PTS field in PORTSC register before asserting controller reset. This is must for successful resetting of the controller and subsequent enumeration of usb devices Signed-off-by: Nikhil Badola Signed-off-by: Suresh Gupta Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-fsl.c | 9 +++++++++ drivers/usb/host/fsl-mph-dr-of.c | 6 ++++++ include/linux/fsl_devices.h | 1 + 3 files changed, 16 insertions(+) (limited to 'drivers/usb/host/fsl-mph-dr-of.c') diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index 5352e74b92e2..716aa8be1d6f 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -129,6 +129,15 @@ static int fsl_ehci_drv_probe(struct platform_device *pdev) if (pdata->have_sysif_regs && pdata->controller_ver < FSL_USB_VER_1_6) setbits32(hcd->regs + FSL_SOC_USB_CTRL, 0x4); + /* + * Enable UTMI phy and program PTS field in UTMI mode before asserting + * controller reset for USB Controller version 2.5 + */ + if (pdata->has_fsl_erratum_a007792) { + writel_be(CTRL_UTMI_PHY_EN, hcd->regs + FSL_SOC_USB_CTRL); + writel(PORT_PTS_UTMI, hcd->regs + FSL_SOC_USB_PORTSC1); + } + /* Don't need to set host mode here. It will be done by tdi_reset() */ retval = usb_add_hcd(hcd, irq, IRQF_SHARED); diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c index 219595637cb1..17e1e6b7a035 100644 --- a/drivers/usb/host/fsl-mph-dr-of.c +++ b/drivers/usb/host/fsl-mph-dr-of.c @@ -214,6 +214,12 @@ static int fsl_usb2_mph_dr_of_probe(struct platform_device *ofdev) pdata->phy_mode = determine_usb_phy(prop); pdata->controller_ver = usb_get_ver_info(np); + /* Activate Erratum by reading property in device tree */ + if (of_get_property(np, "fsl,usb-erratum-a007792", NULL)) + pdata->has_fsl_erratum_a007792 = 1; + else + pdata->has_fsl_erratum_a007792 = 0; + if (pdata->have_sysif_regs) { if (pdata->controller_ver == FSL_USB_VER_NONE) { dev_warn(&ofdev->dev, "Could not get controller version\n"); diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h index 0d4855cd5330..bdb40f67180c 100644 --- a/include/linux/fsl_devices.h +++ b/include/linux/fsl_devices.h @@ -97,6 +97,7 @@ struct fsl_usb2_platform_data { unsigned suspended:1; unsigned already_suspended:1; + unsigned has_fsl_erratum_a007792:1; /* register save area for suspend/resume */ u32 pm_command; -- cgit v1.2.3 From 6009d95e04cf74c6f80db56fddca21fea476ad24 Mon Sep 17 00:00:00 2001 From: Nikhil Badola Date: Mon, 15 Jun 2015 15:48:22 +0530 Subject: drivers:usb:fsl: Introduce FSL_USB2_PHY_UTMI_DUAL macro Introduce FSL_USB2_PHY_UTMI_DUAL macro for setting phy mode in SOCs such has T4240, T1040, T2080 which have utmi dual-phy Signed-off-by: Ramneek Mehresh Signed-off-by: Nikhil Badola Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-fsl.c | 1 + drivers/usb/host/fsl-mph-dr-of.c | 2 ++ include/linux/fsl_devices.h | 1 + 3 files changed, 4 insertions(+) (limited to 'drivers/usb/host/fsl-mph-dr-of.c') diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index 716aa8be1d6f..b04c9dbd5c7d 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -213,6 +213,7 @@ static int ehci_fsl_setup_phy(struct usb_hcd *hcd, portsc |= PORT_PTS_PTW; /* fall through */ case FSL_USB2_PHY_UTMI: + case FSL_USB2_PHY_UTMI_DUAL: if (pdata->have_sysif_regs && pdata->controller_ver) { /* controller version 1.6 or above */ setbits32(non_ehci + FSL_SOC_USB_CTRL, UTMI_PHY_EN); diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c index 17e1e6b7a035..631fc504afda 100644 --- a/drivers/usb/host/fsl-mph-dr-of.c +++ b/drivers/usb/host/fsl-mph-dr-of.c @@ -69,6 +69,8 @@ static enum fsl_usb2_phy_modes determine_usb_phy(const char *phy_type) return FSL_USB2_PHY_UTMI; if (!strcasecmp(phy_type, "utmi_wide")) return FSL_USB2_PHY_UTMI_WIDE; + if (!strcasecmp(phy_type, "utmi_dual")) + return FSL_USB2_PHY_UTMI_DUAL; if (!strcasecmp(phy_type, "serial")) return FSL_USB2_PHY_SERIAL; diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h index bdb40f67180c..070d9aef90a7 100644 --- a/include/linux/fsl_devices.h +++ b/include/linux/fsl_devices.h @@ -69,6 +69,7 @@ enum fsl_usb2_phy_modes { FSL_USB2_PHY_UTMI, FSL_USB2_PHY_UTMI_WIDE, FSL_USB2_PHY_SERIAL, + FSL_USB2_PHY_UTMI_DUAL, }; struct clk; -- cgit v1.2.3 From f4fdfaa280a284be8a056d6840cdbbf42c05bf95 Mon Sep 17 00:00:00 2001 From: Nikhil Badola Date: Tue, 14 Jul 2015 17:28:10 +0530 Subject: drivers: usb: fsl: Modify phy clk valid bit checking Phy_clk_valid bit is checked only when the boolean property phy-clk-valid in present in usb node device tree. This property is added to the usb node via device tree fixup. Signed-off-by: Nikhil Badola Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-fsl.c | 16 ++++++++-------- drivers/usb/host/fsl-mph-dr-of.c | 9 +++++++++ include/linux/fsl_devices.h | 1 + 3 files changed, 18 insertions(+), 8 deletions(-) (limited to 'drivers/usb/host/fsl-mph-dr-of.c') diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index b04c9dbd5c7d..05ebe3dcd618 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -230,14 +230,14 @@ static int ehci_fsl_setup_phy(struct usb_hcd *hcd, break; } - if (pdata->have_sysif_regs && - pdata->controller_ver > FSL_USB_VER_1_6 && - (phy_mode == FSL_USB2_PHY_ULPI)) { - /* check PHY_CLK_VALID to get phy clk valid */ - if (!(spin_event_timeout(in_be32(non_ehci + FSL_SOC_USB_CTRL) & - PHY_CLK_VALID, FSL_USB_PHY_CLK_TIMEOUT, 0) || - in_be32(non_ehci + FSL_SOC_USB_PRICTRL))) { - dev_warn(hcd->self.controller, "USB PHY clock invalid\n"); + /* + * check PHY_CLK_VALID to determine phy clock presence before writing + * to portsc + */ + if (pdata->check_phy_clk_valid) { + if (!(in_be32(non_ehci + FSL_SOC_USB_CTRL) & PHY_CLK_VALID)) { + dev_warn(hcd->self.controller, + "USB PHY clock invalid\n"); return -EINVAL; } } diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c index 631fc504afda..9f731413ab3e 100644 --- a/drivers/usb/host/fsl-mph-dr-of.c +++ b/drivers/usb/host/fsl-mph-dr-of.c @@ -222,6 +222,15 @@ static int fsl_usb2_mph_dr_of_probe(struct platform_device *ofdev) else pdata->has_fsl_erratum_a007792 = 0; + /* + * Determine whether phy_clk_valid needs to be checked + * by reading property in device tree + */ + if (of_get_property(np, "phy-clk-valid", NULL)) + pdata->check_phy_clk_valid = 1; + else + pdata->check_phy_clk_valid = 0; + if (pdata->have_sysif_regs) { if (pdata->controller_ver == FSL_USB_VER_NONE) { dev_warn(&ofdev->dev, "Could not get controller version\n"); diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h index 070d9aef90a7..cebdbbb4aa69 100644 --- a/include/linux/fsl_devices.h +++ b/include/linux/fsl_devices.h @@ -99,6 +99,7 @@ struct fsl_usb2_platform_data { unsigned suspended:1; unsigned already_suspended:1; unsigned has_fsl_erratum_a007792:1; + unsigned check_phy_clk_valid:1; /* register save area for suspend/resume */ u32 pm_command; -- cgit v1.2.3 From f8786a91548df6930643a052e40e5c0b7a8403a5 Mon Sep 17 00:00:00 2001 From: Nikhil Badola Date: Thu, 6 Aug 2015 14:51:27 +0530 Subject: drivers: usb: fsl: Workaround for USB erratum-A005275 Incoming packets in high speed are randomly corrupted by h/w resulting in multiple errors. This workaround makes FS as default mode in all affected socs by disabling HS chirp signalling.This errata does not affect FS and LS mode. Forces all HS devices to connect in FS mode for all socs affected by this erratum: P3041 and P2041 rev 1.0 and 1.1 P5020 and P5010 rev 1.0 and 2.0 P5040, P1010 and T4240 rev 1.0 Signed-off-by: Ramneek Mehresh Signed-off-by: Nikhil Badola Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-fsl.c | 4 ++++ drivers/usb/host/ehci-hub.c | 7 +++++++ drivers/usb/host/ehci.h | 12 ++++++++++++ drivers/usb/host/fsl-mph-dr-of.c | 4 ++++ include/linux/fsl_devices.h | 1 + 5 files changed, 28 insertions(+) (limited to 'drivers/usb/host/fsl-mph-dr-of.c') diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index 202dafb7d0cb..3b6eb219de1a 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -278,6 +278,10 @@ static int ehci_fsl_usb_setup(struct ehci_hcd *ehci) out_be32(non_ehci + FSL_SOC_USB_SNOOP2, 0x80000000 | SNOOP_SIZE_2GB); } + /* Deal with USB erratum A-005275 */ + if (pdata->has_fsl_erratum_a005275 == 1) + ehci->has_fsl_hs_errata = 1; + if ((pdata->operating_mode == FSL_USB2_DR_HOST) || (pdata->operating_mode == FSL_USB2_DR_OTG)) if (ehci_fsl_setup_phy(hcd, pdata->phy_mode, 0)) diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 22abb6830dfa..086a7115d263 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -1221,6 +1221,13 @@ int ehci_hub_control( */ ehci->reset_done [wIndex] = jiffies + msecs_to_jiffies (50); + + /* + * Force full-speed connect for FSL high-speed + * erratum; disable HS Chirp by setting PFSC bit + */ + if (ehci_has_fsl_hs_errata(ehci)) + temp |= (1 << PORTSC_FSL_PFSC); } ehci_writel(ehci, temp, status_reg); break; diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index f700157cd084..46f62e41bcde 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -215,6 +215,7 @@ struct ehci_hcd { /* one per controller */ /* SILICON QUIRKS */ unsigned no_selective_suspend:1; unsigned has_fsl_port_bug:1; /* FreeScale */ + unsigned has_fsl_hs_errata:1; /* Freescale HS quirk */ unsigned big_endian_mmio:1; unsigned big_endian_desc:1; unsigned big_endian_capbase:1; @@ -686,6 +687,17 @@ ehci_port_speed(struct ehci_hcd *ehci, unsigned int portsc) #define ehci_has_fsl_portno_bug(e) (0) #endif +#define PORTSC_FSL_PFSC 24 /* Port Force Full-Speed Connect */ + +#if defined(CONFIG_PPC_85xx) +/* Some Freescale processors have an erratum (USB A-005275) in which + * incoming packets get corrupted in HS mode + */ +#define ehci_has_fsl_hs_errata(e) ((e)->has_fsl_hs_errata) +#else +#define ehci_has_fsl_hs_errata(e) (0) +#endif + /* * While most USB host controllers implement their registers in * little-endian format, a minority (celleb companion chip) implement diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c index 9f731413ab3e..534c4c5d278a 100644 --- a/drivers/usb/host/fsl-mph-dr-of.c +++ b/drivers/usb/host/fsl-mph-dr-of.c @@ -221,6 +221,10 @@ static int fsl_usb2_mph_dr_of_probe(struct platform_device *ofdev) pdata->has_fsl_erratum_a007792 = 1; else pdata->has_fsl_erratum_a007792 = 0; + if (of_get_property(np, "fsl,usb-erratum-a005275", NULL)) + pdata->has_fsl_erratum_a005275 = 1; + else + pdata->has_fsl_erratum_a005275 = 0; /* * Determine whether phy_clk_valid needs to be checked diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h index cebdbbb4aa69..f2912914141a 100644 --- a/include/linux/fsl_devices.h +++ b/include/linux/fsl_devices.h @@ -99,6 +99,7 @@ struct fsl_usb2_platform_data { unsigned suspended:1; unsigned already_suspended:1; unsigned has_fsl_erratum_a007792:1; + unsigned has_fsl_erratum_a005275:1; unsigned check_phy_clk_valid:1; /* register save area for suspend/resume */ -- cgit v1.2.3