123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- From 14909c4e4e836925668e74fc6e0e85ba0283cbf9 Mon Sep 17 00:00:00 2001
- From: Hauke Mehrtens <hauke@hauke-m.de>
- Date: Fri, 6 Jan 2017 17:40:12 +0100
- Subject: [PATCH 2/2] MIPS: lantiq: improve USB initialization
- This adds code to initialize the USB controller and PHY also on Danube,
- Amazon SE and AR10. This code is based on the Vendor driver from
- different UGW versions and compared to the hardware documentation.
- Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
- ---
- arch/mips/lantiq/xway/reset.c | 120 ++++++++++++++++++++++++++++++----------
- arch/mips/lantiq/xway/sysctrl.c | 20 +++++++
- 2 files changed, 110 insertions(+), 30 deletions(-)
- --- a/arch/mips/lantiq/xway/reset.c
- +++ b/arch/mips/lantiq/xway/reset.c
- @@ -72,6 +72,8 @@
- #define RCU_USBCFG_HDSEL_BIT BIT(11)
- #define RCU_USBCFG_HOST_END_BIT BIT(10)
- #define RCU_USBCFG_SLV_END_BIT BIT(9)
- +#define RCU_USBCFG_SLV_END_BIT_AR9 BIT(17)
- +
-
- /* USB reset bits */
- #define RCU_USBRESET 0x0010
- @@ -85,6 +87,8 @@
-
- #define RCU_CFG1A 0x0038
- #define RCU_CFG1B 0x003C
- +#define RCU_CFG1_TX_PEE BIT(0)
- +#define RCU_CFG1_DIS_THR_SHIFT 15 /* Disconnect Threshold */
-
- /* USB PMU devices */
- #define PMU_AHBM BIT(15)
- @@ -306,38 +310,91 @@ static void ltq_usb_init(void)
- /* Power for USB cores 1 & 2 */
- ltq_pmu_enable(PMU_AHBM);
- ltq_pmu_enable(PMU_USB0);
- - ltq_pmu_enable(PMU_USB1);
-
- - ltq_rcu_w32(ltq_rcu_r32(RCU_CFG1A) | BIT(0), RCU_CFG1A);
- - ltq_rcu_w32(ltq_rcu_r32(RCU_CFG1B) | BIT(0), RCU_CFG1B);
- + if (of_machine_is_compatible("lantiq,ar10") ||
- + of_machine_is_compatible("lantiq,grx390") ||
- + of_machine_is_compatible("lantiq,ar9") ||
- + of_machine_is_compatible("lantiq,vr9"))
- + ltq_pmu_enable(PMU_USB1);
- +
- + if (of_machine_is_compatible("lantiq,vr9") ||
- + of_machine_is_compatible("lantiq,ar10")) {
- + ltq_rcu_w32(ltq_rcu_r32(RCU_CFG1A) | RCU_CFG1_TX_PEE |
- + 7 << RCU_CFG1_DIS_THR_SHIFT, RCU_CFG1A);
- + ltq_rcu_w32(ltq_rcu_r32(RCU_CFG1B) | RCU_CFG1_TX_PEE |
- + 7 << RCU_CFG1_DIS_THR_SHIFT, RCU_CFG1B);
- + }
-
- /* Enable USB PHY power for cores 1 & 2 */
- ltq_pmu_enable(PMU_USB0_P);
- - ltq_pmu_enable(PMU_USB1_P);
- + if (of_machine_is_compatible("lantiq,ar10") ||
- + of_machine_is_compatible("lantiq,grx390") ||
- + of_machine_is_compatible("lantiq,ar9") ||
- + of_machine_is_compatible("lantiq,vr9"))
- + ltq_pmu_enable(PMU_USB1_P);
- +
- + if (of_machine_is_compatible("lantiq,ase") ||
- + of_machine_is_compatible("lantiq,danube")) {
- + /* Configure cores to host mode */
- + ltq_rcu_w32(ltq_rcu_r32(RCU_USB1CFG) & ~RCU_USBCFG_HDSEL_BIT,
- + RCU_USB1CFG);
- +
- + /* Select DMA endianness (Host-endian: big-endian) */
- + ltq_rcu_w32((ltq_rcu_r32(RCU_USB1CFG) & ~RCU_USBCFG_SLV_END_BIT)
- + | RCU_USBCFG_HOST_END_BIT, RCU_USB1CFG);
- + }
- +
- + if (of_machine_is_compatible("lantiq,ar9")) {
- + /* Configure cores to host mode */
- + ltq_rcu_w32(ltq_rcu_r32(RCU_USB1CFG) & ~RCU_USBCFG_HDSEL_BIT,
- + RCU_USB1CFG);
- + ltq_rcu_w32(ltq_rcu_r32(RCU_USB2CFG) & ~RCU_USBCFG_HDSEL_BIT,
- + RCU_USB2CFG);
- +
- + /* Select DMA endianness (Host-endian: big-endian) */
- + ltq_rcu_w32((ltq_rcu_r32(RCU_USB1CFG) & ~RCU_USBCFG_SLV_END_BIT_AR9)
- + | RCU_USBCFG_HOST_END_BIT, RCU_USB1CFG);
- + ltq_rcu_w32(ltq_rcu_r32((RCU_USB2CFG) & ~RCU_USBCFG_SLV_END_BIT_AR9)
- + | RCU_USBCFG_HOST_END_BIT, RCU_USB2CFG);
- + }
- +
- + if (of_machine_is_compatible("lantiq,vr9") ||
- + of_machine_is_compatible("lantiq,ar10")) {
- + /* Configure cores to host mode */
- + ltq_rcu_w32(ltq_rcu_r32(RCU_USB1CFG) & ~RCU_USBCFG_HDSEL_BIT,
- + RCU_USB1CFG);
- + ltq_rcu_w32(ltq_rcu_r32(RCU_USB2CFG) & ~RCU_USBCFG_HDSEL_BIT,
- + RCU_USB2CFG);
- +
- + /* Select DMA endianness (Host-endian: big-endian) */
- + ltq_rcu_w32((ltq_rcu_r32(RCU_USB1CFG) & ~RCU_USBCFG_SLV_END_BIT)
- + | RCU_USBCFG_HOST_END_BIT, RCU_USB1CFG);
- + ltq_rcu_w32(ltq_rcu_r32((RCU_USB2CFG) & ~RCU_USBCFG_SLV_END_BIT)
- + | RCU_USBCFG_HOST_END_BIT, RCU_USB2CFG);
- + }
- +
- + if (of_machine_is_compatible("lantiq,ar9")) {
- + /* Hard reset USB state machines */
- + ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET)
- + | USBRESET_BIT | BIT(28), RCU_USBRESET);
- + udelay(50 * 1000);
- + ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET)
- + & ~(USBRESET_BIT | BIT(28)), RCU_USBRESET);
- + } else {
- + /* Hard reset USB state machines */
- + ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET) | USBRESET_BIT, RCU_USBRESET);
- + udelay(50 * 1000);
- + ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET) & ~USBRESET_BIT, RCU_USBRESET);
- + }
-
- - /* Configure cores to host mode */
- - ltq_rcu_w32(ltq_rcu_r32(RCU_USB1CFG) & ~RCU_USBCFG_HDSEL_BIT,
- - RCU_USB1CFG);
- - ltq_rcu_w32(ltq_rcu_r32(RCU_USB2CFG) & ~RCU_USBCFG_HDSEL_BIT,
- - RCU_USB2CFG);
- -
- - /* Select DMA endianness (Host-endian: big-endian) */
- - ltq_rcu_w32((ltq_rcu_r32(RCU_USB1CFG) & ~RCU_USBCFG_SLV_END_BIT)
- - | RCU_USBCFG_HOST_END_BIT, RCU_USB1CFG);
- - ltq_rcu_w32(ltq_rcu_r32((RCU_USB2CFG) & ~RCU_USBCFG_SLV_END_BIT)
- - | RCU_USBCFG_HOST_END_BIT, RCU_USB2CFG);
- -
- - /* Hard reset USB state machines */
- - ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET) | USBRESET_BIT, RCU_USBRESET);
- - udelay(50 * 1000);
- - ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET) & ~USBRESET_BIT, RCU_USBRESET);
- -
- - /* Soft reset USB state machines */
- - ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET2)
- - | USB1RESET_BIT | USB2RESET_BIT, RCU_USBRESET2);
- - udelay(50 * 1000);
- - ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET2)
- - & ~(USB1RESET_BIT | USB2RESET_BIT), RCU_USBRESET2);
- + if (of_machine_is_compatible("lantiq,vr9")) {
- + /* Soft reset USB state machines */
- + ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET2)
- + | USB1RESET_BIT | USB2RESET_BIT, RCU_USBRESET2);
- + udelay(50 * 1000);
- + ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET2)
- + & ~(USB1RESET_BIT | USB2RESET_BIT), RCU_USBRESET2);
- + }
- }
-
- static int __init mips_reboot_setup(void)
- @@ -363,8 +420,11 @@ static int __init mips_reboot_setup(void
- if (!ltq_rcu_membase)
- panic("Failed to remap core memory");
-
- - if (of_machine_is_compatible("lantiq,ar9") ||
- - of_machine_is_compatible("lantiq,vr9"))
- + if (of_machine_is_compatible("lantiq,danube") ||
- + of_machine_is_compatible("lantiq,ase") ||
- + of_machine_is_compatible("lantiq,ar9") ||
- + of_machine_is_compatible("lantiq,vr9") ||
- + of_machine_is_compatible("lantiq,ar10"))
- ltq_usb_init();
-
- if (of_machine_is_compatible("lantiq,vr9"))
- --- a/arch/mips/lantiq/xway/sysctrl.c
- +++ b/arch/mips/lantiq/xway/sysctrl.c
- @@ -254,6 +254,25 @@ static void pmu_disable(struct clk *clk)
- pr_warn("deactivating PMU module failed!");
- }
-
- +static void usb_set_clock(void)
- +{
- + unsigned int val = ltq_cgu_r32(ifccr);
- +
- + if (of_machine_is_compatible("lantiq,ar10") ||
- + of_machine_is_compatible("lantiq,grx390")) {
- + val &= ~0x03; /* XTAL divided by 3 */
- + } else if (of_machine_is_compatible("lantiq,ar9") ||
- + of_machine_is_compatible("lantiq,vr9")) {
- + /* TODO: this depends on the XTAL frequency */
- + val |= 0x03; /* XTAL divided by 3 */
- + } else if (of_machine_is_compatible("lantiq,ase")) {
- + val |= 0x20; /* from XTAL */
- + } else if (of_machine_is_compatible("lantiq,danube")) {
- + val |= 0x30; /* 12 MHz, generated from 36 MHz */
- + }
- + ltq_cgu_w32(val, ifccr);
- +}
- +
- /* the pci enable helper */
- static int pci_enable(struct clk *clk)
- {
- @@ -608,4 +627,5 @@ void __init ltq_soc_init(void)
-
- if (of_machine_is_compatible("lantiq,vr9"))
- xbar_fpi_burst_disable();
- + usb_set_clock();
- }
|