diff options
Diffstat (limited to 'arch/arm/mach-cns3xxx')
-rw-r--r-- | arch/arm/mach-cns3xxx/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/mach-cns3xxx/Makefile | 8 | ||||
-rw-r--r-- | arch/arm/mach-cns3xxx/core.c | 119 |
3 files changed, 125 insertions, 3 deletions
diff --git a/arch/arm/mach-cns3xxx/Kconfig b/arch/arm/mach-cns3xxx/Kconfig index 5720f3df1af2..dbf0df8bb0ac 100644 --- a/arch/arm/mach-cns3xxx/Kconfig +++ b/arch/arm/mach-cns3xxx/Kconfig | |||
@@ -14,6 +14,7 @@ menu "CNS3XXX platform type" | |||
14 | 14 | ||
15 | config MACH_CNS3420VB | 15 | config MACH_CNS3420VB |
16 | bool "Support for CNS3420 Validation Board" | 16 | bool "Support for CNS3420 Validation Board" |
17 | depends on ATAGS | ||
17 | help | 18 | help |
18 | Include support for the Cavium Networks CNS3420 MPCore Platform | 19 | Include support for the Cavium Networks CNS3420 MPCore Platform |
19 | Baseboard. | 20 | Baseboard. |
diff --git a/arch/arm/mach-cns3xxx/Makefile b/arch/arm/mach-cns3xxx/Makefile index 11033f1c2e23..a1ff10848698 100644 --- a/arch/arm/mach-cns3xxx/Makefile +++ b/arch/arm/mach-cns3xxx/Makefile | |||
@@ -1,3 +1,5 @@ | |||
1 | obj-$(CONFIG_ARCH_CNS3XXX) += core.o pm.o devices.o | 1 | obj-$(CONFIG_ARCH_CNS3XXX) += cns3xxx.o |
2 | obj-$(CONFIG_PCI) += pcie.o | 2 | cns3xxx-y += core.o pm.o |
3 | obj-$(CONFIG_MACH_CNS3420VB) += cns3420vb.o | 3 | cns3xxx-$(CONFIG_ATAGS) += devices.o |
4 | cns3xxx-$(CONFIG_PCI) += pcie.o | ||
5 | cns3xxx-$(CONFIG_MACH_CNS3420VB) += cns3420vb.o | ||
diff --git a/arch/arm/mach-cns3xxx/core.c b/arch/arm/mach-cns3xxx/core.c index 012ffdb9e142..49e657c15067 100644 --- a/arch/arm/mach-cns3xxx/core.c +++ b/arch/arm/mach-cns3xxx/core.c | |||
@@ -13,12 +13,18 @@ | |||
13 | #include <linux/clockchips.h> | 13 | #include <linux/clockchips.h> |
14 | #include <linux/io.h> | 14 | #include <linux/io.h> |
15 | #include <linux/irqchip/arm-gic.h> | 15 | #include <linux/irqchip/arm-gic.h> |
16 | #include <linux/of_platform.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/usb/ehci_pdriver.h> | ||
19 | #include <linux/usb/ohci_pdriver.h> | ||
20 | #include <asm/mach/arch.h> | ||
16 | #include <asm/mach/map.h> | 21 | #include <asm/mach/map.h> |
17 | #include <asm/mach/time.h> | 22 | #include <asm/mach/time.h> |
18 | #include <asm/mach/irq.h> | 23 | #include <asm/mach/irq.h> |
19 | #include <asm/hardware/cache-l2x0.h> | 24 | #include <asm/hardware/cache-l2x0.h> |
20 | #include "cns3xxx.h" | 25 | #include "cns3xxx.h" |
21 | #include "core.h" | 26 | #include "core.h" |
27 | #include "pm.h" | ||
22 | 28 | ||
23 | static struct map_desc cns3xxx_io_desc[] __initdata = { | 29 | static struct map_desc cns3xxx_io_desc[] __initdata = { |
24 | { | 30 | { |
@@ -276,3 +282,116 @@ void __init cns3xxx_l2x0_init(void) | |||
276 | } | 282 | } |
277 | 283 | ||
278 | #endif /* CONFIG_CACHE_L2X0 */ | 284 | #endif /* CONFIG_CACHE_L2X0 */ |
285 | |||
286 | static int csn3xxx_usb_power_on(struct platform_device *pdev) | ||
287 | { | ||
288 | /* | ||
289 | * EHCI and OHCI share the same clock and power, | ||
290 | * resetting twice would cause the 1st controller been reset. | ||
291 | * Therefore only do power up at the first up device, and | ||
292 | * power down at the last down device. | ||
293 | * | ||
294 | * Set USB AHB INCR length to 16 | ||
295 | */ | ||
296 | if (atomic_inc_return(&usb_pwr_ref) == 1) { | ||
297 | cns3xxx_pwr_power_up(1 << PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB); | ||
298 | cns3xxx_pwr_clk_en(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST); | ||
299 | cns3xxx_pwr_soft_rst(1 << PM_SOFT_RST_REG_OFFST_USB_HOST); | ||
300 | __raw_writel((__raw_readl(MISC_CHIP_CONFIG_REG) | (0X2 << 24)), | ||
301 | MISC_CHIP_CONFIG_REG); | ||
302 | } | ||
303 | |||
304 | return 0; | ||
305 | } | ||
306 | |||
307 | static void csn3xxx_usb_power_off(struct platform_device *pdev) | ||
308 | { | ||
309 | /* | ||
310 | * EHCI and OHCI share the same clock and power, | ||
311 | * resetting twice would cause the 1st controller been reset. | ||
312 | * Therefore only do power up at the first up device, and | ||
313 | * power down at the last down device. | ||
314 | */ | ||
315 | if (atomic_dec_return(&usb_pwr_ref) == 0) | ||
316 | cns3xxx_pwr_clk_dis(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST); | ||
317 | } | ||
318 | |||
319 | static struct usb_ehci_pdata cns3xxx_usb_ehci_pdata = { | ||
320 | .power_on = csn3xxx_usb_power_on, | ||
321 | .power_off = csn3xxx_usb_power_off, | ||
322 | }; | ||
323 | |||
324 | static struct usb_ohci_pdata cns3xxx_usb_ohci_pdata = { | ||
325 | .num_ports = 1, | ||
326 | .power_on = csn3xxx_usb_power_on, | ||
327 | .power_off = csn3xxx_usb_power_off, | ||
328 | }; | ||
329 | |||
330 | static struct of_dev_auxdata cns3xxx_auxdata[] __initconst = { | ||
331 | { "intel,usb-ehci", CNS3XXX_USB_BASE, "ehci-platform", &cns3xxx_usb_ehci_pdata }, | ||
332 | { "intel,usb-ohci", CNS3XXX_USB_OHCI_BASE, "ohci-platform", &cns3xxx_usb_ohci_pdata }, | ||
333 | { "cavium,cns3420-ahci", CNS3XXX_SATA2_BASE, "ahci", NULL }, | ||
334 | { "cavium,cns3420-sdhci", CNS3XXX_SDIO_BASE, "ahci", NULL }, | ||
335 | {}, | ||
336 | }; | ||
337 | |||
338 | static void __init cns3xxx_init(void) | ||
339 | { | ||
340 | struct device_node *dn; | ||
341 | |||
342 | cns3xxx_l2x0_init(); | ||
343 | |||
344 | dn = of_find_compatible_node(NULL, NULL, "cavium,cns3420-ahci"); | ||
345 | if (of_device_is_available(dn)) { | ||
346 | u32 tmp; | ||
347 | |||
348 | tmp = __raw_readl(MISC_SATA_POWER_MODE); | ||
349 | tmp |= 0x1 << 16; /* Disable SATA PHY 0 from SLUMBER Mode */ | ||
350 | tmp |= 0x1 << 17; /* Disable SATA PHY 1 from SLUMBER Mode */ | ||
351 | __raw_writel(tmp, MISC_SATA_POWER_MODE); | ||
352 | |||
353 | /* Enable SATA PHY */ | ||
354 | cns3xxx_pwr_power_up(0x1 << PM_PLL_HM_PD_CTRL_REG_OFFSET_SATA_PHY0); | ||
355 | cns3xxx_pwr_power_up(0x1 << PM_PLL_HM_PD_CTRL_REG_OFFSET_SATA_PHY1); | ||
356 | |||
357 | /* Enable SATA Clock */ | ||
358 | cns3xxx_pwr_clk_en(0x1 << PM_CLK_GATE_REG_OFFSET_SATA); | ||
359 | |||
360 | /* De-Asscer SATA Reset */ | ||
361 | cns3xxx_pwr_soft_rst(CNS3XXX_PWR_SOFTWARE_RST(SATA)); | ||
362 | } | ||
363 | |||
364 | dn = of_find_compatible_node(NULL, NULL, "cavium,cns3420-sdhci"); | ||
365 | if (of_device_is_available(dn)) { | ||
366 | u32 __iomem *gpioa = IOMEM(CNS3XXX_MISC_BASE_VIRT + 0x0014); | ||
367 | u32 gpioa_pins = __raw_readl(gpioa); | ||
368 | |||
369 | /* MMC/SD pins share with GPIOA */ | ||
370 | gpioa_pins |= 0x1fff0004; | ||
371 | __raw_writel(gpioa_pins, gpioa); | ||
372 | |||
373 | cns3xxx_pwr_clk_en(CNS3XXX_PWR_CLK_EN(SDIO)); | ||
374 | cns3xxx_pwr_soft_rst(CNS3XXX_PWR_SOFTWARE_RST(SDIO)); | ||
375 | } | ||
376 | |||
377 | pm_power_off = cns3xxx_power_off; | ||
378 | |||
379 | of_platform_populate(NULL, of_default_bus_match_table, | ||
380 | cns3xxx_auxdata, NULL); | ||
381 | } | ||
382 | |||
383 | static const char *cns3xxx_dt_compat[] __initdata = { | ||
384 | "cavium,cns3410", | ||
385 | "cavium,cns3420", | ||
386 | NULL, | ||
387 | }; | ||
388 | |||
389 | DT_MACHINE_START(CNS3XXX_DT, "Cavium Networks CNS3xxx") | ||
390 | .dt_compat = cns3xxx_dt_compat, | ||
391 | .nr_irqs = NR_IRQS_CNS3XXX, | ||
392 | .map_io = cns3xxx_map_io, | ||
393 | .init_irq = cns3xxx_init_irq, | ||
394 | .init_time = cns3xxx_timer_init, | ||
395 | .init_machine = cns3xxx_init, | ||
396 | .restart = cns3xxx_restart, | ||
397 | MACHINE_END | ||