189d63fe1SAtsushi Nemoto /* 289d63fe1SAtsushi Nemoto * linux/arch/mips/txx9/generic/setup.c 389d63fe1SAtsushi Nemoto * 489d63fe1SAtsushi Nemoto * Based on linux/arch/mips/txx9/rbtx4938/setup.c, 589d63fe1SAtsushi Nemoto * and RBTX49xx patch from CELF patch archive. 689d63fe1SAtsushi Nemoto * 789d63fe1SAtsushi Nemoto * 2003-2005 (c) MontaVista Software, Inc. 889d63fe1SAtsushi Nemoto * (C) Copyright TOSHIBA CORPORATION 2000-2001, 2004-2007 989d63fe1SAtsushi Nemoto * 1089d63fe1SAtsushi Nemoto * This file is subject to the terms and conditions of the GNU General Public 1189d63fe1SAtsushi Nemoto * License. See the file "COPYING" in the main directory of this archive 1289d63fe1SAtsushi Nemoto * for more details. 1389d63fe1SAtsushi Nemoto */ 1489d63fe1SAtsushi Nemoto #include <linux/init.h> 1589d63fe1SAtsushi Nemoto #include <linux/kernel.h> 1689d63fe1SAtsushi Nemoto #include <linux/types.h> 17edcaf1a6SAtsushi Nemoto #include <linux/interrupt.h> 18edcaf1a6SAtsushi Nemoto #include <linux/string.h> 19edcaf1a6SAtsushi Nemoto #include <linux/module.h> 20edcaf1a6SAtsushi Nemoto #include <linux/clk.h> 21edcaf1a6SAtsushi Nemoto #include <linux/err.h> 22e0eb7307SAtsushi Nemoto #include <linux/gpio.h> 2368314725SAtsushi Nemoto #include <linux/platform_device.h> 247779a5e0SAtsushi Nemoto #include <linux/serial_core.h> 2551f607c7SAtsushi Nemoto #include <linux/mtd/physmap.h> 26ae027eadSAtsushi Nemoto #include <linux/leds.h> 27edcaf1a6SAtsushi Nemoto #include <asm/bootinfo.h> 28e0eb7307SAtsushi Nemoto #include <asm/time.h> 29a49297e8SAtsushi Nemoto #include <asm/reboot.h> 30d10e025fSAtsushi Nemoto #include <asm/r4kcache.h> 31b6263ff2SAtsushi Nemoto #include <asm/sections.h> 3289d63fe1SAtsushi Nemoto #include <asm/txx9/generic.h> 3307517529SAtsushi Nemoto #include <asm/txx9/pci.h> 34496a3b5cSAtsushi Nemoto #include <asm/txx9tmr.h> 35a591f5d3SAtsushi Nemoto #include <asm/txx9/ndfmc.h> 36*f48c8c95SAtsushi Nemoto #include <asm/txx9/dmac.h> 37edcaf1a6SAtsushi Nemoto #ifdef CONFIG_CPU_TX49XX 38edcaf1a6SAtsushi Nemoto #include <asm/txx9/tx4938.h> 39edcaf1a6SAtsushi Nemoto #endif 4089d63fe1SAtsushi Nemoto 4189d63fe1SAtsushi Nemoto /* EBUSC settings of TX4927, etc. */ 4289d63fe1SAtsushi Nemoto struct resource txx9_ce_res[8]; 4389d63fe1SAtsushi Nemoto static char txx9_ce_res_name[8][4]; /* "CEn" */ 4489d63fe1SAtsushi Nemoto 4589d63fe1SAtsushi Nemoto /* pcode, internal register */ 4694a4c329SAtsushi Nemoto unsigned int txx9_pcode; 4789d63fe1SAtsushi Nemoto char txx9_pcode_str[8]; 4889d63fe1SAtsushi Nemoto static struct resource txx9_reg_res = { 4989d63fe1SAtsushi Nemoto .name = txx9_pcode_str, 5089d63fe1SAtsushi Nemoto .flags = IORESOURCE_MEM, 5189d63fe1SAtsushi Nemoto }; 5289d63fe1SAtsushi Nemoto void __init 5389d63fe1SAtsushi Nemoto txx9_reg_res_init(unsigned int pcode, unsigned long base, unsigned long size) 5489d63fe1SAtsushi Nemoto { 5589d63fe1SAtsushi Nemoto int i; 5689d63fe1SAtsushi Nemoto 5789d63fe1SAtsushi Nemoto for (i = 0; i < ARRAY_SIZE(txx9_ce_res); i++) { 5889d63fe1SAtsushi Nemoto sprintf(txx9_ce_res_name[i], "CE%d", i); 5989d63fe1SAtsushi Nemoto txx9_ce_res[i].flags = IORESOURCE_MEM; 6089d63fe1SAtsushi Nemoto txx9_ce_res[i].name = txx9_ce_res_name[i]; 6189d63fe1SAtsushi Nemoto } 6289d63fe1SAtsushi Nemoto 63073828d0SAtsushi Nemoto txx9_pcode = pcode; 6489d63fe1SAtsushi Nemoto sprintf(txx9_pcode_str, "TX%x", pcode); 6589d63fe1SAtsushi Nemoto if (base) { 6689d63fe1SAtsushi Nemoto txx9_reg_res.start = base & 0xfffffffffULL; 6789d63fe1SAtsushi Nemoto txx9_reg_res.end = (base & 0xfffffffffULL) + (size - 1); 6889d63fe1SAtsushi Nemoto request_resource(&iomem_resource, &txx9_reg_res); 6989d63fe1SAtsushi Nemoto } 7089d63fe1SAtsushi Nemoto } 7189d63fe1SAtsushi Nemoto 7289d63fe1SAtsushi Nemoto /* clocks */ 7389d63fe1SAtsushi Nemoto unsigned int txx9_master_clock; 7489d63fe1SAtsushi Nemoto unsigned int txx9_cpu_clock; 7589d63fe1SAtsushi Nemoto unsigned int txx9_gbus_clock; 76edcaf1a6SAtsushi Nemoto 77c7b95bcbSAtsushi Nemoto #ifdef CONFIG_CPU_TX39XX 78c7b95bcbSAtsushi Nemoto /* don't enable by default - see errata */ 79c7b95bcbSAtsushi Nemoto int txx9_ccfg_toeon __initdata; 80c7b95bcbSAtsushi Nemoto #else 8194a4c329SAtsushi Nemoto int txx9_ccfg_toeon __initdata = 1; 82c7b95bcbSAtsushi Nemoto #endif 83edcaf1a6SAtsushi Nemoto 84edcaf1a6SAtsushi Nemoto /* Minimum CLK support */ 85edcaf1a6SAtsushi Nemoto 86edcaf1a6SAtsushi Nemoto struct clk *clk_get(struct device *dev, const char *id) 87edcaf1a6SAtsushi Nemoto { 88edcaf1a6SAtsushi Nemoto if (!strcmp(id, "spi-baseclk")) 8994a4c329SAtsushi Nemoto return (struct clk *)((unsigned long)txx9_gbus_clock / 2 / 4); 90edcaf1a6SAtsushi Nemoto if (!strcmp(id, "imbus_clk")) 9194a4c329SAtsushi Nemoto return (struct clk *)((unsigned long)txx9_gbus_clock / 2); 92edcaf1a6SAtsushi Nemoto return ERR_PTR(-ENOENT); 93edcaf1a6SAtsushi Nemoto } 94edcaf1a6SAtsushi Nemoto EXPORT_SYMBOL(clk_get); 95edcaf1a6SAtsushi Nemoto 96edcaf1a6SAtsushi Nemoto int clk_enable(struct clk *clk) 97edcaf1a6SAtsushi Nemoto { 98edcaf1a6SAtsushi Nemoto return 0; 99edcaf1a6SAtsushi Nemoto } 100edcaf1a6SAtsushi Nemoto EXPORT_SYMBOL(clk_enable); 101edcaf1a6SAtsushi Nemoto 102edcaf1a6SAtsushi Nemoto void clk_disable(struct clk *clk) 103edcaf1a6SAtsushi Nemoto { 104edcaf1a6SAtsushi Nemoto } 105edcaf1a6SAtsushi Nemoto EXPORT_SYMBOL(clk_disable); 106edcaf1a6SAtsushi Nemoto 107edcaf1a6SAtsushi Nemoto unsigned long clk_get_rate(struct clk *clk) 108edcaf1a6SAtsushi Nemoto { 109edcaf1a6SAtsushi Nemoto return (unsigned long)clk; 110edcaf1a6SAtsushi Nemoto } 111edcaf1a6SAtsushi Nemoto EXPORT_SYMBOL(clk_get_rate); 112edcaf1a6SAtsushi Nemoto 113edcaf1a6SAtsushi Nemoto void clk_put(struct clk *clk) 114edcaf1a6SAtsushi Nemoto { 115edcaf1a6SAtsushi Nemoto } 116edcaf1a6SAtsushi Nemoto EXPORT_SYMBOL(clk_put); 117edcaf1a6SAtsushi Nemoto 1188d795f2aSAtsushi Nemoto /* GPIO support */ 1198d795f2aSAtsushi Nemoto 1208d795f2aSAtsushi Nemoto #ifdef CONFIG_GENERIC_GPIO 1218d795f2aSAtsushi Nemoto int gpio_to_irq(unsigned gpio) 1228d795f2aSAtsushi Nemoto { 1238d795f2aSAtsushi Nemoto return -EINVAL; 1248d795f2aSAtsushi Nemoto } 1258d795f2aSAtsushi Nemoto EXPORT_SYMBOL(gpio_to_irq); 1268d795f2aSAtsushi Nemoto 1278d795f2aSAtsushi Nemoto int irq_to_gpio(unsigned irq) 1288d795f2aSAtsushi Nemoto { 1298d795f2aSAtsushi Nemoto return -EINVAL; 1308d795f2aSAtsushi Nemoto } 1318d795f2aSAtsushi Nemoto EXPORT_SYMBOL(irq_to_gpio); 1328d795f2aSAtsushi Nemoto #endif 1338d795f2aSAtsushi Nemoto 134860e546cSAtsushi Nemoto #define BOARD_VEC(board) extern struct txx9_board_vec board; 135860e546cSAtsushi Nemoto #include <asm/txx9/boards.h> 136860e546cSAtsushi Nemoto #undef BOARD_VEC 137edcaf1a6SAtsushi Nemoto 138edcaf1a6SAtsushi Nemoto struct txx9_board_vec *txx9_board_vec __initdata; 139edcaf1a6SAtsushi Nemoto static char txx9_system_type[32]; 140edcaf1a6SAtsushi Nemoto 141860e546cSAtsushi Nemoto static struct txx9_board_vec *board_vecs[] __initdata = { 142860e546cSAtsushi Nemoto #define BOARD_VEC(board) &board, 143860e546cSAtsushi Nemoto #include <asm/txx9/boards.h> 144860e546cSAtsushi Nemoto #undef BOARD_VEC 145860e546cSAtsushi Nemoto }; 146860e546cSAtsushi Nemoto 147860e546cSAtsushi Nemoto static struct txx9_board_vec *__init find_board_byname(const char *name) 148860e546cSAtsushi Nemoto { 149860e546cSAtsushi Nemoto int i; 150860e546cSAtsushi Nemoto 151860e546cSAtsushi Nemoto /* search board_vecs table */ 152860e546cSAtsushi Nemoto for (i = 0; i < ARRAY_SIZE(board_vecs); i++) { 153860e546cSAtsushi Nemoto if (strstr(board_vecs[i]->system, name)) 154860e546cSAtsushi Nemoto return board_vecs[i]; 155860e546cSAtsushi Nemoto } 156860e546cSAtsushi Nemoto return NULL; 157860e546cSAtsushi Nemoto } 158860e546cSAtsushi Nemoto 159e0dfb20cSAtsushi Nemoto static void __init prom_init_cmdline(void) 160edcaf1a6SAtsushi Nemoto { 16197b0511cSGeert Uytterhoeven int argc; 16297b0511cSGeert Uytterhoeven int *argv32; 163edcaf1a6SAtsushi Nemoto int i; /* Always ignore the "-c" at argv[0] */ 164e0dfb20cSAtsushi Nemoto char builtin[CL_SIZE]; 165edcaf1a6SAtsushi Nemoto 16697b0511cSGeert Uytterhoeven if (fw_arg0 >= CKSEG0 || fw_arg1 < CKSEG0) { 16797b0511cSGeert Uytterhoeven /* 16897b0511cSGeert Uytterhoeven * argc is not a valid number, or argv32 is not a valid 16997b0511cSGeert Uytterhoeven * pointer 17097b0511cSGeert Uytterhoeven */ 17197b0511cSGeert Uytterhoeven argc = 0; 17297b0511cSGeert Uytterhoeven argv32 = NULL; 17397b0511cSGeert Uytterhoeven } else { 17497b0511cSGeert Uytterhoeven argc = (int)fw_arg0; 17597b0511cSGeert Uytterhoeven argv32 = (int *)fw_arg1; 17697b0511cSGeert Uytterhoeven } 17797b0511cSGeert Uytterhoeven 178edcaf1a6SAtsushi Nemoto /* ignore all built-in args if any f/w args given */ 179e0dfb20cSAtsushi Nemoto /* 180e0dfb20cSAtsushi Nemoto * But if built-in strings was started with '+', append them 181e0dfb20cSAtsushi Nemoto * to command line args. If built-in was started with '-', 182e0dfb20cSAtsushi Nemoto * ignore all f/w args. 183e0dfb20cSAtsushi Nemoto */ 184e0dfb20cSAtsushi Nemoto builtin[0] = '\0'; 185e0dfb20cSAtsushi Nemoto if (arcs_cmdline[0] == '+') 186e0dfb20cSAtsushi Nemoto strcpy(builtin, arcs_cmdline + 1); 187e0dfb20cSAtsushi Nemoto else if (arcs_cmdline[0] == '-') { 188e0dfb20cSAtsushi Nemoto strcpy(builtin, arcs_cmdline + 1); 189e0dfb20cSAtsushi Nemoto argc = 0; 190e0dfb20cSAtsushi Nemoto } else if (argc <= 1) 191e0dfb20cSAtsushi Nemoto strcpy(builtin, arcs_cmdline); 192e0dfb20cSAtsushi Nemoto arcs_cmdline[0] = '\0'; 193edcaf1a6SAtsushi Nemoto 194edcaf1a6SAtsushi Nemoto for (i = 1; i < argc; i++) { 195e0dfb20cSAtsushi Nemoto char *str = (char *)(long)argv32[i]; 196edcaf1a6SAtsushi Nemoto if (i != 1) 197edcaf1a6SAtsushi Nemoto strcat(arcs_cmdline, " "); 198e0dfb20cSAtsushi Nemoto if (strchr(str, ' ')) { 199e0dfb20cSAtsushi Nemoto strcat(arcs_cmdline, "\""); 200e0dfb20cSAtsushi Nemoto strcat(arcs_cmdline, str); 201e0dfb20cSAtsushi Nemoto strcat(arcs_cmdline, "\""); 202e0dfb20cSAtsushi Nemoto } else 203e0dfb20cSAtsushi Nemoto strcat(arcs_cmdline, str); 204e0dfb20cSAtsushi Nemoto } 205e0dfb20cSAtsushi Nemoto /* append saved builtin args */ 206e0dfb20cSAtsushi Nemoto if (builtin[0]) { 207e0dfb20cSAtsushi Nemoto if (arcs_cmdline[0]) 208e0dfb20cSAtsushi Nemoto strcat(arcs_cmdline, " "); 209e0dfb20cSAtsushi Nemoto strcat(arcs_cmdline, builtin); 210edcaf1a6SAtsushi Nemoto } 211edcaf1a6SAtsushi Nemoto } 212edcaf1a6SAtsushi Nemoto 213d10e025fSAtsushi Nemoto static int txx9_ic_disable __initdata; 214d10e025fSAtsushi Nemoto static int txx9_dc_disable __initdata; 215d10e025fSAtsushi Nemoto 216d10e025fSAtsushi Nemoto #if defined(CONFIG_CPU_TX49XX) 217d10e025fSAtsushi Nemoto /* flush all cache on very early stage (before 4k_cache_init) */ 218d10e025fSAtsushi Nemoto static void __init early_flush_dcache(void) 219d10e025fSAtsushi Nemoto { 220d10e025fSAtsushi Nemoto unsigned int conf = read_c0_config(); 221d10e025fSAtsushi Nemoto unsigned int dc_size = 1 << (12 + ((conf & CONF_DC) >> 6)); 222d10e025fSAtsushi Nemoto unsigned int linesz = 32; 223d10e025fSAtsushi Nemoto unsigned long addr, end; 224d10e025fSAtsushi Nemoto 225d10e025fSAtsushi Nemoto end = INDEX_BASE + dc_size / 4; 226d10e025fSAtsushi Nemoto /* 4way, waybit=0 */ 227d10e025fSAtsushi Nemoto for (addr = INDEX_BASE; addr < end; addr += linesz) { 228d10e025fSAtsushi Nemoto cache_op(Index_Writeback_Inv_D, addr | 0); 229d10e025fSAtsushi Nemoto cache_op(Index_Writeback_Inv_D, addr | 1); 230d10e025fSAtsushi Nemoto cache_op(Index_Writeback_Inv_D, addr | 2); 231d10e025fSAtsushi Nemoto cache_op(Index_Writeback_Inv_D, addr | 3); 232d10e025fSAtsushi Nemoto } 233d10e025fSAtsushi Nemoto } 234d10e025fSAtsushi Nemoto 235d10e025fSAtsushi Nemoto static void __init txx9_cache_fixup(void) 236d10e025fSAtsushi Nemoto { 237d10e025fSAtsushi Nemoto unsigned int conf; 238d10e025fSAtsushi Nemoto 239d10e025fSAtsushi Nemoto conf = read_c0_config(); 240d10e025fSAtsushi Nemoto /* flush and disable */ 241d10e025fSAtsushi Nemoto if (txx9_ic_disable) { 242d10e025fSAtsushi Nemoto conf |= TX49_CONF_IC; 243d10e025fSAtsushi Nemoto write_c0_config(conf); 244d10e025fSAtsushi Nemoto } 245d10e025fSAtsushi Nemoto if (txx9_dc_disable) { 246d10e025fSAtsushi Nemoto early_flush_dcache(); 247d10e025fSAtsushi Nemoto conf |= TX49_CONF_DC; 248d10e025fSAtsushi Nemoto write_c0_config(conf); 249d10e025fSAtsushi Nemoto } 250d10e025fSAtsushi Nemoto 251d10e025fSAtsushi Nemoto /* enable cache */ 252d10e025fSAtsushi Nemoto conf = read_c0_config(); 253d10e025fSAtsushi Nemoto if (!txx9_ic_disable) 254d10e025fSAtsushi Nemoto conf &= ~TX49_CONF_IC; 255d10e025fSAtsushi Nemoto if (!txx9_dc_disable) 256d10e025fSAtsushi Nemoto conf &= ~TX49_CONF_DC; 257d10e025fSAtsushi Nemoto write_c0_config(conf); 258d10e025fSAtsushi Nemoto 259d10e025fSAtsushi Nemoto if (conf & TX49_CONF_IC) 260d10e025fSAtsushi Nemoto pr_info("TX49XX I-Cache disabled.\n"); 261d10e025fSAtsushi Nemoto if (conf & TX49_CONF_DC) 262d10e025fSAtsushi Nemoto pr_info("TX49XX D-Cache disabled.\n"); 263d10e025fSAtsushi Nemoto } 264d10e025fSAtsushi Nemoto #elif defined(CONFIG_CPU_TX39XX) 265d10e025fSAtsushi Nemoto /* flush all cache on very early stage (before tx39_cache_init) */ 266d10e025fSAtsushi Nemoto static void __init early_flush_dcache(void) 267d10e025fSAtsushi Nemoto { 268d10e025fSAtsushi Nemoto unsigned int conf = read_c0_config(); 269d10e025fSAtsushi Nemoto unsigned int dc_size = 1 << (10 + ((conf & TX39_CONF_DCS_MASK) >> 270d10e025fSAtsushi Nemoto TX39_CONF_DCS_SHIFT)); 271d10e025fSAtsushi Nemoto unsigned int linesz = 16; 272d10e025fSAtsushi Nemoto unsigned long addr, end; 273d10e025fSAtsushi Nemoto 274d10e025fSAtsushi Nemoto end = INDEX_BASE + dc_size / 2; 275d10e025fSAtsushi Nemoto /* 2way, waybit=0 */ 276d10e025fSAtsushi Nemoto for (addr = INDEX_BASE; addr < end; addr += linesz) { 277d10e025fSAtsushi Nemoto cache_op(Index_Writeback_Inv_D, addr | 0); 278d10e025fSAtsushi Nemoto cache_op(Index_Writeback_Inv_D, addr | 1); 279d10e025fSAtsushi Nemoto } 280d10e025fSAtsushi Nemoto } 281d10e025fSAtsushi Nemoto 282d10e025fSAtsushi Nemoto static void __init txx9_cache_fixup(void) 283d10e025fSAtsushi Nemoto { 284d10e025fSAtsushi Nemoto unsigned int conf; 285d10e025fSAtsushi Nemoto 286d10e025fSAtsushi Nemoto conf = read_c0_config(); 287d10e025fSAtsushi Nemoto /* flush and disable */ 288d10e025fSAtsushi Nemoto if (txx9_ic_disable) { 289d10e025fSAtsushi Nemoto conf &= ~TX39_CONF_ICE; 290d10e025fSAtsushi Nemoto write_c0_config(conf); 291d10e025fSAtsushi Nemoto } 292d10e025fSAtsushi Nemoto if (txx9_dc_disable) { 293d10e025fSAtsushi Nemoto early_flush_dcache(); 294d10e025fSAtsushi Nemoto conf &= ~TX39_CONF_DCE; 295d10e025fSAtsushi Nemoto write_c0_config(conf); 296d10e025fSAtsushi Nemoto } 297d10e025fSAtsushi Nemoto 298d10e025fSAtsushi Nemoto /* enable cache */ 299d10e025fSAtsushi Nemoto conf = read_c0_config(); 300d10e025fSAtsushi Nemoto if (!txx9_ic_disable) 301d10e025fSAtsushi Nemoto conf |= TX39_CONF_ICE; 302d10e025fSAtsushi Nemoto if (!txx9_dc_disable) 303d10e025fSAtsushi Nemoto conf |= TX39_CONF_DCE; 304d10e025fSAtsushi Nemoto write_c0_config(conf); 305d10e025fSAtsushi Nemoto 306d10e025fSAtsushi Nemoto if (!(conf & TX39_CONF_ICE)) 307d10e025fSAtsushi Nemoto pr_info("TX39XX I-Cache disabled.\n"); 308d10e025fSAtsushi Nemoto if (!(conf & TX39_CONF_DCE)) 309d10e025fSAtsushi Nemoto pr_info("TX39XX D-Cache disabled.\n"); 310d10e025fSAtsushi Nemoto } 311d10e025fSAtsushi Nemoto #else 312d10e025fSAtsushi Nemoto static inline void txx9_cache_fixup(void) 313d10e025fSAtsushi Nemoto { 314d10e025fSAtsushi Nemoto } 315d10e025fSAtsushi Nemoto #endif 316d10e025fSAtsushi Nemoto 317860e546cSAtsushi Nemoto static void __init preprocess_cmdline(void) 318edcaf1a6SAtsushi Nemoto { 319860e546cSAtsushi Nemoto char cmdline[CL_SIZE]; 320860e546cSAtsushi Nemoto char *s; 321860e546cSAtsushi Nemoto 322860e546cSAtsushi Nemoto strcpy(cmdline, arcs_cmdline); 323860e546cSAtsushi Nemoto s = cmdline; 324860e546cSAtsushi Nemoto arcs_cmdline[0] = '\0'; 325860e546cSAtsushi Nemoto while (s && *s) { 326860e546cSAtsushi Nemoto char *str = strsep(&s, " "); 327860e546cSAtsushi Nemoto if (strncmp(str, "board=", 6) == 0) { 328860e546cSAtsushi Nemoto txx9_board_vec = find_board_byname(str + 6); 329860e546cSAtsushi Nemoto continue; 330860e546cSAtsushi Nemoto } else if (strncmp(str, "masterclk=", 10) == 0) { 331860e546cSAtsushi Nemoto unsigned long val; 332860e546cSAtsushi Nemoto if (strict_strtoul(str + 10, 10, &val) == 0) 333860e546cSAtsushi Nemoto txx9_master_clock = val; 334860e546cSAtsushi Nemoto continue; 335d10e025fSAtsushi Nemoto } else if (strcmp(str, "icdisable") == 0) { 336d10e025fSAtsushi Nemoto txx9_ic_disable = 1; 337d10e025fSAtsushi Nemoto continue; 338d10e025fSAtsushi Nemoto } else if (strcmp(str, "dcdisable") == 0) { 339d10e025fSAtsushi Nemoto txx9_dc_disable = 1; 340d10e025fSAtsushi Nemoto continue; 341c7b95bcbSAtsushi Nemoto } else if (strcmp(str, "toeoff") == 0) { 342c7b95bcbSAtsushi Nemoto txx9_ccfg_toeon = 0; 343c7b95bcbSAtsushi Nemoto continue; 344c7b95bcbSAtsushi Nemoto } else if (strcmp(str, "toeon") == 0) { 345c7b95bcbSAtsushi Nemoto txx9_ccfg_toeon = 1; 346c7b95bcbSAtsushi Nemoto continue; 347860e546cSAtsushi Nemoto } 348860e546cSAtsushi Nemoto if (arcs_cmdline[0]) 349860e546cSAtsushi Nemoto strcat(arcs_cmdline, " "); 350860e546cSAtsushi Nemoto strcat(arcs_cmdline, str); 351860e546cSAtsushi Nemoto } 352d10e025fSAtsushi Nemoto 353d10e025fSAtsushi Nemoto txx9_cache_fixup(); 354860e546cSAtsushi Nemoto } 355860e546cSAtsushi Nemoto 356860e546cSAtsushi Nemoto static void __init select_board(void) 357860e546cSAtsushi Nemoto { 358860e546cSAtsushi Nemoto const char *envstr; 359860e546cSAtsushi Nemoto 360860e546cSAtsushi Nemoto /* first, determine by "board=" argument in preprocess_cmdline() */ 361860e546cSAtsushi Nemoto if (txx9_board_vec) 362860e546cSAtsushi Nemoto return; 363860e546cSAtsushi Nemoto /* next, determine by "board" envvar */ 364860e546cSAtsushi Nemoto envstr = prom_getenv("board"); 365860e546cSAtsushi Nemoto if (envstr) { 366860e546cSAtsushi Nemoto txx9_board_vec = find_board_byname(envstr); 367860e546cSAtsushi Nemoto if (txx9_board_vec) 368860e546cSAtsushi Nemoto return; 369860e546cSAtsushi Nemoto } 370860e546cSAtsushi Nemoto 371860e546cSAtsushi Nemoto /* select "default" board */ 372edcaf1a6SAtsushi Nemoto #ifdef CONFIG_CPU_TX39XX 3737a1fdf19SYoichi Yuasa txx9_board_vec = &jmr3927_vec; 374edcaf1a6SAtsushi Nemoto #endif 375edcaf1a6SAtsushi Nemoto #ifdef CONFIG_CPU_TX49XX 376edcaf1a6SAtsushi Nemoto switch (TX4938_REV_PCODE()) { 3778d795f2aSAtsushi Nemoto #ifdef CONFIG_TOSHIBA_RBTX4927 378edcaf1a6SAtsushi Nemoto case 0x4927: 3797a1fdf19SYoichi Yuasa txx9_board_vec = &rbtx4927_vec; 380edcaf1a6SAtsushi Nemoto break; 381edcaf1a6SAtsushi Nemoto case 0x4937: 3827a1fdf19SYoichi Yuasa txx9_board_vec = &rbtx4937_vec; 383edcaf1a6SAtsushi Nemoto break; 3848d795f2aSAtsushi Nemoto #endif 3858d795f2aSAtsushi Nemoto #ifdef CONFIG_TOSHIBA_RBTX4938 386edcaf1a6SAtsushi Nemoto case 0x4938: 3877a1fdf19SYoichi Yuasa txx9_board_vec = &rbtx4938_vec; 388edcaf1a6SAtsushi Nemoto break; 3898d795f2aSAtsushi Nemoto #endif 390b27311e1SAtsushi Nemoto #ifdef CONFIG_TOSHIBA_RBTX4939 391b27311e1SAtsushi Nemoto case 0x4939: 392b27311e1SAtsushi Nemoto txx9_board_vec = &rbtx4939_vec; 393b27311e1SAtsushi Nemoto break; 394b27311e1SAtsushi Nemoto #endif 395edcaf1a6SAtsushi Nemoto } 396edcaf1a6SAtsushi Nemoto #endif 397860e546cSAtsushi Nemoto } 398860e546cSAtsushi Nemoto 399860e546cSAtsushi Nemoto void __init prom_init(void) 400860e546cSAtsushi Nemoto { 401860e546cSAtsushi Nemoto prom_init_cmdline(); 402860e546cSAtsushi Nemoto preprocess_cmdline(); 403860e546cSAtsushi Nemoto select_board(); 4047a1fdf19SYoichi Yuasa 405edcaf1a6SAtsushi Nemoto strcpy(txx9_system_type, txx9_board_vec->system); 4067a1fdf19SYoichi Yuasa 4077b226094SAtsushi Nemoto txx9_board_vec->prom_init(); 408edcaf1a6SAtsushi Nemoto } 409edcaf1a6SAtsushi Nemoto 410edcaf1a6SAtsushi Nemoto void __init prom_free_prom_memory(void) 411edcaf1a6SAtsushi Nemoto { 412b6263ff2SAtsushi Nemoto unsigned long saddr = PAGE_SIZE; 413b6263ff2SAtsushi Nemoto unsigned long eaddr = __pa_symbol(&_text); 414b6263ff2SAtsushi Nemoto 415b6263ff2SAtsushi Nemoto if (saddr < eaddr) 416b6263ff2SAtsushi Nemoto free_init_pages("prom memory", saddr, eaddr); 417edcaf1a6SAtsushi Nemoto } 418edcaf1a6SAtsushi Nemoto 419edcaf1a6SAtsushi Nemoto const char *get_system_type(void) 420edcaf1a6SAtsushi Nemoto { 421edcaf1a6SAtsushi Nemoto return txx9_system_type; 422edcaf1a6SAtsushi Nemoto } 423edcaf1a6SAtsushi Nemoto 424edcaf1a6SAtsushi Nemoto char * __init prom_getcmdline(void) 425edcaf1a6SAtsushi Nemoto { 426edcaf1a6SAtsushi Nemoto return &(arcs_cmdline[0]); 427edcaf1a6SAtsushi Nemoto } 428edcaf1a6SAtsushi Nemoto 429265b89dbSAtsushi Nemoto const char *__init prom_getenv(const char *name) 430265b89dbSAtsushi Nemoto { 43197b0511cSGeert Uytterhoeven const s32 *str; 432265b89dbSAtsushi Nemoto 43397b0511cSGeert Uytterhoeven if (fw_arg2 < CKSEG0) 434265b89dbSAtsushi Nemoto return NULL; 43597b0511cSGeert Uytterhoeven 43697b0511cSGeert Uytterhoeven str = (const s32 *)fw_arg2; 437265b89dbSAtsushi Nemoto /* YAMON style ("name", "value" pairs) */ 438265b89dbSAtsushi Nemoto while (str[0] && str[1]) { 439265b89dbSAtsushi Nemoto if (!strcmp((const char *)(unsigned long)str[0], name)) 440265b89dbSAtsushi Nemoto return (const char *)(unsigned long)str[1]; 441265b89dbSAtsushi Nemoto str += 2; 442265b89dbSAtsushi Nemoto } 443265b89dbSAtsushi Nemoto return NULL; 444265b89dbSAtsushi Nemoto } 445265b89dbSAtsushi Nemoto 446a49297e8SAtsushi Nemoto static void __noreturn txx9_machine_halt(void) 447a49297e8SAtsushi Nemoto { 448a49297e8SAtsushi Nemoto local_irq_disable(); 449a49297e8SAtsushi Nemoto clear_c0_status(ST0_IM); 450a49297e8SAtsushi Nemoto while (1) { 451a49297e8SAtsushi Nemoto if (cpu_wait) { 452a49297e8SAtsushi Nemoto (*cpu_wait)(); 453a49297e8SAtsushi Nemoto if (cpu_has_counter) { 454a49297e8SAtsushi Nemoto /* 455a49297e8SAtsushi Nemoto * Clear counter interrupt while it 456a49297e8SAtsushi Nemoto * breaks WAIT instruction even if 457a49297e8SAtsushi Nemoto * masked. 458a49297e8SAtsushi Nemoto */ 459a49297e8SAtsushi Nemoto write_c0_compare(0); 460a49297e8SAtsushi Nemoto } 461a49297e8SAtsushi Nemoto } 462a49297e8SAtsushi Nemoto } 463a49297e8SAtsushi Nemoto } 464a49297e8SAtsushi Nemoto 46568314725SAtsushi Nemoto /* Watchdog support */ 46668314725SAtsushi Nemoto void __init txx9_wdt_init(unsigned long base) 46768314725SAtsushi Nemoto { 46868314725SAtsushi Nemoto struct resource res = { 46968314725SAtsushi Nemoto .start = base, 47068314725SAtsushi Nemoto .end = base + 0x100 - 1, 47168314725SAtsushi Nemoto .flags = IORESOURCE_MEM, 47268314725SAtsushi Nemoto }; 47368314725SAtsushi Nemoto platform_device_register_simple("txx9wdt", -1, &res, 1); 47468314725SAtsushi Nemoto } 47568314725SAtsushi Nemoto 476496a3b5cSAtsushi Nemoto void txx9_wdt_now(unsigned long base) 477496a3b5cSAtsushi Nemoto { 478496a3b5cSAtsushi Nemoto struct txx9_tmr_reg __iomem *tmrptr = 479496a3b5cSAtsushi Nemoto ioremap(base, sizeof(struct txx9_tmr_reg)); 480496a3b5cSAtsushi Nemoto /* disable watch dog timer */ 481496a3b5cSAtsushi Nemoto __raw_writel(TXx9_TMWTMR_WDIS | TXx9_TMWTMR_TWC, &tmrptr->wtmr); 482496a3b5cSAtsushi Nemoto __raw_writel(0, &tmrptr->tcr); 483496a3b5cSAtsushi Nemoto /* kick watchdog */ 484496a3b5cSAtsushi Nemoto __raw_writel(TXx9_TMWTMR_TWIE, &tmrptr->wtmr); 485496a3b5cSAtsushi Nemoto __raw_writel(1, &tmrptr->cpra); /* immediate */ 486496a3b5cSAtsushi Nemoto __raw_writel(TXx9_TMTCR_TCE | TXx9_TMTCR_CCDE | TXx9_TMTCR_TMODE_WDOG, 487496a3b5cSAtsushi Nemoto &tmrptr->tcr); 488496a3b5cSAtsushi Nemoto } 489496a3b5cSAtsushi Nemoto 490c49f91f5SAtsushi Nemoto /* SPI support */ 491c49f91f5SAtsushi Nemoto void __init txx9_spi_init(int busid, unsigned long base, int irq) 492c49f91f5SAtsushi Nemoto { 493c49f91f5SAtsushi Nemoto struct resource res[] = { 494c49f91f5SAtsushi Nemoto { 495c49f91f5SAtsushi Nemoto .start = base, 496c49f91f5SAtsushi Nemoto .end = base + 0x20 - 1, 497c49f91f5SAtsushi Nemoto .flags = IORESOURCE_MEM, 498c49f91f5SAtsushi Nemoto }, { 499c49f91f5SAtsushi Nemoto .start = irq, 500c49f91f5SAtsushi Nemoto .flags = IORESOURCE_IRQ, 501c49f91f5SAtsushi Nemoto }, 502c49f91f5SAtsushi Nemoto }; 503c49f91f5SAtsushi Nemoto platform_device_register_simple("spi_txx9", busid, 504c49f91f5SAtsushi Nemoto res, ARRAY_SIZE(res)); 505c49f91f5SAtsushi Nemoto } 506c49f91f5SAtsushi Nemoto 507c49f91f5SAtsushi Nemoto void __init txx9_ethaddr_init(unsigned int id, unsigned char *ethaddr) 508c49f91f5SAtsushi Nemoto { 509c49f91f5SAtsushi Nemoto struct platform_device *pdev = 510c49f91f5SAtsushi Nemoto platform_device_alloc("tc35815-mac", id); 511c49f91f5SAtsushi Nemoto if (!pdev || 512c49f91f5SAtsushi Nemoto platform_device_add_data(pdev, ethaddr, 6) || 513c49f91f5SAtsushi Nemoto platform_device_add(pdev)) 514c49f91f5SAtsushi Nemoto platform_device_put(pdev); 515c49f91f5SAtsushi Nemoto } 516c49f91f5SAtsushi Nemoto 5177779a5e0SAtsushi Nemoto void __init txx9_sio_init(unsigned long baseaddr, int irq, 5187779a5e0SAtsushi Nemoto unsigned int line, unsigned int sclk, int nocts) 5197779a5e0SAtsushi Nemoto { 5207779a5e0SAtsushi Nemoto #ifdef CONFIG_SERIAL_TXX9 5217779a5e0SAtsushi Nemoto struct uart_port req; 5227779a5e0SAtsushi Nemoto 5237779a5e0SAtsushi Nemoto memset(&req, 0, sizeof(req)); 5247779a5e0SAtsushi Nemoto req.line = line; 5257779a5e0SAtsushi Nemoto req.iotype = UPIO_MEM; 5267779a5e0SAtsushi Nemoto req.membase = ioremap(baseaddr, 0x24); 5277779a5e0SAtsushi Nemoto req.mapbase = baseaddr; 5287779a5e0SAtsushi Nemoto req.irq = irq; 5297779a5e0SAtsushi Nemoto if (!nocts) 5307779a5e0SAtsushi Nemoto req.flags |= UPF_BUGGY_UART /*HAVE_CTS_LINE*/; 5317779a5e0SAtsushi Nemoto if (sclk) { 5327779a5e0SAtsushi Nemoto req.flags |= UPF_MAGIC_MULTIPLIER /*USE_SCLK*/; 5337779a5e0SAtsushi Nemoto req.uartclk = sclk; 5347779a5e0SAtsushi Nemoto } else 5357779a5e0SAtsushi Nemoto req.uartclk = TXX9_IMCLK; 5367779a5e0SAtsushi Nemoto early_serial_txx9_setup(&req); 5377779a5e0SAtsushi Nemoto #endif /* CONFIG_SERIAL_TXX9 */ 5387779a5e0SAtsushi Nemoto } 5397779a5e0SAtsushi Nemoto 540e352953cSAtsushi Nemoto #ifdef CONFIG_EARLY_PRINTK 541e352953cSAtsushi Nemoto static void __init null_prom_putchar(char c) 542e352953cSAtsushi Nemoto { 543e352953cSAtsushi Nemoto } 544e352953cSAtsushi Nemoto void (*txx9_prom_putchar)(char c) __initdata = null_prom_putchar; 545e352953cSAtsushi Nemoto 546e352953cSAtsushi Nemoto void __init prom_putchar(char c) 547e352953cSAtsushi Nemoto { 548e352953cSAtsushi Nemoto txx9_prom_putchar(c); 549e352953cSAtsushi Nemoto } 550e352953cSAtsushi Nemoto 551e352953cSAtsushi Nemoto static void __iomem *early_txx9_sio_port; 552e352953cSAtsushi Nemoto 553e352953cSAtsushi Nemoto static void __init early_txx9_sio_putchar(char c) 554e352953cSAtsushi Nemoto { 555e352953cSAtsushi Nemoto #define TXX9_SICISR 0x0c 556e352953cSAtsushi Nemoto #define TXX9_SITFIFO 0x1c 557e352953cSAtsushi Nemoto #define TXX9_SICISR_TXALS 0x00000002 558e352953cSAtsushi Nemoto while (!(__raw_readl(early_txx9_sio_port + TXX9_SICISR) & 559e352953cSAtsushi Nemoto TXX9_SICISR_TXALS)) 560e352953cSAtsushi Nemoto ; 561e352953cSAtsushi Nemoto __raw_writel(c, early_txx9_sio_port + TXX9_SITFIFO); 562e352953cSAtsushi Nemoto } 563e352953cSAtsushi Nemoto 564e352953cSAtsushi Nemoto void __init txx9_sio_putchar_init(unsigned long baseaddr) 565e352953cSAtsushi Nemoto { 566e352953cSAtsushi Nemoto early_txx9_sio_port = ioremap(baseaddr, 0x24); 567e352953cSAtsushi Nemoto txx9_prom_putchar = early_txx9_sio_putchar; 568e352953cSAtsushi Nemoto } 569e352953cSAtsushi Nemoto #endif /* CONFIG_EARLY_PRINTK */ 570e352953cSAtsushi Nemoto 571edcaf1a6SAtsushi Nemoto /* wrappers */ 572edcaf1a6SAtsushi Nemoto void __init plat_mem_setup(void) 573edcaf1a6SAtsushi Nemoto { 57494a4c329SAtsushi Nemoto ioport_resource.start = 0; 57594a4c329SAtsushi Nemoto ioport_resource.end = ~0UL; /* no limit */ 57694a4c329SAtsushi Nemoto iomem_resource.start = 0; 57794a4c329SAtsushi Nemoto iomem_resource.end = ~0UL; /* no limit */ 578a49297e8SAtsushi Nemoto 579a49297e8SAtsushi Nemoto /* fallback restart/halt routines */ 580a49297e8SAtsushi Nemoto _machine_restart = (void (*)(char *))txx9_machine_halt; 581a49297e8SAtsushi Nemoto _machine_halt = txx9_machine_halt; 582a49297e8SAtsushi Nemoto pm_power_off = txx9_machine_halt; 583a49297e8SAtsushi Nemoto 58407517529SAtsushi Nemoto #ifdef CONFIG_PCI 58507517529SAtsushi Nemoto pcibios_plat_setup = txx9_pcibios_setup; 58607517529SAtsushi Nemoto #endif 587edcaf1a6SAtsushi Nemoto txx9_board_vec->mem_setup(); 588edcaf1a6SAtsushi Nemoto } 589edcaf1a6SAtsushi Nemoto 590edcaf1a6SAtsushi Nemoto void __init arch_init_irq(void) 591edcaf1a6SAtsushi Nemoto { 592edcaf1a6SAtsushi Nemoto txx9_board_vec->irq_setup(); 593edcaf1a6SAtsushi Nemoto } 594edcaf1a6SAtsushi Nemoto 595edcaf1a6SAtsushi Nemoto void __init plat_time_init(void) 596edcaf1a6SAtsushi Nemoto { 5971374d084SAtsushi Nemoto #ifdef CONFIG_CPU_TX49XX 5981374d084SAtsushi Nemoto mips_hpt_frequency = txx9_cpu_clock / 2; 5991374d084SAtsushi Nemoto #endif 600edcaf1a6SAtsushi Nemoto txx9_board_vec->time_init(); 601edcaf1a6SAtsushi Nemoto } 602edcaf1a6SAtsushi Nemoto 603edcaf1a6SAtsushi Nemoto static int __init _txx9_arch_init(void) 604edcaf1a6SAtsushi Nemoto { 605edcaf1a6SAtsushi Nemoto if (txx9_board_vec->arch_init) 606edcaf1a6SAtsushi Nemoto txx9_board_vec->arch_init(); 607edcaf1a6SAtsushi Nemoto return 0; 608edcaf1a6SAtsushi Nemoto } 609edcaf1a6SAtsushi Nemoto arch_initcall(_txx9_arch_init); 610edcaf1a6SAtsushi Nemoto 611edcaf1a6SAtsushi Nemoto static int __init _txx9_device_init(void) 612edcaf1a6SAtsushi Nemoto { 613edcaf1a6SAtsushi Nemoto if (txx9_board_vec->device_init) 614edcaf1a6SAtsushi Nemoto txx9_board_vec->device_init(); 615edcaf1a6SAtsushi Nemoto return 0; 616edcaf1a6SAtsushi Nemoto } 617edcaf1a6SAtsushi Nemoto device_initcall(_txx9_device_init); 618edcaf1a6SAtsushi Nemoto 619edcaf1a6SAtsushi Nemoto int (*txx9_irq_dispatch)(int pending); 620edcaf1a6SAtsushi Nemoto asmlinkage void plat_irq_dispatch(void) 621edcaf1a6SAtsushi Nemoto { 622edcaf1a6SAtsushi Nemoto int pending = read_c0_status() & read_c0_cause() & ST0_IM; 623edcaf1a6SAtsushi Nemoto int irq = txx9_irq_dispatch(pending); 624edcaf1a6SAtsushi Nemoto 625edcaf1a6SAtsushi Nemoto if (likely(irq >= 0)) 626edcaf1a6SAtsushi Nemoto do_IRQ(irq); 627edcaf1a6SAtsushi Nemoto else 628edcaf1a6SAtsushi Nemoto spurious_interrupt(); 629edcaf1a6SAtsushi Nemoto } 6304c642f3fSAtsushi Nemoto 6314c642f3fSAtsushi Nemoto /* see include/asm-mips/mach-tx39xx/mangle-port.h, for example. */ 6324c642f3fSAtsushi Nemoto #ifdef NEEDS_TXX9_SWIZZLE_ADDR_B 6334c642f3fSAtsushi Nemoto static unsigned long __swizzle_addr_none(unsigned long port) 6344c642f3fSAtsushi Nemoto { 6354c642f3fSAtsushi Nemoto return port; 6364c642f3fSAtsushi Nemoto } 6374c642f3fSAtsushi Nemoto unsigned long (*__swizzle_addr_b)(unsigned long port) = __swizzle_addr_none; 6384c642f3fSAtsushi Nemoto EXPORT_SYMBOL(__swizzle_addr_b); 6394c642f3fSAtsushi Nemoto #endif 64051f607c7SAtsushi Nemoto 6411ba5a176SAtsushi Nemoto #ifdef NEEDS_TXX9_IOSWABW 6421ba5a176SAtsushi Nemoto static u16 ioswabw_default(volatile u16 *a, u16 x) 6431ba5a176SAtsushi Nemoto { 6441ba5a176SAtsushi Nemoto return le16_to_cpu(x); 6451ba5a176SAtsushi Nemoto } 6461ba5a176SAtsushi Nemoto static u16 __mem_ioswabw_default(volatile u16 *a, u16 x) 6471ba5a176SAtsushi Nemoto { 6481ba5a176SAtsushi Nemoto return x; 6491ba5a176SAtsushi Nemoto } 6501ba5a176SAtsushi Nemoto u16 (*ioswabw)(volatile u16 *a, u16 x) = ioswabw_default; 6511ba5a176SAtsushi Nemoto EXPORT_SYMBOL(ioswabw); 6521ba5a176SAtsushi Nemoto u16 (*__mem_ioswabw)(volatile u16 *a, u16 x) = __mem_ioswabw_default; 6531ba5a176SAtsushi Nemoto EXPORT_SYMBOL(__mem_ioswabw); 6541ba5a176SAtsushi Nemoto #endif 6551ba5a176SAtsushi Nemoto 65651f607c7SAtsushi Nemoto void __init txx9_physmap_flash_init(int no, unsigned long addr, 65751f607c7SAtsushi Nemoto unsigned long size, 65851f607c7SAtsushi Nemoto const struct physmap_flash_data *pdata) 65951f607c7SAtsushi Nemoto { 66051f607c7SAtsushi Nemoto #if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) 66151f607c7SAtsushi Nemoto struct resource res = { 66251f607c7SAtsushi Nemoto .start = addr, 66351f607c7SAtsushi Nemoto .end = addr + size - 1, 66451f607c7SAtsushi Nemoto .flags = IORESOURCE_MEM, 66551f607c7SAtsushi Nemoto }; 66651f607c7SAtsushi Nemoto struct platform_device *pdev; 66751f607c7SAtsushi Nemoto #ifdef CONFIG_MTD_PARTITIONS 66851f607c7SAtsushi Nemoto static struct mtd_partition parts[2]; 66951f607c7SAtsushi Nemoto struct physmap_flash_data pdata_part; 67051f607c7SAtsushi Nemoto 67151f607c7SAtsushi Nemoto /* If this area contained boot area, make separate partition */ 67251f607c7SAtsushi Nemoto if (pdata->nr_parts == 0 && !pdata->parts && 67351f607c7SAtsushi Nemoto addr < 0x1fc00000 && addr + size > 0x1fc00000 && 67451f607c7SAtsushi Nemoto !parts[0].name) { 67551f607c7SAtsushi Nemoto parts[0].name = "boot"; 67651f607c7SAtsushi Nemoto parts[0].offset = 0x1fc00000 - addr; 67751f607c7SAtsushi Nemoto parts[0].size = addr + size - 0x1fc00000; 67851f607c7SAtsushi Nemoto parts[1].name = "user"; 67951f607c7SAtsushi Nemoto parts[1].offset = 0; 68051f607c7SAtsushi Nemoto parts[1].size = 0x1fc00000 - addr; 68151f607c7SAtsushi Nemoto pdata_part = *pdata; 68251f607c7SAtsushi Nemoto pdata_part.nr_parts = ARRAY_SIZE(parts); 68351f607c7SAtsushi Nemoto pdata_part.parts = parts; 68451f607c7SAtsushi Nemoto pdata = &pdata_part; 68551f607c7SAtsushi Nemoto } 68651f607c7SAtsushi Nemoto #endif 68751f607c7SAtsushi Nemoto pdev = platform_device_alloc("physmap-flash", no); 68851f607c7SAtsushi Nemoto if (!pdev || 68951f607c7SAtsushi Nemoto platform_device_add_resources(pdev, &res, 1) || 69051f607c7SAtsushi Nemoto platform_device_add_data(pdev, pdata, sizeof(*pdata)) || 69151f607c7SAtsushi Nemoto platform_device_add(pdev)) 69251f607c7SAtsushi Nemoto platform_device_put(pdev); 69351f607c7SAtsushi Nemoto #endif 69451f607c7SAtsushi Nemoto } 695ae027eadSAtsushi Nemoto 696a591f5d3SAtsushi Nemoto void __init txx9_ndfmc_init(unsigned long baseaddr, 697a591f5d3SAtsushi Nemoto const struct txx9ndfmc_platform_data *pdata) 698a591f5d3SAtsushi Nemoto { 699a591f5d3SAtsushi Nemoto #if defined(CONFIG_MTD_NAND_TXX9NDFMC) || \ 700a591f5d3SAtsushi Nemoto defined(CONFIG_MTD_NAND_TXX9NDFMC_MODULE) 701a591f5d3SAtsushi Nemoto struct resource res = { 702a591f5d3SAtsushi Nemoto .start = baseaddr, 703a591f5d3SAtsushi Nemoto .end = baseaddr + 0x1000 - 1, 704a591f5d3SAtsushi Nemoto .flags = IORESOURCE_MEM, 705a591f5d3SAtsushi Nemoto }; 706a591f5d3SAtsushi Nemoto struct platform_device *pdev = platform_device_alloc("txx9ndfmc", -1); 707a591f5d3SAtsushi Nemoto 708a591f5d3SAtsushi Nemoto if (!pdev || 709a591f5d3SAtsushi Nemoto platform_device_add_resources(pdev, &res, 1) || 710a591f5d3SAtsushi Nemoto platform_device_add_data(pdev, pdata, sizeof(*pdata)) || 711a591f5d3SAtsushi Nemoto platform_device_add(pdev)) 712a591f5d3SAtsushi Nemoto platform_device_put(pdev); 713a591f5d3SAtsushi Nemoto #endif 714a591f5d3SAtsushi Nemoto } 715a591f5d3SAtsushi Nemoto 716ae027eadSAtsushi Nemoto #if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) 717ae027eadSAtsushi Nemoto static DEFINE_SPINLOCK(txx9_iocled_lock); 718ae027eadSAtsushi Nemoto 719ae027eadSAtsushi Nemoto #define TXX9_IOCLED_MAXLEDS 8 720ae027eadSAtsushi Nemoto 721ae027eadSAtsushi Nemoto struct txx9_iocled_data { 722ae027eadSAtsushi Nemoto struct gpio_chip chip; 723ae027eadSAtsushi Nemoto u8 cur_val; 724ae027eadSAtsushi Nemoto void __iomem *mmioaddr; 725ae027eadSAtsushi Nemoto struct gpio_led_platform_data pdata; 726ae027eadSAtsushi Nemoto struct gpio_led leds[TXX9_IOCLED_MAXLEDS]; 727ae027eadSAtsushi Nemoto char names[TXX9_IOCLED_MAXLEDS][32]; 728ae027eadSAtsushi Nemoto }; 729ae027eadSAtsushi Nemoto 730ae027eadSAtsushi Nemoto static int txx9_iocled_get(struct gpio_chip *chip, unsigned int offset) 731ae027eadSAtsushi Nemoto { 732ae027eadSAtsushi Nemoto struct txx9_iocled_data *data = 733ae027eadSAtsushi Nemoto container_of(chip, struct txx9_iocled_data, chip); 734ae027eadSAtsushi Nemoto return data->cur_val & (1 << offset); 735ae027eadSAtsushi Nemoto } 736ae027eadSAtsushi Nemoto 737ae027eadSAtsushi Nemoto static void txx9_iocled_set(struct gpio_chip *chip, unsigned int offset, 738ae027eadSAtsushi Nemoto int value) 739ae027eadSAtsushi Nemoto { 740ae027eadSAtsushi Nemoto struct txx9_iocled_data *data = 741ae027eadSAtsushi Nemoto container_of(chip, struct txx9_iocled_data, chip); 742ae027eadSAtsushi Nemoto unsigned long flags; 743ae027eadSAtsushi Nemoto spin_lock_irqsave(&txx9_iocled_lock, flags); 744ae027eadSAtsushi Nemoto if (value) 745ae027eadSAtsushi Nemoto data->cur_val |= 1 << offset; 746ae027eadSAtsushi Nemoto else 747ae027eadSAtsushi Nemoto data->cur_val &= ~(1 << offset); 748ae027eadSAtsushi Nemoto writeb(data->cur_val, data->mmioaddr); 749ae027eadSAtsushi Nemoto mmiowb(); 750ae027eadSAtsushi Nemoto spin_unlock_irqrestore(&txx9_iocled_lock, flags); 751ae027eadSAtsushi Nemoto } 752ae027eadSAtsushi Nemoto 753ae027eadSAtsushi Nemoto static int txx9_iocled_dir_in(struct gpio_chip *chip, unsigned int offset) 754ae027eadSAtsushi Nemoto { 755ae027eadSAtsushi Nemoto return 0; 756ae027eadSAtsushi Nemoto } 757ae027eadSAtsushi Nemoto 758ae027eadSAtsushi Nemoto static int txx9_iocled_dir_out(struct gpio_chip *chip, unsigned int offset, 759ae027eadSAtsushi Nemoto int value) 760ae027eadSAtsushi Nemoto { 761ae027eadSAtsushi Nemoto txx9_iocled_set(chip, offset, value); 762ae027eadSAtsushi Nemoto return 0; 763ae027eadSAtsushi Nemoto } 764ae027eadSAtsushi Nemoto 765ae027eadSAtsushi Nemoto void __init txx9_iocled_init(unsigned long baseaddr, 766ae027eadSAtsushi Nemoto int basenum, unsigned int num, int lowactive, 767ae027eadSAtsushi Nemoto const char *color, char **deftriggers) 768ae027eadSAtsushi Nemoto { 769ae027eadSAtsushi Nemoto struct txx9_iocled_data *iocled; 770ae027eadSAtsushi Nemoto struct platform_device *pdev; 771ae027eadSAtsushi Nemoto int i; 772ae027eadSAtsushi Nemoto static char *default_triggers[] __initdata = { 773ae027eadSAtsushi Nemoto "heartbeat", 774ae027eadSAtsushi Nemoto "ide-disk", 775ae027eadSAtsushi Nemoto "nand-disk", 776ae027eadSAtsushi Nemoto NULL, 777ae027eadSAtsushi Nemoto }; 778ae027eadSAtsushi Nemoto 779ae027eadSAtsushi Nemoto if (!deftriggers) 780ae027eadSAtsushi Nemoto deftriggers = default_triggers; 781ae027eadSAtsushi Nemoto iocled = kzalloc(sizeof(*iocled), GFP_KERNEL); 782ae027eadSAtsushi Nemoto if (!iocled) 783ae027eadSAtsushi Nemoto return; 784ae027eadSAtsushi Nemoto iocled->mmioaddr = ioremap(baseaddr, 1); 785ae027eadSAtsushi Nemoto if (!iocled->mmioaddr) 786ae027eadSAtsushi Nemoto return; 787ae027eadSAtsushi Nemoto iocled->chip.get = txx9_iocled_get; 788ae027eadSAtsushi Nemoto iocled->chip.set = txx9_iocled_set; 789ae027eadSAtsushi Nemoto iocled->chip.direction_input = txx9_iocled_dir_in; 790ae027eadSAtsushi Nemoto iocled->chip.direction_output = txx9_iocled_dir_out; 791ae027eadSAtsushi Nemoto iocled->chip.label = "iocled"; 792ae027eadSAtsushi Nemoto iocled->chip.base = basenum; 793ae027eadSAtsushi Nemoto iocled->chip.ngpio = num; 794ae027eadSAtsushi Nemoto if (gpiochip_add(&iocled->chip)) 795ae027eadSAtsushi Nemoto return; 796ae027eadSAtsushi Nemoto if (basenum < 0) 797ae027eadSAtsushi Nemoto basenum = iocled->chip.base; 798ae027eadSAtsushi Nemoto 799ae027eadSAtsushi Nemoto pdev = platform_device_alloc("leds-gpio", basenum); 800ae027eadSAtsushi Nemoto if (!pdev) 801ae027eadSAtsushi Nemoto return; 802ae027eadSAtsushi Nemoto iocled->pdata.num_leds = num; 803ae027eadSAtsushi Nemoto iocled->pdata.leds = iocled->leds; 804ae027eadSAtsushi Nemoto for (i = 0; i < num; i++) { 805ae027eadSAtsushi Nemoto struct gpio_led *led = &iocled->leds[i]; 806ae027eadSAtsushi Nemoto snprintf(iocled->names[i], sizeof(iocled->names[i]), 807ae027eadSAtsushi Nemoto "iocled:%s:%u", color, i); 808ae027eadSAtsushi Nemoto led->name = iocled->names[i]; 809ae027eadSAtsushi Nemoto led->gpio = basenum + i; 810ae027eadSAtsushi Nemoto led->active_low = lowactive; 811ae027eadSAtsushi Nemoto if (deftriggers && *deftriggers) 812ae027eadSAtsushi Nemoto led->default_trigger = *deftriggers++; 813ae027eadSAtsushi Nemoto } 814ae027eadSAtsushi Nemoto pdev->dev.platform_data = &iocled->pdata; 815ae027eadSAtsushi Nemoto if (platform_device_add(pdev)) 816ae027eadSAtsushi Nemoto platform_device_put(pdev); 817ae027eadSAtsushi Nemoto } 818ae027eadSAtsushi Nemoto #else /* CONFIG_LEDS_GPIO */ 819ae027eadSAtsushi Nemoto void __init txx9_iocled_init(unsigned long baseaddr, 820ae027eadSAtsushi Nemoto int basenum, unsigned int num, int lowactive, 821ae027eadSAtsushi Nemoto const char *color, char **deftriggers) 822ae027eadSAtsushi Nemoto { 823ae027eadSAtsushi Nemoto } 824ae027eadSAtsushi Nemoto #endif /* CONFIG_LEDS_GPIO */ 825*f48c8c95SAtsushi Nemoto 826*f48c8c95SAtsushi Nemoto void __init txx9_dmac_init(int id, unsigned long baseaddr, int irq, 827*f48c8c95SAtsushi Nemoto const struct txx9dmac_platform_data *pdata) 828*f48c8c95SAtsushi Nemoto { 829*f48c8c95SAtsushi Nemoto #if defined(CONFIG_TXX9_DMAC) || defined(CONFIG_TXX9_DMAC_MODULE) 830*f48c8c95SAtsushi Nemoto struct resource res[] = { 831*f48c8c95SAtsushi Nemoto { 832*f48c8c95SAtsushi Nemoto .start = baseaddr, 833*f48c8c95SAtsushi Nemoto .end = baseaddr + 0x800 - 1, 834*f48c8c95SAtsushi Nemoto .flags = IORESOURCE_MEM, 835*f48c8c95SAtsushi Nemoto #ifndef CONFIG_MACH_TX49XX 836*f48c8c95SAtsushi Nemoto }, { 837*f48c8c95SAtsushi Nemoto .start = irq, 838*f48c8c95SAtsushi Nemoto .flags = IORESOURCE_IRQ, 839*f48c8c95SAtsushi Nemoto #endif 840*f48c8c95SAtsushi Nemoto } 841*f48c8c95SAtsushi Nemoto }; 842*f48c8c95SAtsushi Nemoto #ifdef CONFIG_MACH_TX49XX 843*f48c8c95SAtsushi Nemoto struct resource chan_res[] = { 844*f48c8c95SAtsushi Nemoto { 845*f48c8c95SAtsushi Nemoto .flags = IORESOURCE_IRQ, 846*f48c8c95SAtsushi Nemoto } 847*f48c8c95SAtsushi Nemoto }; 848*f48c8c95SAtsushi Nemoto #endif 849*f48c8c95SAtsushi Nemoto struct platform_device *pdev = platform_device_alloc("txx9dmac", id); 850*f48c8c95SAtsushi Nemoto struct txx9dmac_chan_platform_data cpdata; 851*f48c8c95SAtsushi Nemoto int i; 852*f48c8c95SAtsushi Nemoto 853*f48c8c95SAtsushi Nemoto if (!pdev || 854*f48c8c95SAtsushi Nemoto platform_device_add_resources(pdev, res, ARRAY_SIZE(res)) || 855*f48c8c95SAtsushi Nemoto platform_device_add_data(pdev, pdata, sizeof(*pdata)) || 856*f48c8c95SAtsushi Nemoto platform_device_add(pdev)) { 857*f48c8c95SAtsushi Nemoto platform_device_put(pdev); 858*f48c8c95SAtsushi Nemoto return; 859*f48c8c95SAtsushi Nemoto } 860*f48c8c95SAtsushi Nemoto memset(&cpdata, 0, sizeof(cpdata)); 861*f48c8c95SAtsushi Nemoto cpdata.dmac_dev = pdev; 862*f48c8c95SAtsushi Nemoto for (i = 0; i < TXX9_DMA_MAX_NR_CHANNELS; i++) { 863*f48c8c95SAtsushi Nemoto #ifdef CONFIG_MACH_TX49XX 864*f48c8c95SAtsushi Nemoto chan_res[0].start = irq + i; 865*f48c8c95SAtsushi Nemoto #endif 866*f48c8c95SAtsushi Nemoto pdev = platform_device_alloc("txx9dmac-chan", 867*f48c8c95SAtsushi Nemoto id * TXX9_DMA_MAX_NR_CHANNELS + i); 868*f48c8c95SAtsushi Nemoto if (!pdev || 869*f48c8c95SAtsushi Nemoto #ifdef CONFIG_MACH_TX49XX 870*f48c8c95SAtsushi Nemoto platform_device_add_resources(pdev, chan_res, 871*f48c8c95SAtsushi Nemoto ARRAY_SIZE(chan_res)) || 872*f48c8c95SAtsushi Nemoto #endif 873*f48c8c95SAtsushi Nemoto platform_device_add_data(pdev, &cpdata, sizeof(cpdata)) || 874*f48c8c95SAtsushi Nemoto platform_device_add(pdev)) 875*f48c8c95SAtsushi Nemoto platform_device_put(pdev); 876*f48c8c95SAtsushi Nemoto } 877*f48c8c95SAtsushi Nemoto #endif 878*f48c8c95SAtsushi Nemoto } 879