1*94a4c329SAtsushi Nemoto /* 2*94a4c329SAtsushi Nemoto * TX4938/4937 setup routines 3*94a4c329SAtsushi Nemoto * Based on linux/arch/mips/txx9/rbtx4938/setup.c, 4*94a4c329SAtsushi Nemoto * and RBTX49xx patch from CELF patch archive. 5*94a4c329SAtsushi Nemoto * 6*94a4c329SAtsushi Nemoto * 2003-2005 (c) MontaVista Software, Inc. 7*94a4c329SAtsushi Nemoto * (C) Copyright TOSHIBA CORPORATION 2000-2001, 2004-2007 8*94a4c329SAtsushi Nemoto * 9*94a4c329SAtsushi Nemoto * This file is subject to the terms and conditions of the GNU General Public 10*94a4c329SAtsushi Nemoto * License. See the file "COPYING" in the main directory of this archive 11*94a4c329SAtsushi Nemoto * for more details. 12*94a4c329SAtsushi Nemoto */ 13*94a4c329SAtsushi Nemoto #include <linux/init.h> 14*94a4c329SAtsushi Nemoto #include <linux/ioport.h> 15*94a4c329SAtsushi Nemoto #include <linux/delay.h> 16*94a4c329SAtsushi Nemoto #include <linux/serial_core.h> 17*94a4c329SAtsushi Nemoto #include <linux/param.h> 18*94a4c329SAtsushi Nemoto #include <asm/txx9irq.h> 19*94a4c329SAtsushi Nemoto #include <asm/txx9tmr.h> 20*94a4c329SAtsushi Nemoto #include <asm/txx9pio.h> 21*94a4c329SAtsushi Nemoto #include <asm/txx9/generic.h> 22*94a4c329SAtsushi Nemoto #include <asm/txx9/tx4938.h> 23*94a4c329SAtsushi Nemoto 24*94a4c329SAtsushi Nemoto void __init tx4938_wdr_init(void) 25*94a4c329SAtsushi Nemoto { 26*94a4c329SAtsushi Nemoto /* clear WatchDogReset (W1C) */ 27*94a4c329SAtsushi Nemoto tx4938_ccfg_set(TX4938_CCFG_WDRST); 28*94a4c329SAtsushi Nemoto /* do reset on watchdog */ 29*94a4c329SAtsushi Nemoto tx4938_ccfg_set(TX4938_CCFG_WR); 30*94a4c329SAtsushi Nemoto } 31*94a4c329SAtsushi Nemoto 32*94a4c329SAtsushi Nemoto static struct resource tx4938_sdram_resource[4]; 33*94a4c329SAtsushi Nemoto static struct resource tx4938_sram_resource; 34*94a4c329SAtsushi Nemoto 35*94a4c329SAtsushi Nemoto #define TX4938_SRAM_SIZE 0x800 36*94a4c329SAtsushi Nemoto 37*94a4c329SAtsushi Nemoto void __init tx4938_setup(void) 38*94a4c329SAtsushi Nemoto { 39*94a4c329SAtsushi Nemoto int i; 40*94a4c329SAtsushi Nemoto __u32 divmode; 41*94a4c329SAtsushi Nemoto int cpuclk = 0; 42*94a4c329SAtsushi Nemoto u64 ccfg; 43*94a4c329SAtsushi Nemoto 44*94a4c329SAtsushi Nemoto txx9_reg_res_init(TX4938_REV_PCODE(), TX4938_REG_BASE, 45*94a4c329SAtsushi Nemoto TX4938_REG_SIZE); 46*94a4c329SAtsushi Nemoto 47*94a4c329SAtsushi Nemoto /* SDRAMC,EBUSC are configured by PROM */ 48*94a4c329SAtsushi Nemoto for (i = 0; i < 8; i++) { 49*94a4c329SAtsushi Nemoto if (!(TX4938_EBUSC_CR(i) & 0x8)) 50*94a4c329SAtsushi Nemoto continue; /* disabled */ 51*94a4c329SAtsushi Nemoto txx9_ce_res[i].start = (unsigned long)TX4938_EBUSC_BA(i); 52*94a4c329SAtsushi Nemoto txx9_ce_res[i].end = 53*94a4c329SAtsushi Nemoto txx9_ce_res[i].start + TX4938_EBUSC_SIZE(i) - 1; 54*94a4c329SAtsushi Nemoto request_resource(&iomem_resource, &txx9_ce_res[i]); 55*94a4c329SAtsushi Nemoto } 56*94a4c329SAtsushi Nemoto 57*94a4c329SAtsushi Nemoto /* clocks */ 58*94a4c329SAtsushi Nemoto ccfg = ____raw_readq(&tx4938_ccfgptr->ccfg); 59*94a4c329SAtsushi Nemoto if (txx9_master_clock) { 60*94a4c329SAtsushi Nemoto /* calculate gbus_clock and cpu_clock from master_clock */ 61*94a4c329SAtsushi Nemoto divmode = (__u32)ccfg & TX4938_CCFG_DIVMODE_MASK; 62*94a4c329SAtsushi Nemoto switch (divmode) { 63*94a4c329SAtsushi Nemoto case TX4938_CCFG_DIVMODE_8: 64*94a4c329SAtsushi Nemoto case TX4938_CCFG_DIVMODE_10: 65*94a4c329SAtsushi Nemoto case TX4938_CCFG_DIVMODE_12: 66*94a4c329SAtsushi Nemoto case TX4938_CCFG_DIVMODE_16: 67*94a4c329SAtsushi Nemoto case TX4938_CCFG_DIVMODE_18: 68*94a4c329SAtsushi Nemoto txx9_gbus_clock = txx9_master_clock * 4; break; 69*94a4c329SAtsushi Nemoto default: 70*94a4c329SAtsushi Nemoto txx9_gbus_clock = txx9_master_clock; 71*94a4c329SAtsushi Nemoto } 72*94a4c329SAtsushi Nemoto switch (divmode) { 73*94a4c329SAtsushi Nemoto case TX4938_CCFG_DIVMODE_2: 74*94a4c329SAtsushi Nemoto case TX4938_CCFG_DIVMODE_8: 75*94a4c329SAtsushi Nemoto cpuclk = txx9_gbus_clock * 2; break; 76*94a4c329SAtsushi Nemoto case TX4938_CCFG_DIVMODE_2_5: 77*94a4c329SAtsushi Nemoto case TX4938_CCFG_DIVMODE_10: 78*94a4c329SAtsushi Nemoto cpuclk = txx9_gbus_clock * 5 / 2; break; 79*94a4c329SAtsushi Nemoto case TX4938_CCFG_DIVMODE_3: 80*94a4c329SAtsushi Nemoto case TX4938_CCFG_DIVMODE_12: 81*94a4c329SAtsushi Nemoto cpuclk = txx9_gbus_clock * 3; break; 82*94a4c329SAtsushi Nemoto case TX4938_CCFG_DIVMODE_4: 83*94a4c329SAtsushi Nemoto case TX4938_CCFG_DIVMODE_16: 84*94a4c329SAtsushi Nemoto cpuclk = txx9_gbus_clock * 4; break; 85*94a4c329SAtsushi Nemoto case TX4938_CCFG_DIVMODE_4_5: 86*94a4c329SAtsushi Nemoto case TX4938_CCFG_DIVMODE_18: 87*94a4c329SAtsushi Nemoto cpuclk = txx9_gbus_clock * 9 / 2; break; 88*94a4c329SAtsushi Nemoto } 89*94a4c329SAtsushi Nemoto txx9_cpu_clock = cpuclk; 90*94a4c329SAtsushi Nemoto } else { 91*94a4c329SAtsushi Nemoto if (txx9_cpu_clock == 0) 92*94a4c329SAtsushi Nemoto txx9_cpu_clock = 300000000; /* 300MHz */ 93*94a4c329SAtsushi Nemoto /* calculate gbus_clock and master_clock from cpu_clock */ 94*94a4c329SAtsushi Nemoto cpuclk = txx9_cpu_clock; 95*94a4c329SAtsushi Nemoto divmode = (__u32)ccfg & TX4938_CCFG_DIVMODE_MASK; 96*94a4c329SAtsushi Nemoto switch (divmode) { 97*94a4c329SAtsushi Nemoto case TX4938_CCFG_DIVMODE_2: 98*94a4c329SAtsushi Nemoto case TX4938_CCFG_DIVMODE_8: 99*94a4c329SAtsushi Nemoto txx9_gbus_clock = cpuclk / 2; break; 100*94a4c329SAtsushi Nemoto case TX4938_CCFG_DIVMODE_2_5: 101*94a4c329SAtsushi Nemoto case TX4938_CCFG_DIVMODE_10: 102*94a4c329SAtsushi Nemoto txx9_gbus_clock = cpuclk * 2 / 5; break; 103*94a4c329SAtsushi Nemoto case TX4938_CCFG_DIVMODE_3: 104*94a4c329SAtsushi Nemoto case TX4938_CCFG_DIVMODE_12: 105*94a4c329SAtsushi Nemoto txx9_gbus_clock = cpuclk / 3; break; 106*94a4c329SAtsushi Nemoto case TX4938_CCFG_DIVMODE_4: 107*94a4c329SAtsushi Nemoto case TX4938_CCFG_DIVMODE_16: 108*94a4c329SAtsushi Nemoto txx9_gbus_clock = cpuclk / 4; break; 109*94a4c329SAtsushi Nemoto case TX4938_CCFG_DIVMODE_4_5: 110*94a4c329SAtsushi Nemoto case TX4938_CCFG_DIVMODE_18: 111*94a4c329SAtsushi Nemoto txx9_gbus_clock = cpuclk * 2 / 9; break; 112*94a4c329SAtsushi Nemoto } 113*94a4c329SAtsushi Nemoto switch (divmode) { 114*94a4c329SAtsushi Nemoto case TX4938_CCFG_DIVMODE_8: 115*94a4c329SAtsushi Nemoto case TX4938_CCFG_DIVMODE_10: 116*94a4c329SAtsushi Nemoto case TX4938_CCFG_DIVMODE_12: 117*94a4c329SAtsushi Nemoto case TX4938_CCFG_DIVMODE_16: 118*94a4c329SAtsushi Nemoto case TX4938_CCFG_DIVMODE_18: 119*94a4c329SAtsushi Nemoto txx9_master_clock = txx9_gbus_clock / 4; break; 120*94a4c329SAtsushi Nemoto default: 121*94a4c329SAtsushi Nemoto txx9_master_clock = txx9_gbus_clock; 122*94a4c329SAtsushi Nemoto } 123*94a4c329SAtsushi Nemoto } 124*94a4c329SAtsushi Nemoto /* change default value to udelay/mdelay take reasonable time */ 125*94a4c329SAtsushi Nemoto loops_per_jiffy = txx9_cpu_clock / HZ / 2; 126*94a4c329SAtsushi Nemoto 127*94a4c329SAtsushi Nemoto /* CCFG */ 128*94a4c329SAtsushi Nemoto tx4938_wdr_init(); 129*94a4c329SAtsushi Nemoto /* clear BusErrorOnWrite flag (W1C) */ 130*94a4c329SAtsushi Nemoto tx4938_ccfg_set(TX4938_CCFG_BEOW); 131*94a4c329SAtsushi Nemoto /* enable Timeout BusError */ 132*94a4c329SAtsushi Nemoto if (txx9_ccfg_toeon) 133*94a4c329SAtsushi Nemoto tx4938_ccfg_set(TX4938_CCFG_TOE); 134*94a4c329SAtsushi Nemoto 135*94a4c329SAtsushi Nemoto /* DMA selection */ 136*94a4c329SAtsushi Nemoto txx9_clear64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_DMASEL_ALL); 137*94a4c329SAtsushi Nemoto 138*94a4c329SAtsushi Nemoto /* Use external clock for external arbiter */ 139*94a4c329SAtsushi Nemoto if (!(____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_PCIARB)) 140*94a4c329SAtsushi Nemoto txx9_clear64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_PCICLKEN_ALL); 141*94a4c329SAtsushi Nemoto 142*94a4c329SAtsushi Nemoto printk(KERN_INFO "%s -- %dMHz(M%dMHz) CRIR:%08x CCFG:%llx PCFG:%llx\n", 143*94a4c329SAtsushi Nemoto txx9_pcode_str, 144*94a4c329SAtsushi Nemoto (cpuclk + 500000) / 1000000, 145*94a4c329SAtsushi Nemoto (txx9_master_clock + 500000) / 1000000, 146*94a4c329SAtsushi Nemoto (__u32)____raw_readq(&tx4938_ccfgptr->crir), 147*94a4c329SAtsushi Nemoto (unsigned long long)____raw_readq(&tx4938_ccfgptr->ccfg), 148*94a4c329SAtsushi Nemoto (unsigned long long)____raw_readq(&tx4938_ccfgptr->pcfg)); 149*94a4c329SAtsushi Nemoto 150*94a4c329SAtsushi Nemoto printk(KERN_INFO "%s SDRAMC --", txx9_pcode_str); 151*94a4c329SAtsushi Nemoto for (i = 0; i < 4; i++) { 152*94a4c329SAtsushi Nemoto __u64 cr = TX4938_SDRAMC_CR(i); 153*94a4c329SAtsushi Nemoto unsigned long base, size; 154*94a4c329SAtsushi Nemoto if (!((__u32)cr & 0x00000400)) 155*94a4c329SAtsushi Nemoto continue; /* disabled */ 156*94a4c329SAtsushi Nemoto base = (unsigned long)(cr >> 49) << 21; 157*94a4c329SAtsushi Nemoto size = (((unsigned long)(cr >> 33) & 0x7fff) + 1) << 21; 158*94a4c329SAtsushi Nemoto printk(" CR%d:%016llx", i, (unsigned long long)cr); 159*94a4c329SAtsushi Nemoto tx4938_sdram_resource[i].name = "SDRAM"; 160*94a4c329SAtsushi Nemoto tx4938_sdram_resource[i].start = base; 161*94a4c329SAtsushi Nemoto tx4938_sdram_resource[i].end = base + size - 1; 162*94a4c329SAtsushi Nemoto tx4938_sdram_resource[i].flags = IORESOURCE_MEM; 163*94a4c329SAtsushi Nemoto request_resource(&iomem_resource, &tx4938_sdram_resource[i]); 164*94a4c329SAtsushi Nemoto } 165*94a4c329SAtsushi Nemoto printk(" TR:%09llx\n", 166*94a4c329SAtsushi Nemoto (unsigned long long)____raw_readq(&tx4938_sdramcptr->tr)); 167*94a4c329SAtsushi Nemoto 168*94a4c329SAtsushi Nemoto /* SRAM */ 169*94a4c329SAtsushi Nemoto if (txx9_pcode == 0x4938 && ____raw_readq(&tx4938_sramcptr->cr) & 1) { 170*94a4c329SAtsushi Nemoto unsigned int size = TX4938_SRAM_SIZE; 171*94a4c329SAtsushi Nemoto tx4938_sram_resource.name = "SRAM"; 172*94a4c329SAtsushi Nemoto tx4938_sram_resource.start = 173*94a4c329SAtsushi Nemoto (____raw_readq(&tx4938_sramcptr->cr) >> (39-11)) 174*94a4c329SAtsushi Nemoto & ~(size - 1); 175*94a4c329SAtsushi Nemoto tx4938_sram_resource.end = 176*94a4c329SAtsushi Nemoto tx4938_sram_resource.start + TX4938_SRAM_SIZE - 1; 177*94a4c329SAtsushi Nemoto tx4938_sram_resource.flags = IORESOURCE_MEM; 178*94a4c329SAtsushi Nemoto request_resource(&iomem_resource, &tx4938_sram_resource); 179*94a4c329SAtsushi Nemoto } 180*94a4c329SAtsushi Nemoto 181*94a4c329SAtsushi Nemoto /* TMR */ 182*94a4c329SAtsushi Nemoto /* disable all timers */ 183*94a4c329SAtsushi Nemoto for (i = 0; i < TX4938_NR_TMR; i++) 184*94a4c329SAtsushi Nemoto txx9_tmr_init(TX4938_TMR_REG(i) & 0xfffffffffULL); 185*94a4c329SAtsushi Nemoto 186*94a4c329SAtsushi Nemoto /* DMA */ 187*94a4c329SAtsushi Nemoto for (i = 0; i < 2; i++) 188*94a4c329SAtsushi Nemoto ____raw_writeq(TX4938_DMA_MCR_MSTEN, 189*94a4c329SAtsushi Nemoto (void __iomem *)(TX4938_DMA_REG(i) + 0x50)); 190*94a4c329SAtsushi Nemoto 191*94a4c329SAtsushi Nemoto /* PIO */ 192*94a4c329SAtsushi Nemoto txx9_gpio_init(TX4938_PIO_REG & 0xfffffffffULL, 0, TX4938_NUM_PIO); 193*94a4c329SAtsushi Nemoto __raw_writel(0, &tx4938_pioptr->maskcpu); 194*94a4c329SAtsushi Nemoto __raw_writel(0, &tx4938_pioptr->maskext); 195*94a4c329SAtsushi Nemoto 196*94a4c329SAtsushi Nemoto if (txx9_pcode == 0x4938) { 197*94a4c329SAtsushi Nemoto __u64 pcfg = ____raw_readq(&tx4938_ccfgptr->pcfg); 198*94a4c329SAtsushi Nemoto /* set PCIC1 reset */ 199*94a4c329SAtsushi Nemoto txx9_set64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIC1RST); 200*94a4c329SAtsushi Nemoto if (pcfg & (TX4938_PCFG_ETH0_SEL | TX4938_PCFG_ETH1_SEL)) { 201*94a4c329SAtsushi Nemoto mdelay(1); /* at least 128 cpu clock */ 202*94a4c329SAtsushi Nemoto /* clear PCIC1 reset */ 203*94a4c329SAtsushi Nemoto txx9_clear64(&tx4938_ccfgptr->clkctr, 204*94a4c329SAtsushi Nemoto TX4938_CLKCTR_PCIC1RST); 205*94a4c329SAtsushi Nemoto } else { 206*94a4c329SAtsushi Nemoto printk(KERN_INFO "%s: stop PCIC1\n", txx9_pcode_str); 207*94a4c329SAtsushi Nemoto /* stop PCIC1 */ 208*94a4c329SAtsushi Nemoto txx9_set64(&tx4938_ccfgptr->clkctr, 209*94a4c329SAtsushi Nemoto TX4938_CLKCTR_PCIC1CKD); 210*94a4c329SAtsushi Nemoto } 211*94a4c329SAtsushi Nemoto if (!(pcfg & TX4938_PCFG_ETH0_SEL)) { 212*94a4c329SAtsushi Nemoto printk(KERN_INFO "%s: stop ETH0\n", txx9_pcode_str); 213*94a4c329SAtsushi Nemoto txx9_set64(&tx4938_ccfgptr->clkctr, 214*94a4c329SAtsushi Nemoto TX4938_CLKCTR_ETH0RST); 215*94a4c329SAtsushi Nemoto txx9_set64(&tx4938_ccfgptr->clkctr, 216*94a4c329SAtsushi Nemoto TX4938_CLKCTR_ETH0CKD); 217*94a4c329SAtsushi Nemoto } 218*94a4c329SAtsushi Nemoto if (!(pcfg & TX4938_PCFG_ETH1_SEL)) { 219*94a4c329SAtsushi Nemoto printk(KERN_INFO "%s: stop ETH1\n", txx9_pcode_str); 220*94a4c329SAtsushi Nemoto txx9_set64(&tx4938_ccfgptr->clkctr, 221*94a4c329SAtsushi Nemoto TX4938_CLKCTR_ETH1RST); 222*94a4c329SAtsushi Nemoto txx9_set64(&tx4938_ccfgptr->clkctr, 223*94a4c329SAtsushi Nemoto TX4938_CLKCTR_ETH1CKD); 224*94a4c329SAtsushi Nemoto } 225*94a4c329SAtsushi Nemoto } 226*94a4c329SAtsushi Nemoto } 227*94a4c329SAtsushi Nemoto 228*94a4c329SAtsushi Nemoto void __init tx4938_time_init(unsigned int tmrnr) 229*94a4c329SAtsushi Nemoto { 230*94a4c329SAtsushi Nemoto if (____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_TINTDIS) 231*94a4c329SAtsushi Nemoto txx9_clockevent_init(TX4938_TMR_REG(tmrnr) & 0xfffffffffULL, 232*94a4c329SAtsushi Nemoto TXX9_IRQ_BASE + TX4938_IR_TMR(tmrnr), 233*94a4c329SAtsushi Nemoto TXX9_IMCLK); 234*94a4c329SAtsushi Nemoto } 235*94a4c329SAtsushi Nemoto 236*94a4c329SAtsushi Nemoto void __init tx4938_setup_serial(void) 237*94a4c329SAtsushi Nemoto { 238*94a4c329SAtsushi Nemoto #ifdef CONFIG_SERIAL_TXX9 239*94a4c329SAtsushi Nemoto int i; 240*94a4c329SAtsushi Nemoto struct uart_port req; 241*94a4c329SAtsushi Nemoto unsigned int ch_mask = 0; 242*94a4c329SAtsushi Nemoto 243*94a4c329SAtsushi Nemoto if (__raw_readq(&tx4938_ccfgptr->pcfg) & TX4938_PCFG_ETH0_SEL) 244*94a4c329SAtsushi Nemoto ch_mask |= 1 << 1; /* disable SIO1 by PCFG setting */ 245*94a4c329SAtsushi Nemoto for (i = 0; i < 2; i++) { 246*94a4c329SAtsushi Nemoto if ((1 << i) & ch_mask) 247*94a4c329SAtsushi Nemoto continue; 248*94a4c329SAtsushi Nemoto memset(&req, 0, sizeof(req)); 249*94a4c329SAtsushi Nemoto req.line = i; 250*94a4c329SAtsushi Nemoto req.iotype = UPIO_MEM; 251*94a4c329SAtsushi Nemoto req.membase = (unsigned char __iomem *)TX4938_SIO_REG(i); 252*94a4c329SAtsushi Nemoto req.mapbase = TX4938_SIO_REG(i) & 0xfffffffffULL; 253*94a4c329SAtsushi Nemoto req.irq = TXX9_IRQ_BASE + TX4938_IR_SIO(i); 254*94a4c329SAtsushi Nemoto req.flags |= UPF_BUGGY_UART /*HAVE_CTS_LINE*/; 255*94a4c329SAtsushi Nemoto req.uartclk = TXX9_IMCLK; 256*94a4c329SAtsushi Nemoto early_serial_txx9_setup(&req); 257*94a4c329SAtsushi Nemoto } 258*94a4c329SAtsushi Nemoto #endif /* CONFIG_SERIAL_TXX9 */ 259*94a4c329SAtsushi Nemoto } 260