From 073828d078d3e55b23b2b5937a49dc1019c5907d Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Tue, 26 Aug 2008 21:29:58 +0900 Subject: [MIPS] TXx9: Fix txx9_pcode initialization The txx9_pcode variable was introduced in commit fe1c2bc64f65003b39f331a8e4b0d15b235a4afd ("TXx9: Add 64-bit support") but was not initialized properly. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/txx9/generic/setup.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/mips/txx9') diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c index 0afe94c48fb6..fe6bee09cece 100644 --- a/arch/mips/txx9/generic/setup.c +++ b/arch/mips/txx9/generic/setup.c @@ -53,6 +53,7 @@ txx9_reg_res_init(unsigned int pcode, unsigned long base, unsigned long size) txx9_ce_res[i].name = txx9_ce_res_name[i]; } + txx9_pcode = pcode; sprintf(txx9_pcode_str, "TX%x", pcode); if (base) { txx9_reg_res.start = base & 0xfffffffffULL; -- cgit v1.2.3 From f96a3383cfede841cdf80a5927f14478981ed78c Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Tue, 19 Aug 2008 22:55:05 +0900 Subject: MIPS: RBTX4927: More explicit initialization * Make sure all interrupts cleared on startup * Initialize some GPIOs Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/txx9/rbtx4927/irq.c | 5 +++++ arch/mips/txx9/rbtx4927/setup.c | 9 +++++++++ include/asm-mips/txx9/rbtx4927.h | 2 ++ 3 files changed, 16 insertions(+) (limited to 'arch/mips/txx9') diff --git a/arch/mips/txx9/rbtx4927/irq.c b/arch/mips/txx9/rbtx4927/irq.c index 00cd5231da30..22076e3f03a8 100644 --- a/arch/mips/txx9/rbtx4927/irq.c +++ b/arch/mips/txx9/rbtx4927/irq.c @@ -142,6 +142,11 @@ static void __init toshiba_rbtx4927_irq_ioc_init(void) { int i; + /* mask all IOC interrupts */ + writeb(0, rbtx4927_imask_addr); + /* clear SoftInt interrupts */ + writeb(0, rbtx4927_softint_addr); + for (i = RBTX4927_IRQ_IOC; i < RBTX4927_IRQ_IOC + RBTX4927_NR_IRQ_IOC; i++) set_irq_chip_and_handler(i, &toshiba_rbtx4927_irq_ioc_type, diff --git a/arch/mips/txx9/rbtx4927/setup.c b/arch/mips/txx9/rbtx4927/setup.c index 0d39bafea794..5985f330838a 100644 --- a/arch/mips/txx9/rbtx4927/setup.c +++ b/arch/mips/txx9/rbtx4927/setup.c @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -212,6 +213,14 @@ static void __init rbtx4927_mem_setup(void) set_io_port_base(KSEG1 + RBTX4927_ISA_IO_OFFSET); #endif + /* TX4927-SIO DTR on (PIO[15]) */ + gpio_request(15, "sio-dtr"); + gpio_direction_output(15, 1); + gpio_request(0, "led"); + gpio_direction_output(0, 1); + gpio_request(1, "led"); + gpio_direction_output(1, 1); + tx4927_sio_init(0, 0); #ifdef CONFIG_SERIAL_TXX9_CONSOLE argptr = prom_getcmdline(); diff --git a/include/asm-mips/txx9/rbtx4927.h b/include/asm-mips/txx9/rbtx4927.h index 6fcec912c143..c6015463432e 100644 --- a/include/asm-mips/txx9/rbtx4927.h +++ b/include/asm-mips/txx9/rbtx4927.h @@ -36,6 +36,7 @@ #define RBTX4927_IMASK_ADDR (IO_BASE + TXX9_CE(2) + 0x00002000) #define RBTX4927_IMSTAT_ADDR (IO_BASE + TXX9_CE(2) + 0x00002006) +#define RBTX4927_SOFTINT_ADDR (IO_BASE + TXX9_CE(2) + 0x00003000) #define RBTX4927_SOFTRESET_ADDR (IO_BASE + TXX9_CE(2) + 0x0000f000) #define RBTX4927_SOFTRESETLOCK_ADDR (IO_BASE + TXX9_CE(2) + 0x0000f002) #define RBTX4927_PCIRESET_ADDR (IO_BASE + TXX9_CE(2) + 0x0000f006) @@ -47,6 +48,7 @@ #define rbtx4927_imask_addr ((__u8 __iomem *)RBTX4927_IMASK_ADDR) #define rbtx4927_imstat_addr ((__u8 __iomem *)RBTX4927_IMSTAT_ADDR) +#define rbtx4927_softint_addr ((__u8 __iomem *)RBTX4927_SOFTINT_ADDR) #define rbtx4927_softreset_addr ((__u8 __iomem *)RBTX4927_SOFTRESET_ADDR) #define rbtx4927_softresetlock_addr \ ((__u8 __iomem *)RBTX4927_SOFTRESETLOCK_ADDR) -- cgit v1.2.3 From e0dfb20c2b77c6626a24578240266ace928cd2e7 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Tue, 19 Aug 2008 22:55:06 +0900 Subject: MIPS: TXx9: Improve handling of built-in and command-line args * Make prom_init_cmdline() static and be called from prom_init. * Append built-in args if the first character was '+'. * Drop command-line args if the first character of built-in was '-'. * Enclose args include spaces by quotes. * TX4938_NAND_BOOT is no longer needed. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/txx9/Kconfig | 7 ------- arch/mips/txx9/generic/setup.c | 42 ++++++++++++++++++++++++++++++----------- arch/mips/txx9/jmr3927/prom.c | 1 - arch/mips/txx9/rbtx4927/prom.c | 1 - arch/mips/txx9/rbtx4938/prom.c | 3 --- include/asm-mips/txx9/generic.h | 1 - 6 files changed, 31 insertions(+), 24 deletions(-) (limited to 'arch/mips/txx9') diff --git a/arch/mips/txx9/Kconfig b/arch/mips/txx9/Kconfig index 840fe757c48d..6fb2ef09d5dd 100644 --- a/arch/mips/txx9/Kconfig +++ b/arch/mips/txx9/Kconfig @@ -97,13 +97,6 @@ config TOSHIBA_RBTX4938_MPLEX_ATA endchoice -config TX4938_NAND_BOOT - depends on EXPERIMENTAL && TOSHIBA_RBTX4938_MPLEX_NAND - bool "NAND Boot Support (EXPERIMENTAL)" - help - This is only for Toshiba RBTX4938 reference board, which has NAND IPL. - Select this option if you need to use NAND boot. - endif config PCI_TX4927 diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c index fe6bee09cece..33d8c9e3223d 100644 --- a/arch/mips/txx9/generic/setup.c +++ b/arch/mips/txx9/generic/setup.c @@ -127,31 +127,51 @@ extern struct txx9_board_vec rbtx4938_vec; struct txx9_board_vec *txx9_board_vec __initdata; static char txx9_system_type[32]; -void __init prom_init_cmdline(void) +static void __init prom_init_cmdline(void) { int argc = (int)fw_arg0; - char **argv = (char **)fw_arg1; + int *argv32 = (int *)fw_arg1; int i; /* Always ignore the "-c" at argv[0] */ -#ifdef CONFIG_64BIT - char *fixed_argv[32]; - for (i = 0; i < argc; i++) - fixed_argv[i] = (char *)(long)(*((__s32 *)argv + i)); - argv = fixed_argv; -#endif + char builtin[CL_SIZE]; /* ignore all built-in args if any f/w args given */ - if (argc > 1) - *arcs_cmdline = '\0'; + /* + * But if built-in strings was started with '+', append them + * to command line args. If built-in was started with '-', + * ignore all f/w args. + */ + builtin[0] = '\0'; + if (arcs_cmdline[0] == '+') + strcpy(builtin, arcs_cmdline + 1); + else if (arcs_cmdline[0] == '-') { + strcpy(builtin, arcs_cmdline + 1); + argc = 0; + } else if (argc <= 1) + strcpy(builtin, arcs_cmdline); + arcs_cmdline[0] = '\0'; for (i = 1; i < argc; i++) { + char *str = (char *)(long)argv32[i]; if (i != 1) strcat(arcs_cmdline, " "); - strcat(arcs_cmdline, argv[i]); + if (strchr(str, ' ')) { + strcat(arcs_cmdline, "\""); + strcat(arcs_cmdline, str); + strcat(arcs_cmdline, "\""); + } else + strcat(arcs_cmdline, str); + } + /* append saved builtin args */ + if (builtin[0]) { + if (arcs_cmdline[0]) + strcat(arcs_cmdline, " "); + strcat(arcs_cmdline, builtin); } } void __init prom_init(void) { + prom_init_cmdline(); #ifdef CONFIG_CPU_TX39XX txx9_board_vec = &jmr3927_vec; #endif diff --git a/arch/mips/txx9/jmr3927/prom.c b/arch/mips/txx9/jmr3927/prom.c index 70c4c8ec3e84..c899c0c087a0 100644 --- a/arch/mips/txx9/jmr3927/prom.c +++ b/arch/mips/txx9/jmr3927/prom.c @@ -47,7 +47,6 @@ void __init jmr3927_prom_init(void) if ((tx3927_ccfgptr->ccfg & TX3927_CCFG_TLBOFF) == 0) printk(KERN_ERR "TX3927 TLB off\n"); - prom_init_cmdline(); add_memory_region(0, JMR3927_SDRAM_SIZE, BOOT_MEM_RAM); txx9_sio_putchar_init(TX3927_SIO_REG(1)); } diff --git a/arch/mips/txx9/rbtx4927/prom.c b/arch/mips/txx9/rbtx4927/prom.c index 1dc0a5b1956b..cc97c6a6011b 100644 --- a/arch/mips/txx9/rbtx4927/prom.c +++ b/arch/mips/txx9/rbtx4927/prom.c @@ -36,7 +36,6 @@ void __init rbtx4927_prom_init(void) { - prom_init_cmdline(); add_memory_region(0, tx4927_get_mem_size(), BOOT_MEM_RAM); txx9_sio_putchar_init(TX4927_SIO_REG(0) & 0xfffffffffULL); } diff --git a/arch/mips/txx9/rbtx4938/prom.c b/arch/mips/txx9/rbtx4938/prom.c index d73123cd2ab9..bcb469247e8c 100644 --- a/arch/mips/txx9/rbtx4938/prom.c +++ b/arch/mips/txx9/rbtx4938/prom.c @@ -18,9 +18,6 @@ void __init rbtx4938_prom_init(void) { -#ifndef CONFIG_TX4938_NAND_BOOT - prom_init_cmdline(); -#endif add_memory_region(0, tx4938_get_mem_size(), BOOT_MEM_RAM); txx9_sio_putchar_init(TX4938_SIO_REG(0) & 0xfffffffffULL); } diff --git a/include/asm-mips/txx9/generic.h b/include/asm-mips/txx9/generic.h index 5b1ccf901c62..c9eed7ea148c 100644 --- a/include/asm-mips/txx9/generic.h +++ b/include/asm-mips/txx9/generic.h @@ -42,7 +42,6 @@ struct txx9_board_vec { }; extern struct txx9_board_vec *txx9_board_vec; extern int (*txx9_irq_dispatch)(int pending); -void prom_init_cmdline(void); char *prom_getcmdline(void); void txx9_wdt_init(unsigned long base); void txx9_spi_init(int busid, unsigned long base, int irq); -- cgit v1.2.3 From 265b89db1058124ddbf0091ba3f8c020e3a5ae9d Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Tue, 19 Aug 2008 22:55:07 +0900 Subject: MIPS: TXx9: Add prom_getenv Add prom_getenv() which can be used for YAMON. This assumes other firmware should pass NULL for fw_arg2. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/txx9/generic/setup.c | 15 +++++++++++++++ include/asm-mips/txx9/generic.h | 1 + 2 files changed, 16 insertions(+) (limited to 'arch/mips/txx9') diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c index 33d8c9e3223d..005179c2af21 100644 --- a/arch/mips/txx9/generic/setup.c +++ b/arch/mips/txx9/generic/setup.c @@ -212,6 +212,21 @@ char * __init prom_getcmdline(void) return &(arcs_cmdline[0]); } +const char *__init prom_getenv(const char *name) +{ + const s32 *str = (const s32 *)fw_arg2; + + if (!str) + return NULL; + /* YAMON style ("name", "value" pairs) */ + while (str[0] && str[1]) { + if (!strcmp((const char *)(unsigned long)str[0], name)) + return (const char *)(unsigned long)str[1]; + str += 2; + } + return NULL; +} + static void __noreturn txx9_machine_halt(void) { local_irq_disable(); diff --git a/include/asm-mips/txx9/generic.h b/include/asm-mips/txx9/generic.h index c9eed7ea148c..0a225bf73496 100644 --- a/include/asm-mips/txx9/generic.h +++ b/include/asm-mips/txx9/generic.h @@ -43,6 +43,7 @@ struct txx9_board_vec { extern struct txx9_board_vec *txx9_board_vec; extern int (*txx9_irq_dispatch)(int pending); char *prom_getcmdline(void); +const char *prom_getenv(const char *name); void txx9_wdt_init(unsigned long base); void txx9_spi_init(int busid, unsigned long base, int irq); void txx9_ethaddr_init(unsigned int id, unsigned char *ethaddr); -- cgit v1.2.3 From 860e546c19d88c21819c7f0861c505debd2d6eed Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Tue, 19 Aug 2008 22:55:08 +0900 Subject: MIPS: TXx9: Early command-line preprocessing * Select board by command-line option or firmware environment variable. * Handle "masterclk=" option. * Add boards.h to centerize board_vec declaration. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle create mode 100644 include/asm-mips/txx9/boards.h --- arch/mips/txx9/generic/setup.c | 74 ++++++++++++++++++++++++++++++++++++++---- include/asm-mips/txx9/boards.h | 10 ++++++ 2 files changed, 78 insertions(+), 6 deletions(-) create mode 100644 include/asm-mips/txx9/boards.h (limited to 'arch/mips/txx9') diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c index 005179c2af21..dc5dbcc53a91 100644 --- a/arch/mips/txx9/generic/setup.c +++ b/arch/mips/txx9/generic/setup.c @@ -119,14 +119,31 @@ int irq_to_gpio(unsigned irq) EXPORT_SYMBOL(irq_to_gpio); #endif -extern struct txx9_board_vec jmr3927_vec; -extern struct txx9_board_vec rbtx4927_vec; -extern struct txx9_board_vec rbtx4937_vec; -extern struct txx9_board_vec rbtx4938_vec; +#define BOARD_VEC(board) extern struct txx9_board_vec board; +#include +#undef BOARD_VEC struct txx9_board_vec *txx9_board_vec __initdata; static char txx9_system_type[32]; +static struct txx9_board_vec *board_vecs[] __initdata = { +#define BOARD_VEC(board) &board, +#include +#undef BOARD_VEC +}; + +static struct txx9_board_vec *__init find_board_byname(const char *name) +{ + int i; + + /* search board_vecs table */ + for (i = 0; i < ARRAY_SIZE(board_vecs); i++) { + if (strstr(board_vecs[i]->system, name)) + return board_vecs[i]; + } + return NULL; +} + static void __init prom_init_cmdline(void) { int argc = (int)fw_arg0; @@ -169,9 +186,47 @@ static void __init prom_init_cmdline(void) } } -void __init prom_init(void) +static void __init preprocess_cmdline(void) { - prom_init_cmdline(); + char cmdline[CL_SIZE]; + char *s; + + strcpy(cmdline, arcs_cmdline); + s = cmdline; + arcs_cmdline[0] = '\0'; + while (s && *s) { + char *str = strsep(&s, " "); + if (strncmp(str, "board=", 6) == 0) { + txx9_board_vec = find_board_byname(str + 6); + continue; + } else if (strncmp(str, "masterclk=", 10) == 0) { + unsigned long val; + if (strict_strtoul(str + 10, 10, &val) == 0) + txx9_master_clock = val; + continue; + } + if (arcs_cmdline[0]) + strcat(arcs_cmdline, " "); + strcat(arcs_cmdline, str); + } +} + +static void __init select_board(void) +{ + const char *envstr; + + /* first, determine by "board=" argument in preprocess_cmdline() */ + if (txx9_board_vec) + return; + /* next, determine by "board" envvar */ + envstr = prom_getenv("board"); + if (envstr) { + txx9_board_vec = find_board_byname(envstr); + if (txx9_board_vec) + return; + } + + /* select "default" board */ #ifdef CONFIG_CPU_TX39XX txx9_board_vec = &jmr3927_vec; #endif @@ -192,6 +247,13 @@ void __init prom_init(void) #endif } #endif +} + +void __init prom_init(void) +{ + prom_init_cmdline(); + preprocess_cmdline(); + select_board(); strcpy(txx9_system_type, txx9_board_vec->system); diff --git a/include/asm-mips/txx9/boards.h b/include/asm-mips/txx9/boards.h new file mode 100644 index 000000000000..4abc8142fbb7 --- /dev/null +++ b/include/asm-mips/txx9/boards.h @@ -0,0 +1,10 @@ +#ifdef CONFIG_TOSHIBA_JMR3927 +BOARD_VEC(jmr3927_vec) +#endif +#ifdef CONFIG_TOSHIBA_RBTX4927 +BOARD_VEC(rbtx4927_vec) +BOARD_VEC(rbtx4937_vec) +#endif +#ifdef CONFIG_TOSHIBA_RBTX4938 +BOARD_VEC(rbtx4938_vec) +#endif -- cgit v1.2.3 From d10e025f0e4ba4b96d7b5786d232ac5b0b232b11 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Tue, 19 Aug 2008 22:55:09 +0900 Subject: MIPS: TXx9: Cache fixup TX39/TX49 can enable/disable I/D cache at runtime. Add kernel options to control them. This is useful to debug some cache-related issues, such as aliasing or I/D coherency. Also enable CWF bit for TX49 SoCs. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/txx9/generic/setup.c | 113 ++++++++++++++++++++++++++++++++++ arch/mips/txx9/generic/setup_tx3927.c | 18 +++--- arch/mips/txx9/generic/setup_tx4927.c | 1 + arch/mips/txx9/generic/setup_tx4938.c | 1 + arch/mips/txx9/jmr3927/setup.c | 11 +--- arch/mips/txx9/rbtx4927/setup.c | 6 -- 6 files changed, 124 insertions(+), 26 deletions(-) (limited to 'arch/mips/txx9') diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c index dc5dbcc53a91..fa88aefea9ef 100644 --- a/arch/mips/txx9/generic/setup.c +++ b/arch/mips/txx9/generic/setup.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #ifdef CONFIG_CPU_TX49XX @@ -186,6 +187,110 @@ static void __init prom_init_cmdline(void) } } +static int txx9_ic_disable __initdata; +static int txx9_dc_disable __initdata; + +#if defined(CONFIG_CPU_TX49XX) +/* flush all cache on very early stage (before 4k_cache_init) */ +static void __init early_flush_dcache(void) +{ + unsigned int conf = read_c0_config(); + unsigned int dc_size = 1 << (12 + ((conf & CONF_DC) >> 6)); + unsigned int linesz = 32; + unsigned long addr, end; + + end = INDEX_BASE + dc_size / 4; + /* 4way, waybit=0 */ + for (addr = INDEX_BASE; addr < end; addr += linesz) { + cache_op(Index_Writeback_Inv_D, addr | 0); + cache_op(Index_Writeback_Inv_D, addr | 1); + cache_op(Index_Writeback_Inv_D, addr | 2); + cache_op(Index_Writeback_Inv_D, addr | 3); + } +} + +static void __init txx9_cache_fixup(void) +{ + unsigned int conf; + + conf = read_c0_config(); + /* flush and disable */ + if (txx9_ic_disable) { + conf |= TX49_CONF_IC; + write_c0_config(conf); + } + if (txx9_dc_disable) { + early_flush_dcache(); + conf |= TX49_CONF_DC; + write_c0_config(conf); + } + + /* enable cache */ + conf = read_c0_config(); + if (!txx9_ic_disable) + conf &= ~TX49_CONF_IC; + if (!txx9_dc_disable) + conf &= ~TX49_CONF_DC; + write_c0_config(conf); + + if (conf & TX49_CONF_IC) + pr_info("TX49XX I-Cache disabled.\n"); + if (conf & TX49_CONF_DC) + pr_info("TX49XX D-Cache disabled.\n"); +} +#elif defined(CONFIG_CPU_TX39XX) +/* flush all cache on very early stage (before tx39_cache_init) */ +static void __init early_flush_dcache(void) +{ + unsigned int conf = read_c0_config(); + unsigned int dc_size = 1 << (10 + ((conf & TX39_CONF_DCS_MASK) >> + TX39_CONF_DCS_SHIFT)); + unsigned int linesz = 16; + unsigned long addr, end; + + end = INDEX_BASE + dc_size / 2; + /* 2way, waybit=0 */ + for (addr = INDEX_BASE; addr < end; addr += linesz) { + cache_op(Index_Writeback_Inv_D, addr | 0); + cache_op(Index_Writeback_Inv_D, addr | 1); + } +} + +static void __init txx9_cache_fixup(void) +{ + unsigned int conf; + + conf = read_c0_config(); + /* flush and disable */ + if (txx9_ic_disable) { + conf &= ~TX39_CONF_ICE; + write_c0_config(conf); + } + if (txx9_dc_disable) { + early_flush_dcache(); + conf &= ~TX39_CONF_DCE; + write_c0_config(conf); + } + + /* enable cache */ + conf = read_c0_config(); + if (!txx9_ic_disable) + conf |= TX39_CONF_ICE; + if (!txx9_dc_disable) + conf |= TX39_CONF_DCE; + write_c0_config(conf); + + if (!(conf & TX39_CONF_ICE)) + pr_info("TX39XX I-Cache disabled.\n"); + if (!(conf & TX39_CONF_DCE)) + pr_info("TX39XX D-Cache disabled.\n"); +} +#else +static inline void txx9_cache_fixup(void) +{ +} +#endif + static void __init preprocess_cmdline(void) { char cmdline[CL_SIZE]; @@ -204,11 +309,19 @@ static void __init preprocess_cmdline(void) if (strict_strtoul(str + 10, 10, &val) == 0) txx9_master_clock = val; continue; + } else if (strcmp(str, "icdisable") == 0) { + txx9_ic_disable = 1; + continue; + } else if (strcmp(str, "dcdisable") == 0) { + txx9_dc_disable = 1; + continue; } if (arcs_cmdline[0]) strcat(arcs_cmdline, " "); strcat(arcs_cmdline, str); } + + txx9_cache_fixup(); } static void __init select_board(void) diff --git a/arch/mips/txx9/generic/setup_tx3927.c b/arch/mips/txx9/generic/setup_tx3927.c index 7bd963d37fc3..4bc2f859379d 100644 --- a/arch/mips/txx9/generic/setup_tx3927.c +++ b/arch/mips/txx9/generic/setup_tx3927.c @@ -99,16 +99,14 @@ void __init tx3927_setup(void) txx9_gpio_init(TX3927_PIO_REG, 0, 16); conf = read_c0_conf(); - if (!(conf & TX39_CONF_ICE)) - printk(KERN_INFO "TX3927 I-Cache disabled.\n"); - if (!(conf & TX39_CONF_DCE)) - printk(KERN_INFO "TX3927 D-Cache disabled.\n"); - else if (!(conf & TX39_CONF_WBON)) - printk(KERN_INFO "TX3927 D-Cache WriteThrough.\n"); - else if (!(conf & TX39_CONF_CWFON)) - printk(KERN_INFO "TX3927 D-Cache WriteBack.\n"); - else - printk(KERN_INFO "TX3927 D-Cache WriteBack (CWF) .\n"); + if (conf & TX39_CONF_DCE) { + if (!(conf & TX39_CONF_WBON)) + pr_info("TX3927 D-Cache WriteThrough.\n"); + else if (!(conf & TX39_CONF_CWFON)) + pr_info("TX3927 D-Cache WriteBack.\n"); + else + pr_info("TX3927 D-Cache WriteBack (CWF) .\n"); + } } void __init tx3927_time_init(unsigned int evt_tmrnr, unsigned int src_tmrnr) diff --git a/arch/mips/txx9/generic/setup_tx4927.c b/arch/mips/txx9/generic/setup_tx4927.c index f80d4b7a694d..e679c79a4b0f 100644 --- a/arch/mips/txx9/generic/setup_tx4927.c +++ b/arch/mips/txx9/generic/setup_tx4927.c @@ -44,6 +44,7 @@ void __init tx4927_setup(void) txx9_reg_res_init(TX4927_REV_PCODE(), TX4927_REG_BASE, TX4927_REG_SIZE); + set_c0_config(TX49_CONF_CWFON); /* SDRAMC,EBUSC are configured by PROM */ for (i = 0; i < 8; i++) { diff --git a/arch/mips/txx9/generic/setup_tx4938.c b/arch/mips/txx9/generic/setup_tx4938.c index f3040b9ba059..95c058f0a96c 100644 --- a/arch/mips/txx9/generic/setup_tx4938.c +++ b/arch/mips/txx9/generic/setup_tx4938.c @@ -47,6 +47,7 @@ void __init tx4938_setup(void) txx9_reg_res_init(TX4938_REV_PCODE(), TX4938_REG_BASE, TX4938_REG_SIZE); + set_c0_config(TX49_CONF_CWFON); /* SDRAMC,EBUSC are configured by PROM */ for (i = 0; i < 8; i++) { diff --git a/arch/mips/txx9/jmr3927/setup.c b/arch/mips/txx9/jmr3927/setup.c index 87db41be8a56..2e40a9268254 100644 --- a/arch/mips/txx9/jmr3927/setup.c +++ b/arch/mips/txx9/jmr3927/setup.c @@ -62,7 +62,6 @@ static void __init jmr3927_time_init(void) } #define DO_WRITE_THROUGH -#define DO_ENABLE_CACHE static void jmr3927_board_init(void); @@ -77,11 +76,6 @@ static void __init jmr3927_mem_setup(void) /* cache setup */ { unsigned int conf; -#ifdef DO_ENABLE_CACHE - int mips_ic_disable = 0, mips_dc_disable = 0; -#else - int mips_ic_disable = 1, mips_dc_disable = 1; -#endif #ifdef DO_WRITE_THROUGH int mips_config_cwfon = 0; int mips_config_wbon = 0; @@ -91,10 +85,7 @@ static void __init jmr3927_mem_setup(void) #endif conf = read_c0_conf(); - conf &= ~(TX39_CONF_ICE | TX39_CONF_DCE | - TX39_CONF_WBON | TX39_CONF_CWFON); - conf |= mips_ic_disable ? 0 : TX39_CONF_ICE; - conf |= mips_dc_disable ? 0 : TX39_CONF_DCE; + conf &= ~(TX39_CONF_WBON | TX39_CONF_CWFON); conf |= mips_config_wbon ? TX39_CONF_WBON : 0; conf |= mips_config_cwfon ? TX39_CONF_CWFON : 0; diff --git a/arch/mips/txx9/rbtx4927/setup.c b/arch/mips/txx9/rbtx4927/setup.c index 5985f330838a..0464a39b39ac 100644 --- a/arch/mips/txx9/rbtx4927/setup.c +++ b/arch/mips/txx9/rbtx4927/setup.c @@ -186,14 +186,8 @@ static void __init rbtx4937_clock_init(void); static void __init rbtx4927_mem_setup(void) { - u32 cp0_config; char *argptr; - /* enable caches -- HCP5 does this, pmon does not */ - cp0_config = read_c0_config(); - cp0_config = cp0_config & ~(TX49_CONF_IC | TX49_CONF_DC); - write_c0_config(cp0_config); - if (TX4927_REV_PCODE() == 0x4927) { rbtx4927_clock_init(); tx4927_setup(); -- cgit v1.2.3 From c7b95bcb38ea492fd025008ef99501a2b90aa237 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Tue, 19 Aug 2008 22:55:10 +0900 Subject: MIPS: TXx9: Runtime configuration of timeout-error Add kernel options to control bus timeout error. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/txx9/generic/setup.c | 11 +++++++++++ arch/mips/txx9/generic/setup_tx3927.c | 5 ----- 2 files changed, 11 insertions(+), 5 deletions(-) (limited to 'arch/mips/txx9') diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c index fa88aefea9ef..fa45f174b0ee 100644 --- a/arch/mips/txx9/generic/setup.c +++ b/arch/mips/txx9/generic/setup.c @@ -68,7 +68,12 @@ unsigned int txx9_master_clock; unsigned int txx9_cpu_clock; unsigned int txx9_gbus_clock; +#ifdef CONFIG_CPU_TX39XX +/* don't enable by default - see errata */ +int txx9_ccfg_toeon __initdata; +#else int txx9_ccfg_toeon __initdata = 1; +#endif /* Minimum CLK support */ @@ -315,6 +320,12 @@ static void __init preprocess_cmdline(void) } else if (strcmp(str, "dcdisable") == 0) { txx9_dc_disable = 1; continue; + } else if (strcmp(str, "toeoff") == 0) { + txx9_ccfg_toeon = 0; + continue; + } else if (strcmp(str, "toeon") == 0) { + txx9_ccfg_toeon = 1; + continue; } if (arcs_cmdline[0]) strcat(arcs_cmdline, " "); diff --git a/arch/mips/txx9/generic/setup_tx3927.c b/arch/mips/txx9/generic/setup_tx3927.c index 4bc2f859379d..06c492576078 100644 --- a/arch/mips/txx9/generic/setup_tx3927.c +++ b/arch/mips/txx9/generic/setup_tx3927.c @@ -32,11 +32,6 @@ void __init tx3927_setup(void) int i; unsigned int conf; - /* don't enable - see errata */ - txx9_ccfg_toeon = 0; - if (strstr(prom_getcmdline(), "toeon") != NULL) - txx9_ccfg_toeon = 1; - txx9_reg_res_init(TX3927_REV_PCODE(), TX3927_REG_BASE, TX3927_REG_SIZE); -- cgit v1.2.3 From 51f607c76e1e7bd089dcad97b6b0a58649be06a3 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Tue, 19 Aug 2008 22:55:11 +0900 Subject: MIPS: TXx9: Add mtd support Add helper routines to register physmap-flash platform devices for NOR flashes. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/txx9/generic/setup.c | 41 +++++++++++++++++++++++++++++++++++ arch/mips/txx9/generic/setup_tx3927.c | 14 ++++++++++++ arch/mips/txx9/generic/setup_tx4927.c | 14 ++++++++++++ arch/mips/txx9/generic/setup_tx4938.c | 14 ++++++++++++ arch/mips/txx9/jmr3927/setup.c | 9 ++++++++ arch/mips/txx9/rbtx4927/setup.c | 9 ++++++++ arch/mips/txx9/rbtx4938/setup.c | 38 ++++++++++++++++++++++++++++++++ include/asm-mips/txx9/generic.h | 4 ++++ include/asm-mips/txx9/tx3927.h | 2 ++ include/asm-mips/txx9/tx4927.h | 3 +++ include/asm-mips/txx9/tx4938.h | 2 ++ 11 files changed, 150 insertions(+) (limited to 'arch/mips/txx9') diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c index fa45f174b0ee..cfa3ccf493bb 100644 --- a/arch/mips/txx9/generic/setup.c +++ b/arch/mips/txx9/generic/setup.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -593,3 +594,43 @@ static unsigned long __swizzle_addr_none(unsigned long port) unsigned long (*__swizzle_addr_b)(unsigned long port) = __swizzle_addr_none; EXPORT_SYMBOL(__swizzle_addr_b); #endif + +void __init txx9_physmap_flash_init(int no, unsigned long addr, + unsigned long size, + const struct physmap_flash_data *pdata) +{ +#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) + struct resource res = { + .start = addr, + .end = addr + size - 1, + .flags = IORESOURCE_MEM, + }; + struct platform_device *pdev; +#ifdef CONFIG_MTD_PARTITIONS + static struct mtd_partition parts[2]; + struct physmap_flash_data pdata_part; + + /* If this area contained boot area, make separate partition */ + if (pdata->nr_parts == 0 && !pdata->parts && + addr < 0x1fc00000 && addr + size > 0x1fc00000 && + !parts[0].name) { + parts[0].name = "boot"; + parts[0].offset = 0x1fc00000 - addr; + parts[0].size = addr + size - 0x1fc00000; + parts[1].name = "user"; + parts[1].offset = 0; + parts[1].size = 0x1fc00000 - addr; + pdata_part = *pdata; + pdata_part.nr_parts = ARRAY_SIZE(parts); + pdata_part.parts = parts; + pdata = &pdata_part; + } +#endif + pdev = platform_device_alloc("physmap-flash", no); + if (!pdev || + platform_device_add_resources(pdev, &res, 1) || + platform_device_add_data(pdev, pdata, sizeof(*pdata)) || + platform_device_add(pdev)) + platform_device_put(pdev); +#endif +} diff --git a/arch/mips/txx9/generic/setup_tx3927.c b/arch/mips/txx9/generic/setup_tx3927.c index 06c492576078..9505d58454c8 100644 --- a/arch/mips/txx9/generic/setup_tx3927.c +++ b/arch/mips/txx9/generic/setup_tx3927.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -121,3 +122,16 @@ void __init tx3927_sio_init(unsigned int sclk, unsigned int cts_mask) TXX9_IRQ_BASE + TX3927_IR_SIO(i), i, sclk, (1 << i) & cts_mask); } + +void __init tx3927_mtd_init(int ch) +{ + struct physmap_flash_data pdata = { + .width = TX3927_ROMC_WIDTH(ch) / 8, + }; + unsigned long start = txx9_ce_res[ch].start; + unsigned long size = txx9_ce_res[ch].end - start + 1; + + if (!(tx3927_romcptr->cr[ch] & 0x8)) + return; /* disabled */ + txx9_physmap_flash_init(ch, start, size, &pdata); +} diff --git a/arch/mips/txx9/generic/setup_tx4927.c b/arch/mips/txx9/generic/setup_tx4927.c index e679c79a4b0f..0840ef930e40 100644 --- a/arch/mips/txx9/generic/setup_tx4927.c +++ b/arch/mips/txx9/generic/setup_tx4927.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -187,3 +188,16 @@ void __init tx4927_sio_init(unsigned int sclk, unsigned int cts_mask) TXX9_IRQ_BASE + TX4927_IR_SIO(i), i, sclk, (1 << i) & cts_mask); } + +void __init tx4927_mtd_init(int ch) +{ + struct physmap_flash_data pdata = { + .width = TX4927_EBUSC_WIDTH(ch) / 8, + }; + unsigned long start = txx9_ce_res[ch].start; + unsigned long size = txx9_ce_res[ch].end - start + 1; + + if (!(TX4927_EBUSC_CR(ch) & 0x8)) + return; /* disabled */ + txx9_physmap_flash_init(ch, start, size, &pdata); +} diff --git a/arch/mips/txx9/generic/setup_tx4938.c b/arch/mips/txx9/generic/setup_tx4938.c index 95c058f0a96c..630a7aac61f6 100644 --- a/arch/mips/txx9/generic/setup_tx4938.c +++ b/arch/mips/txx9/generic/setup_tx4938.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -269,3 +270,16 @@ void __init tx4938_ethaddr_init(unsigned char *addr0, unsigned char *addr1) if (addr1 && (pcfg & TX4938_PCFG_ETH1_SEL)) txx9_ethaddr_init(TXX9_IRQ_BASE + TX4938_IR_ETH1, addr1); } + +void __init tx4938_mtd_init(int ch) +{ + struct physmap_flash_data pdata = { + .width = TX4938_EBUSC_WIDTH(ch) / 8, + }; + unsigned long start = txx9_ce_res[ch].start; + unsigned long size = txx9_ce_res[ch].end - start + 1; + + if (!(TX4938_EBUSC_CR(ch) & 0x8)) + return; /* disabled */ + txx9_physmap_flash_init(ch, start, size, &pdata); +} diff --git a/arch/mips/txx9/jmr3927/setup.c b/arch/mips/txx9/jmr3927/setup.c index 2e40a9268254..0f3843c92cf7 100644 --- a/arch/mips/txx9/jmr3927/setup.c +++ b/arch/mips/txx9/jmr3927/setup.c @@ -190,11 +190,20 @@ static void __init jmr3927_rtc_init(void) platform_device_register_simple("rtc-ds1742", -1, &res, 1); } +static void __init jmr3927_mtd_init(void) +{ + int i; + + for (i = 0; i < 2; i++) + tx3927_mtd_init(i); +} + static void __init jmr3927_device_init(void) { __swizzle_addr_b = jmr3927_swizzle_addr_b; jmr3927_rtc_init(); tx3927_wdt_init(); + jmr3927_mtd_init(); } struct txx9_board_vec jmr3927_vec __initdata = { diff --git a/arch/mips/txx9/rbtx4927/setup.c b/arch/mips/txx9/rbtx4927/setup.c index 0464a39b39ac..abe32c1a79dc 100644 --- a/arch/mips/txx9/rbtx4927/setup.c +++ b/arch/mips/txx9/rbtx4927/setup.c @@ -307,11 +307,20 @@ static void __init rbtx4927_ne_init(void) platform_device_register_simple("ne", -1, res, ARRAY_SIZE(res)); } +static void __init rbtx4927_mtd_init(void) +{ + int i; + + for (i = 0; i < 2; i++) + tx4927_mtd_init(i); +} + static void __init rbtx4927_device_init(void) { toshiba_rbtx4927_rtc_init(); rbtx4927_ne_init(); tx4927_wdt_init(); + rbtx4927_mtd_init(); } struct txx9_board_vec rbtx4927_vec __initdata = { diff --git a/arch/mips/txx9/rbtx4938/setup.c b/arch/mips/txx9/rbtx4938/setup.c index 9ab48dec0fe8..e7bc5b8c7db8 100644 --- a/arch/mips/txx9/rbtx4938/setup.c +++ b/arch/mips/txx9/rbtx4938/setup.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -294,6 +295,42 @@ static int __init rbtx4938_spi_init(void) return 0; } +static void __init rbtx4938_mtd_init(void) +{ + struct physmap_flash_data pdata = { + .width = 4, + }; + + switch (readb(rbtx4938_bdipsw_addr) & 7) { + case 0: + /* Boot */ + txx9_physmap_flash_init(0, 0x1fc00000, 0x400000, &pdata); + /* System */ + txx9_physmap_flash_init(1, 0x1e000000, 0x1000000, &pdata); + break; + case 1: + /* System */ + txx9_physmap_flash_init(0, 0x1f000000, 0x1000000, &pdata); + /* Boot */ + txx9_physmap_flash_init(1, 0x1ec00000, 0x400000, &pdata); + break; + case 2: + /* Ext */ + txx9_physmap_flash_init(0, 0x1f000000, 0x1000000, &pdata); + /* System */ + txx9_physmap_flash_init(1, 0x1e000000, 0x1000000, &pdata); + /* Boot */ + txx9_physmap_flash_init(2, 0x1dc00000, 0x400000, &pdata); + break; + case 3: + /* Boot */ + txx9_physmap_flash_init(1, 0x1bc00000, 0x400000, &pdata); + /* System */ + txx9_physmap_flash_init(2, 0x1a000000, 0x1000000, &pdata); + break; + } +} + static void __init rbtx4938_arch_init(void) { gpiochip_add(&rbtx4938_spi_gpio_chip); @@ -306,6 +343,7 @@ static void __init rbtx4938_device_init(void) rbtx4938_ethaddr_init(); rbtx4938_ne_init(); tx4938_wdt_init(); + rbtx4938_mtd_init(); } struct txx9_board_vec rbtx4938_vec __initdata = { diff --git a/include/asm-mips/txx9/generic.h b/include/asm-mips/txx9/generic.h index 0a225bf73496..1982c4437b1d 100644 --- a/include/asm-mips/txx9/generic.h +++ b/include/asm-mips/txx9/generic.h @@ -59,4 +59,8 @@ static inline void txx9_sio_putchar_init(unsigned long baseaddr) } #endif +struct physmap_flash_data; +void txx9_physmap_flash_init(int no, unsigned long addr, unsigned long size, + const struct physmap_flash_data *pdata); + #endif /* __ASM_TXX9_GENERIC_H */ diff --git a/include/asm-mips/txx9/tx3927.h b/include/asm-mips/txx9/tx3927.h index 587deb9592d2..dc30c8d42061 100644 --- a/include/asm-mips/txx9/tx3927.h +++ b/include/asm-mips/txx9/tx3927.h @@ -325,6 +325,7 @@ struct tx3927_ccfg_reg { #define TX3927_ROMC_BA(ch) (tx3927_romcptr->cr[(ch)] & 0xfff00000) #define TX3927_ROMC_SIZE(ch) \ (0x00100000 << ((tx3927_romcptr->cr[(ch)] >> 8) & 0xf)) +#define TX3927_ROMC_WIDTH(ch) (32 >> ((tx3927_romcptr->cr[(ch)] >> 7) & 0x1)) void tx3927_wdt_init(void); void tx3927_setup(void); @@ -335,5 +336,6 @@ void tx3927_pcic_setup(struct pci_controller *channel, unsigned long sdram_size, int extarb); void tx3927_setup_pcierr_irq(void); void tx3927_irq_init(void); +void tx3927_mtd_init(int ch); #endif /* __ASM_TXX9_TX3927_H */ diff --git a/include/asm-mips/txx9/tx4927.h b/include/asm-mips/txx9/tx4927.h index 195f6515db9a..36a9241b0cac 100644 --- a/include/asm-mips/txx9/tx4927.h +++ b/include/asm-mips/txx9/tx4927.h @@ -196,6 +196,8 @@ struct tx4927_ccfg_reg { #define TX4927_EBUSC_BA(ch) ((TX4927_EBUSC_CR(ch) >> 48) << 20) #define TX4927_EBUSC_SIZE(ch) \ (0x00100000 << ((unsigned long)(TX4927_EBUSC_CR(ch) >> 8) & 0xf)) +#define TX4927_EBUSC_WIDTH(ch) \ + (64 >> ((__u32)(TX4927_EBUSC_CR(ch) >> 20) & 0x3)) /* utilities */ static inline void txx9_clear64(__u64 __iomem *adr, __u64 bits) @@ -251,5 +253,6 @@ int tx4927_report_pciclk(void); int tx4927_pciclk66_setup(void); void tx4927_setup_pcierr_irq(void); void tx4927_irq_init(void); +void tx4927_mtd_init(int ch); #endif /* __ASM_TXX9_TX4927_H */ diff --git a/include/asm-mips/txx9/tx4938.h b/include/asm-mips/txx9/tx4938.h index 8175d4ccbc39..989e7751135a 100644 --- a/include/asm-mips/txx9/tx4938.h +++ b/include/asm-mips/txx9/tx4938.h @@ -274,6 +274,7 @@ struct tx4938_ccfg_reg { #define TX4938_EBUSC_CR(ch) TX4927_EBUSC_CR(ch) #define TX4938_EBUSC_BA(ch) TX4927_EBUSC_BA(ch) #define TX4938_EBUSC_SIZE(ch) TX4927_EBUSC_SIZE(ch) +#define TX4938_EBUSC_WIDTH(ch) TX4927_EBUSC_WIDTH(ch) #define tx4938_get_mem_size() tx4927_get_mem_size() void tx4938_wdt_init(void); @@ -289,5 +290,6 @@ struct pci_dev; int tx4938_pcic1_map_irq(const struct pci_dev *dev, u8 slot); void tx4938_setup_pcierr_irq(void); void tx4938_irq_init(void); +void tx4938_mtd_init(int ch); #endif -- cgit v1.2.3 From 74894363499942a76f2c20e41e8bfebc9fdc267a Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Tue, 19 Aug 2008 22:55:12 +0900 Subject: MIPS: TXx9: Raise priority of interrupts for errors, timers, SIO Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/txx9/generic/irq_tx4927.c | 11 +++++++++++ arch/mips/txx9/generic/irq_tx4938.c | 11 +++++++++++ include/asm-mips/txx9/tx4927.h | 11 +++++++++++ 3 files changed, 33 insertions(+) (limited to 'arch/mips/txx9') diff --git a/arch/mips/txx9/generic/irq_tx4927.c b/arch/mips/txx9/generic/irq_tx4927.c index cbea1fdde82b..ad2870def8f1 100644 --- a/arch/mips/txx9/generic/irq_tx4927.c +++ b/arch/mips/txx9/generic/irq_tx4927.c @@ -30,8 +30,19 @@ void __init tx4927_irq_init(void) { + int i; + mips_cpu_irq_init(); txx9_irq_init(TX4927_IRC_REG & 0xfffffffffULL); set_irq_chained_handler(MIPS_CPU_IRQ_BASE + TX4927_IRC_INT, handle_simple_irq); + /* raise priority for errors, timers, SIO */ + txx9_irq_set_pri(TX4927_IR_ECCERR, 7); + txx9_irq_set_pri(TX4927_IR_WTOERR, 7); + txx9_irq_set_pri(TX4927_IR_PCIERR, 7); + txx9_irq_set_pri(TX4927_IR_PCIPME, 7); + for (i = 0; i < TX4927_NUM_IR_TMR; i++) + txx9_irq_set_pri(TX4927_IR_TMR(i), 6); + for (i = 0; i < TX4927_NUM_IR_SIO; i++) + txx9_irq_set_pri(TX4927_IR_SIO(i), 5); } diff --git a/arch/mips/txx9/generic/irq_tx4938.c b/arch/mips/txx9/generic/irq_tx4938.c index 6eac684bf190..025ae11359a8 100644 --- a/arch/mips/txx9/generic/irq_tx4938.c +++ b/arch/mips/txx9/generic/irq_tx4938.c @@ -18,8 +18,19 @@ void __init tx4938_irq_init(void) { + int i; + mips_cpu_irq_init(); txx9_irq_init(TX4938_IRC_REG & 0xfffffffffULL); set_irq_chained_handler(MIPS_CPU_IRQ_BASE + TX4938_IRC_INT, handle_simple_irq); + /* raise priority for errors, timers, SIO */ + txx9_irq_set_pri(TX4938_IR_ECCERR, 7); + txx9_irq_set_pri(TX4938_IR_WTOERR, 7); + txx9_irq_set_pri(TX4938_IR_PCIERR, 7); + txx9_irq_set_pri(TX4938_IR_PCIPME, 7); + for (i = 0; i < TX4938_NUM_IR_TMR; i++) + txx9_irq_set_pri(TX4938_IR_TMR(i), 6); + for (i = 0; i < TX4938_NUM_IR_SIO; i++) + txx9_irq_set_pri(TX4938_IR_SIO(i), 5); } diff --git a/include/asm-mips/txx9/tx4927.h b/include/asm-mips/txx9/tx4927.h index 36a9241b0cac..7d813f1cb98d 100644 --- a/include/asm-mips/txx9/tx4927.h +++ b/include/asm-mips/txx9/tx4927.h @@ -50,12 +50,23 @@ #define TX4927_SIO_REG(ch) (TX4927_REG_BASE + 0xf300 + (ch) * 0x100) #define TX4927_PIO_REG (TX4927_REG_BASE + 0xf500) +#define TX4927_IR_ECCERR 0 +#define TX4927_IR_WTOERR 1 +#define TX4927_NUM_IR_INT 6 #define TX4927_IR_INT(n) (2 + (n)) +#define TX4927_NUM_IR_SIO 2 #define TX4927_IR_SIO(n) (8 + (n)) +#define TX4927_NUM_IR_DMA 4 +#define TX4927_IR_DMA(n) (10 + (n)) +#define TX4927_IR_PIO 14 +#define TX4927_IR_PDMAC 15 #define TX4927_IR_PCIC 16 #define TX4927_NUM_IR_TMR 3 #define TX4927_IR_TMR(n) (17 + (n)) #define TX4927_IR_PCIERR 22 +#define TX4927_IR_PCIPME 23 +#define TX4927_IR_ACLC 24 +#define TX4927_IR_ACLCPME 25 #define TX4927_NUM_IR 32 #define TX4927_IRC_INT 2 /* IP[2] in Status register */ -- cgit v1.2.3 From e6332374770ae5aa370af5792115261edbad05c1 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Tue, 19 Aug 2008 22:55:13 +0900 Subject: MIPS: RBTX4938: Add TOSHIBA_RBTX4938_MPLEX_KEEP Add TOSHIBA_RBTX4938_MPLEX_KEEP to keep MPLEX settings by firmware. Also replace some printk with pr_info. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/txx9/Kconfig | 2 ++ arch/mips/txx9/rbtx4938/setup.c | 13 ++++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) (limited to 'arch/mips/txx9') diff --git a/arch/mips/txx9/Kconfig b/arch/mips/txx9/Kconfig index 6fb2ef09d5dd..aade3348af29 100644 --- a/arch/mips/txx9/Kconfig +++ b/arch/mips/txx9/Kconfig @@ -94,6 +94,8 @@ config TOSHIBA_RBTX4938_MPLEX_NAND bool "NAND" config TOSHIBA_RBTX4938_MPLEX_ATA bool "ATA" +config TOSHIBA_RBTX4938_MPLEX_KEEP + bool "Keep firmware settings" endchoice diff --git a/arch/mips/txx9/rbtx4938/setup.c b/arch/mips/txx9/rbtx4938/setup.c index e7bc5b8c7db8..7aba92a12399 100644 --- a/arch/mips/txx9/rbtx4938/setup.c +++ b/arch/mips/txx9/rbtx4938/setup.c @@ -174,23 +174,30 @@ static void __init rbtx4938_mem_setup(void) #endif #ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_PIO58_61 - printk(KERN_INFO "PIOSEL: disabling both ata and nand selection\n"); + pr_info("PIOSEL: disabling both ATA and NAND selection\n"); txx9_clear64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_NDF_SEL | TX4938_PCFG_ATA_SEL); #endif #ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_NAND - printk(KERN_INFO "PIOSEL: enabling nand selection\n"); + pr_info("PIOSEL: enabling NAND selection\n"); txx9_set64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_NDF_SEL); txx9_clear64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_ATA_SEL); #endif #ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_ATA - printk(KERN_INFO "PIOSEL: enabling ata selection\n"); + pr_info("PIOSEL: enabling ATA selection\n"); txx9_set64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_ATA_SEL); txx9_clear64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_NDF_SEL); #endif +#ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_KEEP + pcfg = ____raw_readq(&tx4938_ccfgptr->pcfg); + pr_info("PIOSEL: NAND %s, ATA %s\n", + (pcfg & TX4938_PCFG_NDF_SEL) ? "enabled" : "disabled", + (pcfg & TX4938_PCFG_ATA_SEL) ? "enabled" : "disabled"); +#endif + rbtx4938_spi_setup(); pcfg = ____raw_readq(&tx4938_ccfgptr->pcfg); /* updated */ /* fixup piosel */ -- cgit v1.2.3 From d75a40e90e9eb08c2159e719a90a7922dab231d3 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Tue, 19 Aug 2008 22:55:14 +0900 Subject: MIPS: TXx9: Make spi_eeprom.c more generic Helper routines in txx9/rbtx4938/spi_eeprom.c is not TX4938 specific. Move it to txx9/generic/ directory and make it works with SPI bus number other than 0. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle create mode 100644 arch/mips/txx9/generic/spi_eeprom.c delete mode 100644 arch/mips/txx9/rbtx4938/spi_eeprom.c --- arch/mips/txx9/generic/Makefile | 1 + arch/mips/txx9/generic/spi_eeprom.c | 103 +++++++++++++++++++++++++++++++++++ arch/mips/txx9/rbtx4938/Makefile | 2 +- arch/mips/txx9/rbtx4938/setup.c | 11 ++-- arch/mips/txx9/rbtx4938/spi_eeprom.c | 99 --------------------------------- include/asm-mips/txx9/spi.h | 19 ++++++- 6 files changed, 128 insertions(+), 107 deletions(-) create mode 100644 arch/mips/txx9/generic/spi_eeprom.c delete mode 100644 arch/mips/txx9/rbtx4938/spi_eeprom.c (limited to 'arch/mips/txx9') diff --git a/arch/mips/txx9/generic/Makefile b/arch/mips/txx9/generic/Makefile index 9bb34af26b73..986852cc774c 100644 --- a/arch/mips/txx9/generic/Makefile +++ b/arch/mips/txx9/generic/Makefile @@ -8,5 +8,6 @@ obj-$(CONFIG_SOC_TX3927) += setup_tx3927.o irq_tx3927.o obj-$(CONFIG_SOC_TX4927) += mem_tx4927.o setup_tx4927.o irq_tx4927.o obj-$(CONFIG_SOC_TX4938) += mem_tx4927.o setup_tx4938.o irq_tx4938.o obj-$(CONFIG_TOSHIBA_FPCIB0) += smsc_fdc37m81x.o +obj-$(CONFIG_SPI) += spi_eeprom.o EXTRA_CFLAGS += -Werror diff --git a/arch/mips/txx9/generic/spi_eeprom.c b/arch/mips/txx9/generic/spi_eeprom.c new file mode 100644 index 000000000000..75c347238f47 --- /dev/null +++ b/arch/mips/txx9/generic/spi_eeprom.c @@ -0,0 +1,103 @@ +/* + * spi_eeprom.c + * Copyright (C) 2000-2001 Toshiba Corporation + * + * 2003-2005 (c) MontaVista Software, Inc. 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. + * + * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) + */ +#include +#include +#include +#include +#include + +#define AT250X0_PAGE_SIZE 8 + +/* register board information for at25 driver */ +int __init spi_eeprom_register(int busid, int chipid, int size) +{ + struct spi_board_info info = { + .modalias = "at25", + .max_speed_hz = 1500000, /* 1.5Mbps */ + .bus_num = busid, + .chip_select = chipid, + /* Mode 0: High-Active, Sample-Then-Shift */ + }; + struct spi_eeprom *eeprom; + eeprom = kzalloc(sizeof(*eeprom), GFP_KERNEL); + if (!eeprom) + return -ENOMEM; + strcpy(eeprom->name, "at250x0"); + eeprom->byte_len = size; + eeprom->page_size = AT250X0_PAGE_SIZE; + eeprom->flags = EE_ADDR1; + info.platform_data = eeprom; + return spi_register_board_info(&info, 1); +} + +/* simple temporary spi driver to provide early access to seeprom. */ + +static struct read_param { + int busid; + int chipid; + int address; + unsigned char *buf; + int len; +} *read_param; + +static int __init early_seeprom_probe(struct spi_device *spi) +{ + int stat = 0; + u8 cmd[2]; + int len = read_param->len; + char *buf = read_param->buf; + int address = read_param->address; + + dev_info(&spi->dev, "spiclk %u KHz.\n", + (spi->max_speed_hz + 500) / 1000); + if (read_param->busid != spi->master->bus_num || + read_param->chipid != spi->chip_select) + return -ENODEV; + while (len > 0) { + /* spi_write_then_read can only work with small chunk */ + int c = len < AT250X0_PAGE_SIZE ? len : AT250X0_PAGE_SIZE; + cmd[0] = 0x03; /* AT25_READ */ + cmd[1] = address; + stat = spi_write_then_read(spi, cmd, sizeof(cmd), buf, c); + buf += c; + len -= c; + address += c; + } + return stat; +} + +static struct spi_driver early_seeprom_driver __initdata = { + .driver = { + .name = "at25", + .owner = THIS_MODULE, + }, + .probe = early_seeprom_probe, +}; + +int __init spi_eeprom_read(int busid, int chipid, int address, + unsigned char *buf, int len) +{ + int ret; + struct read_param param = { + .busid = busid, + .chipid = chipid, + .address = address, + .buf = buf, + .len = len + }; + + read_param = ¶m; + ret = spi_register_driver(&early_seeprom_driver); + if (!ret) + spi_unregister_driver(&early_seeprom_driver); + return ret; +} diff --git a/arch/mips/txx9/rbtx4938/Makefile b/arch/mips/txx9/rbtx4938/Makefile index 9dcc52ae5b9d..f3e1f597b4f1 100644 --- a/arch/mips/txx9/rbtx4938/Makefile +++ b/arch/mips/txx9/rbtx4938/Makefile @@ -1,3 +1,3 @@ -obj-y += prom.o setup.o irq.o spi_eeprom.o +obj-y += prom.o setup.o irq.o EXTRA_CFLAGS += -Werror diff --git a/arch/mips/txx9/rbtx4938/setup.c b/arch/mips/txx9/rbtx4938/setup.c index 7aba92a12399..ec6e81258f73 100644 --- a/arch/mips/txx9/rbtx4938/setup.c +++ b/arch/mips/txx9/rbtx4938/setup.c @@ -111,6 +111,7 @@ static void __init rbtx4938_pci_setup(void) #define SEEPROM2_CS 0 /* IOC */ #define SEEPROM3_CS 1 /* IOC */ #define SRTC_CS 2 /* IOC */ +#define SPI_BUSNO 0 static int __init rbtx4938_ethaddr_init(void) { @@ -120,7 +121,7 @@ static int __init rbtx4938_ethaddr_init(void) int i; /* 0-3: "MAC\0", 4-9:eth0, 10-15:eth1, 16:sum */ - if (spi_eeprom_read(SEEPROM1_CS, 0, dat, sizeof(dat))) { + if (spi_eeprom_read(SPI_BUSNO, SEEPROM1_CS, 0, dat, sizeof(dat))) { printk(KERN_ERR "seeprom: read error.\n"); return -ENODEV; } else { @@ -287,9 +288,9 @@ static int __init rbtx4938_spi_init(void) .mode = SPI_MODE_1 | SPI_CS_HIGH, }; spi_register_board_info(&srtc_info, 1); - spi_eeprom_register(SEEPROM1_CS); - spi_eeprom_register(16 + SEEPROM2_CS); - spi_eeprom_register(16 + SEEPROM3_CS); + spi_eeprom_register(SPI_BUSNO, SEEPROM1_CS, 128); + spi_eeprom_register(SPI_BUSNO, 16 + SEEPROM2_CS, 128); + spi_eeprom_register(SPI_BUSNO, 16 + SEEPROM3_CS, 128); gpio_request(16 + SRTC_CS, "rtc-rs5c348"); gpio_direction_output(16 + SRTC_CS, 0); gpio_request(SEEPROM1_CS, "seeprom1"); @@ -298,7 +299,7 @@ static int __init rbtx4938_spi_init(void) gpio_direction_output(16 + SEEPROM2_CS, 1); gpio_request(16 + SEEPROM3_CS, "seeprom3"); gpio_direction_output(16 + SEEPROM3_CS, 1); - tx4938_spi_init(0); + tx4938_spi_init(SPI_BUSNO); return 0; } diff --git a/arch/mips/txx9/rbtx4938/spi_eeprom.c b/arch/mips/txx9/rbtx4938/spi_eeprom.c deleted file mode 100644 index a7ea8b041c1d..000000000000 --- a/arch/mips/txx9/rbtx4938/spi_eeprom.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * spi_eeprom.c - * Copyright (C) 2000-2001 Toshiba Corporation - * - * 2003-2005 (c) MontaVista Software, Inc. 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. - * - * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) - */ -#include -#include -#include -#include -#include - -#define AT250X0_PAGE_SIZE 8 - -/* register board information for at25 driver */ -int __init spi_eeprom_register(int chipid) -{ - static struct spi_eeprom eeprom = { - .name = "at250x0", - .byte_len = 128, - .page_size = AT250X0_PAGE_SIZE, - .flags = EE_ADDR1, - }; - struct spi_board_info info = { - .modalias = "at25", - .max_speed_hz = 1500000, /* 1.5Mbps */ - .bus_num = 0, - .chip_select = chipid, - .platform_data = &eeprom, - /* Mode 0: High-Active, Sample-Then-Shift */ - }; - - return spi_register_board_info(&info, 1); -} - -/* simple temporary spi driver to provide early access to seeprom. */ - -static struct read_param { - int chipid; - int address; - unsigned char *buf; - int len; -} *read_param; - -static int __init early_seeprom_probe(struct spi_device *spi) -{ - int stat = 0; - u8 cmd[2]; - int len = read_param->len; - char *buf = read_param->buf; - int address = read_param->address; - - dev_info(&spi->dev, "spiclk %u KHz.\n", - (spi->max_speed_hz + 500) / 1000); - if (read_param->chipid != spi->chip_select) - return -ENODEV; - while (len > 0) { - /* spi_write_then_read can only work with small chunk */ - int c = len < AT250X0_PAGE_SIZE ? len : AT250X0_PAGE_SIZE; - cmd[0] = 0x03; /* AT25_READ */ - cmd[1] = address; - stat = spi_write_then_read(spi, cmd, sizeof(cmd), buf, c); - buf += c; - len -= c; - address += c; - } - return stat; -} - -static struct spi_driver early_seeprom_driver __initdata = { - .driver = { - .name = "at25", - .owner = THIS_MODULE, - }, - .probe = early_seeprom_probe, -}; - -int __init spi_eeprom_read(int chipid, int address, - unsigned char *buf, int len) -{ - int ret; - struct read_param param = { - .chipid = chipid, - .address = address, - .buf = buf, - .len = len - }; - - read_param = ¶m; - ret = spi_register_driver(&early_seeprom_driver); - if (!ret) - spi_unregister_driver(&early_seeprom_driver); - return ret; -} diff --git a/include/asm-mips/txx9/spi.h b/include/asm-mips/txx9/spi.h index ddfb2a0dc432..0d727f354557 100644 --- a/include/asm-mips/txx9/spi.h +++ b/include/asm-mips/txx9/spi.h @@ -13,7 +13,22 @@ #ifndef __ASM_TXX9_SPI_H #define __ASM_TXX9_SPI_H -extern int spi_eeprom_register(int chipid); -extern int spi_eeprom_read(int chipid, int address, unsigned char *buf, int len); +#include + +#ifdef CONFIG_SPI +int spi_eeprom_register(int busid, int chipid, int size); +int spi_eeprom_read(int busid, int chipid, + int address, unsigned char *buf, int len); +#else +static inline int spi_eeprom_register(int busid, int chipid, int size) +{ + return -ENODEV; +} +static inline int spi_eeprom_read(int busid, int chipid, + int address, unsigned char *buf, int len) +{ + return -ENODEV; +} +#endif #endif /* __ASM_TXX9_SPI_H */ -- cgit v1.2.3 From 496a3b5c2c188e8af07261792b3d4e6cf1c1dab9 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Tue, 19 Aug 2008 22:55:15 +0900 Subject: MIPS: TXx9: Default machine_restart using watchdog reset Add default machine_restart routine using watchdog reset of TX4927 and TX4938. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/txx9/generic/setup.c | 15 +++++++++++++++ arch/mips/txx9/generic/setup_tx4927.c | 28 ++++++++++++++++++++++++++++ arch/mips/txx9/generic/setup_tx4938.c | 28 ++++++++++++++++++++++++++++ include/asm-mips/txx9/generic.h | 1 + 4 files changed, 72 insertions(+) (limited to 'arch/mips/txx9') diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c index cfa3ccf493bb..118d716f7832 100644 --- a/arch/mips/txx9/generic/setup.c +++ b/arch/mips/txx9/generic/setup.c @@ -29,6 +29,7 @@ #include #include #include +#include #ifdef CONFIG_CPU_TX49XX #include #endif @@ -444,6 +445,20 @@ void __init txx9_wdt_init(unsigned long base) platform_device_register_simple("txx9wdt", -1, &res, 1); } +void txx9_wdt_now(unsigned long base) +{ + struct txx9_tmr_reg __iomem *tmrptr = + ioremap(base, sizeof(struct txx9_tmr_reg)); + /* disable watch dog timer */ + __raw_writel(TXx9_TMWTMR_WDIS | TXx9_TMWTMR_TWC, &tmrptr->wtmr); + __raw_writel(0, &tmrptr->tcr); + /* kick watchdog */ + __raw_writel(TXx9_TMWTMR_TWIE, &tmrptr->wtmr); + __raw_writel(1, &tmrptr->cpra); /* immediate */ + __raw_writel(TXx9_TMTCR_TCE | TXx9_TMTCR_CCDE | TXx9_TMTCR_TMODE_WDOG, + &tmrptr->tcr); +} + /* SPI support */ void __init txx9_spi_init(int busid, unsigned long base, int irq) { diff --git a/arch/mips/txx9/generic/setup_tx4927.c b/arch/mips/txx9/generic/setup_tx4927.c index 0840ef930e40..7189675f6a29 100644 --- a/arch/mips/txx9/generic/setup_tx4927.c +++ b/arch/mips/txx9/generic/setup_tx4927.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -23,6 +24,10 @@ static void __init tx4927_wdr_init(void) { + /* report watchdog reset status */ + if (____raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_WDRST) + pr_warning("Watchdog reset detected at 0x%lx\n", + read_c0_errorepc()); /* clear WatchDogReset (W1C) */ tx4927_ccfg_set(TX4927_CCFG_WDRST); /* do reset on watchdog */ @@ -34,6 +39,27 @@ void __init tx4927_wdt_init(void) txx9_wdt_init(TX4927_TMR_REG(2) & 0xfffffffffULL); } +static void tx4927_machine_restart(char *command) +{ + local_irq_disable(); + pr_emerg("Rebooting (with %s watchdog reset)...\n", + (____raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_WDREXEN) ? + "external" : "internal"); + /* clear watchdog status */ + tx4927_ccfg_set(TX4927_CCFG_WDRST); /* W1C */ + txx9_wdt_now(TX4927_TMR_REG(2) & 0xfffffffffULL); + while (!(____raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_WDRST)) + ; + mdelay(10); + if (____raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_WDREXEN) { + pr_emerg("Rebooting (with internal watchdog reset)...\n"); + /* External WDRST failed. Do internal watchdog reset */ + tx4927_ccfg_clear(TX4927_CCFG_WDREXEN); + } + /* fallback */ + (*_machine_halt)(); +} + static struct resource tx4927_sdram_resource[4]; void __init tx4927_setup(void) @@ -169,6 +195,8 @@ void __init tx4927_setup(void) txx9_gpio_init(TX4927_PIO_REG & 0xfffffffffULL, 0, TX4927_NUM_PIO); __raw_writel(0, &tx4927_pioptr->maskcpu); __raw_writel(0, &tx4927_pioptr->maskext); + + _machine_restart = tx4927_machine_restart; } void __init tx4927_time_init(unsigned int tmrnr) diff --git a/arch/mips/txx9/generic/setup_tx4938.c b/arch/mips/txx9/generic/setup_tx4938.c index 630a7aac61f6..4fbc85a8597f 100644 --- a/arch/mips/txx9/generic/setup_tx4938.c +++ b/arch/mips/txx9/generic/setup_tx4938.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -23,6 +24,10 @@ static void __init tx4938_wdr_init(void) { + /* report watchdog reset status */ + if (____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_WDRST) + pr_warning("Watchdog reset detected at 0x%lx\n", + read_c0_errorepc()); /* clear WatchDogReset (W1C) */ tx4938_ccfg_set(TX4938_CCFG_WDRST); /* do reset on watchdog */ @@ -34,6 +39,27 @@ void __init tx4938_wdt_init(void) txx9_wdt_init(TX4938_TMR_REG(2) & 0xfffffffffULL); } +static void tx4938_machine_restart(char *command) +{ + local_irq_disable(); + pr_emerg("Rebooting (with %s watchdog reset)...\n", + (____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_WDREXEN) ? + "external" : "internal"); + /* clear watchdog status */ + tx4938_ccfg_set(TX4938_CCFG_WDRST); /* W1C */ + txx9_wdt_now(TX4938_TMR_REG(2) & 0xfffffffffULL); + while (!(____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_WDRST)) + ; + mdelay(10); + if (____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_WDREXEN) { + pr_emerg("Rebooting (with internal watchdog reset)...\n"); + /* External WDRST failed. Do internal watchdog reset */ + tx4938_ccfg_clear(TX4938_CCFG_WDREXEN); + } + /* fallback */ + (*_machine_halt)(); +} + static struct resource tx4938_sdram_resource[4]; static struct resource tx4938_sram_resource; @@ -229,6 +255,8 @@ void __init tx4938_setup(void) TX4938_CLKCTR_ETH1CKD); } } + + _machine_restart = tx4938_machine_restart; } void __init tx4938_time_init(unsigned int tmrnr) diff --git a/include/asm-mips/txx9/generic.h b/include/asm-mips/txx9/generic.h index 1982c4437b1d..1e1a9f2d2379 100644 --- a/include/asm-mips/txx9/generic.h +++ b/include/asm-mips/txx9/generic.h @@ -45,6 +45,7 @@ extern int (*txx9_irq_dispatch)(int pending); char *prom_getcmdline(void); const char *prom_getenv(const char *name); void txx9_wdt_init(unsigned long base); +void txx9_wdt_now(unsigned long base); void txx9_spi_init(int busid, unsigned long base, int irq); void txx9_ethaddr_init(unsigned int id, unsigned char *ethaddr); void txx9_sio_init(unsigned long baseaddr, int irq, -- cgit v1.2.3 From ce8e74112b1b1215aa5bbe261ed751498ce65434 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Tue, 19 Aug 2008 22:55:16 +0900 Subject: MIPS: TXx9: Add board_be_init for TX4927/TX4938 Setup default board_be_handler for TX4927/TX4938. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/txx9/generic/setup_tx4927.c | 23 +++++++++++++++++++++++ arch/mips/txx9/generic/setup_tx4938.c | 23 +++++++++++++++++++++++ 2 files changed, 46 insertions(+) (limited to 'arch/mips/txx9') diff --git a/arch/mips/txx9/generic/setup_tx4927.c b/arch/mips/txx9/generic/setup_tx4927.c index 7189675f6a29..c4248cbbd84a 100644 --- a/arch/mips/txx9/generic/setup_tx4927.c +++ b/arch/mips/txx9/generic/setup_tx4927.c @@ -14,8 +14,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -60,6 +62,26 @@ static void tx4927_machine_restart(char *command) (*_machine_halt)(); } +void show_registers(struct pt_regs *regs); +static int tx4927_be_handler(struct pt_regs *regs, int is_fixup) +{ + int data = regs->cp0_cause & 4; + console_verbose(); + pr_err("%cBE exception at %#lx\n", data ? 'D' : 'I', regs->cp0_epc); + pr_err("ccfg:%llx, toea:%llx\n", + (unsigned long long)____raw_readq(&tx4927_ccfgptr->ccfg), + (unsigned long long)____raw_readq(&tx4927_ccfgptr->toea)); +#ifdef CONFIG_PCI + tx4927_report_pcic_status(); +#endif + show_registers(regs); + panic("BusError!"); +} +static void __init tx4927_be_init(void) +{ + board_be_handler = tx4927_be_handler; +} + static struct resource tx4927_sdram_resource[4]; void __init tx4927_setup(void) @@ -197,6 +219,7 @@ void __init tx4927_setup(void) __raw_writel(0, &tx4927_pioptr->maskext); _machine_restart = tx4927_machine_restart; + board_be_init = tx4927_be_init; } void __init tx4927_time_init(unsigned int tmrnr) diff --git a/arch/mips/txx9/generic/setup_tx4938.c b/arch/mips/txx9/generic/setup_tx4938.c index 4fbc85a8597f..0d8517ad3ad0 100644 --- a/arch/mips/txx9/generic/setup_tx4938.c +++ b/arch/mips/txx9/generic/setup_tx4938.c @@ -14,8 +14,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -60,6 +62,26 @@ static void tx4938_machine_restart(char *command) (*_machine_halt)(); } +void show_registers(struct pt_regs *regs); +static int tx4938_be_handler(struct pt_regs *regs, int is_fixup) +{ + int data = regs->cp0_cause & 4; + console_verbose(); + pr_err("%cBE exception at %#lx\n", data ? 'D' : 'I', regs->cp0_epc); + pr_err("ccfg:%llx, toea:%llx\n", + (unsigned long long)____raw_readq(&tx4938_ccfgptr->ccfg), + (unsigned long long)____raw_readq(&tx4938_ccfgptr->toea)); +#ifdef CONFIG_PCI + tx4927_report_pcic_status(); +#endif + show_registers(regs); + panic("BusError!"); +} +static void __init tx4938_be_init(void) +{ + board_be_handler = tx4938_be_handler; +} + static struct resource tx4938_sdram_resource[4]; static struct resource tx4938_sram_resource; @@ -257,6 +279,7 @@ void __init tx4938_setup(void) } _machine_restart = tx4938_machine_restart; + board_be_init = tx4938_be_init; } void __init tx4938_time_init(unsigned int tmrnr) -- cgit v1.2.3 From f6d9831bb11eb465f95fb1736b866d405d9c7cbf Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Mon, 1 Sep 2008 22:22:36 +0900 Subject: MIPS: TXx9: stop_unused_modules TXx9 SoCs have pin multiplex. Stop some controller modules which can not be used due to pin configurations. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/txx9/generic/setup_tx4927.c | 31 +++++++++++++++++++ arch/mips/txx9/generic/setup_tx4938.c | 56 +++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) (limited to 'arch/mips/txx9') diff --git a/arch/mips/txx9/generic/setup_tx4927.c b/arch/mips/txx9/generic/setup_tx4927.c index c4248cbbd84a..914e93c62639 100644 --- a/arch/mips/txx9/generic/setup_tx4927.c +++ b/arch/mips/txx9/generic/setup_tx4927.c @@ -252,3 +252,34 @@ void __init tx4927_mtd_init(int ch) return; /* disabled */ txx9_physmap_flash_init(ch, start, size, &pdata); } + +static void __init tx4927_stop_unused_modules(void) +{ + __u64 pcfg, rst = 0, ckd = 0; + char buf[128]; + + buf[0] = '\0'; + local_irq_disable(); + pcfg = ____raw_readq(&tx4927_ccfgptr->pcfg); + if (!(pcfg & TX4927_PCFG_SEL2)) { + rst |= TX4927_CLKCTR_ACLRST; + ckd |= TX4927_CLKCTR_ACLCKD; + strcat(buf, " ACLC"); + } + if (rst | ckd) { + txx9_set64(&tx4927_ccfgptr->clkctr, rst); + txx9_set64(&tx4927_ccfgptr->clkctr, ckd); + } + local_irq_enable(); + if (buf[0]) + pr_info("%s: stop%s\n", txx9_pcode_str, buf); +} + +static int __init tx4927_late_init(void) +{ + if (txx9_pcode != 0x4927) + return -ENODEV; + tx4927_stop_unused_modules(); + return 0; +} +late_initcall(tx4927_late_init); diff --git a/arch/mips/txx9/generic/setup_tx4938.c b/arch/mips/txx9/generic/setup_tx4938.c index 0d8517ad3ad0..af724e53ef91 100644 --- a/arch/mips/txx9/generic/setup_tx4938.c +++ b/arch/mips/txx9/generic/setup_tx4938.c @@ -334,3 +334,59 @@ void __init tx4938_mtd_init(int ch) return; /* disabled */ txx9_physmap_flash_init(ch, start, size, &pdata); } + +static void __init tx4938_stop_unused_modules(void) +{ + __u64 pcfg, rst = 0, ckd = 0; + char buf[128]; + + buf[0] = '\0'; + local_irq_disable(); + pcfg = ____raw_readq(&tx4938_ccfgptr->pcfg); + switch (txx9_pcode) { + case 0x4937: + if (!(pcfg & TX4938_PCFG_SEL2)) { + rst |= TX4938_CLKCTR_ACLRST; + ckd |= TX4938_CLKCTR_ACLCKD; + strcat(buf, " ACLC"); + } + break; + case 0x4938: + if (!(pcfg & TX4938_PCFG_SEL2) || + (pcfg & TX4938_PCFG_ETH0_SEL)) { + rst |= TX4938_CLKCTR_ACLRST; + ckd |= TX4938_CLKCTR_ACLCKD; + strcat(buf, " ACLC"); + } + if ((pcfg & + (TX4938_PCFG_ATA_SEL | TX4938_PCFG_ISA_SEL | + TX4938_PCFG_NDF_SEL)) + != TX4938_PCFG_NDF_SEL) { + rst |= TX4938_CLKCTR_NDFRST; + ckd |= TX4938_CLKCTR_NDFCKD; + strcat(buf, " NDFMC"); + } + if (!(pcfg & TX4938_PCFG_SPI_SEL)) { + rst |= TX4938_CLKCTR_SPIRST; + ckd |= TX4938_CLKCTR_SPICKD; + strcat(buf, " SPI"); + } + break; + } + if (rst | ckd) { + txx9_set64(&tx4938_ccfgptr->clkctr, rst); + txx9_set64(&tx4938_ccfgptr->clkctr, ckd); + } + local_irq_enable(); + if (buf[0]) + pr_info("%s: stop%s\n", txx9_pcode_str, buf); +} + +static int __init tx4938_late_init(void) +{ + if (txx9_pcode != 0x4937 && txx9_pcode != 0x4938) + return -ENODEV; + tx4938_stop_unused_modules(); + return 0; +} +late_initcall(tx4938_late_init); -- cgit v1.2.3 From 21e77df215e58523a755b5dd006cb17610616f20 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Mon, 1 Sep 2008 22:22:37 +0900 Subject: MIPS: TXx9: Microoptimize interrupt handlers The IOC interrupt status register on RBTX49XX only have 8 bits. Use 8-bit version of __fls() to optimize interrupt handlers. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/txx9/rbtx4927/irq.c | 6 +++--- arch/mips/txx9/rbtx4938/irq.c | 8 ++++---- include/asm-mips/txx9/generic.h | 18 ++++++++++++++++++ 3 files changed, 25 insertions(+), 7 deletions(-) (limited to 'arch/mips/txx9') diff --git a/arch/mips/txx9/rbtx4927/irq.c b/arch/mips/txx9/rbtx4927/irq.c index 22076e3f03a8..9c14ebb26cb4 100644 --- a/arch/mips/txx9/rbtx4927/irq.c +++ b/arch/mips/txx9/rbtx4927/irq.c @@ -133,9 +133,9 @@ static int toshiba_rbtx4927_irq_nested(int sw_irq) u8 level3; level3 = readb(rbtx4927_imstat_addr) & 0x1f; - if (level3) - sw_irq = RBTX4927_IRQ_IOC + fls(level3) - 1; - return sw_irq; + if (unlikely(!level3)) + return -1; + return RBTX4927_IRQ_IOC + __fls8(level3); } static void __init toshiba_rbtx4927_irq_ioc_init(void) diff --git a/arch/mips/txx9/rbtx4938/irq.c b/arch/mips/txx9/rbtx4938/irq.c index ca2f8306ce93..7d21befb8932 100644 --- a/arch/mips/txx9/rbtx4938/irq.c +++ b/arch/mips/txx9/rbtx4938/irq.c @@ -85,10 +85,10 @@ static int toshiba_rbtx4938_irq_nested(int sw_irq) u8 level3; level3 = readb(rbtx4938_imstat_addr); - if (level3) - /* must use fls so onboard ATA has priority */ - sw_irq = RBTX4938_IRQ_IOC + fls(level3) - 1; - return sw_irq; + if (unlikely(!level3)) + return -1; + /* must use fls so onboard ATA has priority */ + return RBTX4938_IRQ_IOC + __fls8(level3); } static void __init diff --git a/include/asm-mips/txx9/generic.h b/include/asm-mips/txx9/generic.h index 1e1a9f2d2379..dc85515eac13 100644 --- a/include/asm-mips/txx9/generic.h +++ b/include/asm-mips/txx9/generic.h @@ -64,4 +64,22 @@ struct physmap_flash_data; void txx9_physmap_flash_init(int no, unsigned long addr, unsigned long size, const struct physmap_flash_data *pdata); +/* 8 bit version of __fls(): find first bit set (returns 0..7) */ +static inline unsigned int __fls8(unsigned char x) +{ + int r = 7; + + if (!(x & 0xf0)) { + r -= 4; + x <<= 4; + } + if (!(x & 0xc0)) { + r -= 2; + x <<= 2; + } + if (!(x & 0x80)) + r -= 1; + return r; +} + #endif /* __ASM_TXX9_GENERIC_H */ -- cgit v1.2.3 From ae027ead87b13cff99b4f48da7696aa4fe75393b Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Mon, 1 Sep 2008 22:22:38 +0900 Subject: MIPS: TXx9: IOC LED support Add leds-gpio platform device for controlling LEDs connected to IOC on RBTX49XX and JMR3927 board. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/txx9/generic/setup.c | 111 +++++++++++++++++++++++++++++++++++++++ arch/mips/txx9/jmr3927/setup.c | 5 ++ arch/mips/txx9/rbtx4927/setup.c | 1 + arch/mips/txx9/rbtx4938/setup.c | 1 + include/asm-mips/txx9/generic.h | 4 ++ include/asm-mips/txx9/rbtx4927.h | 1 + 6 files changed, 123 insertions(+) (limited to 'arch/mips/txx9') diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c index 118d716f7832..1ea06553a1e1 100644 --- a/arch/mips/txx9/generic/setup.c +++ b/arch/mips/txx9/generic/setup.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -649,3 +650,113 @@ void __init txx9_physmap_flash_init(int no, unsigned long addr, platform_device_put(pdev); #endif } + +#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) +static DEFINE_SPINLOCK(txx9_iocled_lock); + +#define TXX9_IOCLED_MAXLEDS 8 + +struct txx9_iocled_data { + struct gpio_chip chip; + u8 cur_val; + void __iomem *mmioaddr; + struct gpio_led_platform_data pdata; + struct gpio_led leds[TXX9_IOCLED_MAXLEDS]; + char names[TXX9_IOCLED_MAXLEDS][32]; +}; + +static int txx9_iocled_get(struct gpio_chip *chip, unsigned int offset) +{ + struct txx9_iocled_data *data = + container_of(chip, struct txx9_iocled_data, chip); + return data->cur_val & (1 << offset); +} + +static void txx9_iocled_set(struct gpio_chip *chip, unsigned int offset, + int value) +{ + struct txx9_iocled_data *data = + container_of(chip, struct txx9_iocled_data, chip); + unsigned long flags; + spin_lock_irqsave(&txx9_iocled_lock, flags); + if (value) + data->cur_val |= 1 << offset; + else + data->cur_val &= ~(1 << offset); + writeb(data->cur_val, data->mmioaddr); + mmiowb(); + spin_unlock_irqrestore(&txx9_iocled_lock, flags); +} + +static int txx9_iocled_dir_in(struct gpio_chip *chip, unsigned int offset) +{ + return 0; +} + +static int txx9_iocled_dir_out(struct gpio_chip *chip, unsigned int offset, + int value) +{ + txx9_iocled_set(chip, offset, value); + return 0; +} + +void __init txx9_iocled_init(unsigned long baseaddr, + int basenum, unsigned int num, int lowactive, + const char *color, char **deftriggers) +{ + struct txx9_iocled_data *iocled; + struct platform_device *pdev; + int i; + static char *default_triggers[] __initdata = { + "heartbeat", + "ide-disk", + "nand-disk", + NULL, + }; + + if (!deftriggers) + deftriggers = default_triggers; + iocled = kzalloc(sizeof(*iocled), GFP_KERNEL); + if (!iocled) + return; + iocled->mmioaddr = ioremap(baseaddr, 1); + if (!iocled->mmioaddr) + return; + iocled->chip.get = txx9_iocled_get; + iocled->chip.set = txx9_iocled_set; + iocled->chip.direction_input = txx9_iocled_dir_in; + iocled->chip.direction_output = txx9_iocled_dir_out; + iocled->chip.label = "iocled"; + iocled->chip.base = basenum; + iocled->chip.ngpio = num; + if (gpiochip_add(&iocled->chip)) + return; + if (basenum < 0) + basenum = iocled->chip.base; + + pdev = platform_device_alloc("leds-gpio", basenum); + if (!pdev) + return; + iocled->pdata.num_leds = num; + iocled->pdata.leds = iocled->leds; + for (i = 0; i < num; i++) { + struct gpio_led *led = &iocled->leds[i]; + snprintf(iocled->names[i], sizeof(iocled->names[i]), + "iocled:%s:%u", color, i); + led->name = iocled->names[i]; + led->gpio = basenum + i; + led->active_low = lowactive; + if (deftriggers && *deftriggers) + led->default_trigger = *deftriggers++; + } + pdev->dev.platform_data = &iocled->pdata; + if (platform_device_add(pdev)) + platform_device_put(pdev); +} +#else /* CONFIG_LEDS_GPIO */ +void __init txx9_iocled_init(unsigned long baseaddr, + int basenum, unsigned int num, int lowactive, + const char *color, char **deftriggers) +{ +} +#endif /* CONFIG_LEDS_GPIO */ diff --git a/arch/mips/txx9/jmr3927/setup.c b/arch/mips/txx9/jmr3927/setup.c index 0f3843c92cf7..25e50a7be387 100644 --- a/arch/mips/txx9/jmr3927/setup.c +++ b/arch/mips/txx9/jmr3927/setup.c @@ -200,10 +200,15 @@ static void __init jmr3927_mtd_init(void) static void __init jmr3927_device_init(void) { + unsigned long iocled_base = JMR3927_IOC_LED_ADDR - IO_BASE; +#ifdef __LITTLE_ENDIAN + iocled_base |= 1; +#endif __swizzle_addr_b = jmr3927_swizzle_addr_b; jmr3927_rtc_init(); tx3927_wdt_init(); jmr3927_mtd_init(); + txx9_iocled_init(iocled_base, -1, 8, 1, "green", NULL); } struct txx9_board_vec jmr3927_vec __initdata = { diff --git a/arch/mips/txx9/rbtx4927/setup.c b/arch/mips/txx9/rbtx4927/setup.c index abe32c1a79dc..4a74423b2ba8 100644 --- a/arch/mips/txx9/rbtx4927/setup.c +++ b/arch/mips/txx9/rbtx4927/setup.c @@ -321,6 +321,7 @@ static void __init rbtx4927_device_init(void) rbtx4927_ne_init(); tx4927_wdt_init(); rbtx4927_mtd_init(); + txx9_iocled_init(RBTX4927_LED_ADDR - IO_BASE, -1, 3, 1, "green", NULL); } struct txx9_board_vec rbtx4927_vec __initdata = { diff --git a/arch/mips/txx9/rbtx4938/setup.c b/arch/mips/txx9/rbtx4938/setup.c index ec6e81258f73..e077cc4d3a59 100644 --- a/arch/mips/txx9/rbtx4938/setup.c +++ b/arch/mips/txx9/rbtx4938/setup.c @@ -352,6 +352,7 @@ static void __init rbtx4938_device_init(void) rbtx4938_ne_init(); tx4938_wdt_init(); rbtx4938_mtd_init(); + txx9_iocled_init(RBTX4938_LED_ADDR - IO_BASE, -1, 8, 1, "green", NULL); } struct txx9_board_vec rbtx4938_vec __initdata = { diff --git a/include/asm-mips/txx9/generic.h b/include/asm-mips/txx9/generic.h index dc85515eac13..4316a3e57678 100644 --- a/include/asm-mips/txx9/generic.h +++ b/include/asm-mips/txx9/generic.h @@ -82,4 +82,8 @@ static inline unsigned int __fls8(unsigned char x) return r; } +void txx9_iocled_init(unsigned long baseaddr, + int basenum, unsigned int num, int lowactive, + const char *color, char **deftriggers); + #endif /* __ASM_TXX9_GENERIC_H */ diff --git a/include/asm-mips/txx9/rbtx4927.h b/include/asm-mips/txx9/rbtx4927.h index c6015463432e..b2adab3d1acc 100644 --- a/include/asm-mips/txx9/rbtx4927.h +++ b/include/asm-mips/txx9/rbtx4927.h @@ -34,6 +34,7 @@ #define RBTX4927_PCIIO 0x16000000 #define RBTX4927_PCIIO_SIZE 0x01000000 +#define RBTX4927_LED_ADDR (IO_BASE + TXX9_CE(2) + 0x00001000) #define RBTX4927_IMASK_ADDR (IO_BASE + TXX9_CE(2) + 0x00002000) #define RBTX4927_IMSTAT_ADDR (IO_BASE + TXX9_CE(2) + 0x00002006) #define RBTX4927_SOFTINT_ADDR (IO_BASE + TXX9_CE(2) + 0x00003000) -- cgit v1.2.3 From 0dcdbe6add26719e956299eb519542f7d2f7d0a8 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Mon, 1 Sep 2008 22:22:39 +0900 Subject: MIPS: TXx9: Add TX4939 SoC support Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle create mode 100644 arch/mips/pci/pci-tx4939.c create mode 100644 arch/mips/txx9/generic/irq_tx4939.c create mode 100644 arch/mips/txx9/generic/setup_tx4939.c create mode 100644 include/asm-mips/txx9/tx4939.h --- arch/mips/pci/Makefile | 1 + arch/mips/pci/pci-tx4939.c | 109 +++++++ arch/mips/txx9/Kconfig | 7 + arch/mips/txx9/generic/Makefile | 1 + arch/mips/txx9/generic/irq_tx4939.c | 215 ++++++++++++++ arch/mips/txx9/generic/setup_tx4939.c | 460 ++++++++++++++++++++++++++++ include/asm-mips/txx9/tx4939.h | 544 ++++++++++++++++++++++++++++++++++ 7 files changed, 1337 insertions(+) create mode 100644 arch/mips/pci/pci-tx4939.c create mode 100644 arch/mips/txx9/generic/irq_tx4939.c create mode 100644 arch/mips/txx9/generic/setup_tx4939.c create mode 100644 include/asm-mips/txx9/tx4939.h (limited to 'arch/mips/txx9') diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index c8c32f417b6c..b1886244cedf 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile @@ -45,6 +45,7 @@ obj-$(CONFIG_TANBAC_TB0287) += fixup-tb0287.o obj-$(CONFIG_TOSHIBA_JMR3927) += fixup-jmr3927.o obj-$(CONFIG_SOC_TX4927) += pci-tx4927.o obj-$(CONFIG_SOC_TX4938) += pci-tx4938.o +obj-$(CONFIG_SOC_TX4939) += pci-tx4939.o obj-$(CONFIG_TOSHIBA_RBTX4927) += fixup-rbtx4927.o obj-$(CONFIG_TOSHIBA_RBTX4938) += fixup-rbtx4938.o obj-$(CONFIG_VICTOR_MPC30X) += fixup-mpc30x.o diff --git a/arch/mips/pci/pci-tx4939.c b/arch/mips/pci/pci-tx4939.c new file mode 100644 index 000000000000..5fecf1cdc325 --- /dev/null +++ b/arch/mips/pci/pci-tx4939.c @@ -0,0 +1,109 @@ +/* + * linux/arch/mips/pci/pci-tx4939.c + * + * Based on linux/arch/mips/txx9/rbtx4939/setup.c, + * and RBTX49xx patch from CELF patch archive. + * + * Copyright 2001, 2003-2005 MontaVista Software Inc. + * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org) + * (C) Copyright TOSHIBA CORPORATION 2000-2001, 2004-2007 + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include +#include +#include + +int __init tx4939_report_pciclk(void) +{ + int pciclk = 0; + + pr_info("PCIC --%s PCICLK:", + (__raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_PCI66) ? + " PCI66" : ""); + if (__raw_readq(&tx4939_ccfgptr->pcfg) & TX4939_PCFG_PCICLKEN_ALL) { + pciclk = txx9_master_clock * 20 / 6; + if (!(__raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_PCI66)) + pciclk /= 2; + printk(KERN_CONT "Internal(%u.%uMHz)", + (pciclk + 50000) / 1000000, + ((pciclk + 50000) / 100000) % 10); + } else { + printk(KERN_CONT "External"); + pciclk = -1; + } + printk(KERN_CONT "\n"); + return pciclk; +} + +void __init tx4939_report_pci1clk(void) +{ + unsigned int pciclk = txx9_master_clock * 20 / 6; + + pr_info("PCIC1 -- PCICLK:%u.%uMHz\n", + (pciclk + 50000) / 1000000, + ((pciclk + 50000) / 100000) % 10); +} + +int __init tx4939_pcic1_map_irq(const struct pci_dev *dev, u8 slot) +{ + if (get_tx4927_pcicptr(dev->bus->sysdata) == tx4939_pcic1ptr) { + switch (slot) { + case TX4927_PCIC_IDSEL_AD_TO_SLOT(31): + if (__raw_readq(&tx4939_ccfgptr->pcfg) & + TX4939_PCFG_ET0MODE) + return TXX9_IRQ_BASE + TX4939_IR_ETH(0); + break; + case TX4927_PCIC_IDSEL_AD_TO_SLOT(30): + if (__raw_readq(&tx4939_ccfgptr->pcfg) & + TX4939_PCFG_ET1MODE) + return TXX9_IRQ_BASE + TX4939_IR_ETH(1); + break; + } + return 0; + } + return -1; +} + +int __init tx4939_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +{ + int irq = tx4939_pcic1_map_irq(dev, slot); + + if (irq >= 0) + return irq; + irq = pin; + /* IRQ rotation */ + irq--; /* 0-3 */ + irq = (irq + 33 - slot) % 4; + irq++; /* 1-4 */ + + switch (irq) { + case 1: + irq = TXX9_IRQ_BASE + TX4939_IR_INTA; + break; + case 2: + irq = TXX9_IRQ_BASE + TX4939_IR_INTB; + break; + case 3: + irq = TXX9_IRQ_BASE + TX4939_IR_INTC; + break; + case 4: + irq = TXX9_IRQ_BASE + TX4939_IR_INTD; + break; + } + return irq; +} + +void __init tx4939_setup_pcierr_irq(void) +{ + if (request_irq(TXX9_IRQ_BASE + TX4939_IR_PCIERR, + tx4927_pcierr_interrupt, + IRQF_DISABLED, "PCI error", + (void *)TX4939_PCIC_REG)) + pr_warning("Failed to request irq for PCIERR\n"); +} diff --git a/arch/mips/txx9/Kconfig b/arch/mips/txx9/Kconfig index aade3348af29..58691a1fe779 100644 --- a/arch/mips/txx9/Kconfig +++ b/arch/mips/txx9/Kconfig @@ -71,6 +71,13 @@ config SOC_TX4938 select PCI_TX4927 select GPIO_TXX9 +config SOC_TX4939 + bool + select CEVT_TXX9 + select HAS_TXX9_SERIAL + select HW_HAS_PCI + select PCI_TX4927 + config TOSHIBA_FPCIB0 bool "FPCIB0 Backplane Support" depends on PCI && MACH_TXX9 diff --git a/arch/mips/txx9/generic/Makefile b/arch/mips/txx9/generic/Makefile index 986852cc774c..0030d23bef5b 100644 --- a/arch/mips/txx9/generic/Makefile +++ b/arch/mips/txx9/generic/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_PCI) += pci.o obj-$(CONFIG_SOC_TX3927) += setup_tx3927.o irq_tx3927.o obj-$(CONFIG_SOC_TX4927) += mem_tx4927.o setup_tx4927.o irq_tx4927.o obj-$(CONFIG_SOC_TX4938) += mem_tx4927.o setup_tx4938.o irq_tx4938.o +obj-$(CONFIG_SOC_TX4939) += setup_tx4939.o irq_tx4939.o obj-$(CONFIG_TOSHIBA_FPCIB0) += smsc_fdc37m81x.o obj-$(CONFIG_SPI) += spi_eeprom.o diff --git a/arch/mips/txx9/generic/irq_tx4939.c b/arch/mips/txx9/generic/irq_tx4939.c new file mode 100644 index 000000000000..013213a8706b --- /dev/null +++ b/arch/mips/txx9/generic/irq_tx4939.c @@ -0,0 +1,215 @@ +/* + * TX4939 irq routines + * Based on linux/arch/mips/kernel/irq_txx9.c, + * and RBTX49xx patch from CELF patch archive. + * + * Copyright 2001, 2003-2005 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ahennessy@mvista.com + * source@mvista.com + * Copyright (C) 2000-2001,2005-2007 Toshiba Corporation + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +/* + * TX4939 defines 64 IRQs. + * Similer to irq_txx9.c but different register layouts. + */ +#include +#include +#include +#include +#include +#include + +/* IRCER : Int. Control Enable */ +#define TXx9_IRCER_ICE 0x00000001 + +/* IRCR : Int. Control */ +#define TXx9_IRCR_LOW 0x00000000 +#define TXx9_IRCR_HIGH 0x00000001 +#define TXx9_IRCR_DOWN 0x00000002 +#define TXx9_IRCR_UP 0x00000003 +#define TXx9_IRCR_EDGE(cr) ((cr) & 0x00000002) + +/* IRSCR : Int. Status Control */ +#define TXx9_IRSCR_EIClrE 0x00000100 +#define TXx9_IRSCR_EIClr_MASK 0x0000000f + +/* IRCSR : Int. Current Status */ +#define TXx9_IRCSR_IF 0x00010000 + +#define irc_dlevel 0 +#define irc_elevel 1 + +static struct { + unsigned char level; + unsigned char mode; +} tx4939irq[TX4939_NUM_IR] __read_mostly; + +static void tx4939_irq_unmask(unsigned int irq) +{ + unsigned int irq_nr = irq - TXX9_IRQ_BASE; + u32 __iomem *lvlp; + int ofs; + if (irq_nr < 32) { + irq_nr--; + lvlp = &tx4939_ircptr->lvl[(irq_nr % 16) / 2].r; + } else { + irq_nr -= 32; + lvlp = &tx4939_ircptr->lvl[8 + (irq_nr % 16) / 2].r; + } + ofs = (irq_nr & 16) + (irq_nr & 1) * 8; + __raw_writel((__raw_readl(lvlp) & ~(0xff << ofs)) + | (tx4939irq[irq_nr].level << ofs), + lvlp); +} + +static inline void tx4939_irq_mask(unsigned int irq) +{ + unsigned int irq_nr = irq - TXX9_IRQ_BASE; + u32 __iomem *lvlp; + int ofs; + if (irq_nr < 32) { + irq_nr--; + lvlp = &tx4939_ircptr->lvl[(irq_nr % 16) / 2].r; + } else { + irq_nr -= 32; + lvlp = &tx4939_ircptr->lvl[8 + (irq_nr % 16) / 2].r; + } + ofs = (irq_nr & 16) + (irq_nr & 1) * 8; + __raw_writel((__raw_readl(lvlp) & ~(0xff << ofs)) + | (irc_dlevel << ofs), + lvlp); + mmiowb(); +} + +static void tx4939_irq_mask_ack(unsigned int irq) +{ + unsigned int irq_nr = irq - TXX9_IRQ_BASE; + + tx4939_irq_mask(irq); + if (TXx9_IRCR_EDGE(tx4939irq[irq_nr].mode)) { + irq_nr--; + /* clear edge detection */ + __raw_writel((TXx9_IRSCR_EIClrE | (irq_nr & 0xf)) + << (irq_nr & 0x10), + &tx4939_ircptr->edc.r); + } +} + +static int tx4939_irq_set_type(unsigned int irq, unsigned int flow_type) +{ + unsigned int irq_nr = irq - TXX9_IRQ_BASE; + u32 cr; + u32 __iomem *crp; + int ofs; + int mode; + + if (flow_type & IRQF_TRIGGER_PROBE) + return 0; + switch (flow_type & IRQF_TRIGGER_MASK) { + case IRQF_TRIGGER_RISING: + mode = TXx9_IRCR_UP; + break; + case IRQF_TRIGGER_FALLING: + mode = TXx9_IRCR_DOWN; + break; + case IRQF_TRIGGER_HIGH: + mode = TXx9_IRCR_HIGH; + break; + case IRQF_TRIGGER_LOW: + mode = TXx9_IRCR_LOW; + break; + default: + return -EINVAL; + } + if (irq_nr < 32) { + irq_nr--; + crp = &tx4939_ircptr->dm[(irq_nr & 8) >> 3].r; + } else { + irq_nr -= 32; + crp = &tx4939_ircptr->dm2[((irq_nr & 8) >> 3)].r; + } + ofs = (((irq_nr & 16) >> 1) | (irq_nr & (8 - 1))) * 2; + cr = __raw_readl(crp); + cr &= ~(0x3 << ofs); + cr |= (mode & 0x3) << ofs; + __raw_writel(cr, crp); + tx4939irq[irq_nr].mode = mode; + return 0; +} + +static struct irq_chip tx4939_irq_chip = { + .name = "TX4939", + .ack = tx4939_irq_mask_ack, + .mask = tx4939_irq_mask, + .mask_ack = tx4939_irq_mask_ack, + .unmask = tx4939_irq_unmask, + .set_type = tx4939_irq_set_type, +}; + +static int tx4939_irq_set_pri(int irc_irq, int new_pri) +{ + int old_pri; + + if ((unsigned int)irc_irq >= TX4939_NUM_IR) + return 0; + old_pri = tx4939irq[irc_irq].level; + tx4939irq[irc_irq].level = new_pri; + return old_pri; +} + +void __init tx4939_irq_init(void) +{ + int i; + + mips_cpu_irq_init(); + /* disable interrupt control */ + __raw_writel(0, &tx4939_ircptr->den.r); + __raw_writel(0, &tx4939_ircptr->maskint.r); + __raw_writel(0, &tx4939_ircptr->maskext.r); + /* irq_base + 0 is not used */ + for (i = 1; i < TX4939_NUM_IR; i++) { + tx4939irq[i].level = 4; /* middle level */ + tx4939irq[i].mode = TXx9_IRCR_LOW; + set_irq_chip_and_handler(TXX9_IRQ_BASE + i, + &tx4939_irq_chip, handle_level_irq); + } + + /* mask all IRC interrupts */ + __raw_writel(0, &tx4939_ircptr->msk.r); + for (i = 0; i < 16; i++) + __raw_writel(0, &tx4939_ircptr->lvl[i].r); + /* setup IRC interrupt mode (Low Active) */ + for (i = 0; i < 2; i++) + __raw_writel(0, &tx4939_ircptr->dm[i].r); + for (i = 0; i < 2; i++) + __raw_writel(0, &tx4939_ircptr->dm2[i].r); + /* enable interrupt control */ + __raw_writel(TXx9_IRCER_ICE, &tx4939_ircptr->den.r); + __raw_writel(irc_elevel, &tx4939_ircptr->msk.r); + + set_irq_chained_handler(MIPS_CPU_IRQ_BASE + TX4939_IRC_INT, + handle_simple_irq); + + /* raise priority for errors, timers, sio */ + tx4939_irq_set_pri(TX4939_IR_WTOERR, 7); + tx4939_irq_set_pri(TX4939_IR_PCIERR, 7); + tx4939_irq_set_pri(TX4939_IR_PCIPME, 7); + for (i = 0; i < TX4939_NUM_IR_TMR; i++) + tx4939_irq_set_pri(TX4939_IR_TMR(i), 6); + for (i = 0; i < TX4939_NUM_IR_SIO; i++) + tx4939_irq_set_pri(TX4939_IR_SIO(i), 5); +} + +int tx4939_irq(void) +{ + u32 csr = __raw_readl(&tx4939_ircptr->cs.r); + + if (likely(!(csr & TXx9_IRCSR_IF))) + return TXX9_IRQ_BASE + (csr & (TX4939_NUM_IR - 1)); + return -1; +} diff --git a/arch/mips/txx9/generic/setup_tx4939.c b/arch/mips/txx9/generic/setup_tx4939.c new file mode 100644 index 000000000000..f14a497077da --- /dev/null +++ b/arch/mips/txx9/generic/setup_tx4939.c @@ -0,0 +1,460 @@ +/* + * TX4939 setup routines + * Based on linux/arch/mips/txx9/generic/setup_tx4938.c, + * and RBTX49xx patch from CELF patch archive. + * + * 2003-2005 (c) MontaVista Software, Inc. + * (C) Copyright TOSHIBA CORPORATION 2000-2001, 2004-2007 + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void __init tx4939_wdr_init(void) +{ + /* report watchdog reset status */ + if (____raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_WDRST) + pr_warning("Watchdog reset detected at 0x%lx\n", + read_c0_errorepc()); + /* clear WatchDogReset (W1C) */ + tx4939_ccfg_set(TX4939_CCFG_WDRST); + /* do reset on watchdog */ + tx4939_ccfg_set(TX4939_CCFG_WR); +} + +void __init tx4939_wdt_init(void) +{ + txx9_wdt_init(TX4939_TMR_REG(2) & 0xfffffffffULL); +} + +static void tx4939_machine_restart(char *command) +{ + local_irq_disable(); + pr_emerg("Rebooting (with %s watchdog reset)...\n", + (____raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_WDREXEN) ? + "external" : "internal"); + /* clear watchdog status */ + tx4939_ccfg_set(TX4939_CCFG_WDRST); /* W1C */ + txx9_wdt_now(TX4939_TMR_REG(2) & 0xfffffffffULL); + while (!(____raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_WDRST)) + ; + mdelay(10); + if (____raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_WDREXEN) { + pr_emerg("Rebooting (with internal watchdog reset)...\n"); + /* External WDRST failed. Do internal watchdog reset */ + tx4939_ccfg_clear(TX4939_CCFG_WDREXEN); + } + /* fallback */ + (*_machine_halt)(); +} + +void show_registers(struct pt_regs *regs); +static int tx4939_be_handler(struct pt_regs *regs, int is_fixup) +{ + int data = regs->cp0_cause & 4; + console_verbose(); + pr_err("%cBE exception at %#lx\n", + data ? 'D' : 'I', regs->cp0_epc); + pr_err("ccfg:%llx, toea:%llx\n", + (unsigned long long)____raw_readq(&tx4939_ccfgptr->ccfg), + (unsigned long long)____raw_readq(&tx4939_ccfgptr->toea)); +#ifdef CONFIG_PCI + tx4927_report_pcic_status(); +#endif + show_registers(regs); + panic("BusError!"); +} +static void __init tx4939_be_init(void) +{ + board_be_handler = tx4939_be_handler; +} + +static struct resource tx4939_sdram_resource[4]; +static struct resource tx4939_sram_resource; +#define TX4939_SRAM_SIZE 0x800 + +void __init tx4939_add_memory_regions(void) +{ + int i; + unsigned long start, size; + u64 win; + + for (i = 0; i < 4; i++) { + if (!((__u32)____raw_readq(&tx4939_ddrcptr->winen) & (1 << i))) + continue; + win = ____raw_readq(&tx4939_ddrcptr->win[i]); + start = (unsigned long)(win >> 48); + size = (((unsigned long)(win >> 32) & 0xffff) + 1) - start; + add_memory_region(start << 20, size << 20, BOOT_MEM_RAM); + } +} + +void __init tx4939_setup(void) +{ + int i; + __u32 divmode; + __u64 pcfg; + int cpuclk = 0; + + txx9_reg_res_init(TX4939_REV_PCODE(), TX4939_REG_BASE, + TX4939_REG_SIZE); + set_c0_config(TX49_CONF_CWFON); + + /* SDRAMC,EBUSC are configured by PROM */ + for (i = 0; i < 4; i++) { + if (!(TX4939_EBUSC_CR(i) & 0x8)) + continue; /* disabled */ + txx9_ce_res[i].start = (unsigned long)TX4939_EBUSC_BA(i); + txx9_ce_res[i].end = + txx9_ce_res[i].start + TX4939_EBUSC_SIZE(i) - 1; + request_resource(&iomem_resource, &txx9_ce_res[i]); + } + + /* clocks */ + if (txx9_master_clock) { + /* calculate cpu_clock from master_clock */ + divmode = (__u32)____raw_readq(&tx4939_ccfgptr->ccfg) & + TX4939_CCFG_MULCLK_MASK; + cpuclk = txx9_master_clock * 20 / 2; + switch (divmode) { + case TX4939_CCFG_MULCLK_8: + cpuclk = cpuclk / 3 * 4 /* / 6 * 8 */; break; + case TX4939_CCFG_MULCLK_9: + cpuclk = cpuclk / 2 * 3 /* / 6 * 9 */; break; + case TX4939_CCFG_MULCLK_10: + cpuclk = cpuclk / 3 * 5 /* / 6 * 10 */; break; + case TX4939_CCFG_MULCLK_11: + cpuclk = cpuclk / 6 * 11; break; + case TX4939_CCFG_MULCLK_12: + cpuclk = cpuclk * 2 /* / 6 * 12 */; break; + case TX4939_CCFG_MULCLK_13: + cpuclk = cpuclk / 6 * 13; break; + case TX4939_CCFG_MULCLK_14: + cpuclk = cpuclk / 3 * 7 /* / 6 * 14 */; break; + case TX4939_CCFG_MULCLK_15: + cpuclk = cpuclk / 2 * 5 /* / 6 * 15 */; break; + } + txx9_cpu_clock = cpuclk; + } else { + if (txx9_cpu_clock == 0) + txx9_cpu_clock = 400000000; /* 400MHz */ + /* calculate master_clock from cpu_clock */ + cpuclk = txx9_cpu_clock; + divmode = (__u32)____raw_readq(&tx4939_ccfgptr->ccfg) & + TX4939_CCFG_MULCLK_MASK; + switch (divmode) { + case TX4939_CCFG_MULCLK_8: + txx9_master_clock = cpuclk * 6 / 8; break; + case TX4939_CCFG_MULCLK_9: + txx9_master_clock = cpuclk * 6 / 9; break; + case TX4939_CCFG_MULCLK_10: + txx9_master_clock = cpuclk * 6 / 10; break; + case TX4939_CCFG_MULCLK_11: + txx9_master_clock = cpuclk * 6 / 11; break; + case TX4939_CCFG_MULCLK_12: + txx9_master_clock = cpuclk * 6 / 12; break; + case TX4939_CCFG_MULCLK_13: + txx9_master_clock = cpuclk * 6 / 13; break; + case TX4939_CCFG_MULCLK_14: + txx9_master_clock = cpuclk * 6 / 14; break; + case TX4939_CCFG_MULCLK_15: + txx9_master_clock = cpuclk * 6 / 15; break; + } + txx9_master_clock /= 10; /* * 2 / 20 */ + } + /* calculate gbus_clock from cpu_clock */ + divmode = (__u32)____raw_readq(&tx4939_ccfgptr->ccfg) & + TX4939_CCFG_YDIVMODE_MASK; + txx9_gbus_clock = txx9_cpu_clock; + switch (divmode) { + case TX4939_CCFG_YDIVMODE_2: + txx9_gbus_clock /= 2; break; + case TX4939_CCFG_YDIVMODE_3: + txx9_gbus_clock /= 3; break; + case TX4939_CCFG_YDIVMODE_5: + txx9_gbus_clock /= 5; break; + case TX4939_CCFG_YDIVMODE_6: + txx9_gbus_clock /= 6; break; + } + /* change default value to udelay/mdelay take reasonable time */ + loops_per_jiffy = txx9_cpu_clock / HZ / 2; + + /* CCFG */ + tx4939_wdr_init(); + /* clear BusErrorOnWrite flag (W1C) */ + tx4939_ccfg_set(TX4939_CCFG_WDRST | TX4939_CCFG_BEOW); + /* enable Timeout BusError */ + if (txx9_ccfg_toeon) + tx4939_ccfg_set(TX4939_CCFG_TOE); + + /* DMA selection */ + txx9_clear64(&tx4939_ccfgptr->pcfg, TX4939_PCFG_DMASEL_ALL); + + /* Use external clock for external arbiter */ + if (!(____raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_PCIARB)) + txx9_clear64(&tx4939_ccfgptr->pcfg, TX4939_PCFG_PCICLKEN_ALL); + + pr_info("%s -- %dMHz(M%dMHz,G%dMHz) CRIR:%08x CCFG:%llx PCFG:%llx\n", + txx9_pcode_str, + (cpuclk + 500000) / 1000000, + (txx9_master_clock + 500000) / 1000000, + (txx9_gbus_clock + 500000) / 1000000, + (__u32)____raw_readq(&tx4939_ccfgptr->crir), + (unsigned long long)____raw_readq(&tx4939_ccfgptr->ccfg), + (unsigned long long)____raw_readq(&tx4939_ccfgptr->pcfg)); + + pr_info("%s DDRC -- EN:%08x", txx9_pcode_str, + (__u32)____raw_readq(&tx4939_ddrcptr->winen)); + for (i = 0; i < 4; i++) { + __u64 win = ____raw_readq(&tx4939_ddrcptr->win[i]); + if (!((__u32)____raw_readq(&tx4939_ddrcptr->winen) & (1 << i))) + continue; /* disabled */ + printk(KERN_CONT " #%d:%016llx", i, (unsigned long long)win); + tx4939_sdram_resource[i].name = "DDR SDRAM"; + tx4939_sdram_resource[i].start = + (unsigned long)(win >> 48) << 20; + tx4939_sdram_resource[i].end = + ((((unsigned long)(win >> 32) & 0xffff) + 1) << + 20) - 1; + tx4939_sdram_resource[i].flags = IORESOURCE_MEM; + request_resource(&iomem_resource, &tx4939_sdram_resource[i]); + } + printk(KERN_CONT "\n"); + + /* SRAM */ + if (____raw_readq(&tx4939_sramcptr->cr) & 1) { + unsigned int size = TX4939_SRAM_SIZE; + tx4939_sram_resource.name = "SRAM"; + tx4939_sram_resource.start = + (____raw_readq(&tx4939_sramcptr->cr) >> (39-11)) + & ~(size - 1); + tx4939_sram_resource.end = + tx4939_sram_resource.start + TX4939_SRAM_SIZE - 1; + tx4939_sram_resource.flags = IORESOURCE_MEM; + request_resource(&iomem_resource, &tx4939_sram_resource); + } + + /* TMR */ + /* disable all timers */ + for (i = 0; i < TX4939_NR_TMR; i++) + txx9_tmr_init(TX4939_TMR_REG(i) & 0xfffffffffULL); + + /* DMA */ + for (i = 0; i < 2; i++) + ____raw_writeq(TX4938_DMA_MCR_MSTEN, + (void __iomem *)(TX4939_DMA_REG(i) + 0x50)); + + /* set PCIC1 reset (required to prevent hangup on BIST) */ + txx9_set64(&tx4939_ccfgptr->clkctr, TX4939_CLKCTR_PCI1RST); + pcfg = ____raw_readq(&tx4939_ccfgptr->pcfg); + if (pcfg & (TX4939_PCFG_ET0MODE | TX4939_PCFG_ET1MODE)) { + mdelay(1); /* at least 128 cpu clock */ + /* clear PCIC1 reset */ + txx9_clear64(&tx4939_ccfgptr->clkctr, TX4939_CLKCTR_PCI1RST); + } else { + pr_info("%s: stop PCIC1\n", txx9_pcode_str); + /* stop PCIC1 */ + txx9_set64(&tx4939_ccfgptr->clkctr, TX4939_CLKCTR_PCI1CKD); + } + if (!(pcfg & TX4939_PCFG_ET0MODE)) { + pr_info("%s: stop ETH0\n", txx9_pcode_str); + txx9_set64(&tx4939_ccfgptr->clkctr, TX4939_CLKCTR_ETH0RST); + txx9_set64(&tx4939_ccfgptr->clkctr, TX4939_CLKCTR_ETH0CKD); + } + if (!(pcfg & TX4939_PCFG_ET1MODE)) { + pr_info("%s: stop ETH1\n", txx9_pcode_str); + txx9_set64(&tx4939_ccfgptr->clkctr, TX4939_CLKCTR_ETH1RST); + txx9_set64(&tx4939_ccfgptr->clkctr, TX4939_CLKCTR_ETH1CKD); + } + + _machine_restart = tx4939_machine_restart; + board_be_init = tx4939_be_init; +} + +void __init tx4939_time_init(unsigned int tmrnr) +{ + if (____raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_TINTDIS) + txx9_clockevent_init(TX4939_TMR_REG(tmrnr) & 0xfffffffffULL, + TXX9_IRQ_BASE + TX4939_IR_TMR(tmrnr), + TXX9_IMCLK); +} + +void __init tx4939_sio_init(unsigned int sclk, unsigned int cts_mask) +{ + int i; + unsigned int ch_mask = 0; + __u64 pcfg = __raw_readq(&tx4939_ccfgptr->pcfg); + + cts_mask |= ~1; /* only SIO0 have RTS/CTS */ + if ((pcfg & TX4939_PCFG_SIO2MODE_MASK) != TX4939_PCFG_SIO2MODE_SIO0) + cts_mask |= 1 << 0; /* disable SIO0 RTS/CTS by PCFG setting */ + if ((pcfg & TX4939_PCFG_SIO2MODE_MASK) != TX4939_PCFG_SIO2MODE_SIO2) + ch_mask |= 1 << 2; /* disable SIO2 by PCFG setting */ + if (pcfg & TX4939_PCFG_SIO3MODE) + ch_mask |= 1 << 3; /* disable SIO3 by PCFG setting */ + for (i = 0; i < 4; i++) { + if ((1 << i) & ch_mask) + continue; + txx9_sio_init(TX4939_SIO_REG(i) & 0xfffffffffULL, + TXX9_IRQ_BASE + TX4939_IR_SIO(i), + i, sclk, (1 << i) & cts_mask); + } +} + +#if defined(CONFIG_TC35815) || defined(CONFIG_TC35815_MODULE) +static int tx4939_get_eth_speed(struct net_device *dev) +{ + struct ethtool_cmd cmd = { ETHTOOL_GSET }; + int speed = 100; /* default 100Mbps */ + int err; + if (!dev->ethtool_ops || !dev->ethtool_ops->get_settings) + return speed; + err = dev->ethtool_ops->get_settings(dev, &cmd); + if (err < 0) + return speed; + speed = cmd.speed == SPEED_100 ? 100 : 10; + return speed; +} +static int tx4939_netdev_event(struct notifier_block *this, + unsigned long event, + void *ptr) +{ + struct net_device *dev = ptr; + if (event == NETDEV_CHANGE && netif_carrier_ok(dev)) { + __u64 bit = 0; + if (dev->irq == TXX9_IRQ_BASE + TX4939_IR_ETH(0)) + bit = TX4939_PCFG_SPEED0; + else if (dev->irq == TXX9_IRQ_BASE + TX4939_IR_ETH(1)) + bit = TX4939_PCFG_SPEED1; + if (bit) { + int speed = tx4939_get_eth_speed(dev); + if (speed == 100) + txx9_set64(&tx4939_ccfgptr->pcfg, bit); + else + txx9_clear64(&tx4939_ccfgptr->pcfg, bit); + } + } + return NOTIFY_DONE; +} + +static struct notifier_block tx4939_netdev_notifier = { + .notifier_call = tx4939_netdev_event, + .priority = 1, +}; + +void __init tx4939_ethaddr_init(unsigned char *addr0, unsigned char *addr1) +{ + u64 pcfg = __raw_readq(&tx4939_ccfgptr->pcfg); + + if (addr0 && (pcfg & TX4939_PCFG_ET0MODE)) + txx9_ethaddr_init(TXX9_IRQ_BASE + TX4939_IR_ETH(0), addr0); + if (addr1 && (pcfg & TX4939_PCFG_ET1MODE)) + txx9_ethaddr_init(TXX9_IRQ_BASE + TX4939_IR_ETH(1), addr1); + register_netdevice_notifier(&tx4939_netdev_notifier); +} +#else +void __init tx4939_ethaddr_init(unsigned char *addr0, unsigned char *addr1) +{ +} +#endif + +void __init tx4939_mtd_init(int ch) +{ + struct physmap_flash_data pdata = { + .width = TX4939_EBUSC_WIDTH(ch) / 8, + }; + unsigned long start = txx9_ce_res[ch].start; + unsigned long size = txx9_ce_res[ch].end - start + 1; + + if (!(TX4939_EBUSC_CR(ch) & 0x8)) + return; /* disabled */ + txx9_physmap_flash_init(ch, start, size, &pdata); +} + +static void __init tx4939_stop_unused_modules(void) +{ + __u64 pcfg, rst = 0, ckd = 0; + char buf[128]; + + buf[0] = '\0'; + local_irq_disable(); + pcfg = ____raw_readq(&tx4939_ccfgptr->pcfg); + if ((pcfg & TX4939_PCFG_I2SMODE_MASK) != + TX4939_PCFG_I2SMODE_ACLC) { + rst |= TX4939_CLKCTR_ACLRST; + ckd |= TX4939_CLKCTR_ACLCKD; + strcat(buf, " ACLC"); + } + if ((pcfg & TX4939_PCFG_I2SMODE_MASK) != + TX4939_PCFG_I2SMODE_I2S && + (pcfg & TX4939_PCFG_I2SMODE_MASK) != + TX4939_PCFG_I2SMODE_I2S_ALT) { + rst |= TX4939_CLKCTR_I2SRST; + ckd |= TX4939_CLKCTR_I2SCKD; + strcat(buf, " I2S"); + } + if (!(pcfg & TX4939_PCFG_ATA0MODE)) { + rst |= TX4939_CLKCTR_ATA0RST; + ckd |= TX4939_CLKCTR_ATA0CKD; + strcat(buf, " ATA0"); + } + if (!(pcfg & TX4939_PCFG_ATA1MODE)) { + rst |= TX4939_CLKCTR_ATA1RST; + ckd |= TX4939_CLKCTR_ATA1CKD; + strcat(buf, " ATA1"); + } + if (pcfg & TX4939_PCFG_SPIMODE) { + rst |= TX4939_CLKCTR_SPIRST; + ckd |= TX4939_CLKCTR_SPICKD; + strcat(buf, " SPI"); + } + if (!(pcfg & (TX4939_PCFG_VSSMODE | TX4939_PCFG_VPSMODE))) { + rst |= TX4939_CLKCTR_VPCRST; + ckd |= TX4939_CLKCTR_VPCCKD; + strcat(buf, " VPC"); + } + if ((pcfg & TX4939_PCFG_SIO2MODE_MASK) != TX4939_PCFG_SIO2MODE_SIO2) { + rst |= TX4939_CLKCTR_SIO2RST; + ckd |= TX4939_CLKCTR_SIO2CKD; + strcat(buf, " SIO2"); + } + if (pcfg & TX4939_PCFG_SIO3MODE) { + rst |= TX4939_CLKCTR_SIO3RST; + ckd |= TX4939_CLKCTR_SIO3CKD; + strcat(buf, " SIO3"); + } + if (rst | ckd) { + txx9_set64(&tx4939_ccfgptr->clkctr, rst); + txx9_set64(&tx4939_ccfgptr->clkctr, ckd); + } + local_irq_enable(); + if (buf[0]) + pr_info("%s: stop%s\n", txx9_pcode_str, buf); +} + +static int __init tx4939_late_init(void) +{ + if (txx9_pcode != 0x4939) + return -ENODEV; + tx4939_stop_unused_modules(); + return 0; +} +late_initcall(tx4939_late_init); diff --git a/include/asm-mips/txx9/tx4939.h b/include/asm-mips/txx9/tx4939.h new file mode 100644 index 000000000000..7ce2dff3b7cc --- /dev/null +++ b/include/asm-mips/txx9/tx4939.h @@ -0,0 +1,544 @@ +/* + * Definitions for TX4939 + * + * Copyright (C) 2000-2001,2005-2006 Toshiba Corporation + * 2003-2005 (c) MontaVista Software, Inc. 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. + */ +#ifndef __ASM_TXX9_TX4939_H +#define __ASM_TXX9_TX4939_H + +/* some controllers are compatible with 4927/4938 */ +#include + +#ifdef CONFIG_64BIT +#define TX4939_REG_BASE 0xffffffffff1f0000UL /* == TX4938_REG_BASE */ +#else +#define TX4939_REG_BASE 0xff1f0000UL /* == TX4938_REG_BASE */ +#endif +#define TX4939_REG_SIZE 0x00010000 /* == TX4938_REG_SIZE */ + +#define TX4939_ATA_REG(ch) (TX4939_REG_BASE + 0x3000 + (ch) * 0x1000) +#define TX4939_NDFMC_REG (TX4939_REG_BASE + 0x5000) +#define TX4939_SRAMC_REG (TX4939_REG_BASE + 0x6000) +#define TX4939_CRYPTO_REG (TX4939_REG_BASE + 0x6800) +#define TX4939_PCIC1_REG (TX4939_REG_BASE + 0x7000) +#define TX4939_DDRC_REG (TX4939_REG_BASE + 0x8000) +#define TX4939_EBUSC_REG (TX4939_REG_BASE + 0x9000) +#define TX4939_VPC_REG (TX4939_REG_BASE + 0xa000) +#define TX4939_DMA_REG(ch) (TX4939_REG_BASE + 0xb000 + (ch) * 0x800) +#define TX4939_PCIC_REG (TX4939_REG_BASE + 0xd000) +#define TX4939_CCFG_REG (TX4939_REG_BASE + 0xe000) +#define TX4939_IRC_REG (TX4939_REG_BASE + 0xe800) +#define TX4939_NR_TMR 6 /* 0xf000,0xf100,0xf200,0xfd00,0xfe00,0xff00 */ +#define TX4939_TMR_REG(ch) \ + (TX4939_REG_BASE + 0xf000 + ((ch) + ((ch) >= 3) * 10) * 0x100) +#define TX4939_NR_SIO 4 /* 0xf300, 0xf400, 0xf380, 0xf480 */ +#define TX4939_SIO_REG(ch) \ + (TX4939_REG_BASE + 0xf300 + (((ch) & 1) << 8) + (((ch) & 2) << 6)) +#define TX4939_ACLC_REG (TX4939_REG_BASE + 0xf700) +#define TX4939_SPI_REG (TX4939_REG_BASE + 0xf800) +#define TX4939_I2C_REG (TX4939_REG_BASE + 0xf900) +#define TX4939_I2S_REG (TX4939_REG_BASE + 0xfa00) +#define TX4939_RTC_REG (TX4939_REG_BASE + 0xfb00) +#define TX4939_CIR_REG (TX4939_REG_BASE + 0xfc00) + +struct tx4939_le_reg { + __u32 r; + __u32 unused; +}; + +struct tx4939_ddrc_reg { + struct tx4939_le_reg ctl[47]; + __u64 unused0[17]; + __u64 winen; + __u64 win[4]; +}; + +struct tx4939_ccfg_reg { + __u64 ccfg; + __u64 crir; + __u64 pcfg; + __u64 toea; + __u64 clkctr; + __u64 unused0; + __u64 garbc; + __u64 unused1[2]; + __u64 ramp; + __u64 unused2[2]; + __u64 dskwctrl; + __u64 mclkosc; + __u64 mclkctl; + __u64 unused3[17]; + struct { + __u64 mr; + __u64 dr; + } gpio[2]; +}; + +struct tx4939_irc_reg { + struct tx4939_le_reg den; + struct tx4939_le_reg scipb; + struct tx4939_le_reg dm[2]; + struct tx4939_le_reg lvl[16]; + struct tx4939_le_reg msk; + struct tx4939_le_reg edc; + struct tx4939_le_reg pnd0; + struct tx4939_le_reg cs; + struct tx4939_le_reg pnd1; + struct tx4939_le_reg dm2[2]; + struct tx4939_le_reg dbr[2]; + struct tx4939_le_reg dben; + struct tx4939_le_reg unused0[2]; + struct tx4939_le_reg flag[2]; + struct tx4939_le_reg pol; + struct tx4939_le_reg cnt; + struct tx4939_le_reg maskint; + struct tx4939_le_reg maskext; +}; + +struct tx4939_rtc_reg { + __u32 ctl; + __u32 adr; + __u32 dat; + __u32 tbc; +}; + +struct tx4939_crypto_reg { + struct tx4939_le_reg csr; + struct tx4939_le_reg idesptr; + struct tx4939_le_reg cdesptr; + struct tx4939_le_reg buserr; + struct tx4939_le_reg cip_tout; + struct tx4939_le_reg cir; + union { + struct { + struct tx4939_le_reg data[8]; + struct tx4939_le_reg ctrl; + } gen; + struct { + struct { + struct tx4939_le_reg l; + struct tx4939_le_reg u; + } key[3], ini; + struct tx4939_le_reg ctrl; + } des; + struct { + struct tx4939_le_reg key[4]; + struct tx4939_le_reg ini[4]; + struct tx4939_le_reg ctrl; + } aes; + struct { + struct { + struct tx4939_le_reg l; + struct tx4939_le_reg u; + } cnt; + struct tx4939_le_reg ini[5]; + struct tx4939_le_reg unused; + struct tx4939_le_reg ctrl; + } hash; + } cdr; + struct tx4939_le_reg unused0[7]; + struct tx4939_le_reg rcsr; + struct tx4939_le_reg rpr; + __u64 rdr; + __u64 ror[3]; + struct tx4939_le_reg unused1[2]; + struct tx4939_le_reg xorslr; + struct tx4939_le_reg xorsur; +}; + +struct tx4939_crypto_desc { + __u32 src; + __u32 dst; + __u32 next; + __u32 ctrl; + __u32 index; + __u32 xor; +}; + +struct tx4939_vpc_reg { + struct tx4939_le_reg csr; + struct { + struct tx4939_le_reg ctrlA; + struct tx4939_le_reg ctrlB; + struct tx4939_le_reg idesptr; + struct tx4939_le_reg cdesptr; + } port[3]; + struct tx4939_le_reg buserr; +}; + +struct tx4939_vpc_desc { + __u32 src; + __u32 next; + __u32 ctrl1; + __u32 ctrl2; +}; + +/* + * IRC + */ +#define TX4939_IR_NONE 0 +#define TX4939_IR_DDR 1 +#define TX4939_IR_WTOERR 2 +#define TX4939_NUM_IR_INT 3 +#define TX4939_IR_INT(n) (3 + (n)) +#define TX4939_NUM_IR_ETH 2 +#define TX4939_IR_ETH(n) ((n) ? 43 : 6) +#define TX4939_IR_VIDEO 7 +#define TX4939_IR_CIR 8 +#define TX4939_NUM_IR_SIO 4 +#define TX4939_IR_SIO(n) ((n) ? 43 + (n) : 9) /* 9,44-46 */ +#define TX4939_NUM_IR_DMA 4 +#define TX4939_IR_DMA(ch, n) (((ch) ? 22 : 10) + (n)) /* 10-13,22-25 */ +#define TX4939_IR_IRC 14 +#define TX4939_IR_PDMAC 15 +#define TX4939_NUM_IR_TMR 6 +#define TX4939_IR_TMR(n) (((n) >= 3 ? 45 : 16) + (n)) /* 16-18,48-50 */ +#define TX4939_NUM_IR_ATA 2 +#define TX4939_IR_ATA(n) (19 + (n)) +#define TX4939_IR_ACLC 21 +#define TX4939_IR_CIPHER 26 +#define TX4939_IR_INTA 27 +#define TX4939_IR_INTB 28 +#define TX4939_IR_INTC 29 +#define TX4939_IR_INTD 30 +#define TX4939_IR_I2C 33 +#define TX4939_IR_SPI 34 +#define TX4939_IR_PCIC 35 +#define TX4939_IR_PCIC1 36 +#define TX4939_IR_PCIERR 37 +#define TX4939_IR_PCIPME 38 +#define TX4939_IR_NDFMC 39 +#define TX4939_IR_ACLCPME 40 +#define TX4939_IR_RTC 41 +#define TX4939_IR_RND 42 +#define TX4939_IR_I2S 47 +#define TX4939_NUM_IR 64 + +#define TX4939_IRC_INT 2 /* IP[2] in Status register */ + +/* + * CCFG + */ +/* CCFG : Chip Configuration */ +#define TX4939_CCFG_PCIBOOT 0x0000040000000000ULL +#define TX4939_CCFG_WDRST 0x0000020000000000ULL +#define TX4939_CCFG_WDREXEN 0x0000010000000000ULL +#define TX4939_CCFG_BCFG_MASK 0x000000ff00000000ULL +#define TX4939_CCFG_GTOT_MASK 0x06000000 +#define TX4939_CCFG_GTOT_4096 0x06000000 +#define TX4939_CCFG_GTOT_2048 0x04000000 +#define TX4939_CCFG_GTOT_1024 0x02000000 +#define TX4939_CCFG_GTOT_512 0x00000000 +#define TX4939_CCFG_TINTDIS 0x01000000 +#define TX4939_CCFG_PCI66 0x00800000 +#define TX4939_CCFG_PCIMODE 0x00400000 +#define TX4939_CCFG_SSCG 0x00100000 +#define TX4939_CCFG_MULCLK_MASK 0x000e0000 +#define TX4939_CCFG_MULCLK_8 (0x7 << 17) +#define TX4939_CCFG_MULCLK_9 (0x0 << 17) +#define TX4939_CCFG_MULCLK_10 (0x1 << 17) +#define TX4939_CCFG_MULCLK_11 (0x2 << 17) +#define TX4939_CCFG_MULCLK_12 (0x3 << 17) +#define TX4939_CCFG_MULCLK_13 (0x4 << 17) +#define TX4939_CCFG_MULCLK_14 (0x5 << 17) +#define TX4939_CCFG_MULCLK_15 (0x6 << 17) +#define TX4939_CCFG_BEOW 0x00010000 +#define TX4939_CCFG_WR 0x00008000 +#define TX4939_CCFG_TOE 0x00004000 +#define TX4939_CCFG_PCIARB 0x00002000 +#define TX4939_CCFG_YDIVMODE_MASK 0x00001c00 +#define TX4939_CCFG_YDIVMODE_2 (0x0 << 10) +#define TX4939_CCFG_YDIVMODE_3 (0x1 << 10) +#define TX4939_CCFG_YDIVMODE_5 (0x6 << 10) +#define TX4939_CCFG_YDIVMODE_6 (0x7 << 10) +#define TX4939_CCFG_PTSEL 0x00000200 +#define TX4939_CCFG_BESEL 0x00000100 +#define TX4939_CCFG_SYSSP_MASK 0x000000c0 +#define TX4939_CCFG_ACKSEL 0x00000020 +#define TX4939_CCFG_ROMW 0x00000010 +#define TX4939_CCFG_ENDIAN 0x00000004 +#define TX4939_CCFG_ARMODE 0x00000002 +#define TX4939_CCFG_ACEHOLD 0x00000001 + +/* PCFG : Pin Configuration */ +#define TX4939_PCFG_SIO2MODE_MASK 0xc000000000000000ULL +#define TX4939_PCFG_SIO2MODE_GPIO 0x8000000000000000ULL +#define TX4939_PCFG_SIO2MODE_SIO2 0x4000000000000000ULL +#define TX4939_PCFG_SIO2MODE_SIO0 0x0000000000000000ULL +#define TX4939_PCFG_SPIMODE 0x2000000000000000ULL +#define TX4939_PCFG_I2CMODE 0x1000000000000000ULL +#define TX4939_PCFG_I2SMODE_MASK 0x0c00000000000000ULL +#define TX4939_PCFG_I2SMODE_GPIO 0x0c00000000000000ULL +#define TX4939_PCFG_I2SMODE_I2S 0x0800000000000000ULL +#define TX4939_PCFG_I2SMODE_I2S_ALT 0x0400000000000000ULL +#define TX4939_PCFG_I2SMODE_ACLC 0x0000000000000000ULL +#define TX4939_PCFG_SIO3MODE 0x0200000000000000ULL +#define TX4939_PCFG_DMASEL3 0x0004000000000000ULL +#define TX4939_PCFG_DMASEL3_SIO0 0x0004000000000000ULL +#define TX4939_PCFG_DMASEL3_NDFC 0x0000000000000000ULL +#define TX4939_PCFG_VSSMODE 0x0000200000000000ULL +#define TX4939_PCFG_VPSMODE 0x0000100000000000ULL +#define TX4939_PCFG_ET1MODE 0x0000080000000000ULL +#define TX4939_PCFG_ET0MODE 0x0000040000000000ULL +#define TX4939_PCFG_ATA1MODE 0x0000020000000000ULL +#define TX4939_PCFG_ATA0MODE 0x0000010000000000ULL +#define TX4939_PCFG_BP_PLL 0x0000000100000000ULL + +#define TX4939_PCFG_SYSCLKEN 0x08000000 +#define TX4939_PCFG_PCICLKEN_ALL 0x000f0000 +#define TX4939_PCFG_PCICLKEN(ch) (0x00010000<<(ch)) +#define TX4939_PCFG_SPEED1 0x00002000 +#define TX4939_PCFG_SPEED0 0x00001000 +#define TX4939_PCFG_ITMODE 0x00000300 +#define TX4939_PCFG_DMASEL_ALL (0x00000007 | TX4939_PCFG_DMASEL3) +#define TX4939_PCFG_DMASEL2 0x00000004 +#define TX4939_PCFG_DMASEL2_DRQ2 0x00000000 +#define TX4939_PCFG_DMASEL2_SIO0 0x00000004 +#define TX4939_PCFG_DMASEL1 0x00000002 +#define TX4939_PCFG_DMASEL1_DRQ1 0x00000000 +#define TX4939_PCFG_DMASEL0 0x00000001 +#define TX4939_PCFG_DMASEL0_DRQ0 0x00000000 + +/* CLKCTR : Clock Control */ +#define TX4939_CLKCTR_IOSCKD 0x8000000000000000ULL +#define TX4939_CLKCTR_SYSCKD 0x4000000000000000ULL +#define TX4939_CLKCTR_TM5CKD 0x2000000000000000ULL +#define TX4939_CLKCTR_TM4CKD 0x1000000000000000ULL +#define TX4939_CLKCTR_TM3CKD 0x0800000000000000ULL +#define TX4939_CLKCTR_CIRCKD 0x0400000000000000ULL +#define TX4939_CLKCTR_SIO3CKD 0x0200000000000000ULL +#define TX4939_CLKCTR_SIO2CKD 0x0100000000000000ULL +#define TX4939_CLKCTR_SIO1CKD 0x0080000000000000ULL +#define TX4939_CLKCTR_VPCCKD 0x0040000000000000ULL +#define TX4939_CLKCTR_EPCICKD 0x0020000000000000ULL +#define TX4939_CLKCTR_ETH1CKD 0x0008000000000000ULL +#define TX4939_CLKCTR_ATA1CKD 0x0004000000000000ULL +#define TX4939_CLKCTR_BROMCKD 0x0002000000000000ULL +#define TX4939_CLKCTR_NDCCKD 0x0001000000000000ULL +#define TX4939_CLKCTR_I2CCKD 0x0000800000000000ULL +#define TX4939_CLKCTR_ETH0CKD 0x0000400000000000ULL +#define TX4939_CLKCTR_SPICKD 0x0000200000000000ULL +#define TX4939_CLKCTR_SRAMCKD 0x0000100000000000ULL +#define TX4939_CLKCTR_PCI1CKD 0x0000080000000000ULL +#define TX4939_CLKCTR_DMA1CKD 0x0000040000000000ULL +#define TX4939_CLKCTR_ACLCKD 0x0000020000000000ULL +#define TX4939_CLKCTR_ATA0CKD 0x0000010000000000ULL +#define TX4939_CLKCTR_DMA0CKD 0x0000008000000000ULL +#define TX4939_CLKCTR_PCICCKD 0x0000004000000000ULL +#define TX4939_CLKCTR_I2SCKD 0x0000002000000000ULL +#define TX4939_CLKCTR_TM0CKD 0x0000001000000000ULL +#define TX4939_CLKCTR_TM1CKD 0x0000000800000000ULL +#define TX4939_CLKCTR_TM2CKD 0x0000000400000000ULL +#define TX4939_CLKCTR_SIO0CKD 0x0000000200000000ULL +#define TX4939_CLKCTR_CYPCKD 0x0000000100000000ULL +#define TX4939_CLKCTR_IOSRST 0x80000000 +#define TX4939_CLKCTR_SYSRST 0x40000000 +#define TX4939_CLKCTR_TM5RST 0x20000000 +#define TX4939_CLKCTR_TM4RST 0x10000000 +#define TX4939_CLKCTR_TM3RST 0x08000000 +#define TX4939_CLKCTR_CIRRST 0x04000000 +#define TX4939_CLKCTR_SIO3RST 0x02000000 +#define TX4939_CLKCTR_SIO2RST 0x01000000 +#define TX4939_CLKCTR_SIO1RST 0x00800000 +#define TX4939_CLKCTR_VPCRST 0x00400000 +#define TX4939_CLKCTR_EPCIRST 0x00200000 +#define TX4939_CLKCTR_ETH1RST 0x00080000 +#define TX4939_CLKCTR_ATA1RST 0x00040000 +#define TX4939_CLKCTR_BROMRST 0x00020000 +#define TX4939_CLKCTR_NDCRST 0x00010000 +#define TX4939_CLKCTR_I2CRST 0x00008000 +#define TX4939_CLKCTR_ETH0RST 0x00004000 +#define TX4939_CLKCTR_SPIRST 0x00002000 +#define TX4939_CLKCTR_SRAMRST 0x00001000 +#define TX4939_CLKCTR_PCI1RST 0x00000800 +#define TX4939_CLKCTR_DMA1RST 0x00000400 +#define TX4939_CLKCTR_ACLRST 0x00000200 +#define TX4939_CLKCTR_ATA0RST 0x00000100 +#define TX4939_CLKCTR_DMA0RST 0x00000080 +#define TX4939_CLKCTR_PCICRST 0x00000040 +#define TX4939_CLKCTR_I2SRST 0x00000020 +#define TX4939_CLKCTR_TM0RST 0x00000010 +#define TX4939_CLKCTR_TM1RST 0x00000008 +#define TX4939_CLKCTR_TM2RST 0x00000004 +#define TX4939_CLKCTR_SIO0RST 0x00000002 +#define TX4939_CLKCTR_CYPRST 0x00000001 + +/* + * RTC + */ +#define TX4939_RTCCTL_ALME 0x00000080 +#define TX4939_RTCCTL_ALMD 0x00000040 +#define TX4939_RTCCTL_BUSY 0x00000020 + +#define TX4939_RTCCTL_COMMAND 0x00000007 +#define TX4939_RTCCTL_COMMAND_NOP 0x00000000 +#define TX4939_RTCCTL_COMMAND_GETTIME 0x00000001 +#define TX4939_RTCCTL_COMMAND_SETTIME 0x00000002 +#define TX4939_RTCCTL_COMMAND_GETALARM 0x00000003 +#define TX4939_RTCCTL_COMMAND_SETALARM 0x00000004 + +#define TX4939_RTCTBC_PM 0x00000080 +#define TX4939_RTCTBC_COMP 0x0000007f + +#define TX4939_RTC_REG_RAMSIZE 0x00000100 +#define TX4939_RTC_REG_RWBSIZE 0x00000006 + +/* + * CRYPTO + */ +#define TX4939_CRYPTO_CSR_SAESO 0x08000000 +#define TX4939_CRYPTO_CSR_SAESI 0x04000000 +#define TX4939_CRYPTO_CSR_SDESO 0x02000000 +#define TX4939_CRYPTO_CSR_SDESI 0x01000000 +#define TX4939_CRYPTO_CSR_INDXBST_MASK 0x00700000 +#define TX4939_CRYPTO_CSR_INDXBST(n) ((n) << 20) +#define TX4939_CRYPTO_CSR_TOINT 0x00080000 +#define TX4939_CRYPTO_CSR_DCINT 0x00040000 +#define TX4939_CRYPTO_CSR_GBINT 0x00010000 +#define TX4939_CRYPTO_CSR_INDXAST_MASK 0x0000e000 +#define TX4939_CRYPTO_CSR_INDXAST(n) ((n) << 13) +#define TX4939_CRYPTO_CSR_CSWAP_MASK 0x00001800 +#define TX4939_CRYPTO_CSR_CSWAP_NONE 0x00000000 +#define TX4939_CRYPTO_CSR_CSWAP_IN 0x00000800 +#define TX4939_CRYPTO_CSR_CSWAP_OUT 0x00001000 +#define TX4939_CRYPTO_CSR_CSWAP_BOTH 0x00001800 +#define TX4939_CRYPTO_CSR_CDIV_MASK 0x00000600 +#define TX4939_CRYPTO_CSR_CDIV_DIV2 0x00000000 +#define TX4939_CRYPTO_CSR_CDIV_DIV1 0x00000200 +#define TX4939_CRYPTO_CSR_CDIV_DIV2ALT 0x00000400 +#define TX4939_CRYPTO_CSR_CDIV_DIV1ALT 0x00000600 +#define TX4939_CRYPTO_CSR_PDINT_MASK 0x000000c0 +#define TX4939_CRYPTO_CSR_PDINT_ALL 0x00000000 +#define TX4939_CRYPTO_CSR_PDINT_END 0x00000040 +#define TX4939_CRYPTO_CSR_PDINT_NEXT 0x00000080 +#define TX4939_CRYPTO_CSR_PDINT_NONE 0x000000c0 +#define TX4939_CRYPTO_CSR_GINTE 0x00000008 +#define TX4939_CRYPTO_CSR_RSTD 0x00000004 +#define TX4939_CRYPTO_CSR_RSTC 0x00000002 +#define TX4939_CRYPTO_CSR_ENCR 0x00000001 + +/* bits for tx4939_crypto_reg.cdr.gen.ctrl */ +#define TX4939_CRYPTO_CTX_ENGINE_MASK 0x00000003 +#define TX4939_CRYPTO_CTX_ENGINE_DES 0x00000000 +#define TX4939_CRYPTO_CTX_ENGINE_AES 0x00000001 +#define TX4939_CRYPTO_CTX_ENGINE_MD5 0x00000002 +#define TX4939_CRYPTO_CTX_ENGINE_SHA1 0x00000003 +#define TX4939_CRYPTO_CTX_TDMS 0x00000010 +#define TX4939_CRYPTO_CTX_CMS 0x00000020 +#define TX4939_CRYPTO_CTX_DMS 0x00000040 +#define TX4939_CRYPTO_CTX_UPDATE 0x00000080 + +/* bits for tx4939_crypto_desc.ctrl */ +#define TX4939_CRYPTO_DESC_OB_CNT_MASK 0xffe00000 +#define TX4939_CRYPTO_DESC_OB_CNT(cnt) ((cnt) << 21) +#define TX4939_CRYPTO_DESC_IB_CNT_MASK 0x001ffc00 +#define TX4939_CRYPTO_DESC_IB_CNT(cnt) ((cnt) << 10) +#define TX4939_CRYPTO_DESC_START 0x00000200 +#define TX4939_CRYPTO_DESC_END 0x00000100 +#define TX4939_CRYPTO_DESC_XOR 0x00000010 +#define TX4939_CRYPTO_DESC_LAST 0x00000008 +#define TX4939_CRYPTO_DESC_ERR_MASK 0x00000006 +#define TX4939_CRYPTO_DESC_ERR_NONE 0x00000000 +#define TX4939_CRYPTO_DESC_ERR_TOUT 0x00000002 +#define TX4939_CRYPTO_DESC_ERR_DIGEST 0x00000004 +#define TX4939_CRYPTO_DESC_OWN 0x00000001 + +/* bits for tx4939_crypto_desc.index */ +#define TX4939_CRYPTO_DESC_HASH_IDX_MASK 0x00000070 +#define TX4939_CRYPTO_DESC_HASH_IDX(idx) ((idx) << 4) +#define TX4939_CRYPTO_DESC_ENCRYPT_IDX_MASK 0x00000007 +#define TX4939_CRYPTO_DESC_ENCRYPT_IDX(idx) ((idx) << 0) + +#define TX4939_CRYPTO_NR_SET 6 + +#define TX4939_CRYPTO_RCSR_INTE 0x00000008 +#define TX4939_CRYPTO_RCSR_RST 0x00000004 +#define TX4939_CRYPTO_RCSR_FIN 0x00000002 +#define TX4939_CRYPTO_RCSR_ST 0x00000001 + +/* + * VPC + */ +#define TX4939_VPC_CSR_GBINT 0x00010000 +#define TX4939_VPC_CSR_SWAPO 0x00000020 +#define TX4939_VPC_CSR_SWAPI 0x00000010 +#define TX4939_VPC_CSR_GINTE 0x00000008 +#define TX4939_VPC_CSR_RSTD 0x00000004 +#define TX4939_VPC_CSR_RSTVPC 0x00000002 + +#define TX4939_VPC_CTRLA_VDPSN 0x00000200 +#define TX4939_VPC_CTRLA_PBUSY 0x00000100 +#define TX4939_VPC_CTRLA_DCINT 0x00000080 +#define TX4939_VPC_CTRLA_UOINT 0x00000040 +#define TX4939_VPC_CTRLA_PDINT_MASK 0x00000030 +#define TX4939_VPC_CTRLA_PDINT_ALL 0x00000000 +#define TX4939_VPC_CTRLA_PDINT_NEXT 0x00000010 +#define TX4939_VPC_CTRLA_PDINT_NONE 0x00000030 +#define TX4939_VPC_CTRLA_VDVLDP 0x00000008 +#define TX4939_VPC_CTRLA_VDMODE 0x00000004 +#define TX4939_VPC_CTRLA_VDFOR 0x00000002 +#define TX4939_VPC_CTRLA_ENVPC 0x00000001 + +/* bits for tx4939_vpc_desc.ctrl1 */ +#define TX4939_VPC_DESC_CTRL1_ERR_MASK 0x00000006 +#define TX4939_VPC_DESC_CTRL1_OWN 0x00000001 + +#define tx4939_ddrcptr ((struct tx4939_ddrc_reg __iomem *)TX4939_DDRC_REG) +#define tx4939_ebuscptr tx4938_ebuscptr +#define tx4939_ircptr \ + ((struct tx4939_irc_reg __iomem *)TX4939_IRC_REG) +#define tx4939_pcicptr tx4938_pcicptr +#define tx4939_pcic1ptr tx4938_pcic1ptr +#define tx4939_ccfgptr \ + ((struct tx4939_ccfg_reg __iomem *)TX4939_CCFG_REG) +#define tx4939_sramcptr tx4938_sramcptr +#define tx4939_rtcptr \ + ((struct tx4939_rtc_reg __iomem *)TX4939_RTC_REG) +#define tx4939_cryptoptr \ + ((struct tx4939_crypto_reg __iomem *)TX4939_CRYPTO_REG) +#define tx4939_vpcptr ((struct tx4939_vpc_reg __iomem *)TX4939_VPC_REG) + +#define TX4939_REV_MAJ_MIN() \ + ((__u32)__raw_readq(&tx4939_ccfgptr->crir) & 0x00ff) +#define TX4939_REV_PCODE() \ + ((__u32)__raw_readq(&tx4939_ccfgptr->crir) >> 16) +#define TX4939_CCFG_BCFG() \ + ((__u32)((__raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_BCFG_MASK) \ + >> 32)) + +#define tx4939_ccfg_clear(bits) tx4938_ccfg_clear(bits) +#define tx4939_ccfg_set(bits) tx4938_ccfg_set(bits) +#define tx4939_ccfg_change(change, new) tx4938_ccfg_change(change, new) + +#define TX4939_EBUSC_CR(ch) TX4927_EBUSC_CR(ch) +#define TX4939_EBUSC_BA(ch) TX4927_EBUSC_BA(ch) +#define TX4939_EBUSC_SIZE(ch) TX4927_EBUSC_SIZE(ch) +#define TX4939_EBUSC_WIDTH(ch) \ + (16 >> ((__u32)(TX4939_EBUSC_CR(ch) >> 20) & 0x1)) + +/* SCLK0 = MSTCLK * 429/19 * 16/245 / 2 (14.745MHz for MST 20MHz) */ +#define TX4939_SCLK0(mst) \ + ((((mst) + 245/2) / 245UL * 429 * 16 + 19) / 19 / 2) + +void tx4939_wdt_init(void); +void tx4939_add_memory_regions(void); +void tx4939_setup(void); +void tx4939_time_init(unsigned int tmrnr); +void tx4939_sio_init(unsigned int sclk, unsigned int cts_mask); +void tx4939_spi_init(int busid); +void tx4939_ethaddr_init(unsigned char *addr0, unsigned char *addr1); +int tx4939_report_pciclk(void); +void tx4939_report_pci1clk(void); +struct pci_dev; +int tx4939_pcic1_map_irq(const struct pci_dev *dev, u8 slot); +int tx4939_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin); +void tx4939_setup_pcierr_irq(void); +void tx4939_irq_init(void); +int tx4939_irq(void); +void tx4939_mtd_init(int ch); + +#endif /* __ASM_TXX9_TX4939_H */ -- cgit v1.2.3 From b27311e1cace4e296ace786c886d22f7a8ec78d6 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Mon, 1 Sep 2008 22:22:40 +0900 Subject: MIPS: TXx9: Add RBTX4939 board support Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle create mode 100644 arch/mips/txx9/rbtx4939/Makefile create mode 100644 arch/mips/txx9/rbtx4939/irq.c create mode 100644 arch/mips/txx9/rbtx4939/prom.c create mode 100644 arch/mips/txx9/rbtx4939/setup.c create mode 100644 include/asm-mips/txx9/rbtx4939.h --- arch/mips/Makefile | 8 +- arch/mips/txx9/Kconfig | 8 + arch/mips/txx9/generic/setup.c | 5 + arch/mips/txx9/rbtx4939/Makefile | 3 + arch/mips/txx9/rbtx4939/irq.c | 96 ++++++++++++ arch/mips/txx9/rbtx4939/prom.c | 17 +++ arch/mips/txx9/rbtx4939/setup.c | 306 +++++++++++++++++++++++++++++++++++++++ include/asm-mips/txx9/boards.h | 3 + include/asm-mips/txx9/rbtx4939.h | 133 +++++++++++++++++ 9 files changed, 573 insertions(+), 6 deletions(-) create mode 100644 arch/mips/txx9/rbtx4939/Makefile create mode 100644 arch/mips/txx9/rbtx4939/irq.c create mode 100644 arch/mips/txx9/rbtx4939/prom.c create mode 100644 arch/mips/txx9/rbtx4939/setup.c create mode 100644 include/asm-mips/txx9/rbtx4939.h (limited to 'arch/mips/txx9') diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 9aab51caf16a..87f67228e309 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -567,15 +567,11 @@ cflags-$(CONFIG_MIKROTIK_RB532) += -Iinclude/asm-mips/mach-rc32434 load-$(CONFIG_MIKROTIK_RB532) += 0xffffffff80101000 # -# Toshiba RBTX4927 board or -# Toshiba RBTX4937 board +# Toshiba RBTX49XX boards # core-$(CONFIG_TOSHIBA_RBTX4927) += arch/mips/txx9/rbtx4927/ - -# -# Toshiba RBTX4938 board -# core-$(CONFIG_TOSHIBA_RBTX4938) += arch/mips/txx9/rbtx4938/ +core-$(CONFIG_TOSHIBA_RBTX4939) += arch/mips/txx9/rbtx4939/ cflags-y += -Iinclude/asm-mips/mach-generic drivers-$(CONFIG_PCI) += arch/mips/pci/ diff --git a/arch/mips/txx9/Kconfig b/arch/mips/txx9/Kconfig index 58691a1fe779..17052db4161d 100644 --- a/arch/mips/txx9/Kconfig +++ b/arch/mips/txx9/Kconfig @@ -45,6 +45,14 @@ config TOSHIBA_RBTX4938 This Toshiba board is based on the TX4938 processor. Say Y here to support this machine type +config TOSHIBA_RBTX4939 + bool "Toshiba RBTX4939 bobard" + depends on MACH_TX49XX + select SOC_TX4939 + help + This Toshiba board is based on the TX4939 processor. Say Y here to + support this machine type + config SOC_TX3927 bool select CEVT_TXX9 diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c index 1ea06553a1e1..7a05c34c1dec 100644 --- a/arch/mips/txx9/generic/setup.c +++ b/arch/mips/txx9/generic/setup.c @@ -371,6 +371,11 @@ static void __init select_board(void) case 0x4938: txx9_board_vec = &rbtx4938_vec; break; +#endif +#ifdef CONFIG_TOSHIBA_RBTX4939 + case 0x4939: + txx9_board_vec = &rbtx4939_vec; + break; #endif } #endif diff --git a/arch/mips/txx9/rbtx4939/Makefile b/arch/mips/txx9/rbtx4939/Makefile new file mode 100644 index 000000000000..3232cd03a7d6 --- /dev/null +++ b/arch/mips/txx9/rbtx4939/Makefile @@ -0,0 +1,3 @@ +obj-y += irq.o setup.o prom.o + +EXTRA_CFLAGS += -Werror diff --git a/arch/mips/txx9/rbtx4939/irq.c b/arch/mips/txx9/rbtx4939/irq.c new file mode 100644 index 000000000000..500cc0a908e6 --- /dev/null +++ b/arch/mips/txx9/rbtx4939/irq.c @@ -0,0 +1,96 @@ +/* + * Toshiba RBTX4939 interrupt routines + * Based on linux/arch/mips/txx9/rbtx4938/irq.c, + * and RBTX49xx patch from CELF patch archive. + * + * Copyright (C) 2000-2001,2005-2006 Toshiba Corporation + * 2003-2005 (c) MontaVista Software, Inc. 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 +#include +#include +#include + +/* + * RBTX4939 IOC controller definition + */ + +static void rbtx4939_ioc_irq_unmask(unsigned int irq) +{ + int ioc_nr = irq - RBTX4939_IRQ_IOC; + + writeb(readb(rbtx4939_ien_addr) | (1 << ioc_nr), rbtx4939_ien_addr); +} + +static void rbtx4939_ioc_irq_mask(unsigned int irq) +{ + int ioc_nr = irq - RBTX4939_IRQ_IOC; + + writeb(readb(rbtx4939_ien_addr) & ~(1 << ioc_nr), rbtx4939_ien_addr); + mmiowb(); +} + +static struct irq_chip rbtx4939_ioc_irq_chip = { + .name = "IOC", + .ack = rbtx4939_ioc_irq_mask, + .mask = rbtx4939_ioc_irq_mask, + .mask_ack = rbtx4939_ioc_irq_mask, + .unmask = rbtx4939_ioc_irq_unmask, +}; + + +static inline int rbtx4939_ioc_irqroute(void) +{ + unsigned char istat = readb(rbtx4939_ifac2_addr); + + if (unlikely(istat == 0)) + return -1; + return RBTX4939_IRQ_IOC + __fls8(istat); +} + +static int rbtx4939_irq_dispatch(int pending) +{ + int irq; + + if (pending & CAUSEF_IP7) + return MIPS_CPU_IRQ_BASE + 7; + irq = tx4939_irq(); + if (likely(irq >= 0)) { + /* redirect IOC interrupts */ + switch (irq) { + case RBTX4939_IRQ_IOCINT: + irq = rbtx4939_ioc_irqroute(); + break; + } + } else if (pending & CAUSEF_IP0) + irq = MIPS_CPU_IRQ_BASE + 0; + else if (pending & CAUSEF_IP1) + irq = MIPS_CPU_IRQ_BASE + 1; + else + irq = -1; + return irq; +} + +void __init rbtx4939_irq_setup(void) +{ + int i; + + /* mask all IOC interrupts */ + writeb(0, rbtx4939_ien_addr); + + /* clear SoftInt interrupts */ + writeb(0, rbtx4939_softint_addr); + + txx9_irq_dispatch = rbtx4939_irq_dispatch; + + tx4939_irq_init(); + for (i = RBTX4939_IRQ_IOC; + i < RBTX4939_IRQ_IOC + RBTX4939_NR_IRQ_IOC; i++) + set_irq_chip_and_handler(i, &rbtx4939_ioc_irq_chip, + handle_level_irq); + + set_irq_chained_handler(RBTX4939_IRQ_IOCINT, handle_simple_irq); +} diff --git a/arch/mips/txx9/rbtx4939/prom.c b/arch/mips/txx9/rbtx4939/prom.c new file mode 100644 index 000000000000..bd277ecb4ad6 --- /dev/null +++ b/arch/mips/txx9/rbtx4939/prom.c @@ -0,0 +1,17 @@ +/* + * rbtx4939 specific prom routines + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include +#include +#include + +void __init rbtx4939_prom_init(void) +{ + tx4939_add_memory_regions(); + txx9_sio_putchar_init(TX4939_SIO_REG(0) & 0xfffffffffULL); +} diff --git a/arch/mips/txx9/rbtx4939/setup.c b/arch/mips/txx9/rbtx4939/setup.c new file mode 100644 index 000000000000..277864d5e779 --- /dev/null +++ b/arch/mips/txx9/rbtx4939/setup.c @@ -0,0 +1,306 @@ +/* + * Toshiba RBTX4939 setup routines. + * Based on linux/arch/mips/txx9/rbtx4938/setup.c, + * and RBTX49xx patch from CELF patch archive. + * + * Copyright (C) 2000-2001,2005-2007 Toshiba Corporation + * 2003-2005 (c) MontaVista Software, Inc. 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 +#include +#include +#include +#include +#include +#include +#include +#include + +static void rbtx4939_machine_restart(char *command) +{ + local_irq_disable(); + writeb(1, rbtx4939_reseten_addr); + writeb(1, rbtx4939_softreset_addr); + while (1) + ; +} + +static void __init rbtx4939_time_init(void) +{ + tx4939_time_init(0); +} + +static void __init rbtx4939_pci_setup(void) +{ +#ifdef CONFIG_PCI + int extarb = !(__raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_PCIARB); + struct pci_controller *c = &txx9_primary_pcic; + + register_pci_controller(c); + + tx4939_report_pciclk(); + tx4927_pcic_setup(tx4939_pcicptr, c, extarb); + if (!(__raw_readq(&tx4939_ccfgptr->pcfg) & TX4939_PCFG_ATA1MODE) && + (__raw_readq(&tx4939_ccfgptr->pcfg) & + (TX4939_PCFG_ET0MODE | TX4939_PCFG_ET1MODE))) { + tx4939_report_pci1clk(); + + /* mem:64K(max), io:64K(max) (enough for ETH0,ETH1) */ + c = txx9_alloc_pci_controller(NULL, 0, 0x10000, 0, 0x10000); + register_pci_controller(c); + tx4927_pcic_setup(tx4939_pcic1ptr, c, 0); + } + + tx4939_setup_pcierr_irq(); +#endif /* CONFIG_PCI */ +} + +static unsigned long long default_ebccr[] __initdata = { + 0x01c0000000007608ULL, /* 64M ROM */ + 0x017f000000007049ULL, /* 1M IOC */ + 0x0180000000408608ULL, /* ISA */ + 0, +}; + +static void __init rbtx4939_ebusc_setup(void) +{ + int i; + unsigned int sp; + + /* use user-configured speed */ + sp = TX4939_EBUSC_CR(0) & 0x30; + default_ebccr[0] |= sp; + default_ebccr[1] |= sp; + default_ebccr[2] |= sp; + /* initialise by myself */ + for (i = 0; i < ARRAY_SIZE(default_ebccr); i++) { + if (default_ebccr[i]) + ____raw_writeq(default_ebccr[i], + &tx4939_ebuscptr->cr[i]); + else + ____raw_writeq(____raw_readq(&tx4939_ebuscptr->cr[i]) + & ~8, + &tx4939_ebuscptr->cr[i]); + } +} + +static void __init rbtx4939_update_ioc_pen(void) +{ + __u64 pcfg = ____raw_readq(&tx4939_ccfgptr->pcfg); + __u64 ccfg = ____raw_readq(&tx4939_ccfgptr->ccfg); + __u8 pe1 = readb(rbtx4939_pe1_addr); + __u8 pe2 = readb(rbtx4939_pe2_addr); + __u8 pe3 = readb(rbtx4939_pe3_addr); + if (pcfg & TX4939_PCFG_ATA0MODE) + pe1 |= RBTX4939_PE1_ATA(0); + else + pe1 &= ~RBTX4939_PE1_ATA(0); + if (pcfg & TX4939_PCFG_ATA1MODE) { + pe1 |= RBTX4939_PE1_ATA(1); + pe1 &= ~(RBTX4939_PE1_RMII(0) | RBTX4939_PE1_RMII(1)); + } else { + pe1 &= ~RBTX4939_PE1_ATA(1); + if (pcfg & TX4939_PCFG_ET0MODE) + pe1 |= RBTX4939_PE1_RMII(0); + else + pe1 &= ~RBTX4939_PE1_RMII(0); + if (pcfg & TX4939_PCFG_ET1MODE) + pe1 |= RBTX4939_PE1_RMII(1); + else + pe1 &= ~RBTX4939_PE1_RMII(1); + } + if (ccfg & TX4939_CCFG_PTSEL) + pe3 &= ~(RBTX4939_PE3_VP | RBTX4939_PE3_VP_P | + RBTX4939_PE3_VP_S); + else { + __u64 vmode = pcfg & + (TX4939_PCFG_VSSMODE | TX4939_PCFG_VPSMODE); + if (vmode == 0) + pe3 &= ~(RBTX4939_PE3_VP | RBTX4939_PE3_VP_P | + RBTX4939_PE3_VP_S); + else if (vmode == TX4939_PCFG_VPSMODE) { + pe3 |= RBTX4939_PE3_VP_P; + pe3 &= ~(RBTX4939_PE3_VP | RBTX4939_PE3_VP_S); + } else if (vmode == TX4939_PCFG_VSSMODE) { + pe3 |= RBTX4939_PE3_VP | RBTX4939_PE3_VP_S; + pe3 &= ~RBTX4939_PE3_VP_P; + } else { + pe3 |= RBTX4939_PE3_VP | RBTX4939_PE3_VP_P; + pe3 &= ~RBTX4939_PE3_VP_S; + } + } + if (pcfg & TX4939_PCFG_SPIMODE) { + if (pcfg & TX4939_PCFG_SIO2MODE_GPIO) + pe2 &= ~(RBTX4939_PE2_SIO2 | RBTX4939_PE2_SIO0); + else { + if (pcfg & TX4939_PCFG_SIO2MODE_SIO2) { + pe2 |= RBTX4939_PE2_SIO2; + pe2 &= ~RBTX4939_PE2_SIO0; + } else { + pe2 |= RBTX4939_PE2_SIO0; + pe2 &= ~RBTX4939_PE2_SIO2; + } + } + if (pcfg & TX4939_PCFG_SIO3MODE) + pe2 |= RBTX4939_PE2_SIO3; + else + pe2 &= ~RBTX4939_PE2_SIO3; + pe2 &= ~RBTX4939_PE2_SPI; + } else { + pe2 |= RBTX4939_PE2_SPI; + pe2 &= ~(RBTX4939_PE2_SIO3 | RBTX4939_PE2_SIO2 | + RBTX4939_PE2_SIO0); + } + if ((pcfg & TX4939_PCFG_I2SMODE_MASK) == TX4939_PCFG_I2SMODE_GPIO) + pe2 |= RBTX4939_PE2_GPIO; + else + pe2 &= ~RBTX4939_PE2_GPIO; + writeb(pe1, rbtx4939_pe1_addr); + writeb(pe2, rbtx4939_pe2_addr); + writeb(pe3, rbtx4939_pe3_addr); +} + +#define RBTX4939_MAX_7SEGLEDS 8 + +#if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) +static u8 led_val[RBTX4939_MAX_7SEGLEDS]; +struct rbtx4939_led_data { + struct led_classdev cdev; + char name[32]; + unsigned int num; +}; + +/* Use "dot" in 7seg LEDs */ +static void rbtx4939_led_brightness_set(struct led_classdev *led_cdev, + enum led_brightness value) +{ + struct rbtx4939_led_data *led_dat = + container_of(led_cdev, struct rbtx4939_led_data, cdev); + unsigned int num = led_dat->num; + unsigned long flags; + + local_irq_save(flags); + led_val[num] = (led_val[num] & 0x7f) | (value ? 0x80 : 0); + writeb(led_val[num], rbtx4939_7seg_addr(num / 4, num % 4)); + local_irq_restore(flags); +} + +static int __init rbtx4939_led_probe(struct platform_device *pdev) +{ + struct rbtx4939_led_data *leds_data; + int i; + static char *default_triggers[] __initdata = { + "heartbeat", + "ide-disk", + "nand-disk", + }; + + leds_data = kzalloc(sizeof(*leds_data) * RBTX4939_MAX_7SEGLEDS, + GFP_KERNEL); + if (!leds_data) + return -ENOMEM; + for (i = 0; i < RBTX4939_MAX_7SEGLEDS; i++) { + int rc; + struct rbtx4939_led_data *led_dat = &leds_data[i]; + + led_dat->num = i; + led_dat->cdev.brightness_set = rbtx4939_led_brightness_set; + sprintf(led_dat->name, "rbtx4939:amber:%u", i); + led_dat->cdev.name = led_dat->name; + if (i < ARRAY_SIZE(default_triggers)) + led_dat->cdev.default_trigger = default_triggers[i]; + rc = led_classdev_register(&pdev->dev, &led_dat->cdev); + if (rc < 0) + return rc; + led_dat->cdev.brightness_set(&led_dat->cdev, 0); + } + return 0; + +} + +static struct platform_driver rbtx4939_led_driver = { + .driver = { + .name = "rbtx4939-led", + .owner = THIS_MODULE, + }, +}; + +static void __init rbtx4939_led_setup(void) +{ + platform_device_register_simple("rbtx4939-led", -1, NULL, 0); + platform_driver_probe(&rbtx4939_led_driver, rbtx4939_led_probe); +} +#else +static inline void rbtx4939_led_setup(void) +{ +} +#endif + +static void __init rbtx4939_arch_init(void) +{ + rbtx4939_pci_setup(); +} + +static void __init rbtx4939_device_init(void) +{ +#if defined(CONFIG_TC35815) || defined(CONFIG_TC35815_MODULE) + int i, j; + unsigned char ethaddr[2][6]; + for (i = 0; i < 2; i++) { + unsigned long area = CKSEG1 + 0x1fff0000 + (i * 0x10); + if (readb(rbtx4939_bdipsw_addr) & 8) { + u16 buf[3]; + area -= 0x03000000; + for (j = 0; j < 3; j++) + buf[j] = le16_to_cpup((u16 *)(area + j * 2)); + memcpy(ethaddr[i], buf, 6); + } else + memcpy(ethaddr[i], (void *)area, 6); + } + tx4939_ethaddr_init(ethaddr[0], ethaddr[1]); +#endif + rbtx4939_led_setup(); + tx4939_wdt_init(); +} + +static void __init rbtx4939_setup(void) +{ + rbtx4939_ebusc_setup(); + /* always enable ATA0 */ + txx9_set64(&tx4939_ccfgptr->pcfg, TX4939_PCFG_ATA0MODE); + rbtx4939_update_ioc_pen(); + if (txx9_master_clock == 0) + txx9_master_clock = 20000000; + tx4939_setup(); + + _machine_restart = rbtx4939_machine_restart; + + pr_info("RBTX4939 (Rev %02x) --- FPGA(Rev %02x) DIPSW:%02x,%02x\n", + readb(rbtx4939_board_rev_addr), readb(rbtx4939_ioc_rev_addr), + readb(rbtx4939_udipsw_addr), readb(rbtx4939_bdipsw_addr)); + +#ifdef CONFIG_PCI + txx9_alloc_pci_controller(&txx9_primary_pcic, 0, 0, 0, 0); + txx9_board_pcibios_setup = tx4927_pcibios_setup; +#else + set_io_port_base(RBTX4939_ETHER_BASE); +#endif + + tx4939_sio_init(TX4939_SCLK0(txx9_master_clock), 0); +} + +struct txx9_board_vec rbtx4939_vec __initdata = { + .system = "Tothiba RBTX4939", + .prom_init = rbtx4939_prom_init, + .mem_setup = rbtx4939_setup, + .irq_setup = rbtx4939_irq_setup, + .time_init = rbtx4939_time_init, + .device_init = rbtx4939_device_init, + .arch_init = rbtx4939_arch_init, +#ifdef CONFIG_PCI + .pci_map_irq = tx4939_pci_map_irq, +#endif +}; diff --git a/include/asm-mips/txx9/boards.h b/include/asm-mips/txx9/boards.h index 4abc8142fbb7..cbe9476d963e 100644 --- a/include/asm-mips/txx9/boards.h +++ b/include/asm-mips/txx9/boards.h @@ -8,3 +8,6 @@ BOARD_VEC(rbtx4937_vec) #ifdef CONFIG_TOSHIBA_RBTX4938 BOARD_VEC(rbtx4938_vec) #endif +#ifdef CONFIG_TOSHIBA_RBTX4939 +BOARD_VEC(rbtx4939_vec) +#endif diff --git a/include/asm-mips/txx9/rbtx4939.h b/include/asm-mips/txx9/rbtx4939.h new file mode 100644 index 000000000000..1acf428c0b4f --- /dev/null +++ b/include/asm-mips/txx9/rbtx4939.h @@ -0,0 +1,133 @@ +/* + * Definitions for RBTX4939 + * + * (C) Copyright TOSHIBA CORPORATION 2005-2006 + * 2003-2005 (c) MontaVista Software, Inc. 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. + */ +#ifndef __ASM_TXX9_RBTX4939_H +#define __ASM_TXX9_RBTX4939_H + +#include +#include +#include +#include + +/* Address map */ +#define RBTX4939_IOC_REG_ADDR (IO_BASE + TXX9_CE(1) + 0x00000000) +#define RBTX4939_BOARD_REV_ADDR (IO_BASE + TXX9_CE(1) + 0x00000000) +#define RBTX4939_IOC_REV_ADDR (IO_BASE + TXX9_CE(1) + 0x00000002) +#define RBTX4939_CONFIG1_ADDR (IO_BASE + TXX9_CE(1) + 0x00000004) +#define RBTX4939_CONFIG2_ADDR (IO_BASE + TXX9_CE(1) + 0x00000006) +#define RBTX4939_CONFIG3_ADDR (IO_BASE + TXX9_CE(1) + 0x00000008) +#define RBTX4939_CONFIG4_ADDR (IO_BASE + TXX9_CE(1) + 0x0000000a) +#define RBTX4939_USTAT_ADDR (IO_BASE + TXX9_CE(1) + 0x00001000) +#define RBTX4939_UDIPSW_ADDR (IO_BASE + TXX9_CE(1) + 0x00001002) +#define RBTX4939_BDIPSW_ADDR (IO_BASE + TXX9_CE(1) + 0x00001004) +#define RBTX4939_IEN_ADDR (IO_BASE + TXX9_CE(1) + 0x00002000) +#define RBTX4939_IPOL_ADDR (IO_BASE + TXX9_CE(1) + 0x00002002) +#define RBTX4939_IFAC1_ADDR (IO_BASE + TXX9_CE(1) + 0x00002004) +#define RBTX4939_IFAC2_ADDR (IO_BASE + TXX9_CE(1) + 0x00002006) +#define RBTX4939_SOFTINT_ADDR (IO_BASE + TXX9_CE(1) + 0x00003000) +#define RBTX4939_ISASTAT_ADDR (IO_BASE + TXX9_CE(1) + 0x00004000) +#define RBTX4939_PCISTAT_ADDR (IO_BASE + TXX9_CE(1) + 0x00004002) +#define RBTX4939_ROME_ADDR (IO_BASE + TXX9_CE(1) + 0x00004004) +#define RBTX4939_SPICS_ADDR (IO_BASE + TXX9_CE(1) + 0x00004006) +#define RBTX4939_AUDI_ADDR (IO_BASE + TXX9_CE(1) + 0x00004008) +#define RBTX4939_ISAGPIO_ADDR (IO_BASE + TXX9_CE(1) + 0x0000400a) +#define RBTX4939_PE1_ADDR (IO_BASE + TXX9_CE(1) + 0x00005000) +#define RBTX4939_PE2_ADDR (IO_BASE + TXX9_CE(1) + 0x00005002) +#define RBTX4939_PE3_ADDR (IO_BASE + TXX9_CE(1) + 0x00005004) +#define RBTX4939_VP_ADDR (IO_BASE + TXX9_CE(1) + 0x00005006) +#define RBTX4939_VPRESET_ADDR (IO_BASE + TXX9_CE(1) + 0x00005008) +#define RBTX4939_VPSOUT_ADDR (IO_BASE + TXX9_CE(1) + 0x0000500a) +#define RBTX4939_VPSIN_ADDR (IO_BASE + TXX9_CE(1) + 0x0000500c) +#define RBTX4939_7SEG_ADDR(s, ch) \ + (IO_BASE + TXX9_CE(1) + 0x00006000 + (s) * 16 + ((ch) & 3) * 2) +#define RBTX4939_SOFTRESET_ADDR (IO_BASE + TXX9_CE(1) + 0x00007000) +#define RBTX4939_RESETEN_ADDR (IO_BASE + TXX9_CE(1) + 0x00007002) +#define RBTX4939_RESETSTAT_ADDR (IO_BASE + TXX9_CE(1) + 0x00007004) +#define RBTX4939_ETHER_BASE (IO_BASE + TXX9_CE(1) + 0x00020000) + +/* Ethernet port address */ +#define RBTX4939_ETHER_ADDR (RBTX4939_ETHER_BASE + 0x300) + +/* bits for IEN/IPOL/IFAC */ +#define RBTX4938_INTB_ISA0 0 +#define RBTX4938_INTB_ISA11 1 +#define RBTX4938_INTB_ISA12 2 +#define RBTX4938_INTB_ISA15 3 +#define RBTX4938_INTB_I2S 4 +#define RBTX4938_INTB_SW 5 +#define RBTX4938_INTF_ISA0 (1 << RBTX4938_INTB_ISA0) +#define RBTX4938_INTF_ISA11 (1 << RBTX4938_INTB_ISA11) +#define RBTX4938_INTF_ISA12 (1 << RBTX4938_INTB_ISA12) +#define RBTX4938_INTF_ISA15 (1 << RBTX4938_INTB_ISA15) +#define RBTX4938_INTF_I2S (1 << RBTX4938_INTB_I2S) +#define RBTX4938_INTF_SW (1 << RBTX4938_INTB_SW) + +/* bits for PE1,PE2,PE3 */ +#define RBTX4939_PE1_ATA(ch) (0x01 << (ch)) +#define RBTX4939_PE1_RMII(ch) (0x04 << (ch)) +#define RBTX4939_PE2_SIO0 0x01 +#define RBTX4939_PE2_SIO2 0x02 +#define RBTX4939_PE2_SIO3 0x04 +#define RBTX4939_PE2_CIR 0x08 +#define RBTX4939_PE2_SPI 0x10 +#define RBTX4939_PE2_GPIO 0x20 +#define RBTX4939_PE3_VP 0x01 +#define RBTX4939_PE3_VP_P 0x02 +#define RBTX4939_PE3_VP_S 0x04 + +#define rbtx4939_board_rev_addr ((u8 __iomem *)RBTX4939_BOARD_REV_ADDR) +#define rbtx4939_ioc_rev_addr ((u8 __iomem *)RBTX4939_IOC_REV_ADDR) +#define rbtx4939_config1_addr ((u8 __iomem *)RBTX4939_CONFIG1_ADDR) +#define rbtx4939_config2_addr ((u8 __iomem *)RBTX4939_CONFIG2_ADDR) +#define rbtx4939_config3_addr ((u8 __iomem *)RBTX4939_CONFIG3_ADDR) +#define rbtx4939_config4_addr ((u8 __iomem *)RBTX4939_CONFIG4_ADDR) +#define rbtx4939_ustat_addr ((u8 __iomem *)RBTX4939_USTAT_ADDR) +#define rbtx4939_udipsw_addr ((u8 __iomem *)RBTX4939_UDIPSW_ADDR) +#define rbtx4939_bdipsw_addr ((u8 __iomem *)RBTX4939_BDIPSW_ADDR) +#define rbtx4939_ien_addr ((u8 __iomem *)RBTX4939_IEN_ADDR) +#define rbtx4939_ipol_addr ((u8 __iomem *)RBTX4939_IPOL_ADDR) +#define rbtx4939_ifac1_addr ((u8 __iomem *)RBTX4939_IFAC1_ADDR) +#define rbtx4939_ifac2_addr ((u8 __iomem *)RBTX4939_IFAC2_ADDR) +#define rbtx4939_softint_addr ((u8 __iomem *)RBTX4939_SOFTINT_ADDR) +#define rbtx4939_isastat_addr ((u8 __iomem *)RBTX4939_ISASTAT_ADDR) +#define rbtx4939_pcistat_addr ((u8 __iomem *)RBTX4939_PCISTAT_ADDR) +#define rbtx4939_rome_addr ((u8 __iomem *)RBTX4939_ROME_ADDR) +#define rbtx4939_spics_addr ((u8 __iomem *)RBTX4939_SPICS_ADDR) +#define rbtx4939_audi_addr ((u8 __iomem *)RBTX4939_AUDI_ADDR) +#define rbtx4939_isagpio_addr ((u8 __iomem *)RBTX4939_ISAGPIO_ADDR) +#define rbtx4939_pe1_addr ((u8 __iomem *)RBTX4939_PE1_ADDR) +#define rbtx4939_pe2_addr ((u8 __iomem *)RBTX4939_PE2_ADDR) +#define rbtx4939_pe3_addr ((u8 __iomem *)RBTX4939_PE3_ADDR) +#define rbtx4939_vp_addr ((u8 __iomem *)RBTX4939_VP_ADDR) +#define rbtx4939_vpreset_addr ((u8 __iomem *)RBTX4939_VPRESET_ADDR) +#define rbtx4939_vpsout_addr ((u8 __iomem *)RBTX4939_VPSOUT_ADDR) +#define rbtx4939_vpsin_addr ((u8 __iomem *)RBTX4939_VPSIN_ADDR) +#define rbtx4939_7seg_addr(s, ch) \ + ((u8 __iomem *)RBTX4939_7SEG_ADDR(s, ch)) +#define rbtx4939_softreset_addr ((u8 __iomem *)RBTX4939_SOFTRESET_ADDR) +#define rbtx4939_reseten_addr ((u8 __iomem *)RBTX4939_RESETEN_ADDR) +#define rbtx4939_resetstat_addr ((u8 __iomem *)RBTX4939_RESETSTAT_ADDR) + +/* + * IRQ mappings + */ +#define RBTX4939_NR_IRQ_IOC 8 + +#define RBTX4939_IRQ_IOC (TXX9_IRQ_BASE + TX4939_NUM_IR) +#define RBTX4939_IRQ_END (RBTX4939_IRQ_IOC + RBTX4939_NR_IRQ_IOC) + +/* IOC (ISA, etc) */ +#define RBTX4939_IRQ_IOCINT (TXX9_IRQ_BASE + TX4939_IR_INT(0)) +/* Onboard 10M Ether */ +#define RBTX4939_IRQ_ETHER (TXX9_IRQ_BASE + TX4939_IR_INT(1)) + +void rbtx4939_prom_init(void); +void rbtx4939_irq_setup(void); + +#endif /* __ASM_TXX9_RBTX4939_H */ -- cgit v1.2.3 From b6263ff2d6e58cc2fe615219ab2a06778b5e6cef Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Mon, 1 Sep 2008 22:22:41 +0900 Subject: MIPS: TXx9: Implement prom_free_prom_memory Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/txx9/generic/setup.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch/mips/txx9') diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c index 7a05c34c1dec..5526375010f8 100644 --- a/arch/mips/txx9/generic/setup.c +++ b/arch/mips/txx9/generic/setup.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -394,6 +395,11 @@ void __init prom_init(void) void __init prom_free_prom_memory(void) { + unsigned long saddr = PAGE_SIZE; + unsigned long eaddr = __pa_symbol(&_text); + + if (saddr < eaddr) + free_init_pages("prom memory", saddr, eaddr); } const char *get_system_type(void) -- cgit v1.2.3 From 4bacc68766b11c191ee1567f54103f109c002f4f Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Thu, 18 Sep 2008 00:13:58 +0900 Subject: MIPS: TXx9: Add TX4939 ATA support (v2) Add a helper routine to register tx4939ide driver and use it on RBTX4939 board. Signed-off-by: Atsushi Nemoto Acked-by: Sergei Shtylyov Signed-off-by: Ralf Baechle --- arch/mips/include/asm/txx9/tx4939.h | 1 + arch/mips/txx9/generic/setup_tx4939.c | 46 +++++++++++++++++++++++++++++++++++ arch/mips/txx9/rbtx4939/setup.c | 1 + 3 files changed, 48 insertions(+) (limited to 'arch/mips/txx9') diff --git a/arch/mips/include/asm/txx9/tx4939.h b/arch/mips/include/asm/txx9/tx4939.h index 7ce2dff3b7cc..88badb423010 100644 --- a/arch/mips/include/asm/txx9/tx4939.h +++ b/arch/mips/include/asm/txx9/tx4939.h @@ -540,5 +540,6 @@ void tx4939_setup_pcierr_irq(void); void tx4939_irq_init(void); int tx4939_irq(void); void tx4939_mtd_init(int ch); +void tx4939_ata_init(void); #endif /* __ASM_TXX9_TX4939_H */ diff --git a/arch/mips/txx9/generic/setup_tx4939.c b/arch/mips/txx9/generic/setup_tx4939.c index f14a497077da..6c0049a5bbc1 100644 --- a/arch/mips/txx9/generic/setup_tx4939.c +++ b/arch/mips/txx9/generic/setup_tx4939.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -389,6 +390,51 @@ void __init tx4939_mtd_init(int ch) txx9_physmap_flash_init(ch, start, size, &pdata); } +#define TX4939_ATA_REG_PHYS(ch) (TX4939_ATA_REG(ch) & 0xfffffffffULL) +void __init tx4939_ata_init(void) +{ + static struct resource ata0_res[] = { + { + .start = TX4939_ATA_REG_PHYS(0), + .end = TX4939_ATA_REG_PHYS(0) + 0x1000 - 1, + .flags = IORESOURCE_MEM, + }, { + .start = TXX9_IRQ_BASE + TX4939_IR_ATA(0), + .flags = IORESOURCE_IRQ, + }, + }; + static struct resource ata1_res[] = { + { + .start = TX4939_ATA_REG_PHYS(1), + .end = TX4939_ATA_REG_PHYS(1) + 0x1000 - 1, + .flags = IORESOURCE_MEM, + }, { + .start = TXX9_IRQ_BASE + TX4939_IR_ATA(1), + .flags = IORESOURCE_IRQ, + }, + }; + static struct platform_device ata0_dev = { + .name = "tx4939ide", + .id = 0, + .num_resources = ARRAY_SIZE(ata0_res), + .resource = ata0_res, + }; + static struct platform_device ata1_dev = { + .name = "tx4939ide", + .id = 1, + .num_resources = ARRAY_SIZE(ata1_res), + .resource = ata1_res, + }; + __u64 pcfg = __raw_readq(&tx4939_ccfgptr->pcfg); + + if (pcfg & TX4939_PCFG_ATA0MODE) + platform_device_register(&ata0_dev); + if ((pcfg & (TX4939_PCFG_ATA1MODE | + TX4939_PCFG_ET1MODE | + TX4939_PCFG_ET0MODE)) == TX4939_PCFG_ATA1MODE) + platform_device_register(&ata1_dev); +} + static void __init tx4939_stop_unused_modules(void) { __u64 pcfg, rst = 0, ckd = 0; diff --git a/arch/mips/txx9/rbtx4939/setup.c b/arch/mips/txx9/rbtx4939/setup.c index 277864d5e779..9855d7bccc20 100644 --- a/arch/mips/txx9/rbtx4939/setup.c +++ b/arch/mips/txx9/rbtx4939/setup.c @@ -264,6 +264,7 @@ static void __init rbtx4939_device_init(void) #endif rbtx4939_led_setup(); tx4939_wdt_init(); + tx4939_ata_init(); } static void __init rbtx4939_setup(void) -- cgit v1.2.3