diff options
author | Imre Kaloz <kaloz@openwrt.org> | 2008-06-04 13:51:17 +0000 |
---|---|---|
committer | Imre Kaloz <kaloz@openwrt.org> | 2008-06-04 13:51:17 +0000 |
commit | 7bb65fb9d7860faa4b9b1e07790fb5823a0249e2 (patch) | |
tree | 701aabf12d94bdeddafbf8d328dee2492eef9ad5 /target/linux/orion/patches | |
parent | 0244e57bb9fb9ebd1dd224bd5789ad9cc24b0175 (diff) | |
download | upstream-7bb65fb9d7860faa4b9b1e07790fb5823a0249e2.tar.gz upstream-7bb65fb9d7860faa4b9b1e07790fb5823a0249e2.tar.bz2 upstream-7bb65fb9d7860faa4b9b1e07790fb5823a0249e2.zip |
add preliminary Marvell Orion support
SVN-Revision: 11352
Diffstat (limited to 'target/linux/orion/patches')
19 files changed, 3991 insertions, 0 deletions
diff --git a/target/linux/orion/patches/001-latencytop_support.patch b/target/linux/orion/patches/001-latencytop_support.patch new file mode 100644 index 0000000000..a1fbc17f54 --- /dev/null +++ b/target/linux/orion/patches/001-latencytop_support.patch @@ -0,0 +1,82 @@ +From: Nicolas Pitre <nico@cam.org> + +Signed-off-by: Nicolas Pitre <nico@marvell.com> +Tested-by: Lennert Buytenhek <buytenh@marvell.com> +Signed-off-by: Lennert Buytenhek <buytenh@marvell.com> +--- + arch/arm/Kconfig | 4 ++++ + arch/arm/kernel/stacktrace.c | 26 ++++++++++++++++++++++---- + 2 files changed, 26 insertions(+), 4 deletions(-) + +--- a/arch/arm/Kconfig ++++ b/arch/arm/Kconfig +@@ -84,6 +84,10 @@ + bool + default y + ++config HAVE_LATENCYTOP_SUPPORT ++ bool ++ default y ++ + config LOCKDEP_SUPPORT + bool + default y +--- a/arch/arm/kernel/stacktrace.c ++++ b/arch/arm/kernel/stacktrace.c +@@ -36,6 +36,7 @@ + #ifdef CONFIG_STACKTRACE + struct stack_trace_data { + struct stack_trace *trace; ++ unsigned int no_sched_functions; + unsigned int skip; + }; + +@@ -43,27 +44,44 @@ + { + struct stack_trace_data *data = d; + struct stack_trace *trace = data->trace; ++ unsigned long addr = frame->lr; + ++ if (data->no_sched_functions && in_sched_functions(addr)) ++ return 0; + if (data->skip) { + data->skip--; + return 0; + } + +- trace->entries[trace->nr_entries++] = frame->lr; ++ trace->entries[trace->nr_entries++] = addr; + + return trace->nr_entries >= trace->max_entries; + } + +-void save_stack_trace(struct stack_trace *trace) ++void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) + { + struct stack_trace_data data; + unsigned long fp, base; + + data.trace = trace; + data.skip = trace->skip; +- base = (unsigned long)task_stack_page(current); +- asm("mov %0, fp" : "=r" (fp)); ++ base = (unsigned long)task_stack_page(tsk); ++ ++ if (tsk != current) { ++ data.no_sched_functions = 1; ++ fp = thread_saved_fp(tsk); ++ } else { ++ data.no_sched_functions = 0; ++ asm("mov %0, fp" : "=r" (fp)); ++ } + + walk_stackframe(fp, base, base + THREAD_SIZE, save_trace, &data); ++ if (trace->nr_entries < trace->max_entries) ++ trace->entries[trace->nr_entries++] = ULONG_MAX; ++} ++ ++void save_stack_trace(struct stack_trace *trace) ++{ ++ save_stack_trace_tsk(current, trace); + } + #endif diff --git a/target/linux/orion/patches/002-feroceon__speed_up_flushing_of_the_entire_cache.patch b/target/linux/orion/patches/002-feroceon__speed_up_flushing_of_the_entire_cache.patch new file mode 100644 index 0000000000..c2efe5be22 --- /dev/null +++ b/target/linux/orion/patches/002-feroceon__speed_up_flushing_of_the_entire_cache.patch @@ -0,0 +1,117 @@ +Flushing the L1 D cache with a test/clean/invalidate loop is very +easy in software, but it is not the quickest way of doing it, as +there is a lot of overhead involved in re-scanning the cache from +the beginning every time we hit a dirty line. + +This patch makes proc-feroceon.S use "clean+invalidate by set/way" +loops according to possible cache configuration of Feroceon CPUs +(either direct-mapped or 4-way set associative). + +[nico: optimized the assembly a bit] + +Signed-off-by: Lennert Buytenhek <buytenh@marvell.com> +Signed-off-by: Nicolas Pitre <nico@marvell.com> +--- + arch/arm/mm/proc-feroceon.S | 53 ++++++++++++++++++++++++++++++++++--------- + 1 files changed, 42 insertions(+), 11 deletions(-) + +--- a/arch/arm/mm/proc-feroceon.S ++++ b/arch/arm/mm/proc-feroceon.S +@@ -44,11 +44,31 @@ + */ + #define CACHE_DLINESIZE 32 + ++ .bss ++ .align 3 ++__cache_params_loc: ++ .space 8 ++ + .text ++__cache_params: ++ .word __cache_params_loc ++ + /* + * cpu_feroceon_proc_init() + */ + ENTRY(cpu_feroceon_proc_init) ++ mrc p15, 0, r0, c0, c0, 1 @ read cache type register ++ ldr r1, __cache_params ++ mov r2, #(16 << 5) ++ tst r0, #(1 << 16) @ get way ++ mov r0, r0, lsr #18 @ get cache size order ++ movne r3, #((4 - 1) << 30) @ 4-way ++ and r0, r0, #0xf ++ moveq r3, #0 @ 1-way ++ mov r2, r2, lsl r0 @ actual cache size ++ movne r2, r2, lsr #2 @ turned into # of sets ++ sub r2, r2, #(1 << 5) ++ stmia r1, {r2, r3} + mov pc, lr + + /* +@@ -117,11 +137,19 @@ + */ + ENTRY(feroceon_flush_kern_cache_all) + mov r2, #VM_EXEC +- mov ip, #0 ++ + __flush_whole_cache: +-1: mrc p15, 0, r15, c7, c14, 3 @ test,clean,invalidate +- bne 1b ++ ldr r1, __cache_params ++ ldmia r1, {r1, r3} ++1: orr ip, r1, r3 ++2: mcr p15, 0, ip, c7, c14, 2 @ clean + invalidate D set/way ++ subs ip, ip, #(1 << 30) @ next way ++ bcs 2b ++ subs r1, r1, #(1 << 5) @ next set ++ bcs 1b ++ + tst r2, #VM_EXEC ++ mov ip, #0 + mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache + mcrne p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr +@@ -138,7 +166,6 @@ + */ + .align 5 + ENTRY(feroceon_flush_user_cache_range) +- mov ip, #0 + sub r3, r1, r0 @ calculate total size + cmp r3, #CACHE_DLIMIT + bgt __flush_whole_cache +@@ -152,6 +179,7 @@ + cmp r0, r1 + blo 1b + tst r2, #VM_EXEC ++ mov ip, #0 + mcrne p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +@@ -306,16 +334,19 @@ + .align 5 + ENTRY(cpu_feroceon_switch_mm) + #ifdef CONFIG_MMU +- mov ip, #0 +-@ && 'Clean & Invalidate whole DCache' +-1: mrc p15, 0, r15, c7, c14, 3 @ test,clean,invalidate +- bne 1b +- mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache +- mcr p15, 0, ip, c7, c10, 4 @ drain WB ++ mov r2, lr @ abuse r2 to preserve lr ++ bl __flush_whole_cache ++ @ if r2 contains the VM_EXEC bit then the next 2 ops are done already ++ tst r2, #VM_EXEC ++ mcreq p15, 0, ip, c7, c5, 0 @ invalidate I cache ++ mcreq p15, 0, ip, c7, c10, 4 @ drain WB ++ + mcr p15, 0, r0, c2, c0, 0 @ load page table pointer + mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs +-#endif ++ mov pc, r2 ++#else + mov pc, lr ++#endif + + /* + * cpu_feroceon_set_pte_ext(ptep, pte, ext) diff --git a/target/linux/orion/patches/003-fix_various_whitespace_and_coding_style.patch b/target/linux/orion/patches/003-fix_various_whitespace_and_coding_style.patch new file mode 100644 index 0000000000..02126ca33f --- /dev/null +++ b/target/linux/orion/patches/003-fix_various_whitespace_and_coding_style.patch @@ -0,0 +1,647 @@ +More cosmetic cleanup: +- Replace 8-space indents by proper tab indents. +- In structure initialisers, use a trailing comma for every member. +- Collapse "},\n{" in structure initialiers to "}, {". + +Signed-off-by: Lennert Buytenhek <buytenh@marvell.com> +--- + arch/arm/mach-orion5x/common.c | 91 +++++++++++-------------- + arch/arm/mach-orion5x/db88f5281-setup.c | 13 ++-- + arch/arm/mach-orion5x/dns323-setup.c | 33 +++++---- + arch/arm/mach-orion5x/kurobox_pro-setup.c | 8 +-- + arch/arm/mach-orion5x/pci.c | 14 ++-- + arch/arm/mach-orion5x/rd88f5182-setup.c | 3 +- + arch/arm/mach-orion5x/ts209-setup.c | 103 +++++++++++++++-------------- + arch/arm/mm/proc-feroceon.S | 8 +- + 8 files changed, 132 insertions(+), 141 deletions(-) + +--- a/arch/arm/mach-orion5x/common.c ++++ b/arch/arm/mach-orion5x/common.c +@@ -39,25 +39,22 @@ + .virtual = ORION5X_REGS_VIRT_BASE, + .pfn = __phys_to_pfn(ORION5X_REGS_PHYS_BASE), + .length = ORION5X_REGS_SIZE, +- .type = MT_DEVICE +- }, +- { ++ .type = MT_DEVICE, ++ }, { + .virtual = ORION5X_PCIE_IO_VIRT_BASE, + .pfn = __phys_to_pfn(ORION5X_PCIE_IO_PHYS_BASE), + .length = ORION5X_PCIE_IO_SIZE, +- .type = MT_DEVICE +- }, +- { ++ .type = MT_DEVICE, ++ }, { + .virtual = ORION5X_PCI_IO_VIRT_BASE, + .pfn = __phys_to_pfn(ORION5X_PCI_IO_PHYS_BASE), + .length = ORION5X_PCI_IO_SIZE, +- .type = MT_DEVICE +- }, +- { ++ .type = MT_DEVICE, ++ }, { + .virtual = ORION5X_PCIE_WA_VIRT_BASE, + .pfn = __phys_to_pfn(ORION5X_PCIE_WA_PHYS_BASE), + .length = ORION5X_PCIE_WA_SIZE, +- .type = MT_DEVICE ++ .type = MT_DEVICE, + }, + }; + +@@ -75,18 +72,15 @@ + .start = UART0_PHYS_BASE, + .end = UART0_PHYS_BASE + 0xff, + .flags = IORESOURCE_MEM, +- }, +- { ++ }, { + .start = IRQ_ORION5X_UART0, + .end = IRQ_ORION5X_UART0, + .flags = IORESOURCE_IRQ, +- }, +- { ++ }, { + .start = UART1_PHYS_BASE, + .end = UART1_PHYS_BASE + 0xff, + .flags = IORESOURCE_MEM, +- }, +- { ++ }, { + .start = IRQ_ORION5X_UART1, + .end = IRQ_ORION5X_UART1, + .flags = IORESOURCE_IRQ, +@@ -102,8 +96,7 @@ + .iotype = UPIO_MEM, + .regshift = 2, + .uartclk = ORION5X_TCLK, +- }, +- { ++ }, { + .mapbase = UART1_PHYS_BASE, + .membase = (char *)UART1_VIRT_BASE, + .irq = IRQ_ORION5X_UART1, +@@ -111,8 +104,8 @@ + .iotype = UPIO_MEM, + .regshift = 2, + .uartclk = ORION5X_TCLK, ++ }, { + }, +- { }, + }; + + static struct platform_device orion5x_uart = { +@@ -134,8 +127,7 @@ + .start = ORION5X_USB0_PHYS_BASE, + .end = ORION5X_USB0_PHYS_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, +- }, +- { ++ }, { + .start = IRQ_ORION5X_USB0_CTRL, + .end = IRQ_ORION5X_USB0_CTRL, + .flags = IORESOURCE_IRQ, +@@ -147,8 +139,7 @@ + .start = ORION5X_USB1_PHYS_BASE, + .end = ORION5X_USB1_PHYS_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, +- }, +- { ++ }, { + .start = IRQ_ORION5X_USB1_CTRL, + .end = IRQ_ORION5X_USB1_CTRL, + .flags = IORESOURCE_IRQ, +@@ -219,7 +210,7 @@ + .start = IRQ_ORION5X_ETH_SUM, + .end = IRQ_ORION5X_ETH_SUM, + .flags = IORESOURCE_IRQ, +- } ++ }, + }; + + static struct platform_device orion5x_eth = { +@@ -251,16 +242,15 @@ + + static struct resource orion5x_i2c_resources[] = { + { +- .name = "i2c base", +- .start = I2C_PHYS_BASE, +- .end = I2C_PHYS_BASE + 0x20 -1, +- .flags = IORESOURCE_MEM, +- }, +- { +- .name = "i2c irq", +- .start = IRQ_ORION5X_I2C, +- .end = IRQ_ORION5X_I2C, +- .flags = IORESOURCE_IRQ, ++ .name = "i2c base", ++ .start = I2C_PHYS_BASE, ++ .end = I2C_PHYS_BASE + 0x20 -1, ++ .flags = IORESOURCE_MEM, ++ }, { ++ .name = "i2c irq", ++ .start = IRQ_ORION5X_I2C, ++ .end = IRQ_ORION5X_I2C, ++ .flags = IORESOURCE_IRQ, + }, + }; + +@@ -270,7 +260,7 @@ + .num_resources = ARRAY_SIZE(orion5x_i2c_resources), + .resource = orion5x_i2c_resources, + .dev = { +- .platform_data = &orion5x_i2c_pdata, ++ .platform_data = &orion5x_i2c_pdata, + }, + }; + +@@ -278,28 +268,27 @@ + * Sata port + ****************************************************************************/ + static struct resource orion5x_sata_resources[] = { +- { +- .name = "sata base", +- .start = ORION5X_SATA_PHYS_BASE, +- .end = ORION5X_SATA_PHYS_BASE + 0x5000 - 1, +- .flags = IORESOURCE_MEM, +- }, + { +- .name = "sata irq", +- .start = IRQ_ORION5X_SATA, +- .end = IRQ_ORION5X_SATA, +- .flags = IORESOURCE_IRQ, +- }, ++ .name = "sata base", ++ .start = ORION5X_SATA_PHYS_BASE, ++ .end = ORION5X_SATA_PHYS_BASE + 0x5000 - 1, ++ .flags = IORESOURCE_MEM, ++ }, { ++ .name = "sata irq", ++ .start = IRQ_ORION5X_SATA, ++ .end = IRQ_ORION5X_SATA, ++ .flags = IORESOURCE_IRQ, ++ }, + }; + + static struct platform_device orion5x_sata = { +- .name = "sata_mv", +- .id = 0, ++ .name = "sata_mv", ++ .id = 0, + .dev = { + .coherent_dma_mask = 0xffffffff, + }, +- .num_resources = ARRAY_SIZE(orion5x_sata_resources), +- .resource = orion5x_sata_resources, ++ .num_resources = ARRAY_SIZE(orion5x_sata_resources), ++ .resource = orion5x_sata_resources, + }; + + void __init orion5x_sata_init(struct mv_sata_platform_data *sata_data) +@@ -319,7 +308,7 @@ + } + + struct sys_timer orion5x_timer = { +- .init = orion5x_timer_init, ++ .init = orion5x_timer_init, + }; + + /***************************************************************************** +--- a/arch/arm/mach-orion5x/db88f5281-setup.c ++++ b/arch/arm/mach-orion5x/db88f5281-setup.c +@@ -86,7 +86,7 @@ + .name = "physmap-flash", + .id = 0, + .dev = { +- .platform_data = &db88f5281_boot_flash_data, ++ .platform_data = &db88f5281_boot_flash_data, + }, + .num_resources = 1, + .resource = &db88f5281_boot_flash_resource, +@@ -110,7 +110,7 @@ + .name = "physmap-flash", + .id = 1, + .dev = { +- .platform_data = &db88f5281_nor_flash_data, ++ .platform_data = &db88f5281_nor_flash_data, + }, + .num_resources = 1, + .resource = &db88f5281_nor_flash_resource, +@@ -125,18 +125,15 @@ + .name = "kernel", + .offset = 0, + .size = SZ_2M, +- }, +- { ++ }, { + .name = "root", + .offset = SZ_2M, + .size = (SZ_16M - SZ_2M), +- }, +- { ++ }, { + .name = "user", + .offset = SZ_16M, + .size = SZ_8M, +- }, +- { ++ }, { + .name = "recovery", + .offset = (SZ_16M + SZ_8M), + .size = SZ_8M, +--- a/arch/arm/mach-orion5x/dns323-setup.c ++++ b/arch/arm/mach-orion5x/dns323-setup.c +@@ -119,7 +119,7 @@ + .name = "u-boot", + .size = 0x00030000, + .offset = 0x007d0000, +- } ++ }, + }; + + static struct physmap_flash_data dns323_nor_flash_data = { +@@ -137,7 +137,9 @@ + static struct platform_device dns323_nor_flash = { + .name = "physmap-flash", + .id = 0, +- .dev = { .platform_data = &dns323_nor_flash_data, }, ++ .dev = { ++ .platform_data = &dns323_nor_flash_data, ++ }, + .resource = &dns323_nor_flash_resource, + .num_resources = 1, + }; +@@ -170,7 +172,9 @@ + static struct platform_device dns323_gpio_leds = { + .name = "leds-gpio", + .id = -1, +- .dev = { .platform_data = &dns323_led_data, }, ++ .dev = { ++ .platform_data = &dns323_led_data, ++ }, + }; + + /**************************************************************************** +@@ -183,25 +187,26 @@ + .gpio = DNS323_GPIO_KEY_RESET, + .desc = "Reset Button", + .active_low = 1, +- }, +- { ++ }, { + .code = KEY_POWER, + .gpio = DNS323_GPIO_KEY_POWER, + .desc = "Power Button", + .active_low = 1, +- } ++ }, + }; + + static struct gpio_keys_platform_data dns323_button_data = { + .buttons = dns323_buttons, +- .nbuttons = ARRAY_SIZE(dns323_buttons), ++ .nbuttons = ARRAY_SIZE(dns323_buttons), + }; + + static struct platform_device dns323_button_device = { + .name = "gpio-keys", + .id = -1, + .num_resources = 0, +- .dev = { .platform_data = &dns323_button_data, }, ++ .dev = { ++ .platform_data = &dns323_button_data, ++ }, + }; + + /**************************************************************************** +@@ -225,17 +230,15 @@ + static struct i2c_board_info __initdata dns323_i2c_devices[] = { + { + I2C_BOARD_INFO("g760a", 0x3e), +- }, + #if 0 + /* this entry requires the new-style driver model lm75 driver, + * for the meantime "insmod lm75.ko force_lm75=0,0x48" is needed */ +- { ++ }, { + I2C_BOARD_INFO("g751", 0x48), +- }, + #endif +- { ++ }, { + I2C_BOARD_INFO("m41t80", 0x68), +- } ++ }, + }; + + /* DNS-323 specific power off method */ +@@ -292,8 +295,8 @@ + orion5x_gpio_set_valid_pins(0x07f6); + + /* register dns323 specific power-off method */ +- if ((gpio_request(DNS323_GPIO_POWER_OFF, "POWEROFF") != 0) +- || (gpio_direction_output(DNS323_GPIO_POWER_OFF, 0) != 0)) ++ if (gpio_request(DNS323_GPIO_POWER_OFF, "POWEROFF") != 0 || ++ gpio_direction_output(DNS323_GPIO_POWER_OFF, 0) != 0) + pr_err("DNS323: failed to setup power-off GPIO\n"); + + pm_power_off = dns323_power_off; +--- a/arch/arm/mach-orion5x/kurobox_pro-setup.c ++++ b/arch/arm/mach-orion5x/kurobox_pro-setup.c +@@ -53,13 +53,11 @@ + .name = "uImage", + .offset = 0, + .size = SZ_4M, +- }, +- { ++ }, { + .name = "rootfs", + .offset = SZ_4M, + .size = SZ_64M, +- }, +- { ++ }, { + .name = "extra", + .offset = SZ_4M + SZ_64M, + .size = SZ_256M - (SZ_4M + SZ_64M), +@@ -175,7 +173,7 @@ + * SATA + ****************************************************************************/ + static struct mv_sata_platform_data kurobox_pro_sata_data = { +- .n_ports = 2, ++ .n_ports = 2, + }; + + /***************************************************************************** +--- a/arch/arm/mach-orion5x/pci.c ++++ b/arch/arm/mach-orion5x/pci.c +@@ -240,13 +240,13 @@ + * PCI Address Decode Windows registers + */ + #define PCI_BAR_SIZE_DDR_CS(n) (((n) == 0) ? ORION5X_PCI_REG(0xc08) : \ +- ((n) == 1) ? ORION5X_PCI_REG(0xd08) : \ +- ((n) == 2) ? ORION5X_PCI_REG(0xc0c) : \ +- ((n) == 3) ? ORION5X_PCI_REG(0xd0c) : 0) +-#define PCI_BAR_REMAP_DDR_CS(n) (((n) ==0) ? ORION5X_PCI_REG(0xc48) : \ +- ((n) == 1) ? ORION5X_PCI_REG(0xd48) : \ +- ((n) == 2) ? ORION5X_PCI_REG(0xc4c) : \ +- ((n) == 3) ? ORION5X_PCI_REG(0xd4c) : 0) ++ ((n) == 1) ? ORION5X_PCI_REG(0xd08) : \ ++ ((n) == 2) ? ORION5X_PCI_REG(0xc0c) : \ ++ ((n) == 3) ? ORION5X_PCI_REG(0xd0c) : 0) ++#define PCI_BAR_REMAP_DDR_CS(n) (((n) == 0) ? ORION5X_PCI_REG(0xc48) : \ ++ ((n) == 1) ? ORION5X_PCI_REG(0xd48) : \ ++ ((n) == 2) ? ORION5X_PCI_REG(0xc4c) : \ ++ ((n) == 3) ? ORION5X_PCI_REG(0xd4c) : 0) + #define PCI_BAR_ENABLE ORION5X_PCI_REG(0xc3c) + #define PCI_ADDR_DECODE_CTRL ORION5X_PCI_REG(0xd3c) + +--- a/arch/arm/mach-orion5x/rd88f5182-setup.c ++++ b/arch/arm/mach-orion5x/rd88f5182-setup.c +@@ -125,6 +125,7 @@ + + leds_event = rd88f5182_dbgled_event; + } ++ + return 0; + } + +@@ -234,7 +235,7 @@ + * Sata + ****************************************************************************/ + static struct mv_sata_platform_data rd88f5182_sata_data = { +- .n_ports = 2, ++ .n_ports = 2, + }; + + /***************************************************************************** +--- a/arch/arm/mach-orion5x/ts209-setup.c ++++ b/arch/arm/mach-orion5x/ts209-setup.c +@@ -47,52 +47,54 @@ + ***************************************************************************/ + static struct mtd_partition qnap_ts209_partitions[] = { + { +- .name = "U-Boot", +- .size = 0x00080000, +- .offset = 0x00780000, +- .mask_flags = MTD_WRITEABLE, ++ .name = "U-Boot", ++ .size = 0x00080000, ++ .offset = 0x00780000, ++ .mask_flags = MTD_WRITEABLE, + }, { +- .name = "Kernel", +- .size = 0x00200000, +- .offset = 0, ++ .name = "Kernel", ++ .size = 0x00200000, ++ .offset = 0, + }, { +- .name = "RootFS1", +- .size = 0x00400000, +- .offset = 0x00200000, ++ .name = "RootFS1", ++ .size = 0x00400000, ++ .offset = 0x00200000, + }, { +- .name = "RootFS2", +- .size = 0x00100000, +- .offset = 0x00600000, ++ .name = "RootFS2", ++ .size = 0x00100000, ++ .offset = 0x00600000, + }, { +- .name = "U-Boot Config", +- .size = 0x00020000, +- .offset = 0x00760000, ++ .name = "U-Boot Config", ++ .size = 0x00020000, ++ .offset = 0x00760000, + }, { +- .name = "NAS Config", +- .size = 0x00060000, +- .offset = 0x00700000, +- .mask_flags = MTD_WRITEABLE, +- } ++ .name = "NAS Config", ++ .size = 0x00060000, ++ .offset = 0x00700000, ++ .mask_flags = MTD_WRITEABLE, ++ }, + }; + + static struct physmap_flash_data qnap_ts209_nor_flash_data = { +- .width = 1, +- .parts = qnap_ts209_partitions, +- .nr_parts = ARRAY_SIZE(qnap_ts209_partitions) ++ .width = 1, ++ .parts = qnap_ts209_partitions, ++ .nr_parts = ARRAY_SIZE(qnap_ts209_partitions) + }; + + static struct resource qnap_ts209_nor_flash_resource = { +- .flags = IORESOURCE_MEM, +- .start = QNAP_TS209_NOR_BOOT_BASE, +- .end = QNAP_TS209_NOR_BOOT_BASE + QNAP_TS209_NOR_BOOT_SIZE - 1, ++ .flags = IORESOURCE_MEM, ++ .start = QNAP_TS209_NOR_BOOT_BASE, ++ .end = QNAP_TS209_NOR_BOOT_BASE + QNAP_TS209_NOR_BOOT_SIZE - 1, + }; + + static struct platform_device qnap_ts209_nor_flash = { +- .name = "physmap-flash", +- .id = 0, +- .dev = { .platform_data = &qnap_ts209_nor_flash_data, }, +- .resource = &qnap_ts209_nor_flash_resource, +- .num_resources = 1, ++ .name = "physmap-flash", ++ .id = 0, ++ .dev = { ++ .platform_data = &qnap_ts209_nor_flash_data, ++ }, ++ .resource = &qnap_ts209_nor_flash_resource, ++ .num_resources = 1, + }; + + /***************************************************************************** +@@ -164,12 +166,12 @@ + } + + static struct hw_pci qnap_ts209_pci __initdata = { +- .nr_controllers = 2, +- .preinit = qnap_ts209_pci_preinit, +- .swizzle = pci_std_swizzle, +- .setup = orion5x_pci_sys_setup, +- .scan = orion5x_pci_sys_scan_bus, +- .map_irq = qnap_ts209_pci_map_irq, ++ .nr_controllers = 2, ++ .preinit = qnap_ts209_pci_preinit, ++ .swizzle = pci_std_swizzle, ++ .setup = orion5x_pci_sys_setup, ++ .scan = orion5x_pci_sys_scan_bus, ++ .map_irq = qnap_ts209_pci_map_irq, + }; + + static int __init qnap_ts209_pci_init(void) +@@ -187,8 +189,8 @@ + ****************************************************************************/ + + static struct mv643xx_eth_platform_data qnap_ts209_eth_data = { +- .phy_addr = 8, +- .force_phy_addr = 1, ++ .phy_addr = 8, ++ .force_phy_addr = 1, + }; + + static int __init parse_hex_nibble(char n) +@@ -280,7 +282,7 @@ + + static struct i2c_board_info __initdata qnap_ts209_i2c_rtc = { + I2C_BOARD_INFO("s35390a", 0x30), +- .irq = 0, ++ .irq = 0, + }; + + /**************************************************************************** +@@ -297,32 +299,33 @@ + .gpio = QNAP_TS209_GPIO_KEY_MEDIA, + .desc = "USB Copy Button", + .active_low = 1, +- }, +- { ++ }, { + .code = KEY_POWER, + .gpio = QNAP_TS209_GPIO_KEY_RESET, + .desc = "Reset Button", + .active_low = 1, +- } ++ }, + }; + + static struct gpio_keys_platform_data qnap_ts209_button_data = { + .buttons = qnap_ts209_buttons, +- .nbuttons = ARRAY_SIZE(qnap_ts209_buttons), ++ .nbuttons = ARRAY_SIZE(qnap_ts209_buttons), + }; + + static struct platform_device qnap_ts209_button_device = { + .name = "gpio-keys", + .id = -1, + .num_resources = 0, +- .dev = { .platform_data = &qnap_ts209_button_data, }, ++ .dev = { ++ .platform_data = &qnap_ts209_button_data, ++ }, + }; + + /***************************************************************************** + * SATA + ****************************************************************************/ + static struct mv_sata_platform_data qnap_ts209_sata_data = { +- .n_ports = 2, ++ .n_ports = 2, + }; + + /***************************************************************************** +@@ -339,7 +342,7 @@ + * QNAP TS-[12]09 specific power off method via UART1-attached PIC + */ + +-#define UART1_REG(x) (UART1_VIRT_BASE + ((UART_##x) << 2)) ++#define UART1_REG(x) (UART1_VIRT_BASE + ((UART_##x) << 2)) + + static void qnap_ts209_power_off(void) + { +@@ -372,7 +375,7 @@ + * Setup flash mapping + */ + orion5x_setup_dev_boot_win(QNAP_TS209_NOR_BOOT_BASE, +- QNAP_TS209_NOR_BOOT_SIZE); ++ QNAP_TS209_NOR_BOOT_SIZE); + + /* + * Open a special address decode windows for the PCIe WA. +@@ -432,7 +435,7 @@ + } + + MACHINE_START(TS209, "QNAP TS-109/TS-209") +- /* Maintainer: Byron Bradley <byron.bbradley@gmail.com> */ ++ /* Maintainer: Byron Bradley <byron.bbradley@gmail.com> */ + .phys_io = ORION5X_REGS_PHYS_BASE, + .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC, + .boot_params = 0x00000100, +--- a/arch/arm/mm/proc-feroceon.S ++++ b/arch/arm/mm/proc-feroceon.S +@@ -454,13 +454,13 @@ + __feroceon_old_id_proc_info: + .long 0x41069260 + .long 0xfffffff0 +- .long PMD_TYPE_SECT | \ ++ .long PMD_TYPE_SECT | \ + PMD_SECT_BUFFERABLE | \ + PMD_SECT_CACHEABLE | \ + PMD_BIT4 | \ + PMD_SECT_AP_WRITE | \ + PMD_SECT_AP_READ +- .long PMD_TYPE_SECT | \ ++ .long PMD_TYPE_SECT | \ + PMD_BIT4 | \ + PMD_SECT_AP_WRITE | \ + PMD_SECT_AP_READ +@@ -480,13 +480,13 @@ + __feroceon_proc_info: + .long 0x56055310 + .long 0xfffffff0 +- .long PMD_TYPE_SECT | \ ++ .long PMD_TYPE_SECT | \ + PMD_SECT_BUFFERABLE | \ + PMD_SECT_CACHEABLE | \ + PMD_BIT4 | \ + PMD_SECT_AP_WRITE | \ + PMD_SECT_AP_READ +- .long PMD_TYPE_SECT | \ ++ .long PMD_TYPE_SECT | \ + PMD_BIT4 | \ + PMD_SECT_AP_WRITE | \ + PMD_SECT_AP_READ diff --git a/target/linux/orion/patches/004-make_window_setup_a_little_more_safe.patch b/target/linux/orion/patches/004-make_window_setup_a_little_more_safe.patch new file mode 100644 index 0000000000..f5f1de4c2f --- /dev/null +++ b/target/linux/orion/patches/004-make_window_setup_a_little_more_safe.patch @@ -0,0 +1,79 @@ +Currently, Orion window setup uses hardcoded window indexes for each +of the boot/cs0/cs1/cs2/PCIe WA windows. The static window allocation +used can clash if board support code will ever attempt to configure +both a dev2 and a PCIe WA window, as both of those use CPU mbus window +#7 at present. + +This patch keeps track of the last used window, and opens subsequently +requested windows sequentially, starting from 4. (Windows 0-3 are used +as MEM/IO windows for the PCI/PCIe buses.) + +Signed-off-by: Lennert Buytenhek <buytenh@marvell.com> +--- + arch/arm/mach-orion5x/addr-map.c | 20 +++++++++++++++----- + 1 files changed, 15 insertions(+), 5 deletions(-) + +--- a/arch/arm/mach-orion5x/addr-map.c ++++ b/arch/arm/mach-orion5x/addr-map.c +@@ -70,6 +70,7 @@ + + + struct mbus_dram_target_info orion5x_mbus_dram_info; ++static int __initdata win_alloc_count; + + static int __init orion5x_cpu_win_can_remap(int win) + { +@@ -87,6 +88,9 @@ + static void __init setup_cpu_win(int win, u32 base, u32 size, + u8 target, u8 attr, int remap) + { ++ if (win >= 8) ++ panic("setup_cpu_win: trying to allocate window %d\n", win); ++ + orion5x_write(CPU_WIN_BASE(win), base & 0xffff0000); + orion5x_write(CPU_WIN_CTRL(win), + ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1); +@@ -128,6 +132,7 @@ + TARGET_PCIE, ATTR_PCIE_MEM, -1); + setup_cpu_win(3, ORION5X_PCI_MEM_PHYS_BASE, ORION5X_PCI_MEM_SIZE, + TARGET_PCI, ATTR_PCI_MEM, -1); ++ win_alloc_count = 4; + + /* + * Setup MBUS dram target info. +@@ -156,25 +161,30 @@ + + void __init orion5x_setup_dev_boot_win(u32 base, u32 size) + { +- setup_cpu_win(4, base, size, TARGET_DEV_BUS, ATTR_DEV_BOOT, -1); ++ setup_cpu_win(win_alloc_count++, base, size, ++ TARGET_DEV_BUS, ATTR_DEV_BOOT, -1); + } + + void __init orion5x_setup_dev0_win(u32 base, u32 size) + { +- setup_cpu_win(5, base, size, TARGET_DEV_BUS, ATTR_DEV_CS0, -1); ++ setup_cpu_win(win_alloc_count++, base, size, ++ TARGET_DEV_BUS, ATTR_DEV_CS0, -1); + } + + void __init orion5x_setup_dev1_win(u32 base, u32 size) + { +- setup_cpu_win(6, base, size, TARGET_DEV_BUS, ATTR_DEV_CS1, -1); ++ setup_cpu_win(win_alloc_count++, base, size, ++ TARGET_DEV_BUS, ATTR_DEV_CS1, -1); + } + + void __init orion5x_setup_dev2_win(u32 base, u32 size) + { +- setup_cpu_win(7, base, size, TARGET_DEV_BUS, ATTR_DEV_CS2, -1); ++ setup_cpu_win(win_alloc_count++, base, size, ++ TARGET_DEV_BUS, ATTR_DEV_CS2, -1); + } + + void __init orion5x_setup_pcie_wa_win(u32 base, u32 size) + { +- setup_cpu_win(7, base, size, TARGET_PCIE, ATTR_PCIE_WA, -1); ++ setup_cpu_win(win_alloc_count++, base, size, ++ TARGET_PCIE, ATTR_PCIE_WA, -1); + } diff --git a/target/linux/orion/patches/005-dram_mapping_granularity_is_64kib.patch b/target/linux/orion/patches/005-dram_mapping_granularity_is_64kib.patch new file mode 100644 index 0000000000..2e7815de27 --- /dev/null +++ b/target/linux/orion/patches/005-dram_mapping_granularity_is_64kib.patch @@ -0,0 +1,26 @@ +The DRAM base address and size fields in the CPU's MBUS bridge have +64KiB granularity, instead of the currently used 16MiB. Since all +of the currently supported MBUS peripherals support 64KiB granularity +as well, this patch changes the Orion address map code to stop +rounding base addresses down and sizes up to multiples of 16MiB. + +Found by Ke Wei <kewei@marvell.com>. + +Signed-off-by: Lennert Buytenhek <buytenh@marvell.com> +--- + arch/arm/mach-orion5x/addr-map.c | 4 ++-- + 1 files changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/arm/mach-orion5x/addr-map.c ++++ b/arch/arm/mach-orion5x/addr-map.c +@@ -152,8 +152,8 @@ + w = &orion5x_mbus_dram_info.cs[cs++]; + w->cs_index = i; + w->mbus_attr = 0xf & ~(1 << i); +- w->base = base & 0xff000000; +- w->size = (size | 0x00ffffff) + 1; ++ w->base = base & 0xffff0000; ++ w->size = (size | 0x0000ffff) + 1; + } + } + orion5x_mbus_dram_info.num_cs = cs; diff --git a/target/linux/orion/patches/006-add_a_separate_BRIDGE_INT_TIMER1_CLR_define.patch b/target/linux/orion/patches/006-add_a_separate_BRIDGE_INT_TIMER1_CLR_define.patch new file mode 100644 index 0000000000..75daedd84c --- /dev/null +++ b/target/linux/orion/patches/006-add_a_separate_BRIDGE_INT_TIMER1_CLR_define.patch @@ -0,0 +1,37 @@ +From: Ke Wei <kewei@marvell.com> + +Some Feroceon-based SoCs have an MBUS bridge interrupt controller +that requires writing a one instead of a zero to clear edge +interrupt sources such as timer expiry. + +This patch adds a new BRIDGE_INT_TIMER1_CLR define, which platform +code can set to either ~BRIDGE_INT_TIMER1 (write-zero-to-clear) or +BRIDGE_INT_TIMER1 (write-one-to-clear) depending on the platform. + +Signed-off-by: Lennert Buytenhek <buytenh@marvell.com> +--- + arch/arm/plat-orion/time.c | 2 +- + include/asm-arm/arch-orion5x/orion5x.h | 1 + + 2 files changed, 2 insertions(+), 1 deletions(-) + +--- a/arch/arm/plat-orion/time.c ++++ b/arch/arm/plat-orion/time.c +@@ -74,7 +74,7 @@ + /* + * Clear and enable clockevent timer interrupt. + */ +- writel(~BRIDGE_INT_TIMER1, BRIDGE_CAUSE); ++ writel(BRIDGE_INT_TIMER1_CLR, BRIDGE_CAUSE); + + u = readl(BRIDGE_MASK); + u |= BRIDGE_INT_TIMER1; +--- a/include/asm-arm/arch-orion5x/orion5x.h ++++ b/include/asm-arm/arch-orion5x/orion5x.h +@@ -152,6 +152,7 @@ + #define BRIDGE_MASK ORION5X_BRIDGE_REG(0x114) + #define BRIDGE_INT_TIMER0 0x0002 + #define BRIDGE_INT_TIMER1 0x0004 ++#define BRIDGE_INT_TIMER1_CLR ~0x0004 + #define MAIN_IRQ_CAUSE ORION5X_BRIDGE_REG(0x200) + #define MAIN_IRQ_MASK ORION5X_BRIDGE_REG(0x204) + diff --git a/target/linux/orion/patches/007-annotate_88fr531-vd_cpu_entries.patch b/target/linux/orion/patches/007-annotate_88fr531-vd_cpu_entries.patch new file mode 100644 index 0000000000..5aab94bb86 --- /dev/null +++ b/target/linux/orion/patches/007-annotate_88fr531-vd_cpu_entries.patch @@ -0,0 +1,58 @@ +Annotate the entries for the 88fr531-vd CPU core in +arch/arm/boot/compressed/head.S and arch/arm/mm/proc-feroceon.S +with the full name of the core. + +Signed-off-by: Lennert Buytenhek <buytenh@marvell.com> +--- + arch/arm/boot/compressed/head.S | 2 +- + arch/arm/mm/proc-feroceon.S | 13 +++++++++---- + 2 files changed, 10 insertions(+), 5 deletions(-) + +--- a/arch/arm/boot/compressed/head.S ++++ b/arch/arm/boot/compressed/head.S +@@ -623,7 +623,7 @@ + b __armv4_mmu_cache_off + b __armv4_mmu_cache_flush + +- .word 0x56055310 @ Feroceon ++ .word 0x56055310 @ Feroceon 88FR531-vd + .word 0xfffffff0 + b __armv4_mmu_cache_on + b __armv4_mmu_cache_off +--- a/arch/arm/mm/proc-feroceon.S ++++ b/arch/arm/mm/proc-feroceon.S +@@ -445,6 +445,11 @@ + .asciz "Feroceon" + .size cpu_feroceon_name, . - cpu_feroceon_name + ++ .type cpu_88fr531_name, #object ++cpu_88fr531_name: ++ .asciz "Feroceon 88FR531-vd" ++ .size cpu_88fr531_name, . - cpu_88fr531_name ++ + .align + + .section ".proc.info.init", #alloc, #execinstr +@@ -476,8 +481,8 @@ + .size __feroceon_old_id_proc_info, . - __feroceon_old_id_proc_info + #endif + +- .type __feroceon_proc_info,#object +-__feroceon_proc_info: ++ .type __88fr531_proc_info,#object ++__88fr531_proc_info: + .long 0x56055310 + .long 0xfffffff0 + .long PMD_TYPE_SECT | \ +@@ -494,9 +499,9 @@ + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP +- .long cpu_feroceon_name ++ .long cpu_88fr531_name + .long feroceon_processor_functions + .long v4wbi_tlb_fns + .long feroceon_user_fns + .long feroceon_cache_fns +- .size __feroceon_proc_info, . - __feroceon_proc_info ++ .size __88fr531_proc_info, . - __88fr531_proc_info diff --git a/target/linux/orion/patches/008-top-level_irqs_are_level-triggered.patch b/target/linux/orion/patches/008-top-level_irqs_are_level-triggered.patch new file mode 100644 index 0000000000..add15900c9 --- /dev/null +++ b/target/linux/orion/patches/008-top-level_irqs_are_level-triggered.patch @@ -0,0 +1,35 @@ +Make it clear that Orion top-level IRQs are level-triggered. This +means that we don't need an ->ack() handler, or at least, we don't +need the ->ack() handler (or the acking part of the ->mask_ack() +handler) to actually do anything. + +Given that, we might as well point our ->mask_ack() handler at the +->mask() handler instead of providing a dummy ->ack() handler, since +providing a ->mask_ack() handler on level IRQ sources will prevent +->ack() from ever being called. + +Signed-off-by: Lennert Buytenhek <buytenh@marvell.com> +--- + arch/arm/plat-orion/irq.c | 3 ++- + 1 files changed, 2 insertions(+), 1 deletions(-) + +--- a/arch/arm/plat-orion/irq.c ++++ b/arch/arm/plat-orion/irq.c +@@ -36,8 +36,8 @@ + + static struct irq_chip orion_irq_chip = { + .name = "orion_irq", +- .ack = orion_irq_mask, + .mask = orion_irq_mask, ++ .mask_ack = orion_irq_mask, + .unmask = orion_irq_unmask, + }; + +@@ -59,6 +59,7 @@ + set_irq_chip(irq, &orion_irq_chip); + set_irq_chip_data(irq, maskaddr); + set_irq_handler(irq, handle_level_irq); ++ irq_desc[irq].status |= IRQ_LEVEL; + set_irq_flags(irq, IRQF_VALID); + } + } diff --git a/target/linux/orion/patches/009-delete_unused_IO_SPACE_REMAP_define.patch b/target/linux/orion/patches/009-delete_unused_IO_SPACE_REMAP_define.patch new file mode 100644 index 0000000000..222a6dabcd --- /dev/null +++ b/target/linux/orion/patches/009-delete_unused_IO_SPACE_REMAP_define.patch @@ -0,0 +1,17 @@ +This define isn't used anywhere in the kernel tree -- nuke it. + +Signed-off-by: Lennert Buytenhek <buytenh@marvell.com> +--- + include/asm-arm/arch-orion5x/io.h | 1 - + 1 files changed, 0 insertions(+), 1 deletions(-) + +--- a/include/asm-arm/arch-orion5x/io.h ++++ b/include/asm-arm/arch-orion5x/io.h +@@ -14,7 +14,6 @@ + #include "orion5x.h" + + #define IO_SPACE_LIMIT 0xffffffff +-#define IO_SPACE_REMAP ORION5X_PCI_SYS_IO_BASE + + static inline void __iomem * + __arch_ioremap(unsigned long paddr, size_t size, unsigned int mtype) diff --git a/target/linux/orion/patches/010-move_EHCI_I2C_UART_peripheral_init.patch b/target/linux/orion/patches/010-move_EHCI_I2C_UART_peripheral_init.patch new file mode 100644 index 0000000000..6f11eefad3 --- /dev/null +++ b/target/linux/orion/patches/010-move_EHCI_I2C_UART_peripheral_init.patch @@ -0,0 +1,710 @@ +This patch moves initialisation of EHCI/I2C/UART platform devices +from the common orion5x_init() into the board support code. + +The rationale behind this is that only the board support code knows +whether certain peripherals have been brought out on the board, and +not initialising peripherals that haven't been brought out is +desirable for example: +- to reduce user confusion (e.g. seeing both 'eth0' and 'eth1' + appear while there is only one ethernet port on the board); and +- to allow for future power savings (peripherals that have not + been brought out can be clock gated off entirely.) + +Signed-off-by: Lennert Buytenhek <buytenh@marvell.com> +--- + arch/arm/mach-orion5x/common.c | 226 +++++++++++++++++------------ + arch/arm/mach-orion5x/common.h | 35 ++--- + arch/arm/mach-orion5x/db88f5281-setup.c | 39 +++--- + arch/arm/mach-orion5x/dns323-setup.c | 40 +++--- + arch/arm/mach-orion5x/kurobox_pro-setup.c | 28 +++-- + arch/arm/mach-orion5x/rd88f5182-setup.c | 29 ++-- + arch/arm/mach-orion5x/ts209-setup.c | 38 ++--- + 7 files changed, 240 insertions(+), 195 deletions(-) + +--- a/arch/arm/mach-orion5x/common.c ++++ b/arch/arm/mach-orion5x/common.c +@@ -63,65 +63,20 @@ + iotable_init(orion5x_io_desc, ARRAY_SIZE(orion5x_io_desc)); + } + ++ + /***************************************************************************** +- * UART ++ * EHCI + ****************************************************************************/ +- +-static struct resource orion5x_uart_resources[] = { +- { +- .start = UART0_PHYS_BASE, +- .end = UART0_PHYS_BASE + 0xff, +- .flags = IORESOURCE_MEM, +- }, { +- .start = IRQ_ORION5X_UART0, +- .end = IRQ_ORION5X_UART0, +- .flags = IORESOURCE_IRQ, +- }, { +- .start = UART1_PHYS_BASE, +- .end = UART1_PHYS_BASE + 0xff, +- .flags = IORESOURCE_MEM, +- }, { +- .start = IRQ_ORION5X_UART1, +- .end = IRQ_ORION5X_UART1, +- .flags = IORESOURCE_IRQ, +- }, +-}; +- +-static struct plat_serial8250_port orion5x_uart_data[] = { +- { +- .mapbase = UART0_PHYS_BASE, +- .membase = (char *)UART0_VIRT_BASE, +- .irq = IRQ_ORION5X_UART0, +- .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, +- .iotype = UPIO_MEM, +- .regshift = 2, +- .uartclk = ORION5X_TCLK, +- }, { +- .mapbase = UART1_PHYS_BASE, +- .membase = (char *)UART1_VIRT_BASE, +- .irq = IRQ_ORION5X_UART1, +- .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, +- .iotype = UPIO_MEM, +- .regshift = 2, +- .uartclk = ORION5X_TCLK, +- }, { +- }, ++static struct orion_ehci_data orion5x_ehci_data = { ++ .dram = &orion5x_mbus_dram_info, + }; + +-static struct platform_device orion5x_uart = { +- .name = "serial8250", +- .id = PLAT8250_DEV_PLATFORM, +- .dev = { +- .platform_data = orion5x_uart_data, +- }, +- .resource = orion5x_uart_resources, +- .num_resources = ARRAY_SIZE(orion5x_uart_resources), +-}; ++static u64 ehci_dmamask = 0xffffffffUL; + +-/******************************************************************************* +- * USB Controller - 2 interfaces +- ******************************************************************************/ + ++/***************************************************************************** ++ * EHCI0 ++ ****************************************************************************/ + static struct resource orion5x_ehci0_resources[] = { + { + .start = ORION5X_USB0_PHYS_BASE, +@@ -134,24 +89,6 @@ + }, + }; + +-static struct resource orion5x_ehci1_resources[] = { +- { +- .start = ORION5X_USB1_PHYS_BASE, +- .end = ORION5X_USB1_PHYS_BASE + SZ_4K - 1, +- .flags = IORESOURCE_MEM, +- }, { +- .start = IRQ_ORION5X_USB1_CTRL, +- .end = IRQ_ORION5X_USB1_CTRL, +- .flags = IORESOURCE_IRQ, +- }, +-}; +- +-static struct orion_ehci_data orion5x_ehci_data = { +- .dram = &orion5x_mbus_dram_info, +-}; +- +-static u64 ehci_dmamask = 0xffffffffUL; +- + static struct platform_device orion5x_ehci0 = { + .name = "orion-ehci", + .id = 0, +@@ -164,6 +101,27 @@ + .num_resources = ARRAY_SIZE(orion5x_ehci0_resources), + }; + ++void __init orion5x_ehci0_init(void) ++{ ++ platform_device_register(&orion5x_ehci0); ++} ++ ++ ++/***************************************************************************** ++ * EHCI1 ++ ****************************************************************************/ ++static struct resource orion5x_ehci1_resources[] = { ++ { ++ .start = ORION5X_USB1_PHYS_BASE, ++ .end = ORION5X_USB1_PHYS_BASE + SZ_4K - 1, ++ .flags = IORESOURCE_MEM, ++ }, { ++ .start = IRQ_ORION5X_USB1_CTRL, ++ .end = IRQ_ORION5X_USB1_CTRL, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ + static struct platform_device orion5x_ehci1 = { + .name = "orion-ehci", + .id = 1, +@@ -176,11 +134,15 @@ + .num_resources = ARRAY_SIZE(orion5x_ehci1_resources), + }; + ++void __init orion5x_ehci1_init(void) ++{ ++ platform_device_register(&orion5x_ehci1); ++} ++ ++ + /***************************************************************************** +- * Gigabit Ethernet port +- * (The Orion and Discovery (MV643xx) families use the same Ethernet driver) ++ * GigE + ****************************************************************************/ +- + struct mv643xx_eth_shared_platform_data orion5x_eth_shared_data = { + .dram = &orion5x_mbus_dram_info, + .t_clk = ORION5X_TCLK, +@@ -229,11 +191,10 @@ + platform_device_register(&orion5x_eth); + } + ++ + /***************************************************************************** +- * I2C controller +- * (The Orion and Discovery (MV643xx) families share the same I2C controller) ++ * I2C + ****************************************************************************/ +- + static struct mv64xxx_i2c_pdata orion5x_i2c_pdata = { + .freq_m = 8, /* assumes 166 MHz TCLK */ + .freq_n = 3, +@@ -244,7 +205,7 @@ + { + .name = "i2c base", + .start = I2C_PHYS_BASE, +- .end = I2C_PHYS_BASE + 0x20 -1, ++ .end = I2C_PHYS_BASE + 0x1f, + .flags = IORESOURCE_MEM, + }, { + .name = "i2c irq", +@@ -264,8 +225,14 @@ + }, + }; + ++void __init orion5x_i2c_init(void) ++{ ++ platform_device_register(&orion5x_i2c); ++} ++ ++ + /***************************************************************************** +- * Sata port ++ * SATA + ****************************************************************************/ + static struct resource orion5x_sata_resources[] = { + { +@@ -298,10 +265,98 @@ + platform_device_register(&orion5x_sata); + } + ++ + /***************************************************************************** +- * Time handling ++ * UART0 ++ ****************************************************************************/ ++static struct plat_serial8250_port orion5x_uart0_data[] = { ++ { ++ .mapbase = UART0_PHYS_BASE, ++ .membase = (char *)UART0_VIRT_BASE, ++ .irq = IRQ_ORION5X_UART0, ++ .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, ++ .iotype = UPIO_MEM, ++ .regshift = 2, ++ .uartclk = ORION5X_TCLK, ++ }, { ++ }, ++}; ++ ++static struct resource orion5x_uart0_resources[] = { ++ { ++ .start = UART0_PHYS_BASE, ++ .end = UART0_PHYS_BASE + 0xff, ++ .flags = IORESOURCE_MEM, ++ }, { ++ .start = IRQ_ORION5X_UART0, ++ .end = IRQ_ORION5X_UART0, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static struct platform_device orion5x_uart0 = { ++ .name = "serial8250", ++ .id = PLAT8250_DEV_PLATFORM, ++ .dev = { ++ .platform_data = orion5x_uart0_data, ++ }, ++ .resource = orion5x_uart0_resources, ++ .num_resources = ARRAY_SIZE(orion5x_uart0_resources), ++}; ++ ++void __init orion5x_uart0_init(void) ++{ ++ platform_device_register(&orion5x_uart0); ++} ++ ++ ++/***************************************************************************** ++ * UART1 + ****************************************************************************/ ++static struct plat_serial8250_port orion5x_uart1_data[] = { ++ { ++ .mapbase = UART1_PHYS_BASE, ++ .membase = (char *)UART1_VIRT_BASE, ++ .irq = IRQ_ORION5X_UART1, ++ .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, ++ .iotype = UPIO_MEM, ++ .regshift = 2, ++ .uartclk = ORION5X_TCLK, ++ }, { ++ }, ++}; ++ ++static struct resource orion5x_uart1_resources[] = { ++ { ++ .start = UART1_PHYS_BASE, ++ .end = UART1_PHYS_BASE + 0xff, ++ .flags = IORESOURCE_MEM, ++ }, { ++ .start = IRQ_ORION5X_UART1, ++ .end = IRQ_ORION5X_UART1, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static struct platform_device orion5x_uart1 = { ++ .name = "serial8250", ++ .id = PLAT8250_DEV_PLATFORM1, ++ .dev = { ++ .platform_data = orion5x_uart1_data, ++ }, ++ .resource = orion5x_uart1_resources, ++ .num_resources = ARRAY_SIZE(orion5x_uart1_resources), ++}; ++ ++void __init orion5x_uart1_init(void) ++{ ++ platform_device_register(&orion5x_uart1); ++} + ++ ++/***************************************************************************** ++ * Time handling ++ ****************************************************************************/ + static void orion5x_timer_init(void) + { + orion_time_init(IRQ_ORION5X_BRIDGE, ORION5X_TCLK); +@@ -311,10 +366,10 @@ + .init = orion5x_timer_init, + }; + ++ + /***************************************************************************** + * General + ****************************************************************************/ +- + /* + * Identify device ID and rev from PCIe configuration header space '0'. + */ +@@ -359,15 +414,6 @@ + * Setup Orion address map + */ + orion5x_setup_cpu_mbus_bridge(); +- +- /* +- * Register devices. +- */ +- platform_device_register(&orion5x_uart); +- platform_device_register(&orion5x_ehci0); +- if (dev == MV88F5182_DEV_ID) +- platform_device_register(&orion5x_ehci1); +- platform_device_register(&orion5x_i2c); + } + + /* +--- a/arch/arm/mach-orion5x/common.h ++++ b/arch/arm/mach-orion5x/common.h +@@ -1,10 +1,12 @@ + #ifndef __ARCH_ORION5X_COMMON_H + #define __ARCH_ORION5X_COMMON_H + ++struct mv643xx_eth_platform_data; ++struct mv_sata_platform_data; ++ + /* + * Basic Orion init functions used early by machine-setup. + */ +- + void orion5x_map_io(void); + void orion5x_init_irq(void); + void orion5x_init(void); +@@ -23,13 +25,19 @@ + void orion5x_setup_dev2_win(u32 base, u32 size); + void orion5x_setup_pcie_wa_win(u32 base, u32 size); + ++void orion5x_ehci0_init(void); ++void orion5x_ehci1_init(void); ++void orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data); ++void orion5x_i2c_init(void); ++void orion5x_sata_init(struct mv_sata_platform_data *sata_data); ++void orion5x_uart0_init(void); ++void orion5x_uart1_init(void); ++ + /* +- * Shared code used internally by other Orion core functions. +- * (/mach-orion/pci.c) ++ * PCIe/PCI functions. + */ +- +-struct pci_sys_data; + struct pci_bus; ++struct pci_sys_data; + + void orion5x_pcie_id(u32 *dev, u32 *rev); + int orion5x_pci_sys_setup(int nr, struct pci_sys_data *sys); +@@ -40,26 +48,9 @@ + * Valid GPIO pins according to MPP setup, used by machine-setup. + * (/mach-orion/gpio.c). + */ +- + void orion5x_gpio_set_valid_pins(u32 pins); + void gpio_display(void); /* debug */ + +-/* +- * Pull in Orion Ethernet platform_data, used by machine-setup +- */ +- +-struct mv643xx_eth_platform_data; +- +-void orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data); +- +-/* +- * Orion Sata platform_data, used by machine-setup +- */ +- +-struct mv_sata_platform_data; +- +-void orion5x_sata_init(struct mv_sata_platform_data *sata_data); +- + struct machine_desc; + struct meminfo; + struct tag; +--- a/arch/arm/mach-orion5x/db88f5281-setup.c ++++ b/arch/arm/mach-orion5x/db88f5281-setup.c +@@ -298,13 +298,6 @@ + /***************************************************************************** + * General Setup + ****************************************************************************/ +- +-static struct platform_device *db88f5281_devs[] __initdata = { +- &db88f5281_boot_flash, +- &db88f5281_nor_flash, +- &db88f5281_nand_flash, +-}; +- + static void __init db88f5281_init(void) + { + /* +@@ -313,15 +306,6 @@ + orion5x_init(); + + /* +- * Setup the CPU address decode windows for our on-board devices +- */ +- orion5x_setup_dev_boot_win(DB88F5281_NOR_BOOT_BASE, +- DB88F5281_NOR_BOOT_SIZE); +- orion5x_setup_dev0_win(DB88F5281_7SEG_BASE, DB88F5281_7SEG_SIZE); +- orion5x_setup_dev1_win(DB88F5281_NOR_BASE, DB88F5281_NOR_SIZE); +- orion5x_setup_dev2_win(DB88F5281_NAND_BASE, DB88F5281_NAND_SIZE); +- +- /* + * Setup Multiplexing Pins: + * MPP0: GPIO (USB Over Current) MPP1: GPIO (USB Vbat input) + * MPP2: PCI_REQn[2] MPP3: PCI_GNTn[2] +@@ -342,9 +326,28 @@ + + orion5x_gpio_set_valid_pins(0x00003fc3); + +- platform_add_devices(db88f5281_devs, ARRAY_SIZE(db88f5281_devs)); +- i2c_register_board_info(0, &db88f5281_i2c_rtc, 1); ++ /* ++ * Configure peripherals. ++ */ ++ orion5x_ehci0_init(); + orion5x_eth_init(&db88f5281_eth_data); ++ orion5x_i2c_init(); ++ orion5x_uart0_init(); ++ orion5x_uart1_init(); ++ ++ orion5x_setup_dev_boot_win(DB88F5281_NOR_BOOT_BASE, ++ DB88F5281_NOR_BOOT_SIZE); ++ platform_device_register(&db88f5281_boot_flash); ++ ++ orion5x_setup_dev0_win(DB88F5281_7SEG_BASE, DB88F5281_7SEG_SIZE); ++ ++ orion5x_setup_dev1_win(DB88F5281_NOR_BASE, DB88F5281_NOR_SIZE); ++ platform_device_register(&db88f5281_nor_flash); ++ ++ orion5x_setup_dev2_win(DB88F5281_NAND_BASE, DB88F5281_NAND_SIZE); ++ platform_device_register(&db88f5281_nand_flash); ++ ++ i2c_register_board_info(0, &db88f5281_i2c_rtc, 1); + } + + MACHINE_START(DB88F5281, "Marvell Orion-2 Development Board") +--- a/arch/arm/mach-orion5x/dns323-setup.c ++++ b/arch/arm/mach-orion5x/dns323-setup.c +@@ -213,12 +213,6 @@ + * General Setup + */ + +-static struct platform_device *dns323_plat_devices[] __initdata = { +- &dns323_nor_flash, +- &dns323_gpio_leds, +- &dns323_button_device, +-}; +- + /* + * On the DNS-323 the following devices are attached via I2C: + * +@@ -253,11 +247,6 @@ + /* Setup basic Orion functions. Need to be called early. */ + orion5x_init(); + +- /* setup flash mapping +- * CS3 holds a 8 MB Spansion S29GL064M90TFIR4 +- */ +- orion5x_setup_dev_boot_win(DNS323_NOR_BOOT_BASE, DNS323_NOR_BOOT_SIZE); +- + /* DNS-323 has a Marvell 88X7042 SATA controller attached via PCIe + * + * Open a special address decode windows for the PCIe WA. +@@ -294,21 +283,32 @@ + */ + orion5x_gpio_set_valid_pins(0x07f6); + +- /* register dns323 specific power-off method */ +- if (gpio_request(DNS323_GPIO_POWER_OFF, "POWEROFF") != 0 || +- gpio_direction_output(DNS323_GPIO_POWER_OFF, 0) != 0) +- pr_err("DNS323: failed to setup power-off GPIO\n"); ++ /* ++ * Configure peripherals. ++ */ ++ orion5x_ehci0_init(); ++ orion5x_eth_init(&dns323_eth_data); ++ orion5x_i2c_init(); ++ orion5x_uart0_init(); + +- pm_power_off = dns323_power_off; ++ /* setup flash mapping ++ * CS3 holds a 8 MB Spansion S29GL064M90TFIR4 ++ */ ++ orion5x_setup_dev_boot_win(DNS323_NOR_BOOT_BASE, DNS323_NOR_BOOT_SIZE); ++ platform_device_register(&dns323_nor_flash); ++ ++ platform_device_register(&dns323_gpio_leds); + +- /* register flash and other platform devices */ +- platform_add_devices(dns323_plat_devices, +- ARRAY_SIZE(dns323_plat_devices)); ++ platform_device_register(&dns323_button_device); + + i2c_register_board_info(0, dns323_i2c_devices, + ARRAY_SIZE(dns323_i2c_devices)); + +- orion5x_eth_init(&dns323_eth_data); ++ /* register dns323 specific power-off method */ ++ if (gpio_request(DNS323_GPIO_POWER_OFF, "POWEROFF") != 0 || ++ gpio_direction_output(DNS323_GPIO_POWER_OFF, 0) != 0) ++ pr_err("DNS323: failed to setup power-off GPIO\n"); ++ pm_power_off = dns323_power_off; + } + + /* Warning: D-Link uses a wrong mach-type (=526) in their bootloader */ +--- a/arch/arm/mach-orion5x/kurobox_pro-setup.c ++++ b/arch/arm/mach-orion5x/kurobox_pro-setup.c +@@ -188,13 +188,6 @@ + orion5x_init(); + + /* +- * Setup the CPU address decode windows for our devices +- */ +- orion5x_setup_dev_boot_win(KUROBOX_PRO_NOR_BOOT_BASE, +- KUROBOX_PRO_NOR_BOOT_SIZE); +- orion5x_setup_dev0_win(KUROBOX_PRO_NAND_BASE, KUROBOX_PRO_NAND_SIZE); +- +- /* + * Open a special address decode windows for the PCIe WA. + */ + orion5x_setup_pcie_wa_win(ORION5X_PCIE_WA_PHYS_BASE, +@@ -221,12 +214,27 @@ + + orion5x_gpio_set_valid_pins(0x0000000c); + ++ /* ++ * Configure peripherals. ++ */ ++ orion5x_ehci0_init(); ++ orion5x_ehci1_init(); ++ orion5x_eth_init(&kurobox_pro_eth_data); ++ orion5x_i2c_init(); ++ orion5x_sata_init(&kurobox_pro_sata_data); ++ orion5x_uart0_init(); ++ ++ orion5x_setup_dev_boot_win(KUROBOX_PRO_NOR_BOOT_BASE, ++ KUROBOX_PRO_NOR_BOOT_SIZE); + platform_device_register(&kurobox_pro_nor_flash); +- if (machine_is_kurobox_pro()) ++ ++ if (machine_is_kurobox_pro()) { ++ orion5x_setup_dev0_win(KUROBOX_PRO_NAND_BASE, ++ KUROBOX_PRO_NAND_SIZE); + platform_device_register(&kurobox_pro_nand_flash); ++ } ++ + i2c_register_board_info(0, &kurobox_pro_i2c_rtc, 1); +- orion5x_eth_init(&kurobox_pro_eth_data); +- orion5x_sata_init(&kurobox_pro_sata_data); + } + + #ifdef CONFIG_MACH_KUROBOX_PRO +--- a/arch/arm/mach-orion5x/rd88f5182-setup.c ++++ b/arch/arm/mach-orion5x/rd88f5182-setup.c +@@ -241,11 +241,6 @@ + /***************************************************************************** + * General Setup + ****************************************************************************/ +- +-static struct platform_device *rd88f5182_devices[] __initdata = { +- &rd88f5182_nor_flash, +-}; +- + static void __init rd88f5182_init(void) + { + /* +@@ -254,13 +249,6 @@ + orion5x_init(); + + /* +- * Setup the CPU address decode windows for our devices +- */ +- orion5x_setup_dev_boot_win(RD88F5182_NOR_BOOT_BASE, +- RD88F5182_NOR_BOOT_SIZE); +- orion5x_setup_dev1_win(RD88F5182_NOR_BASE, RD88F5182_NOR_SIZE); +- +- /* + * Open a special address decode windows for the PCIe WA. + */ + orion5x_setup_pcie_wa_win(ORION5X_PCIE_WA_PHYS_BASE, +@@ -296,10 +284,23 @@ + + orion5x_gpio_set_valid_pins(0x000000fb); + +- platform_add_devices(rd88f5182_devices, ARRAY_SIZE(rd88f5182_devices)); +- i2c_register_board_info(0, &rd88f5182_i2c_rtc, 1); ++ /* ++ * Configure peripherals. ++ */ ++ orion5x_ehci0_init(); ++ orion5x_ehci1_init(); + orion5x_eth_init(&rd88f5182_eth_data); ++ orion5x_i2c_init(); + orion5x_sata_init(&rd88f5182_sata_data); ++ orion5x_uart0_init(); ++ ++ orion5x_setup_dev_boot_win(RD88F5182_NOR_BOOT_BASE, ++ RD88F5182_NOR_BOOT_SIZE); ++ ++ orion5x_setup_dev1_win(RD88F5182_NOR_BASE, RD88F5182_NOR_SIZE); ++ platform_device_register(&rd88f5182_nor_flash); ++ ++ i2c_register_board_info(0, &rd88f5182_i2c_rtc, 1); + } + + MACHINE_START(RD88F5182, "Marvell Orion-NAS Reference Design") +--- a/arch/arm/mach-orion5x/ts209-setup.c ++++ b/arch/arm/mach-orion5x/ts209-setup.c +@@ -332,16 +332,9 @@ + + * General Setup + ****************************************************************************/ +- +-static struct platform_device *qnap_ts209_devices[] __initdata = { +- &qnap_ts209_nor_flash, +- &qnap_ts209_button_device, +-}; +- + /* + * QNAP TS-[12]09 specific power off method via UART1-attached PIC + */ +- + #define UART1_REG(x) (UART1_VIRT_BASE + ((UART_##x) << 2)) + + static void qnap_ts209_power_off(void) +@@ -372,12 +365,6 @@ + orion5x_init(); + + /* +- * Setup flash mapping +- */ +- orion5x_setup_dev_boot_win(QNAP_TS209_NOR_BOOT_BASE, +- QNAP_TS209_NOR_BOOT_SIZE); +- +- /* + * Open a special address decode windows for the PCIe WA. + */ + orion5x_setup_pcie_wa_win(ORION5X_PCIE_WA_PHYS_BASE, +@@ -411,11 +398,22 @@ + orion5x_write(MPP_16_19_CTRL, 0x5500); + orion5x_gpio_set_valid_pins(0x3cc0fff); + +- /* register ts209 specific power-off method */ +- pm_power_off = qnap_ts209_power_off; ++ /* ++ * Configure peripherals. ++ */ ++ orion5x_ehci0_init(); ++ orion5x_ehci1_init(); ++ ts209_find_mac_addr(); ++ orion5x_eth_init(&qnap_ts209_eth_data); ++ orion5x_i2c_init(); ++ orion5x_sata_init(&qnap_ts209_sata_data); ++ orion5x_uart0_init(); ++ ++ orion5x_setup_dev_boot_win(QNAP_TS209_NOR_BOOT_BASE, ++ QNAP_TS209_NOR_BOOT_SIZE); ++ platform_device_register(&qnap_ts209_nor_flash); + +- platform_add_devices(qnap_ts209_devices, +- ARRAY_SIZE(qnap_ts209_devices)); ++ platform_device_register(&qnap_ts209_button_device); + + /* Get RTC IRQ and register the chip */ + if (gpio_request(TS209_RTC_GPIO, "rtc") == 0) { +@@ -428,10 +426,8 @@ + pr_warning("qnap_ts209_init: failed to get RTC IRQ\n"); + i2c_register_board_info(0, &qnap_ts209_i2c_rtc, 1); + +- ts209_find_mac_addr(); +- orion5x_eth_init(&qnap_ts209_eth_data); +- +- orion5x_sata_init(&qnap_ts209_sata_data); ++ /* register ts209 specific power-off method */ ++ pm_power_off = qnap_ts209_power_off; + } + + MACHINE_START(TS209, "QNAP TS-109/TS-209") diff --git a/target/linux/orion/patches/011-move_setting_up_pcie_wa_window_into_pcie.patch b/target/linux/orion/patches/011-move_setting_up_pcie_wa_window_into_pcie.patch new file mode 100644 index 0000000000..f6e78d84d8 --- /dev/null +++ b/target/linux/orion/patches/011-move_setting_up_pcie_wa_window_into_pcie.patch @@ -0,0 +1,90 @@ +It makes no sense to do PCIe WA window setup in the individual +board support files while the decision whether or not to use the +PCIe WA access method is made in a different place, in the PCIe +support code. + +This patch moves the configuration of a PCIe WA window from the +individual Orion board support files to the central Orion PCIe +support code. + +Signed-off-by: Lennert Buytenhek <buytenh@marvell.com> +--- + arch/arm/mach-orion5x/dns323-setup.c | 7 ------- + arch/arm/mach-orion5x/kurobox_pro-setup.c | 6 ------ + arch/arm/mach-orion5x/pci.c | 2 ++ + arch/arm/mach-orion5x/rd88f5182-setup.c | 6 ------ + arch/arm/mach-orion5x/ts209-setup.c | 6 ------ + 5 files changed, 2 insertions(+), 25 deletions(-) + +--- a/arch/arm/mach-orion5x/dns323-setup.c ++++ b/arch/arm/mach-orion5x/dns323-setup.c +@@ -247,13 +247,6 @@ + /* Setup basic Orion functions. Need to be called early. */ + orion5x_init(); + +- /* DNS-323 has a Marvell 88X7042 SATA controller attached via PCIe +- * +- * Open a special address decode windows for the PCIe WA. +- */ +- orion5x_setup_pcie_wa_win(ORION5X_PCIE_WA_PHYS_BASE, +- ORION5X_PCIE_WA_SIZE); +- + /* set MPP to 0 as D-Link's 2.6.12.6 kernel did */ + orion5x_write(MPP_0_7_CTRL, 0); + orion5x_write(MPP_8_15_CTRL, 0); +--- a/arch/arm/mach-orion5x/kurobox_pro-setup.c ++++ b/arch/arm/mach-orion5x/kurobox_pro-setup.c +@@ -188,12 +188,6 @@ + orion5x_init(); + + /* +- * Open a special address decode windows for the PCIe WA. +- */ +- orion5x_setup_pcie_wa_win(ORION5X_PCIE_WA_PHYS_BASE, +- ORION5X_PCIE_WA_SIZE); +- +- /* + * Setup Multiplexing Pins -- + * MPP[0-1] Not used + * MPP[2] GPIO Micon +--- a/arch/arm/mach-orion5x/pci.c ++++ b/arch/arm/mach-orion5x/pci.c +@@ -152,6 +152,8 @@ + if (dev == MV88F5181_DEV_ID || dev == MV88F5182_DEV_ID) { + printk(KERN_NOTICE "Applying Orion-1/Orion-NAS PCIe config " + "read transaction workaround\n"); ++ orion5x_setup_pcie_wa_win(ORION5X_PCIE_WA_PHYS_BASE, ++ ORION5X_PCIE_WA_SIZE); + pcie_ops.read = pcie_rd_conf_wa; + } + +--- a/arch/arm/mach-orion5x/rd88f5182-setup.c ++++ b/arch/arm/mach-orion5x/rd88f5182-setup.c +@@ -249,12 +249,6 @@ + orion5x_init(); + + /* +- * Open a special address decode windows for the PCIe WA. +- */ +- orion5x_setup_pcie_wa_win(ORION5X_PCIE_WA_PHYS_BASE, +- ORION5X_PCIE_WA_SIZE); +- +- /* + * Setup Multiplexing Pins -- + * MPP[0] Debug Led (GPIO - Out) + * MPP[1] Debug Led (GPIO - Out) +--- a/arch/arm/mach-orion5x/ts209-setup.c ++++ b/arch/arm/mach-orion5x/ts209-setup.c +@@ -365,12 +365,6 @@ + orion5x_init(); + + /* +- * Open a special address decode windows for the PCIe WA. +- */ +- orion5x_setup_pcie_wa_win(ORION5X_PCIE_WA_PHYS_BASE, +- ORION5X_PCIE_WA_SIZE); +- +- /* + * Setup Multiplexing Pins -- + * MPP[0] Reserved + * MPP[1] USB copy button (0 active) diff --git a/target/linux/orion/patches/012-rework_mpp_handling.patch b/target/linux/orion/patches/012-rework_mpp_handling.patch new file mode 100644 index 0000000000..05e1881259 --- /dev/null +++ b/target/linux/orion/patches/012-rework_mpp_handling.patch @@ -0,0 +1,583 @@ +Instead of having board code poke directly into the MPP configuration +registers, and separately calling orion5x_gpio_set_valid_pins() to +indicate which MPP pins can be used as GPIO pins, introduce a helper +function for configuring the roles of each of the MPP pins, and have +that helper function handle gpio validity internally. + +Signed-off-by: Lennert Buytenhek <buytenh@marvell.com> +Acked-by: Sylver Bruneau <sylver.bruneau@googlemail.com> +--- + arch/arm/mach-orion5x/Makefile | 2 +- + arch/arm/mach-orion5x/common.h | 2 +- + arch/arm/mach-orion5x/db88f5281-setup.c | 42 +++++---- + arch/arm/mach-orion5x/dns323-setup.c | 50 +++++------ + arch/arm/mach-orion5x/gpio.c | 7 +- + arch/arm/mach-orion5x/kurobox_pro-setup.c | 41 ++++---- + arch/arm/mach-orion5x/mpp.c | 142 +++++++++++++++++++++++++++++ + arch/arm/mach-orion5x/mpp.h | 63 +++++++++++++ + arch/arm/mach-orion5x/rd88f5182-setup.c | 43 +++++---- + arch/arm/mach-orion5x/ts209-setup.c | 43 +++++---- + 10 files changed, 321 insertions(+), 114 deletions(-) + create mode 100644 arch/arm/mach-orion5x/mpp.c + create mode 100644 arch/arm/mach-orion5x/mpp.h + +--- a/arch/arm/mach-orion5x/Makefile ++++ b/arch/arm/mach-orion5x/Makefile +@@ -1,4 +1,4 @@ +-obj-y += common.o addr-map.o pci.o gpio.o irq.o ++obj-y += common.o addr-map.o pci.o gpio.o irq.o mpp.o + obj-$(CONFIG_MACH_DB88F5281) += db88f5281-setup.o + obj-$(CONFIG_MACH_RD88F5182) += rd88f5182-setup.o + obj-$(CONFIG_MACH_KUROBOX_PRO) += kurobox_pro-setup.o +--- a/arch/arm/mach-orion5x/common.h ++++ b/arch/arm/mach-orion5x/common.h +@@ -48,7 +48,7 @@ + * Valid GPIO pins according to MPP setup, used by machine-setup. + * (/mach-orion/gpio.c). + */ +-void orion5x_gpio_set_valid_pins(u32 pins); ++void orion5x_gpio_set_valid(unsigned pin, int valid); + void gpio_display(void); /* debug */ + + struct machine_desc; +--- a/arch/arm/mach-orion5x/db88f5281-setup.c ++++ b/arch/arm/mach-orion5x/db88f5281-setup.c +@@ -27,6 +27,7 @@ + #include <asm/arch/orion5x.h> + #include <asm/plat-orion/orion_nand.h> + #include "common.h" ++#include "mpp.h" + + /***************************************************************************** + * DB-88F5281 on board devices +@@ -305,26 +306,27 @@ + */ + orion5x_init(); + +- /* +- * Setup Multiplexing Pins: +- * MPP0: GPIO (USB Over Current) MPP1: GPIO (USB Vbat input) +- * MPP2: PCI_REQn[2] MPP3: PCI_GNTn[2] +- * MPP4: PCI_REQn[3] MPP5: PCI_GNTn[3] +- * MPP6: GPIO (JP0, CON17.2) MPP7: GPIO (JP1, CON17.1) +- * MPP8: GPIO (JP2, CON11.2) MPP9: GPIO (JP3, CON11.3) +- * MPP10: GPIO (RTC int) MPP11: GPIO (Baud Rate Generator) +- * MPP12: GPIO (PCI int 1) MPP13: GPIO (PCI int 2) +- * MPP14: NAND_REn[2] MPP15: NAND_WEn[2] +- * MPP16: UART1_RX MPP17: UART1_TX +- * MPP18: UART1_CTS MPP19: UART1_RTS +- * MPP-DEV: DEV_D[16:31] +- */ +- orion5x_write(MPP_0_7_CTRL, 0x00222203); +- orion5x_write(MPP_8_15_CTRL, 0x44000000); +- orion5x_write(MPP_16_19_CTRL, 0); +- orion5x_write(MPP_DEV_CTRL, 0); +- +- orion5x_gpio_set_valid_pins(0x00003fc3); ++ orion5x_mpp_conf(0, MPP_GPIO); /* USB Over Current */ ++ orion5x_mpp_conf(1, MPP_GPIO); /* USB Vbat input */ ++ orion5x_mpp_conf(2, MPP_PCI_ARB); /* PCI_REQn[2] */ ++ orion5x_mpp_conf(3, MPP_PCI_ARB); /* PCI_GNTn[2] */ ++ orion5x_mpp_conf(4, MPP_PCI_ARB); /* PCI_REQn[3] */ ++ orion5x_mpp_conf(5, MPP_PCI_ARB); /* PCI_GNTn[3] */ ++ orion5x_mpp_conf(6, MPP_GPIO); /* JP0, CON17.2 */ ++ orion5x_mpp_conf(7, MPP_GPIO); /* JP1, CON17.1 */ ++ orion5x_mpp_conf(8, MPP_GPIO); /* JP2, CON11.2 */ ++ orion5x_mpp_conf(9, MPP_GPIO); /* JP3, CON11.3 */ ++ orion5x_mpp_conf(10, MPP_GPIO); /* RTC int */ ++ orion5x_mpp_conf(11, MPP_GPIO); /* Baud Rate Generator */ ++ orion5x_mpp_conf(12, MPP_GPIO); /* PCI int 1 */ ++ orion5x_mpp_conf(13, MPP_GPIO); /* PCI int 2 */ ++ orion5x_mpp_conf(14, MPP_NAND); /* NAND_REn[2] */ ++ orion5x_mpp_conf(15, MPP_NAND); /* NAND_WEn[2] */ ++ orion5x_mpp_conf(16, MPP_UART); /* UART1_RX */ ++ orion5x_mpp_conf(17, MPP_UART); /* UART1_TX */ ++ orion5x_mpp_conf(18, MPP_UART); /* UART1_CTSn */ ++ orion5x_mpp_conf(19, MPP_UART); /* UART1_RTSn */ ++ orion5x_write(MPP_DEV_CTRL, 0); /* DEV_D[31:16] */ + + /* + * Configure peripherals. +--- a/arch/arm/mach-orion5x/dns323-setup.c ++++ b/arch/arm/mach-orion5x/dns323-setup.c +@@ -27,6 +27,7 @@ + #include <asm/mach/pci.h> + #include <asm/arch/orion5x.h> + #include "common.h" ++#include "mpp.h" + + #define DNS323_GPIO_LED_RIGHT_AMBER 1 + #define DNS323_GPIO_LED_LEFT_AMBER 2 +@@ -247,34 +248,27 @@ + /* Setup basic Orion functions. Need to be called early. */ + orion5x_init(); + +- /* set MPP to 0 as D-Link's 2.6.12.6 kernel did */ +- orion5x_write(MPP_0_7_CTRL, 0); +- orion5x_write(MPP_8_15_CTRL, 0); +- orion5x_write(MPP_16_19_CTRL, 0); +- orion5x_write(MPP_DEV_CTRL, 0); +- +- /* Define used GPIO pins +- +- GPIO Map: +- +- | 0 | | PEX_RST_OUT (not controlled by GPIO) +- | 1 | Out | right amber LED (= sata ch0 LED) (low-active) +- | 2 | Out | left amber LED (= sata ch1 LED) (low-active) +- | 3 | Out | //unknown// +- | 4 | Out | power button LED (low-active, together with pin #5) +- | 5 | Out | power button LED (low-active, together with pin #4) +- | 6 | In | GMT G751-2f overtemp. shutdown signal (low-active) +- | 7 | In | M41T80 nIRQ/OUT/SQW signal +- | 8 | Out | triggers power off (high-active) +- | 9 | In | power button switch (low-active) +- | 10 | In | reset button switch (low-active) +- | 11 | Out | //unknown// +- | 12 | Out | //unknown// +- | 13 | Out | //unknown// +- | 14 | Out | //unknown// +- | 15 | Out | //unknown// +- */ +- orion5x_gpio_set_valid_pins(0x07f6); ++ orion5x_mpp_conf(0, MPP_PCIE_RST_OUTn); ++ orion5x_mpp_conf(1, MPP_GPIO); /* right amber LED (sata ch0) */ ++ orion5x_mpp_conf(2, MPP_GPIO); /* left amber LED (sata ch1) */ ++ orion5x_mpp_conf(3, MPP_UNUSED); ++ orion5x_mpp_conf(4, MPP_GPIO); /* power button LED */ ++ orion5x_mpp_conf(5, MPP_GPIO); /* power button LED */ ++ orion5x_mpp_conf(6, MPP_GPIO); /* GMT G751-2f overtemp */ ++ orion5x_mpp_conf(7, MPP_GPIO); /* M41T80 nIRQ/OUT/SQW */ ++ orion5x_mpp_conf(8, MPP_GPIO); /* triggers power off */ ++ orion5x_mpp_conf(9, MPP_GPIO); /* power button switch */ ++ orion5x_mpp_conf(10, MPP_GPIO); /* reset button switch */ ++ orion5x_mpp_conf(11, MPP_UNUSED); ++ orion5x_mpp_conf(12, MPP_UNUSED); ++ orion5x_mpp_conf(13, MPP_UNUSED); ++ orion5x_mpp_conf(14, MPP_UNUSED); ++ orion5x_mpp_conf(15, MPP_UNUSED); ++ orion5x_mpp_conf(16, MPP_UNUSED); ++ orion5x_mpp_conf(17, MPP_UNUSED); ++ orion5x_mpp_conf(18, MPP_UNUSED); ++ orion5x_mpp_conf(19, MPP_UNUSED); ++ orion5x_write(MPP_DEV_CTRL, 0); /* DEV_D[31:16] */ + + /* + * Configure peripherals. +--- a/arch/arm/mach-orion5x/gpio.c ++++ b/arch/arm/mach-orion5x/gpio.c +@@ -24,9 +24,12 @@ + static unsigned long gpio_valid[BITS_TO_LONGS(GPIO_MAX)]; + static const char *gpio_label[GPIO_MAX]; /* non null for allocated GPIOs */ + +-void __init orion5x_gpio_set_valid_pins(u32 pins) ++void __init orion5x_gpio_set_valid(unsigned pin, int valid) + { +- gpio_valid[0] = pins; ++ if (valid) ++ __set_bit(pin, gpio_valid); ++ else ++ __clear_bit(pin, gpio_valid); + } + + /* +--- a/arch/arm/mach-orion5x/kurobox_pro-setup.c ++++ b/arch/arm/mach-orion5x/kurobox_pro-setup.c +@@ -25,6 +25,7 @@ + #include <asm/arch/orion5x.h> + #include <asm/plat-orion/orion_nand.h> + #include "common.h" ++#include "mpp.h" + + /***************************************************************************** + * KUROBOX-PRO Info +@@ -187,26 +188,26 @@ + */ + orion5x_init(); + +- /* +- * Setup Multiplexing Pins -- +- * MPP[0-1] Not used +- * MPP[2] GPIO Micon +- * MPP[3] GPIO RTC +- * MPP[4-5] Not used +- * MPP[6] Nand Flash REn +- * MPP[7] Nand Flash WEn +- * MPP[8-11] Not used +- * MPP[12] SATA 0 presence Indication +- * MPP[13] SATA 1 presence Indication +- * MPP[14] SATA 0 active Indication +- * MPP[15] SATA 1 active indication +- * MPP[16-19] Not used +- */ +- orion5x_write(MPP_0_7_CTRL, 0x44220003); +- orion5x_write(MPP_8_15_CTRL, 0x55550000); +- orion5x_write(MPP_16_19_CTRL, 0x0); +- +- orion5x_gpio_set_valid_pins(0x0000000c); ++ orion5x_mpp_conf(0, MPP_UNUSED); ++ orion5x_mpp_conf(1, MPP_UNUSED); ++ orion5x_mpp_conf(2, MPP_GPIO); /* GPIO Micon */ ++ orion5x_mpp_conf(3, MPP_GPIO); /* GPIO Rtc */ ++ orion5x_mpp_conf(4, MPP_UNUSED); ++ orion5x_mpp_conf(5, MPP_UNUSED); ++ orion5x_mpp_conf(6, MPP_NAND); /* NAND Flash REn */ ++ orion5x_mpp_conf(7, MPP_NAND); /* NAND Flash WEn */ ++ orion5x_mpp_conf(8, MPP_UNUSED); ++ orion5x_mpp_conf(9, MPP_UNUSED); ++ orion5x_mpp_conf(10, MPP_UNUSED); ++ orion5x_mpp_conf(11, MPP_UNUSED); ++ orion5x_mpp_conf(12, MPP_SATA_LED); /* SATA 0 presence */ ++ orion5x_mpp_conf(13, MPP_SATA_LED); /* SATA 1 presence */ ++ orion5x_mpp_conf(14, MPP_SATA_LED); /* SATA 0 active */ ++ orion5x_mpp_conf(15, MPP_SATA_LED); /* SATA 1 active */ ++ orion5x_mpp_conf(16, MPP_UNUSED); ++ orion5x_mpp_conf(17, MPP_UNUSED); ++ orion5x_mpp_conf(18, MPP_UNUSED); ++ orion5x_mpp_conf(19, MPP_UNUSED); + + /* + * Configure peripherals. +--- /dev/null ++++ b/arch/arm/mach-orion5x/mpp.c +@@ -0,0 +1,142 @@ ++/* ++ * arch/arm/mach-orion5x/mpp.c ++ * ++ * MPP functions for Marvell Orion 5x SoCs ++ * ++ * This file is licensed under the terms of the GNU General Public ++ * License version 2. This program is licensed "as is" without any ++ * warranty of any kind, whether express or implied. ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/init.h> ++#include <linux/mbus.h> ++#include <asm/hardware.h> ++#include <asm/io.h> ++#include "common.h" ++#include "mpp.h" ++ ++static int is_5182(void) ++{ ++ u32 dev; ++ u32 rev; ++ ++ orion5x_pcie_id(&dev, &rev); ++ ++ return !!(dev == MV88F5182_DEV_ID); ++} ++ ++static int is_5281(void) ++{ ++ u32 dev; ++ u32 rev; ++ ++ orion5x_pcie_id(&dev, &rev); ++ ++ return !!(dev == MV88F5281_DEV_ID); ++} ++ ++static int __init determine_type_encoding(int mpp, enum orion5x_mpp_type type) ++{ ++ switch (type) { ++ case MPP_UNUSED: ++ case MPP_GPIO: ++ if (mpp == 0) ++ return 3; ++ if (mpp >= 1 && mpp <= 15) ++ return 0; ++ if (mpp >= 16 && mpp <= 19) { ++ if (is_5182()) ++ return 5; ++ if (type == MPP_UNUSED) ++ return 0; ++ } ++ return -1; ++ ++ case MPP_PCIE_RST_OUTn: ++ if (mpp == 0) ++ return 0; ++ return -1; ++ ++ case MPP_PCI_ARB: ++ if (mpp >= 0 && mpp <= 7) ++ return 2; ++ return -1; ++ ++ case MPP_PCI_PMEn: ++ if (mpp == 2) ++ return 3; ++ return -1; ++ ++ case MPP_GIGE: ++ if (mpp >= 8 && mpp <= 15) ++ return 1; ++ return -1; ++ ++ case MPP_NAND: ++ if (is_5182() || is_5281()) { ++ if (mpp >= 4 && mpp <= 7) ++ return 4; ++ if (mpp >= 12 && mpp <= 17) ++ return 4; ++ } ++ return -1; ++ ++ ++ case MPP_SATA_LED: ++ if (is_5182()) { ++ if (mpp >= 4 && mpp <= 7) ++ return 5; ++ if (mpp >= 12 && mpp <= 15) ++ return 5; ++ } ++ return -1; ++ ++ case MPP_UART: ++ if (mpp >= 16 && mpp <= 19) ++ return 0; ++ return -1; ++ } ++ ++ printk(KERN_INFO "unknown MPP type %d\n", type); ++ ++ return -1; ++} ++ ++static void __init set_mpp_type(int mpp, int num_type) ++{ ++ unsigned long reg; ++ u32 value; ++ ++ if (mpp >= 0 && mpp <= 7) ++ reg = MPP_0_7_CTRL; ++ else if (mpp >= 8 && mpp <= 15) ++ reg = MPP_8_15_CTRL; ++ else if (mpp >= 16 && mpp <= 19) ++ reg = MPP_16_19_CTRL; ++ else ++ return; ++ ++ mpp &= 7; ++ ++ value = readl(reg); ++ value &= ~(0xf << (mpp << 2)); ++ value |= (num_type & 0xf) << (mpp << 2); ++ writel(value, reg); ++} ++ ++void __init orion5x_mpp_conf(int mpp, enum orion5x_mpp_type type) ++{ ++ int num_type; ++ ++ num_type = determine_type_encoding(mpp, type); ++ if (num_type < 0) { ++ printk(KERN_ERR "orion5x_mpp_conf: invalid MPP " ++ "combination (%d, %d)\n", mpp, type); ++ return; ++ } ++ ++ set_mpp_type(mpp, num_type); ++ ++ orion5x_gpio_set_valid(mpp, (type == MPP_GPIO) ? 1 : 0); ++} +--- /dev/null ++++ b/arch/arm/mach-orion5x/mpp.h +@@ -0,0 +1,63 @@ ++#ifndef __ARCH_ORION5X_MPP_H ++#define __ARCH_ORION5X_MPP_H ++ ++enum orion5x_mpp_type { ++ /* ++ * This MPP is unused. ++ */ ++ MPP_UNUSED, ++ ++ /* ++ * This MPP pin is used as a generic GPIO pin. Valid for ++ * MPPs 0-15 and device bus data pins 16-31. On 5182, also ++ * valid for MPPs 16-19. ++ */ ++ MPP_GPIO, ++ ++ /* ++ * This MPP is used as PCIe_RST_OUTn pin. Valid for ++ * MPP 0 only. ++ */ ++ MPP_PCIE_RST_OUTn, ++ ++ /* ++ * This MPP is used as PCI arbiter pin (REQn/GNTn.) ++ * Valid for MPPs 0-7 only. ++ */ ++ MPP_PCI_ARB, ++ ++ /* ++ * This MPP is used as PCI_PMEn pin. Valid for MPP 2 only. ++ */ ++ MPP_PCI_PMEn, ++ ++ /* ++ * This MPP is used as GigE half-duplex (COL, CRS) or GMII ++ * (RXERR, CRS, TXERR, TXD[7:4], RXD[7:4]) pin. Valid for ++ * MPPs 8-19 only. ++ */ ++ MPP_GIGE, ++ ++ /* ++ * This MPP is used as NAND REn/WEn pin. Valid for MPPs ++ * 4-7 and 12-17 only, and only on the 5181l/5182/5281. ++ */ ++ MPP_NAND, ++ ++ /* ++ * This MPP is used as a SATA presence/activity LED. ++ * Valid for MPPs 4-7 and 12-15 only, and only on the 5182. ++ */ ++ MPP_SATA_LED, ++ ++ /* ++ * This MPP is used as UART1 RXD/TXD/CTSn/RTSn pin. ++ * Valid for MPPs 16-19 only. ++ */ ++ MPP_UART, ++}; ++ ++void orion5x_mpp_conf(int mpp, enum orion5x_mpp_type type); ++ ++ ++#endif +--- a/arch/arm/mach-orion5x/rd88f5182-setup.c ++++ b/arch/arm/mach-orion5x/rd88f5182-setup.c +@@ -26,6 +26,7 @@ + #include <asm/mach/pci.h> + #include <asm/arch/orion5x.h> + #include "common.h" ++#include "mpp.h" + + /***************************************************************************** + * RD-88F5182 Info +@@ -248,22 +249,28 @@ + */ + orion5x_init(); + ++ orion5x_mpp_conf(0, MPP_GPIO); /* Debug Led */ ++ orion5x_mpp_conf(1, MPP_GPIO); /* Reset Switch */ ++ orion5x_mpp_conf(2, MPP_UNUSED); ++ orion5x_mpp_conf(3, MPP_GPIO); /* RTC Int */ ++ orion5x_mpp_conf(4, MPP_GPIO); ++ orion5x_mpp_conf(5, MPP_GPIO); ++ orion5x_mpp_conf(6, MPP_GPIO); /* PCI_intA */ ++ orion5x_mpp_conf(7, MPP_GPIO); /* PCI_intB */ ++ orion5x_mpp_conf(8, MPP_UNUSED); ++ orion5x_mpp_conf(9, MPP_UNUSED); ++ orion5x_mpp_conf(10, MPP_UNUSED); ++ orion5x_mpp_conf(11, MPP_UNUSED); ++ orion5x_mpp_conf(12, MPP_SATA_LED); /* SATA 0 presence */ ++ orion5x_mpp_conf(13, MPP_SATA_LED); /* SATA 1 presence */ ++ orion5x_mpp_conf(14, MPP_SATA_LED); /* SATA 0 active */ ++ orion5x_mpp_conf(15, MPP_SATA_LED); /* SATA 1 active */ ++ orion5x_mpp_conf(16, MPP_UNUSED); ++ orion5x_mpp_conf(17, MPP_UNUSED); ++ orion5x_mpp_conf(18, MPP_UNUSED); ++ orion5x_mpp_conf(19, MPP_UNUSED); ++ + /* +- * Setup Multiplexing Pins -- +- * MPP[0] Debug Led (GPIO - Out) +- * MPP[1] Debug Led (GPIO - Out) +- * MPP[2] N/A +- * MPP[3] RTC_Int (GPIO - In) +- * MPP[4] GPIO +- * MPP[5] GPIO +- * MPP[6] PCI_intA (GPIO - In) +- * MPP[7] PCI_intB (GPIO - In) +- * MPP[8-11] N/A +- * MPP[12] SATA 0 presence Indication +- * MPP[13] SATA 1 presence Indication +- * MPP[14] SATA 0 active Indication +- * MPP[15] SATA 1 active indication +- * MPP[16-19] Not used + * MPP[20] PCI Clock to MV88F5182 + * MPP[21] PCI Clock to mini PCI CON11 + * MPP[22] USB 0 over current indication +@@ -272,12 +279,6 @@ + * MPP[25] USB 0 over current enable + */ + +- orion5x_write(MPP_0_7_CTRL, 0x00000003); +- orion5x_write(MPP_8_15_CTRL, 0x55550000); +- orion5x_write(MPP_16_19_CTRL, 0x5555); +- +- orion5x_gpio_set_valid_pins(0x000000fb); +- + /* + * Configure peripherals. + */ +--- a/arch/arm/mach-orion5x/ts209-setup.c ++++ b/arch/arm/mach-orion5x/ts209-setup.c +@@ -28,6 +28,7 @@ + #include <asm/mach/pci.h> + #include <asm/arch/orion5x.h> + #include "common.h" ++#include "mpp.h" + + #define QNAP_TS209_NOR_BOOT_BASE 0xf4000000 + #define QNAP_TS209_NOR_BOOT_SIZE SZ_8M +@@ -364,33 +365,33 @@ + */ + orion5x_init(); + ++ orion5x_mpp_conf(0, MPP_UNUSED); ++ orion5x_mpp_conf(1, MPP_GPIO); /* USB copy button */ ++ orion5x_mpp_conf(2, MPP_GPIO); /* Load defaults button */ ++ orion5x_mpp_conf(3, MPP_GPIO); /* GPIO RTC */ ++ orion5x_mpp_conf(4, MPP_UNUSED); ++ orion5x_mpp_conf(5, MPP_UNUSED); ++ orion5x_mpp_conf(6, MPP_GPIO); /* PCI Int A */ ++ orion5x_mpp_conf(7, MPP_GPIO); /* PCI Int B */ ++ orion5x_mpp_conf(8, MPP_UNUSED); ++ orion5x_mpp_conf(9, MPP_UNUSED); ++ orion5x_mpp_conf(10, MPP_UNUSED); ++ orion5x_mpp_conf(11, MPP_UNUSED); ++ orion5x_mpp_conf(12, MPP_SATA_LED); /* SATA 0 presence */ ++ orion5x_mpp_conf(13, MPP_SATA_LED); /* SATA 1 presence */ ++ orion5x_mpp_conf(14, MPP_SATA_LED); /* SATA 0 active */ ++ orion5x_mpp_conf(15, MPP_SATA_LED); /* SATA 1 active */ ++ orion5x_mpp_conf(16, MPP_UART); /* UART1 RXD */ ++ orion5x_mpp_conf(17, MPP_UART); /* UART1 TXD */ ++ orion5x_mpp_conf(18, MPP_GPIO); /* SW_RST */ ++ orion5x_mpp_conf(19, MPP_UNUSED); ++ + /* +- * Setup Multiplexing Pins -- +- * MPP[0] Reserved +- * MPP[1] USB copy button (0 active) +- * MPP[2] Load defaults button (0 active) +- * MPP[3] GPIO RTC +- * MPP[4-5] Reserved +- * MPP[6] PCI Int A +- * MPP[7] PCI Int B +- * MPP[8-11] Reserved +- * MPP[12] SATA 0 presence +- * MPP[13] SATA 1 presence +- * MPP[14] SATA 0 active +- * MPP[15] SATA 1 active +- * MPP[16] UART1 RXD +- * MPP[17] UART1 TXD +- * MPP[18] SW_RST (0 active) +- * MPP[19] Reserved + * MPP[20] PCI clock 0 + * MPP[21] PCI clock 1 + * MPP[22] USB 0 over current + * MPP[23-25] Reserved + */ +- orion5x_write(MPP_0_7_CTRL, 0x3); +- orion5x_write(MPP_8_15_CTRL, 0x55550000); +- orion5x_write(MPP_16_19_CTRL, 0x5500); +- orion5x_gpio_set_valid_pins(0x3cc0fff); + + /* + * Configure peripherals. diff --git a/target/linux/orion/patches/013-add_88f5181l_support.patch b/target/linux/orion/patches/013-add_88f5181l_support.patch new file mode 100644 index 0000000000..b902777701 --- /dev/null +++ b/target/linux/orion/patches/013-add_88f5181l_support.patch @@ -0,0 +1,56 @@ +Signed-off-by: Lennert Buytenhek <buytenh@marvell.com> +--- + arch/arm/Kconfig | 3 ++- + arch/arm/mach-orion5x/common.c | 4 +++- + include/asm-arm/arch-orion5x/orion5x.h | 5 +++-- + 3 files changed, 8 insertions(+), 4 deletions(-) + +--- a/arch/arm/Kconfig ++++ b/arch/arm/Kconfig +@@ -385,7 +385,8 @@ + select PLAT_ORION + help + Support for the following Marvell Orion 5x series SoCs: +- Orion-1 (5181), Orion-NAS (5182), Orion-2 (5281.) ++ Orion-1 (5181), Orion-VoIP (5181L), Orion-NAS (5182), ++ Orion-2 (5281.) + + config ARCH_PNX4008 + bool "Philips Nexperia PNX4008 Mobile" +--- a/arch/arm/mach-orion5x/common.c ++++ b/arch/arm/mach-orion5x/common.c +@@ -394,8 +394,10 @@ + } else if (*dev == MV88F5181_DEV_ID) { + if (*rev == MV88F5181_REV_B1) { + *dev_name = "MV88F5181-Rev-B1"; ++ } else if (*rev == MV88F5181L_REV_A1) { ++ *dev_name = "MV88F5181L-Rev-A1"; + } else { +- *dev_name = "MV88F5181-Rev-Unsupported"; ++ *dev_name = "MV88F5181(L)-Rev-Unsupported"; + } + } else { + *dev_name = "Device-Unknown"; +--- a/include/asm-arm/arch-orion5x/orion5x.h ++++ b/include/asm-arm/arch-orion5x/orion5x.h +@@ -2,7 +2,7 @@ + * include/asm-arm/arch-orion5x/orion5x.h + * + * Generic definitions of Orion SoC flavors: +- * Orion-1, Orion-NAS, Orion-VoIP, and Orion-2. ++ * Orion-1, Orion-VoIP, Orion-NAS, and Orion-2. + * + * Maintainer: Tzachi Perelstein <tzachi@marvell.com> + * +@@ -63,9 +63,10 @@ + /******************************************************************************* + * Supported Devices & Revisions + ******************************************************************************/ +-/* Orion-1 (88F5181) */ ++/* Orion-1 (88F5181) and Orion-VoIP (88F5181L) */ + #define MV88F5181_DEV_ID 0x5181 + #define MV88F5181_REV_B1 3 ++#define MV88F5181L_REV_A1 9 + /* Orion-NAS (88F5182) */ + #define MV88F5182_DEV_ID 0x5182 + #define MV88F5182_REV_A2 2 diff --git a/target/linux/orion/patches/014-avoid_setting_force_phy_addr.patch b/target/linux/orion/patches/014-avoid_setting_force_phy_addr.patch new file mode 100644 index 0000000000..d47e5dd281 --- /dev/null +++ b/target/linux/orion/patches/014-avoid_setting_force_phy_addr.patch @@ -0,0 +1,71 @@ +The mv643xx_eth platform data field ->force_phy_addr only needs +to be set if the passed-in ->phy_addr field is zero (to distinguish +the case of not having specified a phy address +(force_phy_addr = 0) from the case where a phy address of zero needs +to be used (force_phy_addr = 1.)) + +Also, the ->force_phy_addr field will hopefully disappear in a +future mv643xx_eth reorganisation. + +Therefore, this patch deletes the ->force_phy_addr field initialiser +from all Orion board code. + +Signed-off-by: Lennert Buytenhek <buytenh@marvell.com> +--- + arch/arm/mach-orion5x/db88f5281-setup.c | 1 - + arch/arm/mach-orion5x/dns323-setup.c | 1 - + arch/arm/mach-orion5x/kurobox_pro-setup.c | 1 - + arch/arm/mach-orion5x/rd88f5182-setup.c | 1 - + arch/arm/mach-orion5x/ts209-setup.c | 1 - + 5 files changed, 0 insertions(+), 5 deletions(-) + +--- a/arch/arm/mach-orion5x/db88f5281-setup.c ++++ b/arch/arm/mach-orion5x/db88f5281-setup.c +@@ -286,7 +286,6 @@ + ****************************************************************************/ + static struct mv643xx_eth_platform_data db88f5281_eth_data = { + .phy_addr = 8, +- .force_phy_addr = 1, + }; + + /***************************************************************************** +--- a/arch/arm/mach-orion5x/dns323-setup.c ++++ b/arch/arm/mach-orion5x/dns323-setup.c +@@ -82,7 +82,6 @@ + + static struct mv643xx_eth_platform_data dns323_eth_data = { + .phy_addr = 8, +- .force_phy_addr = 1, + }; + + /**************************************************************************** +--- a/arch/arm/mach-orion5x/kurobox_pro-setup.c ++++ b/arch/arm/mach-orion5x/kurobox_pro-setup.c +@@ -160,7 +160,6 @@ + + static struct mv643xx_eth_platform_data kurobox_pro_eth_data = { + .phy_addr = 8, +- .force_phy_addr = 1, + }; + + /***************************************************************************** +--- a/arch/arm/mach-orion5x/rd88f5182-setup.c ++++ b/arch/arm/mach-orion5x/rd88f5182-setup.c +@@ -222,7 +222,6 @@ + + static struct mv643xx_eth_platform_data rd88f5182_eth_data = { + .phy_addr = 8, +- .force_phy_addr = 1, + }; + + /***************************************************************************** +--- a/arch/arm/mach-orion5x/ts209-setup.c ++++ b/arch/arm/mach-orion5x/ts209-setup.c +@@ -191,7 +191,6 @@ + + static struct mv643xx_eth_platform_data qnap_ts209_eth_data = { + .phy_addr = 8, +- .force_phy_addr = 1, + }; + + static int __init parse_hex_nibble(char n) diff --git a/target/linux/orion/patches/015-implement_power-off_method_for_kurobox_pro.patch b/target/linux/orion/patches/015-implement_power-off_method_for_kurobox_pro.patch new file mode 100644 index 0000000000..5814852388 --- /dev/null +++ b/target/linux/orion/patches/015-implement_power-off_method_for_kurobox_pro.patch @@ -0,0 +1,192 @@ +From: Sylver Bruneau <sylver.bruneau@googlemail.com> + +This patch implements the communication with the microcontroller on the +Kurobox Pro and Linkstation Pro/Live boards. This is allowing to send +the commands needed to power-off the board correctly. + +Signed-off-by: Sylver Bruneau <sylver.bruneau@googlemail.com> +--- + arch/arm/mach-orion5x/kurobox_pro-setup.c | 147 ++++++++++++++++++++++++++++- + 1 files changed, 143 insertions(+), 4 deletions(-) + +--- a/arch/arm/mach-orion5x/kurobox_pro-setup.c ++++ b/arch/arm/mach-orion5x/kurobox_pro-setup.c +@@ -13,10 +13,12 @@ + #include <linux/platform_device.h> + #include <linux/pci.h> + #include <linux/irq.h> ++#include <linux/delay.h> + #include <linux/mtd/physmap.h> + #include <linux/mtd/nand.h> + #include <linux/mv643xx_eth.h> + #include <linux/i2c.h> ++#include <linux/serial_reg.h> + #include <linux/ata_platform.h> + #include <asm/mach-types.h> + #include <asm/gpio.h> +@@ -177,6 +179,140 @@ + }; + + /***************************************************************************** ++ * Kurobox Pro specific power off method via UART1-attached microcontroller ++ ****************************************************************************/ ++ ++#define UART1_REG(x) (UART1_VIRT_BASE + ((UART_##x) << 2)) ++ ++static int kurobox_pro_miconread(unsigned char *buf, int count) ++{ ++ int i; ++ int timeout; ++ ++ for (i = 0; i < count; i++) { ++ timeout = 10; ++ ++ while (!(readl(UART1_REG(LSR)) & UART_LSR_DR)) { ++ if (--timeout == 0) ++ break; ++ udelay(1000); ++ } ++ ++ if (timeout == 0) ++ break; ++ buf[i] = readl(UART1_REG(RX)); ++ } ++ ++ /* return read bytes */ ++ return i; ++} ++ ++static int kurobox_pro_miconwrite(const unsigned char *buf, int count) ++{ ++ int i = 0; ++ ++ while (count--) { ++ while (!(readl(UART1_REG(LSR)) & UART_LSR_THRE)) ++ barrier(); ++ writel(buf[i++], UART1_REG(TX)); ++ } ++ ++ return 0; ++} ++ ++static int kurobox_pro_miconsend(const unsigned char *data, int count) ++{ ++ int i; ++ unsigned char checksum = 0; ++ unsigned char recv_buf[40]; ++ unsigned char send_buf[40]; ++ unsigned char correct_ack[3]; ++ int retry = 2; ++ ++ /* Generate checksum */ ++ for (i = 0; i < count; i++) ++ checksum -= data[i]; ++ ++ do { ++ /* Send data */ ++ kurobox_pro_miconwrite(data, count); ++ ++ /* send checksum */ ++ kurobox_pro_miconwrite(&checksum, 1); ++ ++ if (kurobox_pro_miconread(recv_buf, sizeof(recv_buf)) <= 3) { ++ printk(KERN_ERR ">%s: receive failed.\n", __func__); ++ ++ /* send preamble to clear the receive buffer */ ++ memset(&send_buf, 0xff, sizeof(send_buf)); ++ kurobox_pro_miconwrite(send_buf, sizeof(send_buf)); ++ ++ /* make dummy reads */ ++ mdelay(100); ++ kurobox_pro_miconread(recv_buf, sizeof(recv_buf)); ++ } else { ++ /* Generate expected ack */ ++ correct_ack[0] = 0x01; ++ correct_ack[1] = data[1]; ++ correct_ack[2] = 0x00; ++ ++ /* checksum Check */ ++ if ((recv_buf[0] + recv_buf[1] + recv_buf[2] + ++ recv_buf[3]) & 0xFF) { ++ printk(KERN_ERR ">%s: Checksum Error : " ++ "Received data[%02x, %02x, %02x, %02x]" ++ "\n", __func__, recv_buf[0], ++ recv_buf[1], recv_buf[2], recv_buf[3]); ++ } else { ++ /* Check Received Data */ ++ if (correct_ack[0] == recv_buf[0] && ++ correct_ack[1] == recv_buf[1] && ++ correct_ack[2] == recv_buf[2]) { ++ /* Interval for next command */ ++ mdelay(10); ++ ++ /* Receive ACK */ ++ return 0; ++ } ++ } ++ /* Received NAK or illegal Data */ ++ printk(KERN_ERR ">%s: Error : NAK or Illegal Data " ++ "Received\n", __func__); ++ } ++ } while (retry--); ++ ++ /* Interval for next command */ ++ mdelay(10); ++ ++ return -1; ++} ++ ++static void kurobox_pro_power_off(void) ++{ ++ const unsigned char watchdogkill[] = {0x01, 0x35, 0x00}; ++ const unsigned char shutdownwait[] = {0x00, 0x0c}; ++ const unsigned char poweroff[] = {0x00, 0x06}; ++ /* 38400 baud divisor */ ++ const unsigned divisor = ((ORION5X_TCLK + (8 * 38400)) / (16 * 38400)); ++ ++ pr_info("%s: triggering power-off...\n", __func__); ++ ++ /* hijack uart1 and reset into sane state (38400,8n1,even parity) */ ++ writel(0x83, UART1_REG(LCR)); ++ writel(divisor & 0xff, UART1_REG(DLL)); ++ writel((divisor >> 8) & 0xff, UART1_REG(DLM)); ++ writel(0x1b, UART1_REG(LCR)); ++ writel(0x00, UART1_REG(IER)); ++ writel(0x07, UART1_REG(FCR)); ++ writel(0x00, UART1_REG(MCR)); ++ ++ /* Send the commands to shutdown the Kurobox Pro */ ++ kurobox_pro_miconsend(watchdogkill, sizeof(watchdogkill)) ; ++ kurobox_pro_miconsend(shutdownwait, sizeof(shutdownwait)) ; ++ kurobox_pro_miconsend(poweroff, sizeof(poweroff)); ++} ++ ++/***************************************************************************** + * General Setup + ****************************************************************************/ + +@@ -203,10 +339,10 @@ + orion5x_mpp_conf(13, MPP_SATA_LED); /* SATA 1 presence */ + orion5x_mpp_conf(14, MPP_SATA_LED); /* SATA 0 active */ + orion5x_mpp_conf(15, MPP_SATA_LED); /* SATA 1 active */ +- orion5x_mpp_conf(16, MPP_UNUSED); +- orion5x_mpp_conf(17, MPP_UNUSED); +- orion5x_mpp_conf(18, MPP_UNUSED); +- orion5x_mpp_conf(19, MPP_UNUSED); ++ orion5x_mpp_conf(16, MPP_UART); /* UART1 RXD */ ++ orion5x_mpp_conf(17, MPP_UART); /* UART1 TXD */ ++ orion5x_mpp_conf(18, MPP_UART); /* UART1 CTSn */ ++ orion5x_mpp_conf(19, MPP_UART); /* UART1 RTSn */ + + /* + * Configure peripherals. +@@ -229,6 +365,9 @@ + } + + i2c_register_board_info(0, &kurobox_pro_i2c_rtc, 1); ++ ++ /* register Kurobox Pro specific power-off method */ ++ pm_power_off = kurobox_pro_power_off; + } + + #ifdef CONFIG_MACH_KUROBOX_PRO diff --git a/target/linux/orion/patches/016-add_qnap_ts-409_support.patch b/target/linux/orion/patches/016-add_qnap_ts-409_support.patch new file mode 100644 index 0000000000..a0d22f75eb --- /dev/null +++ b/target/linux/orion/patches/016-add_qnap_ts-409_support.patch @@ -0,0 +1,418 @@ +From: Sylver Bruneau <sylver.bruneau@googlemail.com> + +Signed-off-by: Lennert Buytenhek <buytenh@marvell.com> +--- + arch/arm/mach-orion5x/Kconfig | 6 + + arch/arm/mach-orion5x/Makefile | 1 + + arch/arm/mach-orion5x/ts409-setup.c | 383 +++++++++++++++++++++++++++++++++++ + 3 files changed, 390 insertions(+), 0 deletions(-) + create mode 100644 arch/arm/mach-orion5x/ts409-setup.c + +--- a/arch/arm/mach-orion5x/Kconfig ++++ b/arch/arm/mach-orion5x/Kconfig +@@ -44,6 +44,12 @@ + Buffalo Linkstation Pro/Live platform. Both v1 and + v2 devices are supported. + ++config MACH_TS409 ++ bool "QNAP TS-409" ++ help ++ Say 'Y' here if you want your kernel to support the ++ QNAP TS-409 platform. ++ + endmenu + + endif +--- a/arch/arm/mach-orion5x/Makefile ++++ b/arch/arm/mach-orion5x/Makefile +@@ -5,3 +5,4 @@ + obj-$(CONFIG_MACH_LINKSTATION_PRO) += kurobox_pro-setup.o + obj-$(CONFIG_MACH_DNS323) += dns323-setup.o + obj-$(CONFIG_MACH_TS209) += ts209-setup.o ++obj-$(CONFIG_MACH_TS409) += ts409-setup.o +--- /dev/null ++++ b/arch/arm/mach-orion5x/ts409-setup.c +@@ -0,0 +1,383 @@ ++/* ++ * QNAP TS-409 Board Setup ++ * ++ * Maintainer: Sylver Bruneau <sylver.bruneau@gmail.com> ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version ++ * 2 of the License, or (at your option) any later version. ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/init.h> ++#include <linux/platform_device.h> ++#include <linux/pci.h> ++#include <linux/irq.h> ++#include <linux/mtd/physmap.h> ++#include <linux/mv643xx_eth.h> ++#include <linux/gpio_keys.h> ++#include <linux/input.h> ++#include <linux/i2c.h> ++#include <linux/serial_reg.h> ++#include <asm/mach-types.h> ++#include <asm/gpio.h> ++#include <asm/mach/arch.h> ++#include <asm/mach/pci.h> ++#include <asm/arch/orion5x.h> ++#include "common.h" ++#include "mpp.h" ++ ++/***************************************************************************** ++ * QNAP TS-409 Info ++ ****************************************************************************/ ++ ++/* ++ * QNAP TS-409 hardware : ++ * - Marvell 88F5281-D0 ++ * - Marvell 88SX7042 SATA controller (PCIe) ++ * - Marvell 88E1118 Gigabit Ethernet PHY ++ * - RTC S35390A (@0x30) on I2C bus ++ * - 8MB NOR flash ++ * - 256MB of DDR-2 RAM ++ */ ++ ++/* ++ * 8MB NOR flash Device bus boot chip select ++ */ ++ ++#define QNAP_TS409_NOR_BOOT_BASE 0xff800000 ++#define QNAP_TS409_NOR_BOOT_SIZE SZ_8M ++ ++/**************************************************************************** ++ * 8MiB NOR flash. The struct mtd_partition is not in the same order as the ++ * partitions on the device because we want to keep compatability with ++ * existing QNAP firmware. ++ * ++ * Layout as used by QNAP: ++ * [2] 0x00000000-0x00200000 : "Kernel" ++ * [3] 0x00200000-0x00600000 : "RootFS1" ++ * [4] 0x00600000-0x00700000 : "RootFS2" ++ * [6] 0x00700000-0x00760000 : "NAS Config" (read-only) ++ * [5] 0x00760000-0x00780000 : "U-Boot Config" ++ * [1] 0x00780000-0x00800000 : "U-Boot" (read-only) ++ ***************************************************************************/ ++static struct mtd_partition qnap_ts409_partitions[] = { ++ { ++ .name = "U-Boot", ++ .size = 0x00080000, ++ .offset = 0x00780000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "Kernel", ++ .size = 0x00200000, ++ .offset = 0, ++ }, { ++ .name = "RootFS1", ++ .size = 0x00400000, ++ .offset = 0x00200000, ++ }, { ++ .name = "RootFS2", ++ .size = 0x00100000, ++ .offset = 0x00600000, ++ }, { ++ .name = "U-Boot Config", ++ .size = 0x00020000, ++ .offset = 0x00760000, ++ }, { ++ .name = "NAS Config", ++ .size = 0x00060000, ++ .offset = 0x00700000, ++ .mask_flags = MTD_WRITEABLE, ++ }, ++}; ++ ++static struct physmap_flash_data qnap_ts409_nor_flash_data = { ++ .width = 1, ++ .parts = qnap_ts409_partitions, ++ .nr_parts = ARRAY_SIZE(qnap_ts409_partitions) ++}; ++ ++static struct resource qnap_ts409_nor_flash_resource = { ++ .flags = IORESOURCE_MEM, ++ .start = QNAP_TS409_NOR_BOOT_BASE, ++ .end = QNAP_TS409_NOR_BOOT_BASE + QNAP_TS409_NOR_BOOT_SIZE - 1, ++}; ++ ++static struct platform_device qnap_ts409_nor_flash = { ++ .name = "physmap-flash", ++ .id = 0, ++ .dev = { .platform_data = &qnap_ts409_nor_flash_data, }, ++ .num_resources = 1, ++ .resource = &qnap_ts409_nor_flash_resource, ++}; ++ ++/***************************************************************************** ++ * PCI ++ ****************************************************************************/ ++ ++static int __init qnap_ts409_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) ++{ ++ int irq; ++ ++ /* ++ * Check for devices with hard-wired IRQs. ++ */ ++ irq = orion5x_pci_map_irq(dev, slot, pin); ++ if (irq != -1) ++ return irq; ++ ++ /* ++ * PCI isn't used on the TS-409 ++ */ ++ printk(KERN_ERR "kurobox_pro_pci_map_irq failed, unknown bus\n"); ++ return -1; ++} ++ ++static struct hw_pci qnap_ts409_pci __initdata = { ++ .nr_controllers = 2, ++ .swizzle = pci_std_swizzle, ++ .setup = orion5x_pci_sys_setup, ++ .scan = orion5x_pci_sys_scan_bus, ++ .map_irq = qnap_ts409_pci_map_irq, ++}; ++ ++static int __init qnap_ts409_pci_init(void) ++{ ++ if (machine_is_ts409()) ++ pci_common_init(&qnap_ts409_pci); ++ ++ return 0; ++} ++ ++subsys_initcall(qnap_ts409_pci_init); ++ ++/***************************************************************************** ++ * Ethernet ++ ****************************************************************************/ ++ ++static struct mv643xx_eth_platform_data qnap_ts409_eth_data = { ++ .phy_addr = 8, ++}; ++ ++static int __init parse_hex_nibble(char n) ++{ ++ if (n >= '0' && n <= '9') ++ return n - '0'; ++ ++ if (n >= 'A' && n <= 'F') ++ return n - 'A' + 10; ++ ++ if (n >= 'a' && n <= 'f') ++ return n - 'a' + 10; ++ ++ return -1; ++} ++ ++static int __init parse_hex_byte(const char *b) ++{ ++ int hi; ++ int lo; ++ ++ hi = parse_hex_nibble(b[0]); ++ lo = parse_hex_nibble(b[1]); ++ ++ if (hi < 0 || lo < 0) ++ return -1; ++ ++ return (hi << 4) | lo; ++} ++ ++static int __init check_mac_addr(const char *addr_str) ++{ ++ u_int8_t addr[6]; ++ int i; ++ ++ for (i = 0; i < 6; i++) { ++ int byte; ++ ++ /* ++ * Enforce "xx:xx:xx:xx:xx:xx\n" format. ++ */ ++ if (addr_str[(i * 3) + 2] != ((i < 5) ? ':' : '\n')) ++ return -1; ++ ++ byte = parse_hex_byte(addr_str + (i * 3)); ++ if (byte < 0) ++ return -1; ++ addr[i] = byte; ++ } ++ ++ printk(KERN_INFO "ts409: found ethernet mac address "); ++ for (i = 0; i < 6; i++) ++ printk("%.2x%s", addr[i], (i < 5) ? ":" : ".\n"); ++ ++ memcpy(qnap_ts409_eth_data.mac_addr, addr, 6); ++ ++ return 0; ++} ++ ++/* ++ * The 'NAS Config' flash partition has an ext2 filesystem which ++ * contains a file that has the ethernet MAC address in plain text ++ * (format "xx:xx:xx:xx:xx:xx\n".) ++ */ ++static void __init ts409_find_mac_addr(void) ++{ ++ unsigned long addr; ++ ++ for (addr = 0x00700000; addr < 0x00760000; addr += 1024) { ++ char *nor_page; ++ int ret = 0; ++ ++ nor_page = ioremap(QNAP_TS409_NOR_BOOT_BASE + addr, 1024); ++ if (nor_page != NULL) { ++ ret = check_mac_addr(nor_page); ++ iounmap(nor_page); ++ } ++ ++ if (ret == 0) ++ break; ++ } ++} ++ ++/***************************************************************************** ++ * RTC S35390A on I2C bus ++ ****************************************************************************/ ++ ++#define TS409_RTC_GPIO 10 ++ ++static struct i2c_board_info __initdata qnap_ts409_i2c_rtc = { ++ I2C_BOARD_INFO("s35390a", 0x30), ++ .irq = 0, ++}; ++ ++/**************************************************************************** ++ * GPIO Attached Keys ++ * Power button is attached to the PIC microcontroller ++ ****************************************************************************/ ++ ++#define QNAP_TS409_GPIO_KEY_MEDIA 15 ++ ++static struct gpio_keys_button qnap_ts409_buttons[] = { ++ { ++ .code = KEY_RESTART, ++ .gpio = QNAP_TS409_GPIO_KEY_MEDIA, ++ .desc = "USB Copy Button", ++ .active_low = 1, ++ }, ++}; ++ ++static struct gpio_keys_platform_data qnap_ts409_button_data = { ++ .buttons = qnap_ts409_buttons, ++ .nbuttons = ARRAY_SIZE(qnap_ts409_buttons), ++}; ++ ++static struct platform_device qnap_ts409_button_device = { ++ .name = "gpio-keys", ++ .id = -1, ++ .num_resources = 0, ++ .dev = { ++ .platform_data = &qnap_ts409_button_data, ++ }, ++}; ++ ++/***************************************************************************** ++ * General Setup ++ ****************************************************************************/ ++ ++/* ++ * QNAP TS-409 specific power off method via UART1-attached PIC ++ */ ++ ++#define UART1_REG(x) (UART1_VIRT_BASE + ((UART_##x) << 2)) ++ ++static void qnap_ts409_power_off(void) ++{ ++ /* 19200 baud divisor */ ++ const unsigned divisor = ((ORION5X_TCLK + (8 * 19200)) / (16 * 19200)); ++ ++ pr_info("%s: triggering power-off...\n", __func__); ++ ++ /* hijack uart1 and reset into sane state (19200,8n1) */ ++ writel(0x83, UART1_REG(LCR)); ++ writel(divisor & 0xff, UART1_REG(DLL)); ++ writel((divisor >> 8) & 0xff, UART1_REG(DLM)); ++ writel(0x03, UART1_REG(LCR)); ++ writel(0x00, UART1_REG(IER)); ++ writel(0x00, UART1_REG(FCR)); ++ writel(0x00, UART1_REG(MCR)); ++ ++ /* send the power-off command 'A' to PIC */ ++ writel('A', UART1_REG(TX)); ++} ++ ++static void __init qnap_ts409_init(void) ++{ ++ /* ++ * Setup basic Orion functions. Need to be called early. ++ */ ++ orion5x_init(); ++ ++ orion5x_mpp_conf(0, MPP_UNUSED); ++ orion5x_mpp_conf(1, MPP_UNUSED); ++ orion5x_mpp_conf(2, MPP_UNUSED); ++ orion5x_mpp_conf(3, MPP_UNUSED); ++ orion5x_mpp_conf(4, MPP_GPIO); /* HDD 1 status */ ++ orion5x_mpp_conf(5, MPP_GPIO); /* HDD 2 status */ ++ orion5x_mpp_conf(6, MPP_GPIO); /* HDD 3 status */ ++ orion5x_mpp_conf(7, MPP_GPIO); /* HDD 4 status */ ++ orion5x_mpp_conf(8, MPP_UNUSED); ++ orion5x_mpp_conf(9, MPP_UNUSED); ++ orion5x_mpp_conf(10, MPP_GPIO); /* RTC int */ ++ orion5x_mpp_conf(11, MPP_UNUSED); ++ orion5x_mpp_conf(12, MPP_UNUSED); ++ orion5x_mpp_conf(13, MPP_UNUSED); ++ orion5x_mpp_conf(14, MPP_GPIO); /* SW_RST */ ++ orion5x_mpp_conf(15, MPP_GPIO); /* USB copy button */ ++ orion5x_mpp_conf(16, MPP_UART); /* UART1 RXD */ ++ orion5x_mpp_conf(17, MPP_UART); /* UART1 TXD */ ++ orion5x_mpp_conf(18, MPP_UNUSED); ++ orion5x_mpp_conf(19, MPP_UNUSED); ++ ++ /* ++ * Configure peripherals. ++ */ ++ orion5x_ehci0_init(); ++ ts409_find_mac_addr(); ++ orion5x_eth_init(&qnap_ts409_eth_data); ++ orion5x_i2c_init(); ++ orion5x_uart0_init(); ++ ++ orion5x_setup_dev_boot_win(QNAP_TS409_NOR_BOOT_BASE, ++ QNAP_TS409_NOR_BOOT_SIZE); ++ platform_device_register(&qnap_ts409_nor_flash); ++ ++ platform_device_register(&qnap_ts409_button_device); ++ ++ /* Get RTC IRQ and register the chip */ ++ if (gpio_request(TS409_RTC_GPIO, "rtc") == 0) { ++ if (gpio_direction_input(TS409_RTC_GPIO) == 0) ++ qnap_ts409_i2c_rtc.irq = gpio_to_irq(TS409_RTC_GPIO); ++ else ++ gpio_free(TS409_RTC_GPIO); ++ } ++ if (qnap_ts409_i2c_rtc.irq == 0) ++ pr_warning("qnap_ts409_init: failed to get RTC IRQ\n"); ++ i2c_register_board_info(0, &qnap_ts409_i2c_rtc, 1); ++ ++ /* register ts409 specific power-off method */ ++ pm_power_off = qnap_ts409_power_off; ++} ++ ++MACHINE_START(TS409, "QNAP TS-409") ++ /* Maintainer: Sylver Bruneau <sylver.bruneau@gmail.com> */ ++ .phys_io = ORION5X_REGS_PHYS_BASE, ++ .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC, ++ .boot_params = 0x00000100, ++ .init_machine = qnap_ts409_init, ++ .map_io = orion5x_map_io, ++ .init_irq = orion5x_init_irq, ++ .timer = &orion5x_timer, ++ .fixup = tag_fixup_mem32, ++MACHINE_END diff --git a/target/linux/orion/patches/017-add_linksys_wrt350n_v2_support.patch b/target/linux/orion/patches/017-add_linksys_wrt350n_v2_support.patch new file mode 100644 index 0000000000..5faa9597a0 --- /dev/null +++ b/target/linux/orion/patches/017-add_linksys_wrt350n_v2_support.patch @@ -0,0 +1,205 @@ +Signed-off-by: Lennert Buytenhek <buytenh@marvell.com> +Tested-by: Dirk Teurlings <dirk@upexia.nl> +Tested-by: Peter van Valderen <p.v.valderen@gmail.com> +--- + arch/arm/mach-orion5x/Kconfig | 6 + + arch/arm/mach-orion5x/Makefile | 1 + + arch/arm/mach-orion5x/wrt350n-v2-setup.c | 170 ++++++++++++++++++++++++++++++ + 3 files changed, 177 insertions(+), 0 deletions(-) + create mode 100644 arch/arm/mach-orion5x/wrt350n-v2-setup.c + +--- a/arch/arm/mach-orion5x/Kconfig ++++ b/arch/arm/mach-orion5x/Kconfig +@@ -50,6 +50,12 @@ + Say 'Y' here if you want your kernel to support the + QNAP TS-409 platform. + ++config MACH_WRT350N_V2 ++ bool "Linksys WRT350N v2" ++ help ++ Say 'Y' here if you want your kernel to support the ++ Linksys WRT350N v2 platform. ++ + endmenu + + endif +--- a/arch/arm/mach-orion5x/Makefile ++++ b/arch/arm/mach-orion5x/Makefile +@@ -6,3 +6,4 @@ + obj-$(CONFIG_MACH_DNS323) += dns323-setup.o + obj-$(CONFIG_MACH_TS209) += ts209-setup.o + obj-$(CONFIG_MACH_TS409) += ts409-setup.o ++obj-$(CONFIG_MACH_WRT350N_V2) += wrt350n-v2-setup.o +--- /dev/null ++++ b/arch/arm/mach-orion5x/wrt350n-v2-setup.c +@@ -0,0 +1,170 @@ ++/* ++ * arch/arm/mach-orion5x/wrt350n-v2-setup.c ++ * ++ * This file is licensed under the terms of the GNU General Public ++ * License version 2. This program is licensed "as is" without any ++ * warranty of any kind, whether express or implied. ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/init.h> ++#include <linux/platform_device.h> ++#include <linux/pci.h> ++#include <linux/irq.h> ++#include <linux/delay.h> ++#include <linux/mtd/physmap.h> ++#include <linux/mv643xx_eth.h> ++#include <asm/mach-types.h> ++#include <asm/gpio.h> ++#include <asm/mach/arch.h> ++#include <asm/mach/pci.h> ++#include <asm/arch/orion5x.h> ++#include "common.h" ++#include "mpp.h" ++ ++/* ++ * 8M NOR flash Device bus boot chip select ++ */ ++#define WRT350N_V2_NOR_BOOT_BASE 0xf4000000 ++#define WRT350N_V2_NOR_BOOT_SIZE SZ_8M ++ ++static struct mtd_partition wrt350n_v2_nor_flash_partitions[] = { ++ { ++ .name = "kernel", ++ .offset = 0x00000000, ++ .size = 0x00760000, ++ }, { ++ .name = "rootfs", ++ .offset = 0x001a0000, ++ .size = 0x005c0000, ++ }, { ++ .name = "lang", ++ .offset = 0x00760000, ++ .size = 0x00040000, ++ }, { ++ .name = "nvram", ++ .offset = 0x007a0000, ++ .size = 0x00020000, ++ }, { ++ .name = "u-boot", ++ .offset = 0x007c0000, ++ .size = 0x00040000, ++ }, ++}; ++ ++static struct physmap_flash_data wrt350n_v2_nor_flash_data = { ++ .width = 1, ++ .parts = wrt350n_v2_nor_flash_partitions, ++ .nr_parts = ARRAY_SIZE(wrt350n_v2_nor_flash_partitions), ++}; ++ ++static struct resource wrt350n_v2_nor_flash_resource = { ++ .flags = IORESOURCE_MEM, ++ .start = WRT350N_V2_NOR_BOOT_BASE, ++ .end = WRT350N_V2_NOR_BOOT_BASE + WRT350N_V2_NOR_BOOT_SIZE - 1, ++}; ++ ++static struct platform_device wrt350n_v2_nor_flash = { ++ .name = "physmap-flash", ++ .id = 0, ++ .dev = { ++ .platform_data = &wrt350n_v2_nor_flash_data, ++ }, ++ .num_resources = 1, ++ .resource = &wrt350n_v2_nor_flash_resource, ++}; ++ ++static struct mv643xx_eth_platform_data wrt350n_v2_eth_data = { ++ .phy_addr = -1, ++}; ++ ++static void __init wrt350n_v2_init(void) ++{ ++ /* ++ * Setup basic Orion functions. Need to be called early. ++ */ ++ orion5x_init(); ++ ++ orion5x_mpp_conf(0, MPP_GPIO); /* Power LED green (0=on) */ ++ orion5x_mpp_conf(1, MPP_GPIO); /* Security LED (0=on) */ ++ orion5x_mpp_conf(2, MPP_GPIO); /* Internal Button (0=on) */ ++ orion5x_mpp_conf(3, MPP_GPIO); /* Reset Button (0=on) */ ++ orion5x_mpp_conf(4, MPP_GPIO); /* PCI int */ ++ orion5x_mpp_conf(5, MPP_GPIO); /* Power LED orange (0=on) */ ++ orion5x_mpp_conf(6, MPP_GPIO); /* USB LED (0=on) */ ++ orion5x_mpp_conf(7, MPP_GPIO); /* Wireless LED (0=on) */ ++ orion5x_mpp_conf(8, MPP_UNUSED); /* ??? */ ++ orion5x_mpp_conf(9, MPP_GIGE); /* GE_RXERR */ ++ orion5x_mpp_conf(10, MPP_UNUSED); /* ??? */ ++ orion5x_mpp_conf(11, MPP_UNUSED); /* ??? */ ++ orion5x_mpp_conf(12, MPP_GIGE); /* GE_TXD[4] */ ++ orion5x_mpp_conf(13, MPP_GIGE); /* GE_TXD[5] */ ++ orion5x_mpp_conf(14, MPP_GIGE); /* GE_TXD[6] */ ++ orion5x_mpp_conf(15, MPP_GIGE); /* GE_TXD[7] */ ++ orion5x_mpp_conf(16, MPP_GIGE); /* GE_RXD[4] */ ++ orion5x_mpp_conf(17, MPP_GIGE); /* GE_RXD[5] */ ++ orion5x_mpp_conf(18, MPP_GIGE); /* GE_RXD[6] */ ++ orion5x_mpp_conf(19, MPP_GIGE); /* GE_RXD[7] */ ++ ++ /* ++ * Configure peripherals. ++ */ ++ orion5x_ehci0_init(); ++ orion5x_eth_init(&wrt350n_v2_eth_data); ++ orion5x_uart0_init(); ++ ++ orion5x_setup_dev_boot_win(WRT350N_V2_NOR_BOOT_BASE, ++ WRT350N_V2_NOR_BOOT_SIZE); ++ platform_device_register(&wrt350n_v2_nor_flash); ++} ++ ++static int __init wrt350n_v2_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) ++{ ++ int irq; ++ ++ /* ++ * Check for devices with hard-wired IRQs. ++ */ ++ irq = orion5x_pci_map_irq(dev, slot, pin); ++ if (irq != -1) ++ return irq; ++ ++ /* ++ * Mini-PCI slot. ++ */ ++ if (slot == 7) ++ return gpio_to_irq(4); ++ ++ printk(KERN_ERR "wrt350n_v2_pci_map_irq failed, unknown bus\n"); ++ ++ return -1; ++} ++ ++static struct hw_pci wrt350n_v2_pci __initdata = { ++ .nr_controllers = 2, ++ .swizzle = pci_std_swizzle, ++ .setup = orion5x_pci_sys_setup, ++ .scan = orion5x_pci_sys_scan_bus, ++ .map_irq = wrt350n_v2_pci_map_irq, ++}; ++ ++static int __init wrt350n_v2_pci_init(void) ++{ ++ if (machine_is_wrt350n_v2()) ++ pci_common_init(&wrt350n_v2_pci); ++ ++ return 0; ++} ++subsys_initcall(wrt350n_v2_pci_init); ++ ++MACHINE_START(WRT350N_V2, "Linksys WRT350N v2") ++ /* Maintainer: Lennert Buytenhek <buytenh@marvell.com> */ ++ .phys_io = ORION5X_REGS_PHYS_BASE, ++ .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC, ++ .boot_params = 0x00000100, ++ .init_machine = wrt350n_v2_init, ++ .map_io = orion5x_map_io, ++ .init_irq = orion5x_init_irq, ++ .timer = &orion5x_timer, ++ .fixup = tag_fixup_mem32, ++MACHINE_END diff --git a/target/linux/orion/patches/018-add_hp_media_vault_mv2120_support.patch b/target/linux/orion/patches/018-add_hp_media_vault_mv2120_support.patch new file mode 100644 index 0000000000..02a93c95c5 --- /dev/null +++ b/target/linux/orion/patches/018-add_hp_media_vault_mv2120_support.patch @@ -0,0 +1,263 @@ +From: Martin Michlmayr <tbm@cyrius.com> + +Signed-off-by: Lennert Buytenhek <buytenh@marvell.com> +--- + arch/arm/mach-orion5x/Kconfig | 6 + + arch/arm/mach-orion5x/Makefile | 1 + + arch/arm/mach-orion5x/mv2120-setup.c | 228 ++++++++++++++++++++++++++++++++++ + 3 files changed, 235 insertions(+), 0 deletions(-) + create mode 100644 arch/arm/mach-orion5x/mv2120-setup.c + +--- a/arch/arm/mach-orion5x/Kconfig ++++ b/arch/arm/mach-orion5x/Kconfig +@@ -56,6 +56,12 @@ + Say 'Y' here if you want your kernel to support the + Linksys WRT350N v2 platform. + ++config MACH_MV2120 ++ bool "HP Media Vault mv2120" ++ help ++ Say 'Y' here if you want your kernel to support the ++ HP Media Vault mv2120 or mv5100. ++ + endmenu + + endif +--- a/arch/arm/mach-orion5x/Makefile ++++ b/arch/arm/mach-orion5x/Makefile +@@ -7,3 +7,4 @@ + obj-$(CONFIG_MACH_TS209) += ts209-setup.o + obj-$(CONFIG_MACH_TS409) += ts409-setup.o + obj-$(CONFIG_MACH_WRT350N_V2) += wrt350n-v2-setup.o ++obj-$(CONFIG_MACH_MV2120) += mv2120-setup.o +--- /dev/null ++++ b/arch/arm/mach-orion5x/mv2120-setup.c +@@ -0,0 +1,228 @@ ++/* ++ * Copyright (C) 2007 Herbert Valerio Riedel <hvr@gnu.org> ++ * Copyright (C) 2008 Martin Michlmayr <tbm@cyrius.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2 of the ++ * License, or (at your option) any later version. ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/init.h> ++#include <linux/platform_device.h> ++#include <linux/pci.h> ++#include <linux/irq.h> ++#include <linux/mtd/physmap.h> ++#include <linux/mv643xx_eth.h> ++#include <linux/leds.h> ++#include <linux/gpio_keys.h> ++#include <linux/input.h> ++#include <linux/i2c.h> ++#include <linux/ata_platform.h> ++#include <asm/mach-types.h> ++#include <asm/gpio.h> ++#include <asm/mach/arch.h> ++#include <asm/mach/pci.h> ++#include <asm/arch/orion5x.h> ++#include "common.h" ++#include "mpp.h" ++ ++#define MV2120_NOR_BOOT_BASE 0xf4000000 ++#define MV2120_NOR_BOOT_SIZE SZ_512K ++ ++#define MV2120_GPIO_RTC_IRQ 3 ++#define MV2120_GPIO_KEY_RESET 17 ++#define MV2120_GPIO_KEY_POWER 18 ++#define MV2120_GPIO_POWER_OFF 19 ++ ++ ++/**************************************************************************** ++ * PCI setup ++ ****************************************************************************/ ++static int __init mv2120_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) ++{ ++ int irq; ++ ++ /* ++ * Check for devices with hard-wired IRQs. ++ */ ++ irq = orion5x_pci_map_irq(dev, slot, pin); ++ if (irq != -1) ++ return irq; ++ ++ pr_err("%s: requested mapping for unknown bus\n", __func__); ++ ++ return -1; ++} ++ ++static struct hw_pci mv2120_pci __initdata = { ++ .nr_controllers = 2, ++ .swizzle = pci_std_swizzle, ++ .setup = orion5x_pci_sys_setup, ++ .scan = orion5x_pci_sys_scan_bus, ++ .map_irq = mv2120_pci_map_irq, ++}; ++ ++static int __init mv2120_pci_init(void) ++{ ++ if (machine_is_mv2120()) ++ pci_common_init(&mv2120_pci); ++ ++ return 0; ++} ++subsys_initcall(mv2120_pci_init); ++ ++ ++/***************************************************************************** ++ * Ethernet ++ ****************************************************************************/ ++static struct mv643xx_eth_platform_data mv2120_eth_data = { ++ .phy_addr = 8, ++}; ++ ++static struct mv_sata_platform_data mv2120_sata_data = { ++ .n_ports = 2, ++}; ++ ++static struct mtd_partition mv2120_partitions[] = { ++ { ++ .name = "firmware", ++ .size = 0x00080000, ++ .offset = 0, ++ }, ++}; ++ ++static struct physmap_flash_data mv2120_nor_flash_data = { ++ .width = 1, ++ .parts = mv2120_partitions, ++ .nr_parts = ARRAY_SIZE(mv2120_partitions) ++}; ++ ++static struct resource mv2120_nor_flash_resource = { ++ .flags = IORESOURCE_MEM, ++ .start = MV2120_NOR_BOOT_BASE, ++ .end = MV2120_NOR_BOOT_BASE + MV2120_NOR_BOOT_SIZE - 1, ++}; ++ ++static struct platform_device mv2120_nor_flash = { ++ .name = "physmap-flash", ++ .id = 0, ++ .dev = { ++ .platform_data = &mv2120_nor_flash_data, ++ }, ++ .resource = &mv2120_nor_flash_resource, ++ .num_resources = 1, ++}; ++ ++static struct gpio_keys_button mv2120_buttons[] = { ++ { ++ .code = KEY_RESTART, ++ .gpio = MV2120_GPIO_KEY_RESET, ++ .desc = "Reset Button", ++ .active_low = 1, ++ }, { ++ .code = KEY_POWER, ++ .gpio = MV2120_GPIO_KEY_POWER, ++ .desc = "Power Button", ++ .active_low = 1, ++ }, ++}; ++ ++static struct gpio_keys_platform_data mv2120_button_data = { ++ .buttons = mv2120_buttons, ++ .nbuttons = ARRAY_SIZE(mv2120_buttons), ++}; ++ ++static struct platform_device mv2120_button_device = { ++ .name = "gpio-keys", ++ .id = -1, ++ .num_resources = 0, ++ .dev = { ++ .platform_data = &mv2120_button_data, ++ }, ++}; ++ ++ ++/**************************************************************************** ++ * General Setup ++ ****************************************************************************/ ++static struct i2c_board_info __initdata mv2120_i2c_rtc = { ++ I2C_BOARD_INFO("rtc-pcf8563", 0x51), ++ .irq = 0, ++}; ++ ++static void mv2120_power_off(void) ++{ ++ pr_info("%s: triggering power-off...\n", __func__); ++ gpio_set_value(MV2120_GPIO_POWER_OFF, 0); ++} ++ ++static void __init mv2120_init(void) ++{ ++ /* Setup basic Orion functions. Need to be called early. */ ++ orion5x_init(); ++ ++ orion5x_mpp_conf(0, MPP_GPIO); /* Sys status LED */ ++ orion5x_mpp_conf(1, MPP_GPIO); /* Sys error LED */ ++ orion5x_mpp_conf(2, MPP_GPIO); /* OverTemp interrupt */ ++ orion5x_mpp_conf(3, MPP_GPIO); /* RTC interrupt */ ++ orion5x_mpp_conf(4, MPP_GPIO); /* V_LED 5V */ ++ orion5x_mpp_conf(5, MPP_GPIO); /* V_LED 3.3V */ ++ orion5x_mpp_conf(6, MPP_UNUSED); ++ orion5x_mpp_conf(7, MPP_UNUSED); ++ orion5x_mpp_conf(8, MPP_GPIO); /* SATA 0 fail LED */ ++ orion5x_mpp_conf(9, MPP_GPIO); /* SATA 1 fail LED */ ++ orion5x_mpp_conf(10, MPP_UNUSED); ++ orion5x_mpp_conf(11, MPP_UNUSED); ++ orion5x_mpp_conf(12, MPP_SATA_LED); /* SATA 0 presence */ ++ orion5x_mpp_conf(13, MPP_SATA_LED); /* SATA 1 presence */ ++ orion5x_mpp_conf(14, MPP_SATA_LED); /* SATA 0 active */ ++ orion5x_mpp_conf(15, MPP_SATA_LED); /* SATA 1 active */ ++ orion5x_mpp_conf(16, MPP_UNUSED); ++ orion5x_mpp_conf(17, MPP_GPIO); /* Reset button */ ++ orion5x_mpp_conf(18, MPP_GPIO); /* Power button */ ++ orion5x_mpp_conf(19, MPP_GPIO); /* Power off */ ++ ++ /* ++ * Configure peripherals. ++ */ ++ orion5x_ehci0_init(); ++ orion5x_ehci1_init(); ++ orion5x_eth_init(&mv2120_eth_data); ++ orion5x_i2c_init(); ++ orion5x_sata_init(&mv2120_sata_data); ++ orion5x_uart0_init(); ++ ++ orion5x_setup_dev_boot_win(MV2120_NOR_BOOT_BASE, MV2120_NOR_BOOT_SIZE); ++ platform_device_register(&mv2120_nor_flash); ++ ++ platform_device_register(&mv2120_button_device); ++ ++ if (gpio_request(MV2120_GPIO_RTC_IRQ, "rtc") == 0) { ++ if (gpio_direction_input(MV2120_GPIO_RTC_IRQ) == 0) ++ mv2120_i2c_rtc.irq = gpio_to_irq(MV2120_GPIO_RTC_IRQ); ++ else ++ gpio_free(MV2120_GPIO_RTC_IRQ); ++ } ++ i2c_register_board_info(0, &mv2120_i2c_rtc, 1); ++ ++ /* register mv2120 specific power-off method */ ++ if (gpio_request(MV2120_GPIO_POWER_OFF, "POWEROFF") != 0 || ++ gpio_direction_output(MV2120_GPIO_POWER_OFF, 1) != 0) ++ pr_err("mv2120: failed to setup power-off GPIO\n"); ++ pm_power_off = mv2120_power_off; ++} ++ ++/* Warning: HP uses a wrong mach-type (=526) in their bootloader */ ++MACHINE_START(MV2120, "HP Media Vault mv2120") ++ /* Maintainer: Martin Michlmayr <tbm@cyrius.com> */ ++ .phys_io = ORION5X_REGS_PHYS_BASE, ++ .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC, ++ .boot_params = 0x00000100, ++ .init_machine = mv2120_init, ++ .map_io = orion5x_map_io, ++ .init_irq = orion5x_init_irq, ++ .timer = &orion5x_timer, ++ .fixup = tag_fixup_mem32 ++MACHINE_END diff --git a/target/linux/orion/patches/019-add_technologic_systems_ts-78xx_support.patch b/target/linux/orion/patches/019-add_technologic_systems_ts-78xx_support.patch new file mode 100644 index 0000000000..a74464c7bb --- /dev/null +++ b/target/linux/orion/patches/019-add_technologic_systems_ts-78xx_support.patch @@ -0,0 +1,305 @@ +Hi, + +The following patch series adds support for the Technologic Systems +TS-7800[1]. This is an updated driver to the one I posted before[2] which +takes on all the advice and fixes suggested here. + +Cheers + +Alex + +Signed-off-by: Alexander Clouter <alex@digriz.org.uk> + +[1] http://www.embeddedarm.com/products/board-detail.php?product=TS-7800 +[2] http://lists.arm.linux.org.uk/lurker/message/20080522.190133.54887e96.en.html + +--- + arch/arm/mach-orion5x/Kconfig | 7 + + arch/arm/mach-orion5x/Makefile | 1 + + arch/arm/mach-orion5x/ts78xx-setup.c | 257 ++++++++++++++++++++++++++++++++++ + 3 files changed, 265 insertions(+), 0 deletions(-) + create mode 100644 arch/arm/mach-orion5x/ts78xx-setup.c + +--- a/arch/arm/mach-orion5x/Kconfig ++++ b/arch/arm/mach-orion5x/Kconfig +@@ -62,6 +62,13 @@ + Say 'Y' here if you want your kernel to support the + HP Media Vault mv2120 or mv5100. + ++config MACH_TS78XX ++ bool "Technologic Systems TS-78xx" ++ select CPU_FEROCEON_OLD_ID ++ help ++ Say 'Y' here if you want your kernel to support the ++ Technologic Systems TS-78xx platform. ++ + endmenu + + endif +--- a/arch/arm/mach-orion5x/Makefile ++++ b/arch/arm/mach-orion5x/Makefile +@@ -8,3 +8,4 @@ + obj-$(CONFIG_MACH_TS409) += ts409-setup.o + obj-$(CONFIG_MACH_WRT350N_V2) += wrt350n-v2-setup.o + obj-$(CONFIG_MACH_MV2120) += mv2120-setup.o ++obj-$(CONFIG_MACH_TS78XX) += ts78xx-setup.o +--- /dev/null ++++ b/arch/arm/mach-orion5x/ts78xx-setup.c +@@ -0,0 +1,257 @@ ++/* ++ * arch/arm/mach-orion5x/ts78xx-setup.c ++ * ++ * Maintainer: Alexander Clouter <alex@digriz.org.uk> ++ * ++ * This file is licensed under the terms of the GNU General Public ++ * License version 2. This program is licensed "as is" without any ++ * warranty of any kind, whether express or implied. ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/init.h> ++#include <linux/platform_device.h> ++#include <linux/mtd/physmap.h> ++#include <linux/mv643xx_eth.h> ++#include <linux/ata_platform.h> ++#include <linux/m48t86.h> ++#include <asm/mach-types.h> ++#include <asm/mach/arch.h> ++#include <asm/mach/map.h> ++#include <asm/arch/orion5x.h> ++#include "common.h" ++#include "mpp.h" ++ ++/***************************************************************************** ++ * TS-78xx Info ++ ****************************************************************************/ ++ ++/* ++ * FPGA - lives where the PCI bus would be at ORION5X_PCI_MEM_PHYS_BASE ++ */ ++#define TS78XX_FPGA_REGS_PHYS_BASE 0xe8000000 ++#define TS78XX_FPGA_REGS_VIRT_BASE 0xff900000 ++#define TS78XX_FPGA_REGS_SIZE SZ_1M ++ ++#define TS78XX_FPGA_REGS_RTC_CTRL TS78XX_FPGA_REGS_VIRT_BASE | 0x808 ++#define TS78XX_FPGA_REGS_RTC_DATA TS78XX_FPGA_REGS_VIRT_BASE | 0x80c ++ ++/* ++ * 512kB NOR flash Device ++ */ ++#define TS78XX_NOR_BOOT_BASE 0xff800000 ++#define TS78XX_NOR_BOOT_SIZE SZ_512K ++ ++/***************************************************************************** ++ * I/O Address Mapping ++ ****************************************************************************/ ++static struct map_desc ts78xx_io_desc[] __initdata = { ++ { ++ .virtual = TS78XX_FPGA_REGS_VIRT_BASE, ++ .pfn = __phys_to_pfn(TS78XX_FPGA_REGS_PHYS_BASE), ++ .length = TS78XX_FPGA_REGS_SIZE, ++ .type = MT_DEVICE, ++ }, ++}; ++ ++void __init ts78xx_map_io(void) ++{ ++ orion5x_map_io(); ++ iotable_init(ts78xx_io_desc, ARRAY_SIZE(ts78xx_io_desc)); ++} ++ ++/***************************************************************************** ++ * 512kB NOR Boot Flash - the chip is a M25P40 ++ ****************************************************************************/ ++static struct mtd_partition ts78xx_nor_boot_flash_resources[] = { ++ { ++ .name = "ts-bootrom", ++ .offset = 0, ++ /* only the first 256kB is used */ ++ .size = SZ_256K, ++ .mask_flags = MTD_WRITEABLE, ++ }, ++}; ++ ++static struct physmap_flash_data ts78xx_nor_boot_flash_data = { ++ .width = 1, ++ .parts = ts78xx_nor_boot_flash_resources, ++ .nr_parts = ARRAY_SIZE(ts78xx_nor_boot_flash_resources), ++}; ++ ++static struct resource ts78xx_nor_boot_flash_resource = { ++ .flags = IORESOURCE_MEM, ++ .start = TS78XX_NOR_BOOT_BASE, ++ .end = TS78XX_NOR_BOOT_BASE + TS78XX_NOR_BOOT_SIZE - 1, ++}; ++ ++static struct platform_device ts78xx_nor_boot_flash = { ++ .name = "physmap-flash", ++ .id = -1, ++ .dev = { ++ .platform_data = &ts78xx_nor_boot_flash_data, ++ }, ++ .num_resources = 1, ++ .resource = &ts78xx_nor_boot_flash_resource, ++}; ++ ++/***************************************************************************** ++ * PCI ++ ****************************************************************************/ ++ ++/* ++ * WARNING: TS shunt the PCI IO via the FPGA so that you could build soft-PCI ++ * devices for it and what-not. There is nothing on the PCI or ++ * PCIe buses so probably nothing really to do yet here, if ever ++ */ ++ ++/***************************************************************************** ++ * Ethernet ++ ****************************************************************************/ ++static struct mv643xx_eth_platform_data ts78xx_eth_data = { ++ .phy_addr = 0, ++ .force_phy_addr = 1, ++}; ++ ++/***************************************************************************** ++ * RTC M48T86 - nicked^Wborrowed from arch/arm/mach-ep93xx/ts72xx.c ++ ****************************************************************************/ ++static unsigned char ts78xx_rtc_readbyte(unsigned long addr) ++{ ++ writeb(addr, TS78XX_FPGA_REGS_RTC_CTRL); ++ return readb(TS78XX_FPGA_REGS_RTC_DATA); ++} ++ ++static void ts78xx_rtc_writebyte(unsigned char value, unsigned long addr) ++{ ++ writeb(addr, TS78XX_FPGA_REGS_RTC_CTRL); ++ writeb(value, TS78XX_FPGA_REGS_RTC_DATA); ++} ++ ++static struct m48t86_ops ts78xx_rtc_ops = { ++ .readbyte = ts78xx_rtc_readbyte, ++ .writebyte = ts78xx_rtc_writebyte, ++}; ++ ++static struct platform_device ts78xx_rtc_device = { ++ .name = "rtc-m48t86", ++ .id = -1, ++ .dev = { ++ .platform_data = &ts78xx_rtc_ops, ++ }, ++ .num_resources = 0, ++}; ++ ++/***************************************************************************** ++ * SATA ++ ****************************************************************************/ ++static struct mv_sata_platform_data ts78xx_sata_data = { ++ .n_ports = 2, ++}; ++ ++/***************************************************************************** ++ * General Setup ++ ****************************************************************************/ ++static void __init ts78xx_init(void) ++{ ++#ifdef CONFIG_RTC_DRV_M48T86 ++ unsigned char tmp_rtc0, tmp_rtc1; ++#endif ++ ++ /* ++ * Setup basic Orion functions. Need to be called early. ++ */ ++ orion5x_init(); ++ ++ orion5x_mpp_conf(0, MPP_UNUSED); ++ ++ /* ++ * MPP[1] JTAG Clock ++ * MPP[2] JTAG Data In ++ * MPP[3] Lattice ECP2 256 FPGA - PB2B ++ * MPP[4] JTAG Data Out ++ * MPP[5] JTAG TMS ++ * MPP[6] Lattice ECP2 256 FPGA - PB31A_CLK4+ ++ * MPP[7] Lattice ECP2 256 FPGA - PB22B ++ */ ++ ++ orion5x_mpp_conf(8, MPP_UNUSED); ++ orion5x_mpp_conf(9, MPP_UNUSED); ++ orion5x_mpp_conf(10, MPP_UNUSED); ++ orion5x_mpp_conf(11, MPP_UNUSED); ++ orion5x_mpp_conf(12, MPP_UNUSED); ++ orion5x_mpp_conf(13, MPP_UNUSED); ++ orion5x_mpp_conf(14, MPP_UNUSED); ++ orion5x_mpp_conf(15, MPP_UNUSED); ++ orion5x_mpp_conf(16, MPP_UART); ++ orion5x_mpp_conf(17, MPP_UART); ++ orion5x_mpp_conf(18, MPP_UART); ++ orion5x_mpp_conf(19, MPP_UART); ++ ++ /* ++ * MPP[20] PCI Clock Out 1 ++ * MPP[21] PCI Clock Out 0 ++ * MPP[22] Unused ++ * MPP[23] Unused ++ * MPP[24] Unused ++ * MPP[25] Unused ++ */ ++ ++ /* ++ * Configure peripherals. ++ */ ++ orion5x_ehci0_init(); ++ orion5x_ehci1_init(); ++ orion5x_eth_init(&ts78xx_eth_data); ++ orion5x_sata_init(&ts78xx_sata_data); ++ orion5x_uart0_init(); ++ orion5x_uart1_init(); ++ ++ orion5x_setup_dev_boot_win(TS78XX_NOR_BOOT_BASE, ++ TS78XX_NOR_BOOT_SIZE); ++ platform_device_register(&ts78xx_nor_boot_flash); ++ ++#ifdef CONFIG_RTC_DRV_M48T86 ++ /* ++ * TS uses some of the user storage space on the RTC chip so see if it ++ * is present; as it's an optional feature at purchase time and not all ++ * boards will have it present ++ * ++ * I've used the method TS use in their rtc7800.c example for the ++ * detection logic; a little 'funky' but thats what floats my boat ++ * ++ * TODO: track down a guinea pig without an RTC to see if we can work ++ * out a better RTC detection routine ++ */ ++ tmp_rtc0 = ts78xx_rtc_readbyte(126); ++ tmp_rtc1 = ts78xx_rtc_readbyte(127); ++ ++ ts78xx_rtc_writebyte(0x00, 126); ++ ts78xx_rtc_writebyte(0x55, 127); ++ if (ts78xx_rtc_readbyte(127) == 0x55) { ++ ts78xx_rtc_writebyte(0xaa, 127); ++ if (ts78xx_rtc_readbyte(127) == 0xaa ++ && ts78xx_rtc_readbyte(126) == 0x00) { ++ ts78xx_rtc_writebyte(tmp_rtc0, 126); ++ ts78xx_rtc_writebyte(tmp_rtc1, 127); ++ platform_device_register(&ts78xx_rtc_device); ++ goto rtcok; ++ } ++ } ++ printk(KERN_INFO "TS-78xx RTC not detected\n"); ++ ++ rtcok: ++ ; ++#endif ++} ++ ++MACHINE_START(TS78XX, "Technologic Systems TS-78xx SBC") ++ /* Maintainer: Alexander Clouter <alex@digriz.org.uk> */ ++ .phys_io = ORION5X_REGS_PHYS_BASE, ++ .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC, ++ .boot_params = 0x00000100, ++ .init_machine = ts78xx_init, ++ .map_io = ts78xx_map_io, ++ .init_irq = orion5x_init_irq, ++ .timer = &orion5x_timer, ++MACHINE_END |