diff options
| author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-22 10:38:37 -0500 |
|---|---|---|
| committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-22 10:38:37 -0500 |
| commit | fcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch) | |
| tree | a57612d1888735a2ec7972891b68c1ac5ec8faea /arch/mips/lantiq | |
| parent | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff) | |
Diffstat (limited to 'arch/mips/lantiq')
| -rw-r--r-- | arch/mips/lantiq/devices.c | 120 | ||||
| -rw-r--r-- | arch/mips/lantiq/devices.h | 23 | ||||
| -rw-r--r-- | arch/mips/lantiq/machtypes.h | 20 | ||||
| -rw-r--r-- | arch/mips/lantiq/setup.c | 66 | ||||
| -rw-r--r-- | arch/mips/lantiq/xway/Kconfig | 23 | ||||
| -rw-r--r-- | arch/mips/lantiq/xway/clk-ase.c | 48 | ||||
| -rw-r--r-- | arch/mips/lantiq/xway/clk-xway.c | 223 | ||||
| -rw-r--r-- | arch/mips/lantiq/xway/devices.c | 119 | ||||
| -rw-r--r-- | arch/mips/lantiq/xway/devices.h | 20 | ||||
| -rw-r--r-- | arch/mips/lantiq/xway/ebu.c | 52 | ||||
| -rw-r--r-- | arch/mips/lantiq/xway/gpio.c | 195 | ||||
| -rw-r--r-- | arch/mips/lantiq/xway/gpio_ebu.c | 126 | ||||
| -rw-r--r-- | arch/mips/lantiq/xway/gpio_stp.c | 157 | ||||
| -rw-r--r-- | arch/mips/lantiq/xway/mach-easy50601.c | 57 | ||||
| -rw-r--r-- | arch/mips/lantiq/xway/mach-easy50712.c | 74 | ||||
| -rw-r--r-- | arch/mips/lantiq/xway/pmu.c | 69 | ||||
| -rw-r--r-- | arch/mips/lantiq/xway/prom-ase.c | 39 | ||||
| -rw-r--r-- | arch/mips/lantiq/xway/prom-xway.c | 54 | ||||
| -rw-r--r-- | arch/mips/lantiq/xway/setup-ase.c | 19 | ||||
| -rw-r--r-- | arch/mips/lantiq/xway/setup-xway.c | 20 |
20 files changed, 1524 insertions, 0 deletions
diff --git a/arch/mips/lantiq/devices.c b/arch/mips/lantiq/devices.c new file mode 100644 index 00000000000..44a36771c81 --- /dev/null +++ b/arch/mips/lantiq/devices.c | |||
| @@ -0,0 +1,120 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or modify it | ||
| 3 | * under the terms of the GNU General Public License version 2 as published | ||
| 4 | * by the Free Software Foundation. | ||
| 5 | * | ||
| 6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <linux/init.h> | ||
| 10 | #include <linux/module.h> | ||
| 11 | #include <linux/types.h> | ||
| 12 | #include <linux/string.h> | ||
| 13 | #include <linux/kernel.h> | ||
| 14 | #include <linux/reboot.h> | ||
| 15 | #include <linux/platform_device.h> | ||
| 16 | #include <linux/leds.h> | ||
| 17 | #include <linux/etherdevice.h> | ||
| 18 | #include <linux/time.h> | ||
| 19 | #include <linux/io.h> | ||
| 20 | #include <linux/gpio.h> | ||
| 21 | |||
| 22 | #include <asm/bootinfo.h> | ||
| 23 | #include <asm/irq.h> | ||
| 24 | |||
| 25 | #include <lantiq_soc.h> | ||
| 26 | |||
| 27 | #include "devices.h" | ||
| 28 | |||
| 29 | /* nor flash */ | ||
| 30 | static struct resource ltq_nor_resource = { | ||
| 31 | .name = "nor", | ||
| 32 | .start = LTQ_FLASH_START, | ||
| 33 | .end = LTQ_FLASH_START + LTQ_FLASH_MAX - 1, | ||
| 34 | .flags = IORESOURCE_MEM, | ||
| 35 | }; | ||
| 36 | |||
| 37 | static struct platform_device ltq_nor = { | ||
| 38 | .name = "ltq_nor", | ||
| 39 | .resource = <q_nor_resource, | ||
| 40 | .num_resources = 1, | ||
| 41 | }; | ||
| 42 | |||
| 43 | void __init ltq_register_nor(struct physmap_flash_data *data) | ||
| 44 | { | ||
| 45 | ltq_nor.dev.platform_data = data; | ||
| 46 | platform_device_register(<q_nor); | ||
| 47 | } | ||
| 48 | |||
| 49 | /* watchdog */ | ||
| 50 | static struct resource ltq_wdt_resource = { | ||
| 51 | .name = "watchdog", | ||
| 52 | .start = LTQ_WDT_BASE_ADDR, | ||
| 53 | .end = LTQ_WDT_BASE_ADDR + LTQ_WDT_SIZE - 1, | ||
| 54 | .flags = IORESOURCE_MEM, | ||
| 55 | }; | ||
| 56 | |||
| 57 | void __init ltq_register_wdt(void) | ||
| 58 | { | ||
| 59 | platform_device_register_simple("ltq_wdt", 0, <q_wdt_resource, 1); | ||
| 60 | } | ||
| 61 | |||
| 62 | /* asc ports */ | ||
| 63 | static struct resource ltq_asc0_resources[] = { | ||
| 64 | { | ||
| 65 | .name = "asc0", | ||
| 66 | .start = LTQ_ASC0_BASE_ADDR, | ||
| 67 | .end = LTQ_ASC0_BASE_ADDR + LTQ_ASC_SIZE - 1, | ||
| 68 | .flags = IORESOURCE_MEM, | ||
| 69 | }, | ||
| 70 | IRQ_RES(tx, LTQ_ASC_TIR(0)), | ||
| 71 | IRQ_RES(rx, LTQ_ASC_RIR(0)), | ||
| 72 | IRQ_RES(err, LTQ_ASC_EIR(0)), | ||
| 73 | }; | ||
| 74 | |||
| 75 | static struct resource ltq_asc1_resources[] = { | ||
| 76 | { | ||
| 77 | .name = "asc1", | ||
| 78 | .start = LTQ_ASC1_BASE_ADDR, | ||
| 79 | .end = LTQ_ASC1_BASE_ADDR + LTQ_ASC_SIZE - 1, | ||
| 80 | .flags = IORESOURCE_MEM, | ||
| 81 | }, | ||
| 82 | IRQ_RES(tx, LTQ_ASC_TIR(1)), | ||
| 83 | IRQ_RES(rx, LTQ_ASC_RIR(1)), | ||
| 84 | IRQ_RES(err, LTQ_ASC_EIR(1)), | ||
| 85 | }; | ||
| 86 | |||
| 87 | void __init ltq_register_asc(int port) | ||
| 88 | { | ||
| 89 | switch (port) { | ||
| 90 | case 0: | ||
| 91 | platform_device_register_simple("ltq_asc", 0, | ||
| 92 | ltq_asc0_resources, ARRAY_SIZE(ltq_asc0_resources)); | ||
| 93 | break; | ||
| 94 | case 1: | ||
| 95 | platform_device_register_simple("ltq_asc", 1, | ||
| 96 | ltq_asc1_resources, ARRAY_SIZE(ltq_asc1_resources)); | ||
| 97 | break; | ||
| 98 | default: | ||
| 99 | break; | ||
| 100 | } | ||
| 101 | } | ||
| 102 | |||
| 103 | #ifdef CONFIG_PCI | ||
| 104 | /* pci */ | ||
| 105 | static struct platform_device ltq_pci = { | ||
| 106 | .name = "ltq_pci", | ||
| 107 | .num_resources = 0, | ||
| 108 | }; | ||
| 109 | |||
| 110 | void __init ltq_register_pci(struct ltq_pci_data *data) | ||
| 111 | { | ||
| 112 | ltq_pci.dev.platform_data = data; | ||
| 113 | platform_device_register(<q_pci); | ||
| 114 | } | ||
| 115 | #else | ||
| 116 | void __init ltq_register_pci(struct ltq_pci_data *data) | ||
| 117 | { | ||
| 118 | pr_err("kernel is compiled without PCI support\n"); | ||
| 119 | } | ||
| 120 | #endif | ||
diff --git a/arch/mips/lantiq/devices.h b/arch/mips/lantiq/devices.h new file mode 100644 index 00000000000..2947bb19a52 --- /dev/null +++ b/arch/mips/lantiq/devices.h | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or modify it | ||
| 3 | * under the terms of the GNU General Public License version 2 as published | ||
| 4 | * by the Free Software Foundation. | ||
| 5 | * | ||
| 6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
| 7 | */ | ||
| 8 | |||
| 9 | #ifndef _LTQ_DEVICES_H__ | ||
| 10 | #define _LTQ_DEVICES_H__ | ||
| 11 | |||
| 12 | #include <lantiq_platform.h> | ||
| 13 | #include <linux/mtd/physmap.h> | ||
| 14 | |||
| 15 | #define IRQ_RES(resname, irq) \ | ||
| 16 | {.name = #resname, .start = (irq), .flags = IORESOURCE_IRQ} | ||
| 17 | |||
| 18 | extern void ltq_register_nor(struct physmap_flash_data *data); | ||
| 19 | extern void ltq_register_wdt(void); | ||
| 20 | extern void ltq_register_asc(int port); | ||
| 21 | extern void ltq_register_pci(struct ltq_pci_data *data); | ||
| 22 | |||
| 23 | #endif | ||
diff --git a/arch/mips/lantiq/machtypes.h b/arch/mips/lantiq/machtypes.h new file mode 100644 index 00000000000..7e01b8c484e --- /dev/null +++ b/arch/mips/lantiq/machtypes.h | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or modify it | ||
| 3 | * under the terms of the GNU General Public License version 2 as published | ||
| 4 | * by the Free Software Foundation. | ||
| 5 | * | ||
| 6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
| 7 | */ | ||
| 8 | |||
| 9 | #ifndef _LANTIQ_MACH_H__ | ||
| 10 | #define _LANTIQ_MACH_H__ | ||
| 11 | |||
| 12 | #include <asm/mips_machine.h> | ||
| 13 | |||
| 14 | enum lantiq_mach_type { | ||
| 15 | LTQ_MACH_GENERIC = 0, | ||
| 16 | LTQ_MACH_EASY50712, /* Danube evaluation board */ | ||
| 17 | LTQ_MACH_EASY50601, /* Amazon SE evaluation board */ | ||
| 18 | }; | ||
| 19 | |||
| 20 | #endif | ||
diff --git a/arch/mips/lantiq/setup.c b/arch/mips/lantiq/setup.c new file mode 100644 index 00000000000..9b8af77ed0f --- /dev/null +++ b/arch/mips/lantiq/setup.c | |||
| @@ -0,0 +1,66 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or modify it | ||
| 3 | * under the terms of the GNU General Public License version 2 as published | ||
| 4 | * by the Free Software Foundation. | ||
| 5 | * | ||
| 6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <linux/kernel.h> | ||
| 10 | #include <linux/module.h> | ||
| 11 | #include <linux/io.h> | ||
| 12 | #include <linux/ioport.h> | ||
| 13 | #include <asm/bootinfo.h> | ||
| 14 | |||
| 15 | #include <lantiq_soc.h> | ||
| 16 | |||
| 17 | #include "machtypes.h" | ||
| 18 | #include "devices.h" | ||
| 19 | #include "prom.h" | ||
| 20 | |||
| 21 | void __init plat_mem_setup(void) | ||
| 22 | { | ||
| 23 | /* assume 16M as default incase uboot fails to pass proper ramsize */ | ||
| 24 | unsigned long memsize = 16; | ||
| 25 | char **envp = (char **) KSEG1ADDR(fw_arg2); | ||
| 26 | |||
| 27 | ioport_resource.start = IOPORT_RESOURCE_START; | ||
| 28 | ioport_resource.end = IOPORT_RESOURCE_END; | ||
| 29 | iomem_resource.start = IOMEM_RESOURCE_START; | ||
| 30 | iomem_resource.end = IOMEM_RESOURCE_END; | ||
| 31 | |||
| 32 | set_io_port_base((unsigned long) KSEG1); | ||
| 33 | |||
| 34 | while (*envp) { | ||
| 35 | char *e = (char *)KSEG1ADDR(*envp); | ||
| 36 | if (!strncmp(e, "memsize=", 8)) { | ||
| 37 | e += 8; | ||
| 38 | if (strict_strtoul(e, 0, &memsize)) | ||
| 39 | pr_warn("bad memsize specified\n"); | ||
| 40 | } | ||
| 41 | envp++; | ||
| 42 | } | ||
| 43 | memsize *= 1024 * 1024; | ||
| 44 | add_memory_region(0x00000000, memsize, BOOT_MEM_RAM); | ||
| 45 | } | ||
| 46 | |||
| 47 | static int __init | ||
| 48 | lantiq_setup(void) | ||
| 49 | { | ||
| 50 | ltq_soc_setup(); | ||
| 51 | mips_machine_setup(); | ||
| 52 | return 0; | ||
| 53 | } | ||
| 54 | |||
| 55 | arch_initcall(lantiq_setup); | ||
| 56 | |||
| 57 | static void __init | ||
| 58 | lantiq_generic_init(void) | ||
| 59 | { | ||
| 60 | /* Nothing to do */ | ||
| 61 | } | ||
| 62 | |||
| 63 | MIPS_MACHINE(LTQ_MACH_GENERIC, | ||
| 64 | "Generic", | ||
| 65 | "Generic Lantiq based board", | ||
| 66 | lantiq_generic_init); | ||
diff --git a/arch/mips/lantiq/xway/Kconfig b/arch/mips/lantiq/xway/Kconfig new file mode 100644 index 00000000000..2b857de3662 --- /dev/null +++ b/arch/mips/lantiq/xway/Kconfig | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | if SOC_XWAY | ||
| 2 | |||
| 3 | menu "MIPS Machine" | ||
| 4 | |||
| 5 | config LANTIQ_MACH_EASY50712 | ||
| 6 | bool "Easy50712 - Danube" | ||
| 7 | default y | ||
| 8 | |||
| 9 | endmenu | ||
| 10 | |||
| 11 | endif | ||
| 12 | |||
| 13 | if SOC_AMAZON_SE | ||
| 14 | |||
| 15 | menu "MIPS Machine" | ||
| 16 | |||
| 17 | config LANTIQ_MACH_EASY50601 | ||
| 18 | bool "Easy50601 - Amazon SE" | ||
| 19 | default y | ||
| 20 | |||
| 21 | endmenu | ||
| 22 | |||
| 23 | endif | ||
diff --git a/arch/mips/lantiq/xway/clk-ase.c b/arch/mips/lantiq/xway/clk-ase.c new file mode 100644 index 00000000000..22d823acd53 --- /dev/null +++ b/arch/mips/lantiq/xway/clk-ase.c | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or modify it | ||
| 3 | * under the terms of the GNU General Public License version 2 as published | ||
| 4 | * by the Free Software Foundation. | ||
| 5 | * | ||
| 6 | * Copyright (C) 2011 John Crispin <blogic@openwrt.org> | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <linux/io.h> | ||
| 10 | #include <linux/module.h> | ||
| 11 | #include <linux/init.h> | ||
| 12 | #include <linux/clk.h> | ||
| 13 | |||
| 14 | #include <asm/time.h> | ||
| 15 | #include <asm/irq.h> | ||
| 16 | #include <asm/div64.h> | ||
| 17 | |||
| 18 | #include <lantiq_soc.h> | ||
| 19 | |||
| 20 | /* cgu registers */ | ||
| 21 | #define LTQ_CGU_SYS 0x0010 | ||
| 22 | |||
| 23 | unsigned int ltq_get_io_region_clock(void) | ||
| 24 | { | ||
| 25 | return CLOCK_133M; | ||
| 26 | } | ||
| 27 | EXPORT_SYMBOL(ltq_get_io_region_clock); | ||
| 28 | |||
| 29 | unsigned int ltq_get_fpi_bus_clock(int fpi) | ||
| 30 | { | ||
| 31 | return CLOCK_133M; | ||
| 32 | } | ||
| 33 | EXPORT_SYMBOL(ltq_get_fpi_bus_clock); | ||
| 34 | |||
| 35 | unsigned int ltq_get_cpu_hz(void) | ||
| 36 | { | ||
| 37 | if (ltq_cgu_r32(LTQ_CGU_SYS) & (1 << 5)) | ||
| 38 | return CLOCK_266M; | ||
| 39 | else | ||
| 40 | return CLOCK_133M; | ||
| 41 | } | ||
| 42 | EXPORT_SYMBOL(ltq_get_cpu_hz); | ||
| 43 | |||
| 44 | unsigned int ltq_get_fpi_hz(void) | ||
| 45 | { | ||
| 46 | return CLOCK_133M; | ||
| 47 | } | ||
| 48 | EXPORT_SYMBOL(ltq_get_fpi_hz); | ||
diff --git a/arch/mips/lantiq/xway/clk-xway.c b/arch/mips/lantiq/xway/clk-xway.c new file mode 100644 index 00000000000..ddd39593c58 --- /dev/null +++ b/arch/mips/lantiq/xway/clk-xway.c | |||
| @@ -0,0 +1,223 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or modify it | ||
| 3 | * under the terms of the GNU General Public License version 2 as published | ||
| 4 | * by the Free Software Foundation. | ||
| 5 | * | ||
| 6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <linux/io.h> | ||
| 10 | #include <linux/module.h> | ||
| 11 | #include <linux/init.h> | ||
| 12 | #include <linux/clk.h> | ||
| 13 | |||
| 14 | #include <asm/time.h> | ||
| 15 | #include <asm/irq.h> | ||
| 16 | #include <asm/div64.h> | ||
| 17 | |||
| 18 | #include <lantiq_soc.h> | ||
| 19 | |||
| 20 | static unsigned int ltq_ram_clocks[] = { | ||
| 21 | CLOCK_167M, CLOCK_133M, CLOCK_111M, CLOCK_83M }; | ||
| 22 | #define DDR_HZ ltq_ram_clocks[ltq_cgu_r32(LTQ_CGU_SYS) & 0x3] | ||
| 23 | |||
| 24 | #define BASIC_FREQUENCY_1 35328000 | ||
| 25 | #define BASIC_FREQUENCY_2 36000000 | ||
| 26 | #define BASIS_REQUENCY_USB 12000000 | ||
| 27 | |||
| 28 | #define GET_BITS(x, msb, lsb) \ | ||
| 29 | (((x) & ((1 << ((msb) + 1)) - 1)) >> (lsb)) | ||
| 30 | |||
| 31 | #define LTQ_CGU_PLL0_CFG 0x0004 | ||
| 32 | #define LTQ_CGU_PLL1_CFG 0x0008 | ||
| 33 | #define LTQ_CGU_PLL2_CFG 0x000C | ||
| 34 | #define LTQ_CGU_SYS 0x0010 | ||
| 35 | #define LTQ_CGU_UPDATE 0x0014 | ||
| 36 | #define LTQ_CGU_IF_CLK 0x0018 | ||
| 37 | #define LTQ_CGU_OSC_CON 0x001C | ||
| 38 | #define LTQ_CGU_SMD 0x0020 | ||
| 39 | #define LTQ_CGU_CT1SR 0x0028 | ||
| 40 | #define LTQ_CGU_CT2SR 0x002C | ||
| 41 | #define LTQ_CGU_PCMCR 0x0030 | ||
| 42 | #define LTQ_CGU_PCI_CR 0x0034 | ||
| 43 | #define LTQ_CGU_PD_PC 0x0038 | ||
| 44 | #define LTQ_CGU_FMR 0x003C | ||
| 45 | |||
| 46 | #define CGU_PLL0_PHASE_DIVIDER_ENABLE \ | ||
| 47 | (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 31)) | ||
| 48 | #define CGU_PLL0_BYPASS \ | ||
| 49 | (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 30)) | ||
| 50 | #define CGU_PLL0_CFG_DSMSEL \ | ||
| 51 | (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 28)) | ||
| 52 | #define CGU_PLL0_CFG_FRAC_EN \ | ||
| 53 | (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 27)) | ||
| 54 | #define CGU_PLL1_SRC \ | ||
| 55 | (ltq_cgu_r32(LTQ_CGU_PLL1_CFG) & (1 << 31)) | ||
| 56 | #define CGU_PLL2_PHASE_DIVIDER_ENABLE \ | ||
| 57 | (ltq_cgu_r32(LTQ_CGU_PLL2_CFG) & (1 << 20)) | ||
| 58 | #define CGU_SYS_FPI_SEL (1 << 6) | ||
| 59 | #define CGU_SYS_DDR_SEL 0x3 | ||
| 60 | #define CGU_PLL0_SRC (1 << 29) | ||
| 61 | |||
| 62 | #define CGU_PLL0_CFG_PLLK GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL0_CFG), 26, 17) | ||
| 63 | #define CGU_PLL0_CFG_PLLN GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL0_CFG), 12, 6) | ||
| 64 | #define CGU_PLL0_CFG_PLLM GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL0_CFG), 5, 2) | ||
| 65 | #define CGU_PLL2_SRC GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL2_CFG), 18, 17) | ||
| 66 | #define CGU_PLL2_CFG_INPUT_DIV GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL2_CFG), 16, 13) | ||
| 67 | |||
| 68 | static unsigned int ltq_get_pll0_fdiv(void); | ||
| 69 | |||
| 70 | static inline unsigned int get_input_clock(int pll) | ||
| 71 | { | ||
| 72 | switch (pll) { | ||
| 73 | case 0: | ||
| 74 | if (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & CGU_PLL0_SRC) | ||
| 75 | return BASIS_REQUENCY_USB; | ||
| 76 | else if (CGU_PLL0_PHASE_DIVIDER_ENABLE) | ||
| 77 | return BASIC_FREQUENCY_1; | ||
| 78 | else | ||
| 79 | return BASIC_FREQUENCY_2; | ||
| 80 | case 1: | ||
| 81 | if (CGU_PLL1_SRC) | ||
| 82 | return BASIS_REQUENCY_USB; | ||
| 83 | else if (CGU_PLL0_PHASE_DIVIDER_ENABLE) | ||
| 84 | return BASIC_FREQUENCY_1; | ||
| 85 | else | ||
| 86 | return BASIC_FREQUENCY_2; | ||
| 87 | case 2: | ||
| 88 | switch (CGU_PLL2_SRC) { | ||
| 89 | case 0: | ||
| 90 | return ltq_get_pll0_fdiv(); | ||
| 91 | case 1: | ||
| 92 | return CGU_PLL2_PHASE_DIVIDER_ENABLE ? | ||
| 93 | BASIC_FREQUENCY_1 : | ||
| 94 | BASIC_FREQUENCY_2; | ||
| 95 | case 2: | ||
| 96 | return BASIS_REQUENCY_USB; | ||
| 97 | } | ||
| 98 | default: | ||
| 99 | return 0; | ||
| 100 | } | ||
| 101 | } | ||
| 102 | |||
| 103 | static inline unsigned int cal_dsm(int pll, unsigned int num, unsigned int den) | ||
| 104 | { | ||
| 105 | u64 res, clock = get_input_clock(pll); | ||
| 106 | |||
| 107 | res = num * clock; | ||
| 108 | do_div(res, den); | ||
| 109 | return res; | ||
| 110 | } | ||
| 111 | |||
| 112 | static inline unsigned int mash_dsm(int pll, unsigned int M, unsigned int N, | ||
| 113 | unsigned int K) | ||
| 114 | { | ||
| 115 | unsigned int num = ((N + 1) << 10) + K; | ||
| 116 | unsigned int den = (M + 1) << 10; | ||
| 117 | |||
| 118 | return cal_dsm(pll, num, den); | ||
| 119 | } | ||
| 120 | |||
| 121 | static inline unsigned int ssff_dsm_1(int pll, unsigned int M, unsigned int N, | ||
| 122 | unsigned int K) | ||
| 123 | { | ||
| 124 | unsigned int num = ((N + 1) << 11) + K + 512; | ||
| 125 | unsigned int den = (M + 1) << 11; | ||
| 126 | |||
| 127 | return cal_dsm(pll, num, den); | ||
| 128 | } | ||
| 129 | |||
| 130 | static inline unsigned int ssff_dsm_2(int pll, unsigned int M, unsigned int N, | ||
| 131 | unsigned int K) | ||
| 132 | { | ||
| 133 | unsigned int num = K >= 512 ? | ||
| 134 | ((N + 1) << 12) + K - 512 : ((N + 1) << 12) + K + 3584; | ||
| 135 | unsigned int den = (M + 1) << 12; | ||
| 136 | |||
| 137 | return cal_dsm(pll, num, den); | ||
| 138 | } | ||
| 139 | |||
| 140 | static inline unsigned int dsm(int pll, unsigned int M, unsigned int N, | ||
| 141 | unsigned int K, unsigned int dsmsel, unsigned int phase_div_en) | ||
| 142 | { | ||
| 143 | if (!dsmsel) | ||
| 144 | return mash_dsm(pll, M, N, K); | ||
| 145 | else if (!phase_div_en) | ||
| 146 | return mash_dsm(pll, M, N, K); | ||
| 147 | else | ||
| 148 | return ssff_dsm_2(pll, M, N, K); | ||
| 149 | } | ||
| 150 | |||
| 151 | static inline unsigned int ltq_get_pll0_fosc(void) | ||
| 152 | { | ||
| 153 | if (CGU_PLL0_BYPASS) | ||
| 154 | return get_input_clock(0); | ||
| 155 | else | ||
| 156 | return !CGU_PLL0_CFG_FRAC_EN | ||
| 157 | ? dsm(0, CGU_PLL0_CFG_PLLM, CGU_PLL0_CFG_PLLN, 0, | ||
| 158 | CGU_PLL0_CFG_DSMSEL, | ||
| 159 | CGU_PLL0_PHASE_DIVIDER_ENABLE) | ||
| 160 | : dsm(0, CGU_PLL0_CFG_PLLM, CGU_PLL0_CFG_PLLN, | ||
| 161 | CGU_PLL0_CFG_PLLK, CGU_PLL0_CFG_DSMSEL, | ||
| 162 | CGU_PLL0_PHASE_DIVIDER_ENABLE); | ||
| 163 | } | ||
| 164 | |||
| 165 | static unsigned int ltq_get_pll0_fdiv(void) | ||
| 166 | { | ||
| 167 | unsigned int div = CGU_PLL2_CFG_INPUT_DIV + 1; | ||
| 168 | |||
| 169 | return (ltq_get_pll0_fosc() + (div >> 1)) / div; | ||
| 170 | } | ||
| 171 | |||
| 172 | unsigned int ltq_get_io_region_clock(void) | ||
| 173 | { | ||
| 174 | unsigned int ret = ltq_get_pll0_fosc(); | ||
| 175 | |||
| 176 | switch (ltq_cgu_r32(LTQ_CGU_PLL2_CFG) & CGU_SYS_DDR_SEL) { | ||
| 177 | default: | ||
| 178 | case 0: | ||
| 179 | return (ret + 1) / 2; | ||
| 180 | case 1: | ||
| 181 | return (ret * 2 + 2) / 5; | ||
| 182 | case 2: | ||
| 183 | return (ret + 1) / 3; | ||
| 184 | case 3: | ||
| 185 | return (ret + 2) / 4; | ||
| 186 | } | ||
| 187 | } | ||
| 188 | EXPORT_SYMBOL(ltq_get_io_region_clock); | ||
| 189 | |||
| 190 | unsigned int ltq_get_fpi_bus_clock(int fpi) | ||
| 191 | { | ||
| 192 | unsigned int ret = ltq_get_io_region_clock(); | ||
| 193 | |||
| 194 | if ((fpi == 2) && (ltq_cgu_r32(LTQ_CGU_SYS) & CGU_SYS_FPI_SEL)) | ||
| 195 | ret >>= 1; | ||
| 196 | return ret; | ||
| 197 | } | ||
| 198 | EXPORT_SYMBOL(ltq_get_fpi_bus_clock); | ||
| 199 | |||
| 200 | unsigned int ltq_get_cpu_hz(void) | ||
| 201 | { | ||
| 202 | switch (ltq_cgu_r32(LTQ_CGU_SYS) & 0xc) { | ||
| 203 | case 0: | ||
| 204 | return CLOCK_333M; | ||
| 205 | case 4: | ||
| 206 | return DDR_HZ; | ||
| 207 | case 8: | ||
| 208 | return DDR_HZ << 1; | ||
| 209 | default: | ||
| 210 | return DDR_HZ >> 1; | ||
| 211 | } | ||
| 212 | } | ||
| 213 | EXPORT_SYMBOL(ltq_get_cpu_hz); | ||
| 214 | |||
| 215 | unsigned int ltq_get_fpi_hz(void) | ||
| 216 | { | ||
| 217 | unsigned int ddr_clock = DDR_HZ; | ||
| 218 | |||
| 219 | if (ltq_cgu_r32(LTQ_CGU_SYS) & 0x40) | ||
| 220 | return ddr_clock >> 1; | ||
| 221 | return ddr_clock; | ||
| 222 | } | ||
| 223 | EXPORT_SYMBOL(ltq_get_fpi_hz); | ||
diff --git a/arch/mips/lantiq/xway/devices.c b/arch/mips/lantiq/xway/devices.c new file mode 100644 index 00000000000..d0e32ab2ea0 --- /dev/null +++ b/arch/mips/lantiq/xway/devices.c | |||
| @@ -0,0 +1,119 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or modify it | ||
| 3 | * under the terms of the GNU General Public License version 2 as published | ||
| 4 | * by the Free Software Foundation. | ||
| 5 | * | ||
| 6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <linux/init.h> | ||
| 10 | #include <linux/module.h> | ||
| 11 | #include <linux/types.h> | ||
| 12 | #include <linux/string.h> | ||
| 13 | #include <linux/mtd/physmap.h> | ||
| 14 | #include <linux/kernel.h> | ||
| 15 | #include <linux/reboot.h> | ||
| 16 | #include <linux/platform_device.h> | ||
| 17 | #include <linux/leds.h> | ||
| 18 | #include <linux/etherdevice.h> | ||
| 19 | #include <linux/time.h> | ||
| 20 | #include <linux/io.h> | ||
| 21 | #include <linux/gpio.h> | ||
| 22 | |||
| 23 | #include <asm/bootinfo.h> | ||
| 24 | #include <asm/irq.h> | ||
| 25 | |||
| 26 | #include <lantiq_soc.h> | ||
| 27 | #include <lantiq_irq.h> | ||
| 28 | #include <lantiq_platform.h> | ||
| 29 | |||
| 30 | #include "devices.h" | ||
| 31 | |||
| 32 | /* gpio */ | ||
| 33 | static struct resource ltq_gpio_resource[] = { | ||
| 34 | { | ||
| 35 | .name = "gpio0", | ||
| 36 | .start = LTQ_GPIO0_BASE_ADDR, | ||
| 37 | .end = LTQ_GPIO0_BASE_ADDR + LTQ_GPIO_SIZE - 1, | ||
| 38 | .flags = IORESOURCE_MEM, | ||
| 39 | }, { | ||
| 40 | .name = "gpio1", | ||
| 41 | .start = LTQ_GPIO1_BASE_ADDR, | ||
| 42 | .end = LTQ_GPIO1_BASE_ADDR + LTQ_GPIO_SIZE - 1, | ||
| 43 | .flags = IORESOURCE_MEM, | ||
| 44 | }, { | ||
| 45 | .name = "gpio2", | ||
| 46 | .start = LTQ_GPIO2_BASE_ADDR, | ||
| 47 | .end = LTQ_GPIO2_BASE_ADDR + LTQ_GPIO_SIZE - 1, | ||
| 48 | .flags = IORESOURCE_MEM, | ||
| 49 | } | ||
| 50 | }; | ||
| 51 | |||
| 52 | void __init ltq_register_gpio(void) | ||
| 53 | { | ||
| 54 | platform_device_register_simple("ltq_gpio", 0, | ||
| 55 | <q_gpio_resource[0], 1); | ||
| 56 | platform_device_register_simple("ltq_gpio", 1, | ||
| 57 | <q_gpio_resource[1], 1); | ||
| 58 | |||
| 59 | /* AR9 and VR9 have an extra gpio block */ | ||
| 60 | if (ltq_is_ar9() || ltq_is_vr9()) { | ||
| 61 | platform_device_register_simple("ltq_gpio", 2, | ||
| 62 | <q_gpio_resource[2], 1); | ||
| 63 | } | ||
| 64 | } | ||
| 65 | |||
| 66 | /* serial to parallel conversion */ | ||
| 67 | static struct resource ltq_stp_resource = { | ||
| 68 | .name = "stp", | ||
| 69 | .start = LTQ_STP_BASE_ADDR, | ||
| 70 | .end = LTQ_STP_BASE_ADDR + LTQ_STP_SIZE - 1, | ||
| 71 | .flags = IORESOURCE_MEM, | ||
| 72 | }; | ||
| 73 | |||
| 74 | void __init ltq_register_gpio_stp(void) | ||
| 75 | { | ||
| 76 | platform_device_register_simple("ltq_stp", 0, <q_stp_resource, 1); | ||
| 77 | } | ||
| 78 | |||
| 79 | /* asc ports - amazon se has its own serial mapping */ | ||
| 80 | static struct resource ltq_ase_asc_resources[] = { | ||
| 81 | { | ||
| 82 | .name = "asc0", | ||
| 83 | .start = LTQ_ASC1_BASE_ADDR, | ||
| 84 | .end = LTQ_ASC1_BASE_ADDR + LTQ_ASC_SIZE - 1, | ||
| 85 | .flags = IORESOURCE_MEM, | ||
| 86 | }, | ||
| 87 | IRQ_RES(tx, LTQ_ASC_ASE_TIR), | ||
| 88 | IRQ_RES(rx, LTQ_ASC_ASE_RIR), | ||
| 89 | IRQ_RES(err, LTQ_ASC_ASE_EIR), | ||
| 90 | }; | ||
| 91 | |||
| 92 | void __init ltq_register_ase_asc(void) | ||
| 93 | { | ||
| 94 | platform_device_register_simple("ltq_asc", 0, | ||
| 95 | ltq_ase_asc_resources, ARRAY_SIZE(ltq_ase_asc_resources)); | ||
| 96 | } | ||
| 97 | |||
| 98 | /* ethernet */ | ||
| 99 | static struct resource ltq_etop_resources = { | ||
| 100 | .name = "etop", | ||
| 101 | .start = LTQ_ETOP_BASE_ADDR, | ||
| 102 | .end = LTQ_ETOP_BASE_ADDR + LTQ_ETOP_SIZE - 1, | ||
| 103 | .flags = IORESOURCE_MEM, | ||
| 104 | }; | ||
| 105 | |||
| 106 | static struct platform_device ltq_etop = { | ||
| 107 | .name = "ltq_etop", | ||
| 108 | .resource = <q_etop_resources, | ||
| 109 | .num_resources = 1, | ||
| 110 | }; | ||
| 111 | |||
| 112 | void __init | ||
| 113 | ltq_register_etop(struct ltq_eth_data *eth) | ||
| 114 | { | ||
| 115 | if (eth) { | ||
| 116 | ltq_etop.dev.platform_data = eth; | ||
| 117 | platform_device_register(<q_etop); | ||
| 118 | } | ||
| 119 | } | ||
diff --git a/arch/mips/lantiq/xway/devices.h b/arch/mips/lantiq/xway/devices.h new file mode 100644 index 00000000000..e90493471bc --- /dev/null +++ b/arch/mips/lantiq/xway/devices.h | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or modify it | ||
| 3 | * under the terms of the GNU General Public License version 2 as published | ||
| 4 | * by the Free Software Foundation. | ||
| 5 | * | ||
| 6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
| 7 | */ | ||
| 8 | |||
| 9 | #ifndef _LTQ_DEVICES_XWAY_H__ | ||
| 10 | #define _LTQ_DEVICES_XWAY_H__ | ||
| 11 | |||
| 12 | #include "../devices.h" | ||
| 13 | #include <linux/phy.h> | ||
| 14 | |||
| 15 | extern void ltq_register_gpio(void); | ||
| 16 | extern void ltq_register_gpio_stp(void); | ||
| 17 | extern void ltq_register_ase_asc(void); | ||
| 18 | extern void ltq_register_etop(struct ltq_eth_data *eth); | ||
| 19 | |||
| 20 | #endif | ||
diff --git a/arch/mips/lantiq/xway/ebu.c b/arch/mips/lantiq/xway/ebu.c new file mode 100644 index 00000000000..033b3184c7a --- /dev/null +++ b/arch/mips/lantiq/xway/ebu.c | |||
| @@ -0,0 +1,52 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or modify it | ||
| 3 | * under the terms of the GNU General Public License version 2 as published | ||
| 4 | * by the Free Software Foundation. | ||
| 5 | * | ||
| 6 | * EBU - the external bus unit attaches PCI, NOR and NAND | ||
| 7 | * | ||
| 8 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
| 9 | */ | ||
| 10 | |||
| 11 | #include <linux/kernel.h> | ||
| 12 | #include <linux/module.h> | ||
| 13 | #include <linux/ioport.h> | ||
| 14 | |||
| 15 | #include <lantiq_soc.h> | ||
| 16 | |||
| 17 | /* all access to the ebu must be locked */ | ||
| 18 | DEFINE_SPINLOCK(ebu_lock); | ||
| 19 | EXPORT_SYMBOL_GPL(ebu_lock); | ||
| 20 | |||
| 21 | static struct resource ltq_ebu_resource = { | ||
| 22 | .name = "ebu", | ||
| 23 | .start = LTQ_EBU_BASE_ADDR, | ||
| 24 | .end = LTQ_EBU_BASE_ADDR + LTQ_EBU_SIZE - 1, | ||
| 25 | .flags = IORESOURCE_MEM, | ||
| 26 | }; | ||
| 27 | |||
| 28 | /* remapped base addr of the clock unit and external bus unit */ | ||
| 29 | void __iomem *ltq_ebu_membase; | ||
| 30 | |||
| 31 | static int __init lantiq_ebu_init(void) | ||
| 32 | { | ||
| 33 | /* insert and request the memory region */ | ||
| 34 | if (insert_resource(&iomem_resource, <q_ebu_resource) < 0) | ||
| 35 | panic("Failed to insert ebu memory\n"); | ||
| 36 | |||
| 37 | if (request_mem_region(ltq_ebu_resource.start, | ||
| 38 | resource_size(<q_ebu_resource), "ebu") < 0) | ||
| 39 | panic("Failed to request ebu memory\n"); | ||
| 40 | |||
| 41 | /* remap ebu register range */ | ||
| 42 | ltq_ebu_membase = ioremap_nocache(ltq_ebu_resource.start, | ||
| 43 | resource_size(<q_ebu_resource)); | ||
| 44 | if (!ltq_ebu_membase) | ||
| 45 | panic("Failed to remap ebu memory\n"); | ||
| 46 | |||
| 47 | /* make sure to unprotect the memory region where flash is located */ | ||
| 48 | ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_BUSCON0) & ~EBU_WRDIS, LTQ_EBU_BUSCON0); | ||
| 49 | return 0; | ||
| 50 | } | ||
| 51 | |||
| 52 | postcore_initcall(lantiq_ebu_init); | ||
diff --git a/arch/mips/lantiq/xway/gpio.c b/arch/mips/lantiq/xway/gpio.c new file mode 100644 index 00000000000..a321451a545 --- /dev/null +++ b/arch/mips/lantiq/xway/gpio.c | |||
| @@ -0,0 +1,195 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or modify it | ||
| 3 | * under the terms of the GNU General Public License version 2 as published | ||
| 4 | * by the Free Software Foundation. | ||
| 5 | * | ||
| 6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <linux/slab.h> | ||
| 10 | #include <linux/module.h> | ||
| 11 | #include <linux/platform_device.h> | ||
| 12 | #include <linux/gpio.h> | ||
| 13 | #include <linux/ioport.h> | ||
| 14 | #include <linux/io.h> | ||
| 15 | |||
| 16 | #include <lantiq_soc.h> | ||
| 17 | |||
| 18 | #define LTQ_GPIO_OUT 0x00 | ||
| 19 | #define LTQ_GPIO_IN 0x04 | ||
| 20 | #define LTQ_GPIO_DIR 0x08 | ||
| 21 | #define LTQ_GPIO_ALTSEL0 0x0C | ||
| 22 | #define LTQ_GPIO_ALTSEL1 0x10 | ||
| 23 | #define LTQ_GPIO_OD 0x14 | ||
| 24 | |||
| 25 | #define PINS_PER_PORT 16 | ||
| 26 | #define MAX_PORTS 3 | ||
| 27 | |||
| 28 | #define ltq_gpio_getbit(m, r, p) (!!(ltq_r32(m + r) & (1 << p))) | ||
| 29 | #define ltq_gpio_setbit(m, r, p) ltq_w32_mask(0, (1 << p), m + r) | ||
| 30 | #define ltq_gpio_clearbit(m, r, p) ltq_w32_mask((1 << p), 0, m + r) | ||
| 31 | |||
| 32 | struct ltq_gpio { | ||
| 33 | void __iomem *membase; | ||
| 34 | struct gpio_chip chip; | ||
| 35 | }; | ||
| 36 | |||
| 37 | static struct ltq_gpio ltq_gpio_port[MAX_PORTS]; | ||
| 38 | |||
| 39 | int gpio_to_irq(unsigned int gpio) | ||
| 40 | { | ||
| 41 | return -EINVAL; | ||
| 42 | } | ||
| 43 | EXPORT_SYMBOL(gpio_to_irq); | ||
| 44 | |||
| 45 | int irq_to_gpio(unsigned int gpio) | ||
| 46 | { | ||
| 47 | return -EINVAL; | ||
| 48 | } | ||
| 49 | EXPORT_SYMBOL(irq_to_gpio); | ||
| 50 | |||
| 51 | int ltq_gpio_request(unsigned int pin, unsigned int alt0, | ||
| 52 | unsigned int alt1, unsigned int dir, const char *name) | ||
| 53 | { | ||
| 54 | int id = 0; | ||
| 55 | |||
| 56 | if (pin >= (MAX_PORTS * PINS_PER_PORT)) | ||
| 57 | return -EINVAL; | ||
| 58 | if (gpio_request(pin, name)) { | ||
| 59 | pr_err("failed to setup lantiq gpio: %s\n", name); | ||
| 60 | return -EBUSY; | ||
| 61 | } | ||
| 62 | if (dir) | ||
| 63 | gpio_direction_output(pin, 1); | ||
| 64 | else | ||
| 65 | gpio_direction_input(pin); | ||
| 66 | while (pin >= PINS_PER_PORT) { | ||
| 67 | pin -= PINS_PER_PORT; | ||
| 68 | id++; | ||
| 69 | } | ||
| 70 | if (alt0) | ||
| 71 | ltq_gpio_setbit(ltq_gpio_port[id].membase, | ||
| 72 | LTQ_GPIO_ALTSEL0, pin); | ||
| 73 | else | ||
| 74 | ltq_gpio_clearbit(ltq_gpio_port[id].membase, | ||
| 75 | LTQ_GPIO_ALTSEL0, pin); | ||
| 76 | if (alt1) | ||
| 77 | ltq_gpio_setbit(ltq_gpio_port[id].membase, | ||
| 78 | LTQ_GPIO_ALTSEL1, pin); | ||
| 79 | else | ||
| 80 | ltq_gpio_clearbit(ltq_gpio_port[id].membase, | ||
| 81 | LTQ_GPIO_ALTSEL1, pin); | ||
| 82 | return 0; | ||
| 83 | } | ||
| 84 | EXPORT_SYMBOL(ltq_gpio_request); | ||
| 85 | |||
| 86 | static void ltq_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) | ||
| 87 | { | ||
| 88 | struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip); | ||
| 89 | |||
| 90 | if (value) | ||
| 91 | ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_OUT, offset); | ||
| 92 | else | ||
| 93 | ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_OUT, offset); | ||
| 94 | } | ||
| 95 | |||
| 96 | static int ltq_gpio_get(struct gpio_chip *chip, unsigned int offset) | ||
| 97 | { | ||
| 98 | struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip); | ||
| 99 | |||
| 100 | return ltq_gpio_getbit(ltq_gpio->membase, LTQ_GPIO_IN, offset); | ||
| 101 | } | ||
| 102 | |||
| 103 | static int ltq_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) | ||
| 104 | { | ||
| 105 | struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip); | ||
| 106 | |||
| 107 | ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_OD, offset); | ||
| 108 | ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_DIR, offset); | ||
| 109 | |||
| 110 | return 0; | ||
| 111 | } | ||
| 112 | |||
| 113 | static int ltq_gpio_direction_output(struct gpio_chip *chip, | ||
| 114 | unsigned int offset, int value) | ||
| 115 | { | ||
| 116 | struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip); | ||
| 117 | |||
| 118 | ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_OD, offset); | ||
| 119 | ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_DIR, offset); | ||
| 120 | ltq_gpio_set(chip, offset, value); | ||
| 121 | |||
| 122 | return 0; | ||
| 123 | } | ||
| 124 | |||
| 125 | static int ltq_gpio_req(struct gpio_chip *chip, unsigned offset) | ||
| 126 | { | ||
| 127 | struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip); | ||
| 128 | |||
| 129 | ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_ALTSEL0, offset); | ||
| 130 | ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_ALTSEL1, offset); | ||
| 131 | return 0; | ||
| 132 | } | ||
| 133 | |||
| 134 | static int ltq_gpio_probe(struct platform_device *pdev) | ||
| 135 | { | ||
| 136 | struct resource *res; | ||
| 137 | |||
| 138 | if (pdev->id >= MAX_PORTS) { | ||
| 139 | dev_err(&pdev->dev, "invalid gpio port %d\n", | ||
| 140 | pdev->id); | ||
| 141 | return -EINVAL; | ||
| 142 | } | ||
| 143 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 144 | if (!res) { | ||
| 145 | dev_err(&pdev->dev, "failed to get memory for gpio port %d\n", | ||
| 146 | pdev->id); | ||
| 147 | return -ENOENT; | ||
| 148 | } | ||
| 149 | res = devm_request_mem_region(&pdev->dev, res->start, | ||
| 150 | resource_size(res), dev_name(&pdev->dev)); | ||
| 151 | if (!res) { | ||
| 152 | dev_err(&pdev->dev, | ||
| 153 | "failed to request memory for gpio port %d\n", | ||
| 154 | pdev->id); | ||
| 155 | return -EBUSY; | ||
| 156 | } | ||
| 157 | ltq_gpio_port[pdev->id].membase = devm_ioremap_nocache(&pdev->dev, | ||
| 158 | res->start, resource_size(res)); | ||
| 159 | if (!ltq_gpio_port[pdev->id].membase) { | ||
| 160 | dev_err(&pdev->dev, "failed to remap memory for gpio port %d\n", | ||
| 161 | pdev->id); | ||
| 162 | return -ENOMEM; | ||
| 163 | } | ||
| 164 | ltq_gpio_port[pdev->id].chip.label = "ltq_gpio"; | ||
| 165 | ltq_gpio_port[pdev->id].chip.direction_input = ltq_gpio_direction_input; | ||
| 166 | ltq_gpio_port[pdev->id].chip.direction_output = | ||
| 167 | ltq_gpio_direction_output; | ||
| 168 | ltq_gpio_port[pdev->id].chip.get = ltq_gpio_get; | ||
| 169 | ltq_gpio_port[pdev->id].chip.set = ltq_gpio_set; | ||
| 170 | ltq_gpio_port[pdev->id].chip.request = ltq_gpio_req; | ||
| 171 | ltq_gpio_port[pdev->id].chip.base = PINS_PER_PORT * pdev->id; | ||
| 172 | ltq_gpio_port[pdev->id].chip.ngpio = PINS_PER_PORT; | ||
| 173 | platform_set_drvdata(pdev, <q_gpio_port[pdev->id]); | ||
| 174 | return gpiochip_add(<q_gpio_port[pdev->id].chip); | ||
| 175 | } | ||
| 176 | |||
| 177 | static struct platform_driver | ||
| 178 | ltq_gpio_driver = { | ||
| 179 | .probe = ltq_gpio_probe, | ||
| 180 | .driver = { | ||
| 181 | .name = "ltq_gpio", | ||
| 182 | .owner = THIS_MODULE, | ||
| 183 | }, | ||
| 184 | }; | ||
| 185 | |||
| 186 | int __init ltq_gpio_init(void) | ||
| 187 | { | ||
| 188 | int ret = platform_driver_register(<q_gpio_driver); | ||
| 189 | |||
| 190 | if (ret) | ||
| 191 | pr_info("ltq_gpio : Error registering platfom driver!"); | ||
| 192 | return ret; | ||
| 193 | } | ||
| 194 | |||
| 195 | postcore_initcall(ltq_gpio_init); | ||
diff --git a/arch/mips/lantiq/xway/gpio_ebu.c b/arch/mips/lantiq/xway/gpio_ebu.c new file mode 100644 index 00000000000..a479355abdb --- /dev/null +++ b/arch/mips/lantiq/xway/gpio_ebu.c | |||
| @@ -0,0 +1,126 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or modify it | ||
| 3 | * under the terms of the GNU General Public License version 2 as published | ||
| 4 | * by the Free Software Foundation. | ||
| 5 | * | ||
| 6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <linux/init.h> | ||
| 10 | #include <linux/module.h> | ||
| 11 | #include <linux/types.h> | ||
| 12 | #include <linux/platform_device.h> | ||
| 13 | #include <linux/mutex.h> | ||
| 14 | #include <linux/gpio.h> | ||
| 15 | #include <linux/io.h> | ||
| 16 | |||
| 17 | #include <lantiq_soc.h> | ||
| 18 | |||
| 19 | /* | ||
| 20 | * By attaching hardware latches to the EBU it is possible to create output | ||
| 21 | * only gpios. This driver configures a special memory address, which when | ||
| 22 | * written to outputs 16 bit to the latches. | ||
| 23 | */ | ||
| 24 | |||
| 25 | #define LTQ_EBU_BUSCON 0x1e7ff /* 16 bit access, slowest timing */ | ||
| 26 | #define LTQ_EBU_WP 0x80000000 /* write protect bit */ | ||
| 27 | |||
| 28 | /* we keep a shadow value of the last value written to the ebu */ | ||
| 29 | static int ltq_ebu_gpio_shadow = 0x0; | ||
| 30 | static void __iomem *ltq_ebu_gpio_membase; | ||
| 31 | |||
| 32 | static void ltq_ebu_apply(void) | ||
| 33 | { | ||
| 34 | unsigned long flags; | ||
| 35 | |||
| 36 | spin_lock_irqsave(&ebu_lock, flags); | ||
| 37 | ltq_ebu_w32(LTQ_EBU_BUSCON, LTQ_EBU_BUSCON1); | ||
| 38 | *((__u16 *)ltq_ebu_gpio_membase) = ltq_ebu_gpio_shadow; | ||
| 39 | ltq_ebu_w32(LTQ_EBU_BUSCON | LTQ_EBU_WP, LTQ_EBU_BUSCON1); | ||
| 40 | spin_unlock_irqrestore(&ebu_lock, flags); | ||
| 41 | } | ||
| 42 | |||
| 43 | static void ltq_ebu_set(struct gpio_chip *chip, unsigned offset, int value) | ||
| 44 | { | ||
| 45 | if (value) | ||
| 46 | ltq_ebu_gpio_shadow |= (1 << offset); | ||
| 47 | else | ||
| 48 | ltq_ebu_gpio_shadow &= ~(1 << offset); | ||
| 49 | ltq_ebu_apply(); | ||
| 50 | } | ||
| 51 | |||
| 52 | static int ltq_ebu_direction_output(struct gpio_chip *chip, unsigned offset, | ||
| 53 | int value) | ||
| 54 | { | ||
| 55 | ltq_ebu_set(chip, offset, value); | ||
| 56 | |||
| 57 | return 0; | ||
| 58 | } | ||
| 59 | |||
| 60 | static struct gpio_chip ltq_ebu_chip = { | ||
| 61 | .label = "ltq_ebu", | ||
| 62 | .direction_output = ltq_ebu_direction_output, | ||
| 63 | .set = ltq_ebu_set, | ||
| 64 | .base = 72, | ||
| 65 | .ngpio = 16, | ||
| 66 | .can_sleep = 1, | ||
| 67 | .owner = THIS_MODULE, | ||
| 68 | }; | ||
| 69 | |||
| 70 | static int ltq_ebu_probe(struct platform_device *pdev) | ||
| 71 | { | ||
| 72 | int ret = 0; | ||
| 73 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 74 | |||
| 75 | if (!res) { | ||
| 76 | dev_err(&pdev->dev, "failed to get memory resource\n"); | ||
| 77 | return -ENOENT; | ||
| 78 | } | ||
| 79 | |||
| 80 | res = devm_request_mem_region(&pdev->dev, res->start, | ||
| 81 | resource_size(res), dev_name(&pdev->dev)); | ||
| 82 | if (!res) { | ||
| 83 | dev_err(&pdev->dev, "failed to request memory resource\n"); | ||
| 84 | return -EBUSY; | ||
| 85 | } | ||
| 86 | |||
| 87 | ltq_ebu_gpio_membase = devm_ioremap_nocache(&pdev->dev, res->start, | ||
| 88 | resource_size(res)); | ||
| 89 | if (!ltq_ebu_gpio_membase) { | ||
| 90 | dev_err(&pdev->dev, "Failed to ioremap mem region\n"); | ||
| 91 | return -ENOMEM; | ||
| 92 | } | ||
| 93 | |||
| 94 | /* grab the default shadow value passed form the platform code */ | ||
| 95 | ltq_ebu_gpio_shadow = (unsigned int) pdev->dev.platform_data; | ||
| 96 | |||
| 97 | /* tell the ebu controller which memory address we will be using */ | ||
| 98 | ltq_ebu_w32(pdev->resource->start | 0x1, LTQ_EBU_ADDRSEL1); | ||
| 99 | |||
| 100 | /* write protect the region */ | ||
| 101 | ltq_ebu_w32(LTQ_EBU_BUSCON | LTQ_EBU_WP, LTQ_EBU_BUSCON1); | ||
| 102 | |||
| 103 | ret = gpiochip_add(<q_ebu_chip); | ||
| 104 | if (!ret) | ||
| 105 | ltq_ebu_apply(); | ||
| 106 | return ret; | ||
| 107 | } | ||
| 108 | |||
| 109 | static struct platform_driver ltq_ebu_driver = { | ||
| 110 | .probe = ltq_ebu_probe, | ||
| 111 | .driver = { | ||
| 112 | .name = "ltq_ebu", | ||
| 113 | .owner = THIS_MODULE, | ||
| 114 | }, | ||
| 115 | }; | ||
| 116 | |||
| 117 | static int __init ltq_ebu_init(void) | ||
| 118 | { | ||
| 119 | int ret = platform_driver_register(<q_ebu_driver); | ||
| 120 | |||
| 121 | if (ret) | ||
| 122 | pr_info("ltq_ebu : Error registering platfom driver!"); | ||
| 123 | return ret; | ||
| 124 | } | ||
| 125 | |||
| 126 | postcore_initcall(ltq_ebu_init); | ||
diff --git a/arch/mips/lantiq/xway/gpio_stp.c b/arch/mips/lantiq/xway/gpio_stp.c new file mode 100644 index 00000000000..67d59d69034 --- /dev/null +++ b/arch/mips/lantiq/xway/gpio_stp.c | |||
| @@ -0,0 +1,157 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or modify it | ||
| 3 | * under the terms of the GNU General Public License version 2 as published | ||
| 4 | * by the Free Software Foundation. | ||
| 5 | * | ||
| 6 | * Copyright (C) 2007 John Crispin <blogic@openwrt.org> | ||
| 7 | * | ||
| 8 | */ | ||
| 9 | |||
| 10 | #include <linux/slab.h> | ||
| 11 | #include <linux/init.h> | ||
| 12 | #include <linux/module.h> | ||
| 13 | #include <linux/types.h> | ||
| 14 | #include <linux/platform_device.h> | ||
| 15 | #include <linux/mutex.h> | ||
| 16 | #include <linux/io.h> | ||
| 17 | #include <linux/gpio.h> | ||
| 18 | |||
| 19 | #include <lantiq_soc.h> | ||
| 20 | |||
| 21 | #define LTQ_STP_CON0 0x00 | ||
| 22 | #define LTQ_STP_CON1 0x04 | ||
| 23 | #define LTQ_STP_CPU0 0x08 | ||
| 24 | #define LTQ_STP_CPU1 0x0C | ||
| 25 | #define LTQ_STP_AR 0x10 | ||
| 26 | |||
| 27 | #define LTQ_STP_CON_SWU (1 << 31) | ||
| 28 | #define LTQ_STP_2HZ 0 | ||
| 29 | #define LTQ_STP_4HZ (1 << 23) | ||
| 30 | #define LTQ_STP_8HZ (2 << 23) | ||
| 31 | #define LTQ_STP_10HZ (3 << 23) | ||
| 32 | #define LTQ_STP_SPEED_MASK (0xf << 23) | ||
| 33 | #define LTQ_STP_UPD_FPI (1 << 31) | ||
| 34 | #define LTQ_STP_UPD_MASK (3 << 30) | ||
| 35 | #define LTQ_STP_ADSL_SRC (3 << 24) | ||
| 36 | |||
| 37 | #define LTQ_STP_GROUP0 (1 << 0) | ||
| 38 | |||
| 39 | #define LTQ_STP_RISING 0 | ||
| 40 | #define LTQ_STP_FALLING (1 << 26) | ||
| 41 | #define LTQ_STP_EDGE_MASK (1 << 26) | ||
| 42 | |||
| 43 | #define ltq_stp_r32(reg) __raw_readl(ltq_stp_membase + reg) | ||
| 44 | #define ltq_stp_w32(val, reg) __raw_writel(val, ltq_stp_membase + reg) | ||
| 45 | #define ltq_stp_w32_mask(clear, set, reg) \ | ||
| 46 | ltq_w32((ltq_r32(ltq_stp_membase + reg) & ~(clear)) | (set), \ | ||
| 47 | ltq_stp_membase + (reg)) | ||
| 48 | |||
| 49 | static int ltq_stp_shadow = 0xffff; | ||
| 50 | static void __iomem *ltq_stp_membase; | ||
| 51 | |||
| 52 | static void ltq_stp_set(struct gpio_chip *chip, unsigned offset, int value) | ||
| 53 | { | ||
| 54 | if (value) | ||
| 55 | ltq_stp_shadow |= (1 << offset); | ||
| 56 | else | ||
| 57 | ltq_stp_shadow &= ~(1 << offset); | ||
| 58 | ltq_stp_w32(ltq_stp_shadow, LTQ_STP_CPU0); | ||
| 59 | } | ||
| 60 | |||
| 61 | static int ltq_stp_direction_output(struct gpio_chip *chip, unsigned offset, | ||
| 62 | int value) | ||
| 63 | { | ||
| 64 | ltq_stp_set(chip, offset, value); | ||
| 65 | |||
| 66 | return 0; | ||
| 67 | } | ||
| 68 | |||
| 69 | static struct gpio_chip ltq_stp_chip = { | ||
| 70 | .label = "ltq_stp", | ||
| 71 | .direction_output = ltq_stp_direction_output, | ||
| 72 | .set = ltq_stp_set, | ||
| 73 | .base = 48, | ||
| 74 | .ngpio = 24, | ||
| 75 | .can_sleep = 1, | ||
| 76 | .owner = THIS_MODULE, | ||
| 77 | }; | ||
| 78 | |||
| 79 | static int ltq_stp_hw_init(void) | ||
| 80 | { | ||
| 81 | /* the 3 pins used to control the external stp */ | ||
| 82 | ltq_gpio_request(4, 1, 0, 1, "stp-st"); | ||
| 83 | ltq_gpio_request(5, 1, 0, 1, "stp-d"); | ||
| 84 | ltq_gpio_request(6, 1, 0, 1, "stp-sh"); | ||
| 85 | |||
| 86 | /* sane defaults */ | ||
| 87 | ltq_stp_w32(0, LTQ_STP_AR); | ||
| 88 | ltq_stp_w32(0, LTQ_STP_CPU0); | ||
| 89 | ltq_stp_w32(0, LTQ_STP_CPU1); | ||
| 90 | ltq_stp_w32(LTQ_STP_CON_SWU, LTQ_STP_CON0); | ||
| 91 | ltq_stp_w32(0, LTQ_STP_CON1); | ||
| 92 | |||
| 93 | /* rising or falling edge */ | ||
| 94 | ltq_stp_w32_mask(LTQ_STP_EDGE_MASK, LTQ_STP_FALLING, LTQ_STP_CON0); | ||
| 95 | |||
| 96 | /* per default stp 15-0 are set */ | ||
| 97 | ltq_stp_w32_mask(0, LTQ_STP_GROUP0, LTQ_STP_CON1); | ||
| 98 | |||
| 99 | /* stp are update periodically by the FPI bus */ | ||
| 100 | ltq_stp_w32_mask(LTQ_STP_UPD_MASK, LTQ_STP_UPD_FPI, LTQ_STP_CON1); | ||
| 101 | |||
| 102 | /* set stp update speed */ | ||
| 103 | ltq_stp_w32_mask(LTQ_STP_SPEED_MASK, LTQ_STP_8HZ, LTQ_STP_CON1); | ||
| 104 | |||
| 105 | /* tell the hardware that pin (led) 0 and 1 are controlled | ||
| 106 | * by the dsl arc | ||
| 107 | */ | ||
| 108 | ltq_stp_w32_mask(0, LTQ_STP_ADSL_SRC, LTQ_STP_CON0); | ||
| 109 | |||
| 110 | ltq_pmu_enable(PMU_LED); | ||
| 111 | return 0; | ||
| 112 | } | ||
| 113 | |||
| 114 | static int __devinit ltq_stp_probe(struct platform_device *pdev) | ||
| 115 | { | ||
| 116 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 117 | int ret = 0; | ||
| 118 | |||
| 119 | if (!res) | ||
| 120 | return -ENOENT; | ||
| 121 | res = devm_request_mem_region(&pdev->dev, res->start, | ||
| 122 | resource_size(res), dev_name(&pdev->dev)); | ||
| 123 | if (!res) { | ||
| 124 | dev_err(&pdev->dev, "failed to request STP memory\n"); | ||
| 125 | return -EBUSY; | ||
| 126 | } | ||
| 127 | ltq_stp_membase = devm_ioremap_nocache(&pdev->dev, res->start, | ||
| 128 | resource_size(res)); | ||
| 129 | if (!ltq_stp_membase) { | ||
| 130 | dev_err(&pdev->dev, "failed to remap STP memory\n"); | ||
| 131 | return -ENOMEM; | ||
| 132 | } | ||
| 133 | ret = gpiochip_add(<q_stp_chip); | ||
| 134 | if (!ret) | ||
| 135 | ret = ltq_stp_hw_init(); | ||
| 136 | |||
| 137 | return ret; | ||
| 138 | } | ||
| 139 | |||
| 140 | static struct platform_driver ltq_stp_driver = { | ||
| 141 | .probe = ltq_stp_probe, | ||
| 142 | .driver = { | ||
| 143 | .name = "ltq_stp", | ||
| 144 | .owner = THIS_MODULE, | ||
| 145 | }, | ||
| 146 | }; | ||
| 147 | |||
| 148 | int __init ltq_stp_init(void) | ||
| 149 | { | ||
| 150 | int ret = platform_driver_register(<q_stp_driver); | ||
| 151 | |||
| 152 | if (ret) | ||
| 153 | pr_info("ltq_stp: error registering platfom driver"); | ||
| 154 | return ret; | ||
| 155 | } | ||
| 156 | |||
| 157 | postcore_initcall(ltq_stp_init); | ||
diff --git a/arch/mips/lantiq/xway/mach-easy50601.c b/arch/mips/lantiq/xway/mach-easy50601.c new file mode 100644 index 00000000000..d5aaf637ab1 --- /dev/null +++ b/arch/mips/lantiq/xway/mach-easy50601.c | |||
| @@ -0,0 +1,57 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or modify it | ||
| 3 | * under the terms of the GNU General Public License version 2 as published | ||
| 4 | * by the Free Software Foundation. | ||
| 5 | * | ||
| 6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <linux/init.h> | ||
| 10 | #include <linux/platform_device.h> | ||
| 11 | #include <linux/mtd/mtd.h> | ||
| 12 | #include <linux/mtd/partitions.h> | ||
| 13 | #include <linux/mtd/physmap.h> | ||
| 14 | #include <linux/input.h> | ||
| 15 | |||
| 16 | #include <lantiq.h> | ||
| 17 | |||
| 18 | #include "../machtypes.h" | ||
| 19 | #include "devices.h" | ||
| 20 | |||
| 21 | static struct mtd_partition easy50601_partitions[] = { | ||
| 22 | { | ||
| 23 | .name = "uboot", | ||
| 24 | .offset = 0x0, | ||
| 25 | .size = 0x10000, | ||
| 26 | }, | ||
| 27 | { | ||
| 28 | .name = "uboot_env", | ||
| 29 | .offset = 0x10000, | ||
| 30 | .size = 0x10000, | ||
| 31 | }, | ||
| 32 | { | ||
| 33 | .name = "linux", | ||
| 34 | .offset = 0x20000, | ||
| 35 | .size = 0xE0000, | ||
| 36 | }, | ||
| 37 | { | ||
| 38 | .name = "rootfs", | ||
| 39 | .offset = 0x100000, | ||
| 40 | .size = 0x300000, | ||
| 41 | }, | ||
| 42 | }; | ||
| 43 | |||
| 44 | static struct physmap_flash_data easy50601_flash_data = { | ||
| 45 | .nr_parts = ARRAY_SIZE(easy50601_partitions), | ||
| 46 | .parts = easy50601_partitions, | ||
| 47 | }; | ||
| 48 | |||
| 49 | static void __init easy50601_init(void) | ||
| 50 | { | ||
| 51 | ltq_register_nor(&easy50601_flash_data); | ||
| 52 | } | ||
| 53 | |||
| 54 | MIPS_MACHINE(LTQ_MACH_EASY50601, | ||
| 55 | "EASY50601", | ||
| 56 | "EASY50601 Eval Board", | ||
| 57 | easy50601_init); | ||
diff --git a/arch/mips/lantiq/xway/mach-easy50712.c b/arch/mips/lantiq/xway/mach-easy50712.c new file mode 100644 index 00000000000..ea5027b3239 --- /dev/null +++ b/arch/mips/lantiq/xway/mach-easy50712.c | |||
| @@ -0,0 +1,74 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or modify it | ||
| 3 | * under the terms of the GNU General Public License version 2 as published | ||
| 4 | * by the Free Software Foundation. | ||
| 5 | * | ||
| 6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <linux/init.h> | ||
| 10 | #include <linux/platform_device.h> | ||
| 11 | #include <linux/mtd/mtd.h> | ||
| 12 | #include <linux/mtd/partitions.h> | ||
| 13 | #include <linux/mtd/physmap.h> | ||
| 14 | #include <linux/input.h> | ||
| 15 | #include <linux/phy.h> | ||
| 16 | |||
| 17 | #include <lantiq_soc.h> | ||
| 18 | #include <irq.h> | ||
| 19 | |||
| 20 | #include "../machtypes.h" | ||
| 21 | #include "devices.h" | ||
| 22 | |||
| 23 | static struct mtd_partition easy50712_partitions[] = { | ||
| 24 | { | ||
| 25 | .name = "uboot", | ||
| 26 | .offset = 0x0, | ||
| 27 | .size = 0x10000, | ||
| 28 | }, | ||
| 29 | { | ||
| 30 | .name = "uboot_env", | ||
| 31 | .offset = 0x10000, | ||
| 32 | .size = 0x10000, | ||
| 33 | }, | ||
| 34 | { | ||
| 35 | .name = "linux", | ||
| 36 | .offset = 0x20000, | ||
| 37 | .size = 0xe0000, | ||
| 38 | }, | ||
| 39 | { | ||
| 40 | .name = "rootfs", | ||
| 41 | .offset = 0x100000, | ||
| 42 | .size = 0x300000, | ||
| 43 | }, | ||
| 44 | }; | ||
| 45 | |||
| 46 | static struct physmap_flash_data easy50712_flash_data = { | ||
| 47 | .nr_parts = ARRAY_SIZE(easy50712_partitions), | ||
| 48 | .parts = easy50712_partitions, | ||
| 49 | }; | ||
| 50 | |||
| 51 | static struct ltq_pci_data ltq_pci_data = { | ||
| 52 | .clock = PCI_CLOCK_INT, | ||
| 53 | .gpio = PCI_GNT1 | PCI_REQ1, | ||
| 54 | .irq = { | ||
| 55 | [14] = INT_NUM_IM0_IRL0 + 22, | ||
| 56 | }, | ||
| 57 | }; | ||
| 58 | |||
| 59 | static struct ltq_eth_data ltq_eth_data = { | ||
| 60 | .mii_mode = PHY_INTERFACE_MODE_MII, | ||
| 61 | }; | ||
| 62 | |||
| 63 | static void __init easy50712_init(void) | ||
| 64 | { | ||
| 65 | ltq_register_gpio_stp(); | ||
| 66 | ltq_register_nor(&easy50712_flash_data); | ||
| 67 | ltq_register_pci(<q_pci_data); | ||
| 68 | ltq_register_etop(<q_eth_data); | ||
| 69 | } | ||
| 70 | |||
| 71 | MIPS_MACHINE(LTQ_MACH_EASY50712, | ||
| 72 | "EASY50712", | ||
| 73 | "EASY50712 Eval Board", | ||
| 74 | easy50712_init); | ||
diff --git a/arch/mips/lantiq/xway/pmu.c b/arch/mips/lantiq/xway/pmu.c new file mode 100644 index 00000000000..39f0d2641cb --- /dev/null +++ b/arch/mips/lantiq/xway/pmu.c | |||
| @@ -0,0 +1,69 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or modify it | ||
| 3 | * under the terms of the GNU General Public License version 2 as published | ||
| 4 | * by the Free Software Foundation. | ||
| 5 | * | ||
| 6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <linux/kernel.h> | ||
| 10 | #include <linux/module.h> | ||
| 11 | #include <linux/ioport.h> | ||
| 12 | |||
| 13 | #include <lantiq_soc.h> | ||
| 14 | |||
| 15 | /* PMU - the power management unit allows us to turn part of the core | ||
| 16 | * on and off | ||
| 17 | */ | ||
| 18 | |||
| 19 | /* the enable / disable registers */ | ||
| 20 | #define LTQ_PMU_PWDCR 0x1C | ||
| 21 | #define LTQ_PMU_PWDSR 0x20 | ||
| 22 | |||
| 23 | #define ltq_pmu_w32(x, y) ltq_w32((x), ltq_pmu_membase + (y)) | ||
| 24 | #define ltq_pmu_r32(x) ltq_r32(ltq_pmu_membase + (x)) | ||
| 25 | |||
| 26 | static struct resource ltq_pmu_resource = { | ||
| 27 | .name = "pmu", | ||
| 28 | .start = LTQ_PMU_BASE_ADDR, | ||
| 29 | .end = LTQ_PMU_BASE_ADDR + LTQ_PMU_SIZE - 1, | ||
| 30 | .flags = IORESOURCE_MEM, | ||
| 31 | }; | ||
| 32 | |||
| 33 | static void __iomem *ltq_pmu_membase; | ||
| 34 | |||
| 35 | void ltq_pmu_enable(unsigned int module) | ||
| 36 | { | ||
| 37 | int err = 1000000; | ||
| 38 | |||
| 39 | ltq_pmu_w32(ltq_pmu_r32(LTQ_PMU_PWDCR) & ~module, LTQ_PMU_PWDCR); | ||
| 40 | do {} while (--err && (ltq_pmu_r32(LTQ_PMU_PWDSR) & module)); | ||
| 41 | |||
| 42 | if (!err) | ||
| 43 | panic("activating PMU module failed!\n"); | ||
| 44 | } | ||
| 45 | EXPORT_SYMBOL(ltq_pmu_enable); | ||
| 46 | |||
| 47 | void ltq_pmu_disable(unsigned int module) | ||
| 48 | { | ||
| 49 | ltq_pmu_w32(ltq_pmu_r32(LTQ_PMU_PWDCR) | module, LTQ_PMU_PWDCR); | ||
| 50 | } | ||
| 51 | EXPORT_SYMBOL(ltq_pmu_disable); | ||
| 52 | |||
| 53 | int __init ltq_pmu_init(void) | ||
| 54 | { | ||
| 55 | if (insert_resource(&iomem_resource, <q_pmu_resource) < 0) | ||
| 56 | panic("Failed to insert pmu memory\n"); | ||
| 57 | |||
| 58 | if (request_mem_region(ltq_pmu_resource.start, | ||
| 59 | resource_size(<q_pmu_resource), "pmu") < 0) | ||
| 60 | panic("Failed to request pmu memory\n"); | ||
| 61 | |||
| 62 | ltq_pmu_membase = ioremap_nocache(ltq_pmu_resource.start, | ||
| 63 | resource_size(<q_pmu_resource)); | ||
| 64 | if (!ltq_pmu_membase) | ||
| 65 | panic("Failed to remap pmu memory\n"); | ||
| 66 | return 0; | ||
| 67 | } | ||
| 68 | |||
| 69 | core_initcall(ltq_pmu_init); | ||
diff --git a/arch/mips/lantiq/xway/prom-ase.c b/arch/mips/lantiq/xway/prom-ase.c new file mode 100644 index 00000000000..abe49f4db57 --- /dev/null +++ b/arch/mips/lantiq/xway/prom-ase.c | |||
| @@ -0,0 +1,39 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or modify it | ||
| 3 | * under the terms of the GNU General Public License version 2 as published | ||
| 4 | * by the Free Software Foundation. | ||
| 5 | * | ||
| 6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <linux/module.h> | ||
| 10 | #include <linux/clk.h> | ||
| 11 | #include <asm/bootinfo.h> | ||
| 12 | #include <asm/time.h> | ||
| 13 | |||
| 14 | #include <lantiq_soc.h> | ||
| 15 | |||
| 16 | #include "../prom.h" | ||
| 17 | |||
| 18 | #define SOC_AMAZON_SE "Amazon_SE" | ||
| 19 | |||
| 20 | #define PART_SHIFT 12 | ||
| 21 | #define PART_MASK 0x0FFFFFFF | ||
| 22 | #define REV_SHIFT 28 | ||
| 23 | #define REV_MASK 0xF0000000 | ||
| 24 | |||
| 25 | void __init ltq_soc_detect(struct ltq_soc_info *i) | ||
| 26 | { | ||
| 27 | i->partnum = (ltq_r32(LTQ_MPS_CHIPID) & PART_MASK) >> PART_SHIFT; | ||
| 28 | i->rev = (ltq_r32(LTQ_MPS_CHIPID) & REV_MASK) >> REV_SHIFT; | ||
| 29 | switch (i->partnum) { | ||
| 30 | case SOC_ID_AMAZON_SE: | ||
| 31 | i->name = SOC_AMAZON_SE; | ||
| 32 | i->type = SOC_TYPE_AMAZON_SE; | ||
| 33 | break; | ||
| 34 | |||
| 35 | default: | ||
| 36 | unreachable(); | ||
| 37 | break; | ||
| 38 | } | ||
| 39 | } | ||
diff --git a/arch/mips/lantiq/xway/prom-xway.c b/arch/mips/lantiq/xway/prom-xway.c new file mode 100644 index 00000000000..1686692ac24 --- /dev/null +++ b/arch/mips/lantiq/xway/prom-xway.c | |||
| @@ -0,0 +1,54 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or modify it | ||
| 3 | * under the terms of the GNU General Public License version 2 as published | ||
| 4 | * by the Free Software Foundation. | ||
| 5 | * | ||
| 6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <linux/module.h> | ||
| 10 | #include <linux/clk.h> | ||
| 11 | #include <asm/bootinfo.h> | ||
| 12 | #include <asm/time.h> | ||
| 13 | |||
| 14 | #include <lantiq_soc.h> | ||
| 15 | |||
| 16 | #include "../prom.h" | ||
| 17 | |||
| 18 | #define SOC_DANUBE "Danube" | ||
| 19 | #define SOC_TWINPASS "Twinpass" | ||
| 20 | #define SOC_AR9 "AR9" | ||
| 21 | |||
| 22 | #define PART_SHIFT 12 | ||
| 23 | #define PART_MASK 0x0FFFFFFF | ||
| 24 | #define REV_SHIFT 28 | ||
| 25 | #define REV_MASK 0xF0000000 | ||
| 26 | |||
| 27 | void __init ltq_soc_detect(struct ltq_soc_info *i) | ||
| 28 | { | ||
| 29 | i->partnum = (ltq_r32(LTQ_MPS_CHIPID) & PART_MASK) >> PART_SHIFT; | ||
| 30 | i->rev = (ltq_r32(LTQ_MPS_CHIPID) & REV_MASK) >> REV_SHIFT; | ||
| 31 | switch (i->partnum) { | ||
| 32 | case SOC_ID_DANUBE1: | ||
| 33 | case SOC_ID_DANUBE2: | ||
| 34 | i->name = SOC_DANUBE; | ||
| 35 | i->type = SOC_TYPE_DANUBE; | ||
| 36 | break; | ||
| 37 | |||
| 38 | case SOC_ID_TWINPASS: | ||
| 39 | i->name = SOC_TWINPASS; | ||
| 40 | i->type = SOC_TYPE_DANUBE; | ||
| 41 | break; | ||
| 42 | |||
| 43 | case SOC_ID_ARX188: | ||
| 44 | case SOC_ID_ARX168: | ||
| 45 | case SOC_ID_ARX182: | ||
| 46 | i->name = SOC_AR9; | ||
| 47 | i->type = SOC_TYPE_AR9; | ||
| 48 | break; | ||
| 49 | |||
| 50 | default: | ||
| 51 | unreachable(); | ||
| 52 | break; | ||
| 53 | } | ||
| 54 | } | ||
diff --git a/arch/mips/lantiq/xway/setup-ase.c b/arch/mips/lantiq/xway/setup-ase.c new file mode 100644 index 00000000000..f6f326798a3 --- /dev/null +++ b/arch/mips/lantiq/xway/setup-ase.c | |||
| @@ -0,0 +1,19 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or modify it | ||
| 3 | * under the terms of the GNU General Public License version 2 as published | ||
| 4 | * by the Free Software Foundation. | ||
| 5 | * | ||
| 6 | * Copyright (C) 2011 John Crispin <blogic@openwrt.org> | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <lantiq_soc.h> | ||
| 10 | |||
| 11 | #include "../prom.h" | ||
| 12 | #include "devices.h" | ||
| 13 | |||
| 14 | void __init ltq_soc_setup(void) | ||
| 15 | { | ||
| 16 | ltq_register_ase_asc(); | ||
| 17 | ltq_register_gpio(); | ||
| 18 | ltq_register_wdt(); | ||
| 19 | } | ||
diff --git a/arch/mips/lantiq/xway/setup-xway.c b/arch/mips/lantiq/xway/setup-xway.c new file mode 100644 index 00000000000..c292f643a85 --- /dev/null +++ b/arch/mips/lantiq/xway/setup-xway.c | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or modify it | ||
| 3 | * under the terms of the GNU General Public License version 2 as published | ||
| 4 | * by the Free Software Foundation. | ||
| 5 | * | ||
| 6 | * Copyright (C) 2011 John Crispin <blogic@openwrt.org> | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <lantiq_soc.h> | ||
| 10 | |||
| 11 | #include "../prom.h" | ||
| 12 | #include "devices.h" | ||
| 13 | |||
| 14 | void __init ltq_soc_setup(void) | ||
| 15 | { | ||
| 16 | ltq_register_asc(0); | ||
| 17 | ltq_register_asc(1); | ||
| 18 | ltq_register_gpio(); | ||
| 19 | ltq_register_wdt(); | ||
| 20 | } | ||
