Commit ede4d5e3872d04c75a30c5e234786b012f1c6d34
Committed by
Marek Vasut
1 parent
a405764c1e
Exists in
v2017.01-smarct4x
and in
40 other branches
usb: ehci: rmobile: Add support ehci host driver of rmobile SoCs
The rmobile SoC has usb host controller. This supports USB controllers listed in the R8A7790, R8A7791 and R8A7740. Signed-off-by: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com> Reviewed-by: Marek Vasut <marex@denx.de>
Showing 3 changed files with 278 additions and 0 deletions Side-by-side Diff
arch/arm/include/asm/arch-rmobile/ehci-rmobile.h
1 | +/* | |
2 | + * Copyright (C) 2013,2014 Renesas Electronics Corporation | |
3 | + * Copyright (C) 2014 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com> | |
4 | + * | |
5 | + * SPDX-License-Identifier: GPL-2.0 | |
6 | + */ | |
7 | + | |
8 | +#ifndef __EHCI_RMOBILE_H__ | |
9 | +#define __EHCI_RMOBILE_H__ | |
10 | + | |
11 | +/* Register offset */ | |
12 | +#define OHCI_OFFSET 0x00 | |
13 | +#define OHCI_SIZE 0x1000 | |
14 | +#define EHCI_OFFSET 0x1000 | |
15 | +#define EHCI_SIZE 0x1000 | |
16 | + | |
17 | +#define EHCI_USBCMD (EHCI_OFFSET + 0x0020) | |
18 | + | |
19 | +/* USBCTR */ | |
20 | +#define DIRPD (1 << 8) | |
21 | +#define PLL_RST (1 << 2) | |
22 | +#define PCICLK_MASK (1 << 1) | |
23 | +#define USBH_RST (1 << 0) | |
24 | + | |
25 | +/* CMND_STS */ | |
26 | +#define SERREN (1 << 8) | |
27 | +#define PERREN (1 << 6) | |
28 | +#define MASTEREN (1 << 2) | |
29 | +#define MEMEN (1 << 1) | |
30 | + | |
31 | +/* PCIAHB_WIN1_CTR and PCIAHB_WIN2_CTR */ | |
32 | +#define PCIAHB_WIN_PREFETCH ((1 << 1)|(1 << 0)) | |
33 | + | |
34 | +/* AHBPCI_WIN1_CTR */ | |
35 | +#define PCIWIN1_PCICMD ((1 << 3)|(1 << 1)) | |
36 | +#define AHB_CFG_AHBPCI 0x40000000 | |
37 | +#define AHB_CFG_HOST 0x80000000 | |
38 | + | |
39 | +/* AHBPCI_WIN2_CTR */ | |
40 | +#define PCIWIN2_PCICMD ((1 << 2)|(1 << 1)) | |
41 | + | |
42 | +/* PCI_INT_ENABLE */ | |
43 | +#define USBH_PMEEN (1 << 19) | |
44 | +#define USBH_INTBEN (1 << 17) | |
45 | +#define USBH_INTAEN (1 << 16) | |
46 | + | |
47 | +/* AHB_BUS_CTR */ | |
48 | +#define SMODE_READY_CTR (1 << 17) | |
49 | +#define SMODE_READ_BURST (1 << 16) | |
50 | +#define MMODE_HBUSREQ (1 << 7) | |
51 | +#define MMODE_BOUNDARY ((1 << 6)|(1 << 5)) | |
52 | +#define MMODE_BURST_WIDTH ((1 << 4)|(1 << 3)) | |
53 | +#define MMODE_SINGLE_MODE ((1 << 4)|(1 << 3)) | |
54 | +#define MMODE_WR_INCR (1 << 2) | |
55 | +#define MMODE_BYTE_BURST (1 << 1) | |
56 | +#define MMODE_HTRANS (1 << 0) | |
57 | + | |
58 | +/* PCI_ARBITER_CTR */ | |
59 | +#define PCIBUS_PARK_TIMER 0x00FF0000 | |
60 | +#define PCIBUS_PARK_TIMER_SET 0x00070000 | |
61 | +#define PCIBP_MODE (1 << 12) | |
62 | +#define PCIREQ7 (1 << 7) | |
63 | +#define PCIREQ6 (1 << 6) | |
64 | +#define PCIREQ5 (1 << 5) | |
65 | +#define PCIREQ4 (1 << 4) | |
66 | +#define PCIREQ3 (1 << 3) | |
67 | +#define PCIREQ2 (1 << 2) | |
68 | +#define PCIREQ1 (1 << 1) | |
69 | +#define PCIREQ0 (1 << 0) | |
70 | + | |
71 | +#define SMSTPCR7 0xE615014C | |
72 | +#define SMSTPCR703 (1 << 3) | |
73 | + | |
74 | +/* Init AHB master and slave functions of the host logic */ | |
75 | +#define AHB_BUS_CTR_INIT \ | |
76 | + (SMODE_READY_CTR | MMODE_HBUSREQ | MMODE_WR_INCR | \ | |
77 | + MMODE_BYTE_BURST | MMODE_HTRANS) | |
78 | + | |
79 | +#define USBCTR_WIN_SIZE_1GB 0x800 | |
80 | + | |
81 | +/* PCI Configuration Registers */ | |
82 | +#define PCI_CONF_OHCI_OFFSET 0x10000 | |
83 | +#define PCI_CONF_EHCI_OFFSET 0x10100 | |
84 | +struct ahb_pciconf { | |
85 | + u32 vid_did; | |
86 | + u32 cmnd_sts; | |
87 | + u32 rev; | |
88 | + u32 cache_line; | |
89 | + u32 basead; | |
90 | +}; | |
91 | + | |
92 | +/* PCI Configuration Registers for AHB-PCI Bridge Registers */ | |
93 | +#define PCI_CONF_AHBPCI_OFFSET 0x10000 | |
94 | +struct ahbconf_pci_bridge { | |
95 | + u32 vid_did; /* 0x00 */ | |
96 | + u32 cmnd_sts; | |
97 | + u32 revid_cc; | |
98 | + u32 cls_lt_ht_bist; | |
99 | + u32 basead; /* 0x10 */ | |
100 | + u32 win1_basead; | |
101 | + u32 win2_basead; | |
102 | + u32 dummy0[5]; | |
103 | + u32 ssvdi_ssid; /* 0x2C */ | |
104 | + u32 dummy1[4]; | |
105 | + u32 intr_line_pin; | |
106 | +}; | |
107 | + | |
108 | +/* AHB-PCI Bridge PCI Communication Registers */ | |
109 | +#define AHBPCI_OFFSET 0x10800 | |
110 | +struct ahbcom_pci_bridge { | |
111 | + u32 pciahb_win1_ctr; /* 0x00 */ | |
112 | + u32 pciahb_win2_ctr; | |
113 | + u32 pciahb_dct_ctr; | |
114 | + u32 dummy0; | |
115 | + u32 ahbpci_win1_ctr; /* 0x10 */ | |
116 | + u32 ahbpci_win2_ctr; | |
117 | + u32 dummy1; | |
118 | + u32 ahbpci_dct_ctr; | |
119 | + u32 pci_int_enable; /* 0x20 */ | |
120 | + u32 pci_int_status; | |
121 | + u32 dummy2[2]; | |
122 | + u32 ahb_bus_ctr; /* 0x30 */ | |
123 | + u32 usbctr; | |
124 | + u32 dummy3[2]; | |
125 | + u32 pci_arbiter_ctr; /* 0x40 */ | |
126 | + u32 dummy4; | |
127 | + u32 pci_unit_rev; /* 0x48 */ | |
128 | +}; | |
129 | + | |
130 | +struct rmobile_ehci_reg { | |
131 | + u32 hciversion; /* hciversion/caplength */ | |
132 | + u32 hcsparams; /* hcsparams */ | |
133 | + u32 hccparams; /* hccparams */ | |
134 | + u32 hcsp_portroute; /* hcsp_portroute */ | |
135 | + u32 usbcmd; /* usbcmd */ | |
136 | + u32 usbsts; /* usbsts */ | |
137 | + u32 usbintr; /* usbintr */ | |
138 | + u32 frindex; /* frindex */ | |
139 | + u32 ctrldssegment; /* ctrldssegment */ | |
140 | + u32 periodiclistbase; /* periodiclistbase */ | |
141 | + u32 asynclistaddr; /* asynclistaddr */ | |
142 | + u32 dummy[9]; | |
143 | + u32 configflag; /* configflag */ | |
144 | + u32 portsc; /* portsc */ | |
145 | +}; | |
146 | + | |
147 | +#endif /* __EHCI_RMOBILE_H__ */ |
drivers/usb/host/Makefile
... | ... | @@ -36,6 +36,7 @@ |
36 | 36 | obj-$(CONFIG_USB_EHCI_SPEAR) += ehci-spear.o |
37 | 37 | obj-$(CONFIG_USB_EHCI_TEGRA) += ehci-tegra.o |
38 | 38 | obj-$(CONFIG_USB_EHCI_VCT) += ehci-vct.o |
39 | +obj-$(CONFIG_USB_EHCI_RMOBILE) += ehci-rmobile.o | |
39 | 40 | |
40 | 41 | # xhci |
41 | 42 | obj-$(CONFIG_USB_XHCI) += xhci.o xhci-mem.o xhci-ring.o |
drivers/usb/host/ehci-rmobile.c
1 | +/* | |
2 | + * EHCI HCD (Host Controller Driver) for USB. | |
3 | + * | |
4 | + * Copyright (C) 2013,2014 Renesas Electronics Corporation | |
5 | + * Copyright (C) 2014 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com> | |
6 | + * | |
7 | + * SPDX-License-Identifier: GPL-2.0 | |
8 | + */ | |
9 | + | |
10 | +#include <common.h> | |
11 | +#include <asm/io.h> | |
12 | +#include <asm/arch/ehci-rmobile.h> | |
13 | +#include "ehci.h" | |
14 | + | |
15 | +#if defined(CONFIG_R8A7740) | |
16 | +static u32 usb_base_address[CONFIG_USB_MAX_CONTROLLER_COUNT] = { | |
17 | + 0xC6700000 | |
18 | +}; | |
19 | +#elif defined(CONFIG_R8A7790) | |
20 | +static u32 usb_base_address[CONFIG_USB_MAX_CONTROLLER_COUNT] = { | |
21 | + 0xEE080000, /* USB0 (EHCI) */ | |
22 | + 0xEE0A0000, /* USB1 */ | |
23 | + 0xEE0C0000, /* USB2 */ | |
24 | + 0xEE000000 /* USB3 (USB3.0 Host)*/ | |
25 | +}; | |
26 | +#elif defined(CONFIG_R8A7791) | |
27 | +static u32 usb_base_address[CONFIG_USB_MAX_CONTROLLER_COUNT] = { | |
28 | + 0xEE080000, /* USB0 (EHCI) */ | |
29 | + 0xEE0C0000, /* USB1 */ | |
30 | + 0xEE000000 /* USB3 (USB3.0 Host)*/ | |
31 | +}; | |
32 | +#else | |
33 | +#error rmobile EHCI USB driver not supported on this platform | |
34 | +#endif | |
35 | + | |
36 | +int ehci_hcd_stop(int index) | |
37 | +{ | |
38 | + int i; | |
39 | + u32 base; | |
40 | + struct ahbcom_pci_bridge *ahbcom_pci; | |
41 | + | |
42 | + base = usb_base_address[index]; | |
43 | + ahbcom_pci = (struct ahbcom_pci_bridge *)(base + AHBPCI_OFFSET); | |
44 | + writel(0, &ahbcom_pci->ahb_bus_ctr); | |
45 | + | |
46 | + /* reset ehci */ | |
47 | + setbits_le32(base + EHCI_USBCMD, CMD_RESET); | |
48 | + for (i = 100; i > 0; i--) { | |
49 | + if (!(readl(base + EHCI_USBCMD) & CMD_RESET)) | |
50 | + break; | |
51 | + udelay(100); | |
52 | + } | |
53 | + | |
54 | + if (!i) | |
55 | + printf("error : ehci(%d) reset failed.\n", index); | |
56 | + | |
57 | + if (index == (CONFIG_USB_MAX_CONTROLLER_COUNT - 1)) | |
58 | + setbits_le32(SMSTPCR7, SMSTPCR703); | |
59 | + | |
60 | + return 0; | |
61 | +} | |
62 | + | |
63 | +int ehci_hcd_init(int index, enum usb_init_type init, | |
64 | + struct ehci_hccr **hccr, struct ehci_hcor **hcor) | |
65 | +{ | |
66 | + u32 base; | |
67 | + u32 phys_base; | |
68 | + struct rmobile_ehci_reg *rehci; | |
69 | + struct ahbcom_pci_bridge *ahbcom_pci; | |
70 | + struct ahbconf_pci_bridge *ahbconf_pci; | |
71 | + struct ahb_pciconf *ahb_pciconf_ohci; | |
72 | + struct ahb_pciconf *ahb_pciconf_ehci; | |
73 | + uint32_t cap_base; | |
74 | + | |
75 | + base = usb_base_address[index]; | |
76 | + phys_base = base; | |
77 | + if (index == 0) | |
78 | + clrbits_le32(SMSTPCR7, SMSTPCR703); | |
79 | + | |
80 | + rehci = (struct rmobile_ehci_reg *)(base + EHCI_OFFSET); | |
81 | + ahbcom_pci = (struct ahbcom_pci_bridge *)(base + AHBPCI_OFFSET); | |
82 | + ahbconf_pci = | |
83 | + (struct ahbconf_pci_bridge *)(base + PCI_CONF_AHBPCI_OFFSET); | |
84 | + ahb_pciconf_ohci = (struct ahb_pciconf *)(base + PCI_CONF_OHCI_OFFSET); | |
85 | + ahb_pciconf_ehci = (struct ahb_pciconf *)(base + PCI_CONF_EHCI_OFFSET); | |
86 | + | |
87 | + /* Clock & Reset & Direct Power Down */ | |
88 | + clrsetbits_le32(&ahbcom_pci->usbctr, | |
89 | + (DIRPD | PCICLK_MASK | USBH_RST), USBCTR_WIN_SIZE_1GB); | |
90 | + clrbits_le32(&ahbcom_pci->usbctr, PLL_RST); | |
91 | + | |
92 | + /* AHB-PCI Bridge Communication Registers */ | |
93 | + writel(AHB_BUS_CTR_INIT, &ahbcom_pci->ahb_bus_ctr); | |
94 | + writel((CONFIG_SYS_SDRAM_BASE & 0xf0000000) | PCIAHB_WIN_PREFETCH, | |
95 | + &ahbcom_pci->pciahb_win1_ctr); | |
96 | + writel(0xf0000000 | PCIAHB_WIN_PREFETCH, | |
97 | + &ahbcom_pci->pciahb_win2_ctr); | |
98 | + writel(phys_base | PCIWIN2_PCICMD, &ahbcom_pci->ahbpci_win2_ctr); | |
99 | + | |
100 | + setbits_le32(&ahbcom_pci->pci_arbiter_ctr, | |
101 | + PCIBP_MODE | PCIREQ1 | PCIREQ0); | |
102 | + | |
103 | + /* PCI Configuration Registers for AHBPCI */ | |
104 | + writel(PCIWIN1_PCICMD | AHB_CFG_AHBPCI, | |
105 | + &ahbcom_pci->ahbpci_win1_ctr); | |
106 | + writel(phys_base + AHBPCI_OFFSET, &ahbconf_pci->basead); | |
107 | + writel(CONFIG_SYS_SDRAM_BASE & 0xf0000000, &ahbconf_pci->win1_basead); | |
108 | + writel(0xf0000000, &ahbconf_pci->win2_basead); | |
109 | + writel(SERREN | PERREN | MASTEREN | MEMEN, | |
110 | + &ahbconf_pci->cmnd_sts); | |
111 | + | |
112 | + /* PCI Configuration Registers for EHCI */ | |
113 | + writel(PCIWIN1_PCICMD | AHB_CFG_HOST, &ahbcom_pci->ahbpci_win1_ctr); | |
114 | + writel(phys_base + OHCI_OFFSET, &ahb_pciconf_ohci->basead); | |
115 | + writel(phys_base + EHCI_OFFSET, &ahb_pciconf_ehci->basead); | |
116 | + writel(SERREN | PERREN | MASTEREN | MEMEN, | |
117 | + &ahb_pciconf_ohci->cmnd_sts); | |
118 | + writel(SERREN | PERREN | MASTEREN | MEMEN, | |
119 | + &ahb_pciconf_ehci->cmnd_sts); | |
120 | + | |
121 | + /* Enable PCI interrupt */ | |
122 | + setbits_le32(&ahbcom_pci->pci_int_enable, | |
123 | + USBH_PMEEN | USBH_INTBEN | USBH_INTAEN); | |
124 | + | |
125 | + *hccr = (struct ehci_hccr *)((uint32_t)&rehci->hciversion); | |
126 | + cap_base = ehci_readl(&(*hccr)->cr_capbase); | |
127 | + *hcor = (struct ehci_hcor *)((uint32_t)*hccr + HC_LENGTH(cap_base)); | |
128 | + | |
129 | + return 0; | |
130 | +} |