diff options
author | Manuel Lauss <manuel.lauss@googlemail.com> | 2011-11-01 15:03:30 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2011-12-07 17:02:05 -0500 |
commit | 809f36c6f4a0568178c909ff1096ca83eae33f7d (patch) | |
tree | 6b99b1ac701c0bd581811c39e85856f3bcbda22d /drivers | |
parent | fb469f084fdf1631e31d87270f5263c20a7f5cd6 (diff) |
MIPS: Alchemy: Au1300 SoC support
Add basic support for the Au1300 variant(s):
- New GPIO/Interrupt controller
- DBDMA ids
- USB setup
- MMC support
- enable various PSC drivers
- detection code.
Signed-off-by: Manuel Lauss <manuel.lauss@googlemail.com>
To: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/2866/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/i2c/busses/Kconfig | 4 | ||||
-rw-r--r-- | drivers/mmc/host/au1xmmc.c | 45 | ||||
-rw-r--r-- | drivers/spi/Kconfig | 4 | ||||
-rw-r--r-- | drivers/usb/host/alchemy-common.c | 277 | ||||
-rw-r--r-- | drivers/usb/host/ohci-au1xxx.c | 13 | ||||
-rw-r--r-- | drivers/video/Kconfig | 8 |
6 files changed, 322 insertions, 29 deletions
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index a3afac4be73..cbe7a2fb779 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig | |||
@@ -299,11 +299,11 @@ config I2C_AT91 | |||
299 | unless your system can cope with those limitations. | 299 | unless your system can cope with those limitations. |
300 | 300 | ||
301 | config I2C_AU1550 | 301 | config I2C_AU1550 |
302 | tristate "Au1550/Au1200 SMBus interface" | 302 | tristate "Au1550/Au1200/Au1300 SMBus interface" |
303 | depends on MIPS_ALCHEMY | 303 | depends on MIPS_ALCHEMY |
304 | help | 304 | help |
305 | If you say yes to this option, support will be included for the | 305 | If you say yes to this option, support will be included for the |
306 | Au1550 and Au1200 SMBus interface. | 306 | Au1550/Au1200/Au1300 SMBus interface. |
307 | 307 | ||
308 | This driver can also be built as a module. If so, the module | 308 | This driver can also be built as a module. If so, the module |
309 | will be called i2c-au1550. | 309 | will be called i2c-au1550. |
diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c index 5d3b9ae6452..dbd0c8a4e98 100644 --- a/drivers/mmc/host/au1xmmc.c +++ b/drivers/mmc/host/au1xmmc.c | |||
@@ -153,6 +153,7 @@ static inline int has_dbdma(void) | |||
153 | { | 153 | { |
154 | switch (alchemy_get_cputype()) { | 154 | switch (alchemy_get_cputype()) { |
155 | case ALCHEMY_CPU_AU1200: | 155 | case ALCHEMY_CPU_AU1200: |
156 | case ALCHEMY_CPU_AU1300: | ||
156 | return 1; | 157 | return 1; |
157 | default: | 158 | default: |
158 | return 0; | 159 | return 0; |
@@ -768,11 +769,15 @@ static void au1xmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
768 | 769 | ||
769 | config2 = au_readl(HOST_CONFIG2(host)); | 770 | config2 = au_readl(HOST_CONFIG2(host)); |
770 | switch (ios->bus_width) { | 771 | switch (ios->bus_width) { |
772 | case MMC_BUS_WIDTH_8: | ||
773 | config2 |= SD_CONFIG2_BB; | ||
774 | break; | ||
771 | case MMC_BUS_WIDTH_4: | 775 | case MMC_BUS_WIDTH_4: |
776 | config2 &= ~SD_CONFIG2_BB; | ||
772 | config2 |= SD_CONFIG2_WB; | 777 | config2 |= SD_CONFIG2_WB; |
773 | break; | 778 | break; |
774 | case MMC_BUS_WIDTH_1: | 779 | case MMC_BUS_WIDTH_1: |
775 | config2 &= ~SD_CONFIG2_WB; | 780 | config2 &= ~(SD_CONFIG2_WB | SD_CONFIG2_BB); |
776 | break; | 781 | break; |
777 | } | 782 | } |
778 | au_writel(config2, HOST_CONFIG2(host)); | 783 | au_writel(config2, HOST_CONFIG2(host)); |
@@ -943,7 +948,7 @@ static int __devinit au1xmmc_probe(struct platform_device *pdev) | |||
943 | struct mmc_host *mmc; | 948 | struct mmc_host *mmc; |
944 | struct au1xmmc_host *host; | 949 | struct au1xmmc_host *host; |
945 | struct resource *r; | 950 | struct resource *r; |
946 | int ret; | 951 | int ret, iflag; |
947 | 952 | ||
948 | mmc = mmc_alloc_host(sizeof(struct au1xmmc_host), &pdev->dev); | 953 | mmc = mmc_alloc_host(sizeof(struct au1xmmc_host), &pdev->dev); |
949 | if (!mmc) { | 954 | if (!mmc) { |
@@ -982,37 +987,43 @@ static int __devinit au1xmmc_probe(struct platform_device *pdev) | |||
982 | dev_err(&pdev->dev, "no IRQ defined\n"); | 987 | dev_err(&pdev->dev, "no IRQ defined\n"); |
983 | goto out3; | 988 | goto out3; |
984 | } | 989 | } |
985 | |||
986 | host->irq = r->start; | 990 | host->irq = r->start; |
987 | /* IRQ is shared among both SD controllers */ | ||
988 | ret = request_irq(host->irq, au1xmmc_irq, IRQF_SHARED, | ||
989 | DRIVER_NAME, host); | ||
990 | if (ret) { | ||
991 | dev_err(&pdev->dev, "cannot grab IRQ\n"); | ||
992 | goto out3; | ||
993 | } | ||
994 | 991 | ||
995 | mmc->ops = &au1xmmc_ops; | 992 | mmc->ops = &au1xmmc_ops; |
996 | 993 | ||
997 | mmc->f_min = 450000; | 994 | mmc->f_min = 450000; |
998 | mmc->f_max = 24000000; | 995 | mmc->f_max = 24000000; |
999 | 996 | ||
997 | mmc->max_blk_size = 2048; | ||
998 | mmc->max_blk_count = 512; | ||
999 | |||
1000 | mmc->ocr_avail = AU1XMMC_OCR; | ||
1001 | mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ; | ||
1002 | mmc->max_segs = AU1XMMC_DESCRIPTOR_COUNT; | ||
1003 | |||
1004 | iflag = IRQF_SHARED; /* Au1100/Au1200: one int for both ctrls */ | ||
1005 | |||
1000 | switch (alchemy_get_cputype()) { | 1006 | switch (alchemy_get_cputype()) { |
1001 | case ALCHEMY_CPU_AU1100: | 1007 | case ALCHEMY_CPU_AU1100: |
1002 | mmc->max_seg_size = AU1100_MMC_DESCRIPTOR_SIZE; | 1008 | mmc->max_seg_size = AU1100_MMC_DESCRIPTOR_SIZE; |
1003 | mmc->max_segs = AU1XMMC_DESCRIPTOR_COUNT; | ||
1004 | break; | 1009 | break; |
1005 | case ALCHEMY_CPU_AU1200: | 1010 | case ALCHEMY_CPU_AU1200: |
1006 | mmc->max_seg_size = AU1200_MMC_DESCRIPTOR_SIZE; | 1011 | mmc->max_seg_size = AU1200_MMC_DESCRIPTOR_SIZE; |
1007 | mmc->max_segs = AU1XMMC_DESCRIPTOR_COUNT; | 1012 | break; |
1013 | case ALCHEMY_CPU_AU1300: | ||
1014 | iflag = 0; /* nothing is shared */ | ||
1015 | mmc->max_seg_size = AU1200_MMC_DESCRIPTOR_SIZE; | ||
1016 | mmc->f_max = 52000000; | ||
1017 | if (host->ioarea->start == AU1100_SD0_PHYS_ADDR) | ||
1018 | mmc->caps |= MMC_CAP_8_BIT_DATA; | ||
1008 | break; | 1019 | break; |
1009 | } | 1020 | } |
1010 | 1021 | ||
1011 | mmc->max_blk_size = 2048; | 1022 | ret = request_irq(host->irq, au1xmmc_irq, iflag, DRIVER_NAME, host); |
1012 | mmc->max_blk_count = 512; | 1023 | if (ret) { |
1013 | 1024 | dev_err(&pdev->dev, "cannot grab IRQ\n"); | |
1014 | mmc->ocr_avail = AU1XMMC_OCR; | 1025 | goto out3; |
1015 | mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ; | 1026 | } |
1016 | 1027 | ||
1017 | host->status = HOST_S_IDLE; | 1028 | host->status = HOST_S_IDLE; |
1018 | 1029 | ||
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index a1fd73df541..369e092bf3d 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig | |||
@@ -87,12 +87,12 @@ config SPI_BFIN_SPORT | |||
87 | Enable support for a SPI bus via the Blackfin SPORT peripheral. | 87 | Enable support for a SPI bus via the Blackfin SPORT peripheral. |
88 | 88 | ||
89 | config SPI_AU1550 | 89 | config SPI_AU1550 |
90 | tristate "Au1550/Au12x0 SPI Controller" | 90 | tristate "Au1550/Au1200/Au1300 SPI Controller" |
91 | depends on MIPS_ALCHEMY && EXPERIMENTAL | 91 | depends on MIPS_ALCHEMY && EXPERIMENTAL |
92 | select SPI_BITBANG | 92 | select SPI_BITBANG |
93 | help | 93 | help |
94 | If you say yes to this option, support will be included for the | 94 | If you say yes to this option, support will be included for the |
95 | Au1550 SPI controller (may also work with Au1200,Au1210,Au1250). | 95 | PSC SPI controller found on Au1550, Au1200 and Au1300 series. |
96 | 96 | ||
97 | config SPI_BITBANG | 97 | config SPI_BITBANG |
98 | tristate "Utilities for Bitbanging SPI masters" | 98 | tristate "Utilities for Bitbanging SPI masters" |
diff --git a/drivers/usb/host/alchemy-common.c b/drivers/usb/host/alchemy-common.c index b4192c964d0..936af8359fb 100644 --- a/drivers/usb/host/alchemy-common.c +++ b/drivers/usb/host/alchemy-common.c | |||
@@ -52,9 +52,263 @@ | |||
52 | USBCFG_EBE | USBCFG_EME | USBCFG_OBE | \ | 52 | USBCFG_EBE | USBCFG_EME | USBCFG_OBE | \ |
53 | USBCFG_OME) | 53 | USBCFG_OME) |
54 | 54 | ||
55 | /* Au1300 USB config registers */ | ||
56 | #define USB_DWC_CTRL1 0x00 | ||
57 | #define USB_DWC_CTRL2 0x04 | ||
58 | #define USB_VBUS_TIMER 0x10 | ||
59 | #define USB_SBUS_CTRL 0x14 | ||
60 | #define USB_MSR_ERR 0x18 | ||
61 | #define USB_DWC_CTRL3 0x1C | ||
62 | #define USB_DWC_CTRL4 0x20 | ||
63 | #define USB_OTG_STATUS 0x28 | ||
64 | #define USB_DWC_CTRL5 0x2C | ||
65 | #define USB_DWC_CTRL6 0x30 | ||
66 | #define USB_DWC_CTRL7 0x34 | ||
67 | #define USB_PHY_STATUS 0xC0 | ||
68 | #define USB_INT_STATUS 0xC4 | ||
69 | #define USB_INT_ENABLE 0xC8 | ||
70 | |||
71 | #define USB_DWC_CTRL1_OTGD 0x04 /* set to DISable OTG */ | ||
72 | #define USB_DWC_CTRL1_HSTRS 0x02 /* set to ENable EHCI */ | ||
73 | #define USB_DWC_CTRL1_DCRS 0x01 /* set to ENable UDC */ | ||
74 | |||
75 | #define USB_DWC_CTRL2_PHY1RS 0x04 /* set to enable PHY1 */ | ||
76 | #define USB_DWC_CTRL2_PHY0RS 0x02 /* set to enable PHY0 */ | ||
77 | #define USB_DWC_CTRL2_PHYRS 0x01 /* set to enable PHY */ | ||
78 | |||
79 | #define USB_DWC_CTRL3_OHCI1_CKEN (1 << 19) | ||
80 | #define USB_DWC_CTRL3_OHCI0_CKEN (1 << 18) | ||
81 | #define USB_DWC_CTRL3_EHCI0_CKEN (1 << 17) | ||
82 | #define USB_DWC_CTRL3_OTG0_CKEN (1 << 16) | ||
83 | |||
84 | #define USB_SBUS_CTRL_SBCA 0x04 /* coherent access */ | ||
85 | |||
86 | #define USB_INTEN_FORCE 0x20 | ||
87 | #define USB_INTEN_PHY 0x10 | ||
88 | #define USB_INTEN_UDC 0x08 | ||
89 | #define USB_INTEN_EHCI 0x04 | ||
90 | #define USB_INTEN_OHCI1 0x02 | ||
91 | #define USB_INTEN_OHCI0 0x01 | ||
55 | 92 | ||
56 | static DEFINE_SPINLOCK(alchemy_usb_lock); | 93 | static DEFINE_SPINLOCK(alchemy_usb_lock); |
57 | 94 | ||
95 | static inline void __au1300_usb_phyctl(void __iomem *base, int enable) | ||
96 | { | ||
97 | unsigned long r, s; | ||
98 | |||
99 | r = __raw_readl(base + USB_DWC_CTRL2); | ||
100 | s = __raw_readl(base + USB_DWC_CTRL3); | ||
101 | |||
102 | s &= USB_DWC_CTRL3_OHCI1_CKEN | USB_DWC_CTRL3_OHCI0_CKEN | | ||
103 | USB_DWC_CTRL3_EHCI0_CKEN | USB_DWC_CTRL3_OTG0_CKEN; | ||
104 | |||
105 | if (enable) { | ||
106 | /* simply enable all PHYs */ | ||
107 | r |= USB_DWC_CTRL2_PHY1RS | USB_DWC_CTRL2_PHY0RS | | ||
108 | USB_DWC_CTRL2_PHYRS; | ||
109 | __raw_writel(r, base + USB_DWC_CTRL2); | ||
110 | wmb(); | ||
111 | } else if (!s) { | ||
112 | /* no USB block active, do disable all PHYs */ | ||
113 | r &= ~(USB_DWC_CTRL2_PHY1RS | USB_DWC_CTRL2_PHY0RS | | ||
114 | USB_DWC_CTRL2_PHYRS); | ||
115 | __raw_writel(r, base + USB_DWC_CTRL2); | ||
116 | wmb(); | ||
117 | } | ||
118 | } | ||
119 | |||
120 | static inline void __au1300_ohci_control(void __iomem *base, int enable, int id) | ||
121 | { | ||
122 | unsigned long r; | ||
123 | |||
124 | if (enable) { | ||
125 | __raw_writel(1, base + USB_DWC_CTRL7); /* start OHCI clock */ | ||
126 | wmb(); | ||
127 | |||
128 | r = __raw_readl(base + USB_DWC_CTRL3); /* enable OHCI block */ | ||
129 | r |= (id == 0) ? USB_DWC_CTRL3_OHCI0_CKEN | ||
130 | : USB_DWC_CTRL3_OHCI1_CKEN; | ||
131 | __raw_writel(r, base + USB_DWC_CTRL3); | ||
132 | wmb(); | ||
133 | |||
134 | __au1300_usb_phyctl(base, enable); /* power up the PHYs */ | ||
135 | |||
136 | r = __raw_readl(base + USB_INT_ENABLE); | ||
137 | r |= (id == 0) ? USB_INTEN_OHCI0 : USB_INTEN_OHCI1; | ||
138 | __raw_writel(r, base + USB_INT_ENABLE); | ||
139 | wmb(); | ||
140 | |||
141 | /* reset the OHCI start clock bit */ | ||
142 | __raw_writel(0, base + USB_DWC_CTRL7); | ||
143 | wmb(); | ||
144 | } else { | ||
145 | r = __raw_readl(base + USB_INT_ENABLE); | ||
146 | r &= ~((id == 0) ? USB_INTEN_OHCI0 : USB_INTEN_OHCI1); | ||
147 | __raw_writel(r, base + USB_INT_ENABLE); | ||
148 | wmb(); | ||
149 | |||
150 | r = __raw_readl(base + USB_DWC_CTRL3); | ||
151 | r &= ~((id == 0) ? USB_DWC_CTRL3_OHCI0_CKEN | ||
152 | : USB_DWC_CTRL3_OHCI1_CKEN); | ||
153 | __raw_writel(r, base + USB_DWC_CTRL3); | ||
154 | wmb(); | ||
155 | |||
156 | __au1300_usb_phyctl(base, enable); | ||
157 | } | ||
158 | } | ||
159 | |||
160 | static inline void __au1300_ehci_control(void __iomem *base, int enable) | ||
161 | { | ||
162 | unsigned long r; | ||
163 | |||
164 | if (enable) { | ||
165 | r = __raw_readl(base + USB_DWC_CTRL3); | ||
166 | r |= USB_DWC_CTRL3_EHCI0_CKEN; | ||
167 | __raw_writel(r, base + USB_DWC_CTRL3); | ||
168 | wmb(); | ||
169 | |||
170 | r = __raw_readl(base + USB_DWC_CTRL1); | ||
171 | r |= USB_DWC_CTRL1_HSTRS; | ||
172 | __raw_writel(r, base + USB_DWC_CTRL1); | ||
173 | wmb(); | ||
174 | |||
175 | __au1300_usb_phyctl(base, enable); | ||
176 | |||
177 | r = __raw_readl(base + USB_INT_ENABLE); | ||
178 | r |= USB_INTEN_EHCI; | ||
179 | __raw_writel(r, base + USB_INT_ENABLE); | ||
180 | wmb(); | ||
181 | } else { | ||
182 | r = __raw_readl(base + USB_INT_ENABLE); | ||
183 | r &= ~USB_INTEN_EHCI; | ||
184 | __raw_writel(r, base + USB_INT_ENABLE); | ||
185 | wmb(); | ||
186 | |||
187 | r = __raw_readl(base + USB_DWC_CTRL1); | ||
188 | r &= ~USB_DWC_CTRL1_HSTRS; | ||
189 | __raw_writel(r, base + USB_DWC_CTRL1); | ||
190 | wmb(); | ||
191 | |||
192 | r = __raw_readl(base + USB_DWC_CTRL3); | ||
193 | r &= ~USB_DWC_CTRL3_EHCI0_CKEN; | ||
194 | __raw_writel(r, base + USB_DWC_CTRL3); | ||
195 | wmb(); | ||
196 | |||
197 | __au1300_usb_phyctl(base, enable); | ||
198 | } | ||
199 | } | ||
200 | |||
201 | static inline void __au1300_udc_control(void __iomem *base, int enable) | ||
202 | { | ||
203 | unsigned long r; | ||
204 | |||
205 | if (enable) { | ||
206 | r = __raw_readl(base + USB_DWC_CTRL1); | ||
207 | r |= USB_DWC_CTRL1_DCRS; | ||
208 | __raw_writel(r, base + USB_DWC_CTRL1); | ||
209 | wmb(); | ||
210 | |||
211 | __au1300_usb_phyctl(base, enable); | ||
212 | |||
213 | r = __raw_readl(base + USB_INT_ENABLE); | ||
214 | r |= USB_INTEN_UDC; | ||
215 | __raw_writel(r, base + USB_INT_ENABLE); | ||
216 | wmb(); | ||
217 | } else { | ||
218 | r = __raw_readl(base + USB_INT_ENABLE); | ||
219 | r &= ~USB_INTEN_UDC; | ||
220 | __raw_writel(r, base + USB_INT_ENABLE); | ||
221 | wmb(); | ||
222 | |||
223 | r = __raw_readl(base + USB_DWC_CTRL1); | ||
224 | r &= ~USB_DWC_CTRL1_DCRS; | ||
225 | __raw_writel(r, base + USB_DWC_CTRL1); | ||
226 | wmb(); | ||
227 | |||
228 | __au1300_usb_phyctl(base, enable); | ||
229 | } | ||
230 | } | ||
231 | |||
232 | static inline void __au1300_otg_control(void __iomem *base, int enable) | ||
233 | { | ||
234 | unsigned long r; | ||
235 | if (enable) { | ||
236 | r = __raw_readl(base + USB_DWC_CTRL3); | ||
237 | r |= USB_DWC_CTRL3_OTG0_CKEN; | ||
238 | __raw_writel(r, base + USB_DWC_CTRL3); | ||
239 | wmb(); | ||
240 | |||
241 | r = __raw_readl(base + USB_DWC_CTRL1); | ||
242 | r &= ~USB_DWC_CTRL1_OTGD; | ||
243 | __raw_writel(r, base + USB_DWC_CTRL1); | ||
244 | wmb(); | ||
245 | |||
246 | __au1300_usb_phyctl(base, enable); | ||
247 | } else { | ||
248 | r = __raw_readl(base + USB_DWC_CTRL1); | ||
249 | r |= USB_DWC_CTRL1_OTGD; | ||
250 | __raw_writel(r, base + USB_DWC_CTRL1); | ||
251 | wmb(); | ||
252 | |||
253 | r = __raw_readl(base + USB_DWC_CTRL3); | ||
254 | r &= ~USB_DWC_CTRL3_OTG0_CKEN; | ||
255 | __raw_writel(r, base + USB_DWC_CTRL3); | ||
256 | wmb(); | ||
257 | |||
258 | __au1300_usb_phyctl(base, enable); | ||
259 | } | ||
260 | } | ||
261 | |||
262 | static inline int au1300_usb_control(int block, int enable) | ||
263 | { | ||
264 | void __iomem *base = | ||
265 | (void __iomem *)KSEG1ADDR(AU1300_USB_CTL_PHYS_ADDR); | ||
266 | int ret = 0; | ||
267 | |||
268 | switch (block) { | ||
269 | case ALCHEMY_USB_OHCI0: | ||
270 | __au1300_ohci_control(base, enable, 0); | ||
271 | break; | ||
272 | case ALCHEMY_USB_OHCI1: | ||
273 | __au1300_ohci_control(base, enable, 1); | ||
274 | break; | ||
275 | case ALCHEMY_USB_EHCI0: | ||
276 | __au1300_ehci_control(base, enable); | ||
277 | break; | ||
278 | case ALCHEMY_USB_UDC0: | ||
279 | __au1300_udc_control(base, enable); | ||
280 | break; | ||
281 | case ALCHEMY_USB_OTG0: | ||
282 | __au1300_otg_control(base, enable); | ||
283 | break; | ||
284 | default: | ||
285 | ret = -ENODEV; | ||
286 | } | ||
287 | return ret; | ||
288 | } | ||
289 | |||
290 | static inline void au1300_usb_init(void) | ||
291 | { | ||
292 | void __iomem *base = | ||
293 | (void __iomem *)KSEG1ADDR(AU1300_USB_CTL_PHYS_ADDR); | ||
294 | |||
295 | /* set some sane defaults. Note: we don't fiddle with DWC_CTRL4 | ||
296 | * here at all: Port 2 routing (EHCI or UDC) must be set either | ||
297 | * by boot firmware or platform init code; I can't autodetect | ||
298 | * a sane setting. | ||
299 | */ | ||
300 | __raw_writel(0, base + USB_INT_ENABLE); /* disable all USB irqs */ | ||
301 | wmb(); | ||
302 | __raw_writel(0, base + USB_DWC_CTRL3); /* disable all clocks */ | ||
303 | wmb(); | ||
304 | __raw_writel(~0, base + USB_MSR_ERR); /* clear all errors */ | ||
305 | wmb(); | ||
306 | __raw_writel(~0, base + USB_INT_STATUS); /* clear int status */ | ||
307 | wmb(); | ||
308 | /* set coherent access bit */ | ||
309 | __raw_writel(USB_SBUS_CTRL_SBCA, base + USB_SBUS_CTRL); | ||
310 | wmb(); | ||
311 | } | ||
58 | 312 | ||
59 | static inline void __au1200_ohci_control(void __iomem *base, int enable) | 313 | static inline void __au1200_ohci_control(void __iomem *base, int enable) |
60 | { | 314 | { |
@@ -233,6 +487,9 @@ int alchemy_usb_control(int block, int enable) | |||
233 | case ALCHEMY_CPU_AU1200: | 487 | case ALCHEMY_CPU_AU1200: |
234 | ret = au1200_usb_control(block, enable); | 488 | ret = au1200_usb_control(block, enable); |
235 | break; | 489 | break; |
490 | case ALCHEMY_CPU_AU1300: | ||
491 | ret = au1300_usb_control(block, enable); | ||
492 | break; | ||
236 | default: | 493 | default: |
237 | ret = -ENODEV; | 494 | ret = -ENODEV; |
238 | } | 495 | } |
@@ -281,6 +538,20 @@ static void au1200_usb_pm(int susp) | |||
281 | } | 538 | } |
282 | } | 539 | } |
283 | 540 | ||
541 | static void au1300_usb_pm(int susp) | ||
542 | { | ||
543 | void __iomem *base = | ||
544 | (void __iomem *)KSEG1ADDR(AU1300_USB_CTL_PHYS_ADDR); | ||
545 | /* remember Port2 routing */ | ||
546 | if (susp) { | ||
547 | alchemy_usb_pmdata[0] = __raw_readl(base + USB_DWC_CTRL4); | ||
548 | } else { | ||
549 | au1300_usb_init(); | ||
550 | __raw_writel(alchemy_usb_pmdata[0], base + USB_DWC_CTRL4); | ||
551 | wmb(); | ||
552 | } | ||
553 | } | ||
554 | |||
284 | static void alchemy_usb_pm(int susp) | 555 | static void alchemy_usb_pm(int susp) |
285 | { | 556 | { |
286 | switch (alchemy_get_cputype()) { | 557 | switch (alchemy_get_cputype()) { |
@@ -295,6 +566,9 @@ static void alchemy_usb_pm(int susp) | |||
295 | case ALCHEMY_CPU_AU1200: | 566 | case ALCHEMY_CPU_AU1200: |
296 | au1200_usb_pm(susp); | 567 | au1200_usb_pm(susp); |
297 | break; | 568 | break; |
569 | case ALCHEMY_CPU_AU1300: | ||
570 | au1300_usb_pm(susp); | ||
571 | break; | ||
298 | } | 572 | } |
299 | } | 573 | } |
300 | 574 | ||
@@ -328,6 +602,9 @@ static int __init alchemy_usb_init(void) | |||
328 | case ALCHEMY_CPU_AU1200: | 602 | case ALCHEMY_CPU_AU1200: |
329 | au1200_usb_init(); | 603 | au1200_usb_init(); |
330 | break; | 604 | break; |
605 | case ALCHEMY_CPU_AU1300: | ||
606 | au1300_usb_init(); | ||
607 | break; | ||
331 | } | 608 | } |
332 | 609 | ||
333 | register_syscore_ops(&alchemy_usb_pm_ops); | 610 | register_syscore_ops(&alchemy_usb_pm_ops); |
diff --git a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c index 9b66df8278f..95d1a71dcca 100644 --- a/drivers/usb/host/ohci-au1xxx.c +++ b/drivers/usb/host/ohci-au1xxx.c | |||
@@ -89,7 +89,7 @@ static const struct hc_driver ohci_au1xxx_hc_driver = { | |||
89 | 89 | ||
90 | static int ohci_hcd_au1xxx_drv_probe(struct platform_device *pdev) | 90 | static int ohci_hcd_au1xxx_drv_probe(struct platform_device *pdev) |
91 | { | 91 | { |
92 | int ret; | 92 | int ret, unit; |
93 | struct usb_hcd *hcd; | 93 | struct usb_hcd *hcd; |
94 | 94 | ||
95 | if (usb_disabled()) | 95 | if (usb_disabled()) |
@@ -120,7 +120,9 @@ static int ohci_hcd_au1xxx_drv_probe(struct platform_device *pdev) | |||
120 | goto err2; | 120 | goto err2; |
121 | } | 121 | } |
122 | 122 | ||
123 | if (alchemy_usb_control(ALCHEMY_USB_OHCI0, 1)) { | 123 | unit = (hcd->rsrc_start == AU1300_USB_OHCI1_PHYS_ADDR) ? |
124 | ALCHEMY_USB_OHCI1 : ALCHEMY_USB_OHCI0; | ||
125 | if (alchemy_usb_control(unit, 1)) { | ||
124 | printk(KERN_INFO "%s: controller init failed!\n", pdev->name); | 126 | printk(KERN_INFO "%s: controller init failed!\n", pdev->name); |
125 | ret = -ENODEV; | 127 | ret = -ENODEV; |
126 | goto err3; | 128 | goto err3; |
@@ -135,7 +137,7 @@ static int ohci_hcd_au1xxx_drv_probe(struct platform_device *pdev) | |||
135 | return ret; | 137 | return ret; |
136 | } | 138 | } |
137 | 139 | ||
138 | alchemy_usb_control(ALCHEMY_USB_OHCI0, 0); | 140 | alchemy_usb_control(unit, 0); |
139 | err3: | 141 | err3: |
140 | iounmap(hcd->regs); | 142 | iounmap(hcd->regs); |
141 | err2: | 143 | err2: |
@@ -148,9 +150,12 @@ err1: | |||
148 | static int ohci_hcd_au1xxx_drv_remove(struct platform_device *pdev) | 150 | static int ohci_hcd_au1xxx_drv_remove(struct platform_device *pdev) |
149 | { | 151 | { |
150 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | 152 | struct usb_hcd *hcd = platform_get_drvdata(pdev); |
153 | int unit; | ||
151 | 154 | ||
155 | unit = (hcd->rsrc_start == AU1300_USB_OHCI1_PHYS_ADDR) ? | ||
156 | ALCHEMY_USB_OHCI1 : ALCHEMY_USB_OHCI0; | ||
152 | usb_remove_hcd(hcd); | 157 | usb_remove_hcd(hcd); |
153 | alchemy_usb_control(ALCHEMY_USB_OHCI0, 0); | 158 | alchemy_usb_control(unit, 0); |
154 | iounmap(hcd->regs); | 159 | iounmap(hcd->regs); |
155 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | 160 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); |
156 | usb_put_hcd(hcd); | 161 | usb_put_hcd(hcd); |
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index d83e967e4e1..acd4ba555e3 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
@@ -1763,16 +1763,16 @@ config FB_AU1100 | |||
1763 | au1100fb:panel=<name>. | 1763 | au1100fb:panel=<name>. |
1764 | 1764 | ||
1765 | config FB_AU1200 | 1765 | config FB_AU1200 |
1766 | bool "Au1200 LCD Driver" | 1766 | bool "Au1200/Au1300 LCD Driver" |
1767 | depends on (FB = y) && MIPS_ALCHEMY | 1767 | depends on (FB = y) && MIPS_ALCHEMY |
1768 | select FB_SYS_FILLRECT | 1768 | select FB_SYS_FILLRECT |
1769 | select FB_SYS_COPYAREA | 1769 | select FB_SYS_COPYAREA |
1770 | select FB_SYS_IMAGEBLIT | 1770 | select FB_SYS_IMAGEBLIT |
1771 | select FB_SYS_FOPS | 1771 | select FB_SYS_FOPS |
1772 | help | 1772 | help |
1773 | This is the framebuffer driver for the AMD Au1200 SOC. It can drive | 1773 | This is the framebuffer driver for the Au1200/Au1300 SOCs. |
1774 | various panels and CRTs by passing in kernel cmd line option | 1774 | It can drive various panels and CRTs by passing in kernel cmd line |
1775 | au1200fb:panel=<name>. | 1775 | option au1200fb:panel=<name>. |
1776 | 1776 | ||
1777 | config FB_VT8500 | 1777 | config FB_VT8500 |
1778 | bool "VT8500 LCD Driver" | 1778 | bool "VT8500 LCD Driver" |