1/* 2 * linux/arch/arm/mach-sa1100/system3.c 3 * 4 * Copyright (C) 2001 Stefan Eletzhofer <stefan.eletzhofer@eletztrick.de> 5 * 6 * $Id: system3.c,v 1.1.1.1 2008/10/15 03:26:00 james26_jang Exp $ 7 * 8 * This file contains all PT Sytsem 3 tweaks. Based on original work from 9 * Nicolas Pitre's assabet fixes 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License version 2 as 13 * published by the Free Software Foundation. 14 * 15 * $Log: system3.c,v $ 16 * Revision 1.1.1.1 2008/10/15 03:26:00 james26_jang 17 * Initial. 18 * 19 * Revision 1.1.1.1 2008/07/21 09:14:22 james26_jang 20 * New UI, New QoS, New wireless driver(4.151.10.29), ipmonitor. 21 * 22 * Revision 1.1.1.1 2008/07/02 14:38:28 james26_jang 23 * 4.100.10.29, New QoS and New UI. 24 * 25 * Revision 1.1.1.1 2007/02/15 12:10:52 jiahao 26 * initial update 27 * 28 * Revision 1.1.1.1 2007/01/25 12:51:48 jiahao_jhou 29 * 30 * 31 * Revision 1.1.1.1 2003/02/03 22:37:19 mhuang 32 * LINUX_2_4 branch snapshot from linux-mips.org CVS 33 * 34 * Revision 1.1.6.1 2001/12/04 17:28:06 seletz 35 * - merged from previous branch 36 * 37 * Revision 1.1.4.3 2001/12/04 15:16:31 seletz 38 * - merged from linux_2_4_13_ac5_rmk2 39 * 40 * Revision 1.1.4.2 2001/11/19 17:18:57 seletz 41 * - more code cleanups 42 * 43 * Revision 1.1.4.1 2001/11/16 13:52:05 seletz 44 * - PT Digital Board Support Code 45 * 46 * Revision 1.1.2.2 2001/11/05 16:46:18 seletz 47 * - cleanups 48 * 49 * Revision 1.1.2.1 2001/10/15 16:00:43 seletz 50 * - first revision working with new board 51 * 52 * 53 */ 54 55#include <linux/config.h> 56#include <linux/init.h> 57#include <linux/kernel.h> 58#include <linux/sched.h> 59#include <linux/tty.h> 60#include <linux/module.h> 61#include <linux/errno.h> 62#include <linux/cpufreq.h> 63 64#include <asm/hardware.h> 65#include <asm/setup.h> 66#include <asm/page.h> 67#include <asm/pgtable.h> 68#include <asm/irq.h> 69 70#include <asm/mach/arch.h> 71#include <asm/mach/map.h> 72#include <asm/mach/irq.h> 73#include <asm/mach/serial_sa1100.h> 74 75#include <asm/arch/irq.h> 76 77#include <linux/serial_core.h> 78 79#include "generic.h" 80#include "sa1111.h" 81 82#define DEBUG 1 83 84#ifdef DEBUG 85# define DPRINTK( x, args... ) printk( "%s: line %d: "x, __FUNCTION__, __LINE__, ## args ); 86#else 87# define DPRINTK( x, args... ) /* nix */ 88#endif 89 90/********************************************************************** 91 * prototypes 92 */ 93 94/* init funcs */ 95static void __init fixup_system3(struct machine_desc *desc, 96 struct param_struct *params, char **cmdline, struct meminfo *mi); 97static void __init get_system3_scr(void); 98static int __init system3_init(void); 99static void __init system3_init_irq(void); 100static void __init system3_map_io(void); 101 102static void system3_IRQ_demux( int irq, void *dev_id, struct pt_regs *regs ); 103static int system3_get_mctrl(struct uart_port *port); 104static void system3_set_mctrl(struct uart_port *port, u_int mctrl); 105static void system3_uart_pm(struct uart_port *port, u_int state, u_int oldstate); 106static int sdram_notifier(struct notifier_block *nb, unsigned long event, void *data); 107 108extern void convert_to_tag_list(struct param_struct *params, int mem_init); 109 110 111/********************************************************************** 112 * global data 113 */ 114 115/********************************************************************** 116 * static data 117 */ 118 119static struct map_desc system3_io_desc[] __initdata = { 120 /* virtual physical length domain r w c b */ 121 { 0xe8000000, 0x00000000, 0x01000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 0 */ 122 { 0xf3000000, 0x10000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* System Registers */ 123 { 0xf4000000, 0x40000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* SA-1111 */ 124 LAST_DESC 125}; 126 127static struct sa1100_port_fns system3_port_fns __initdata = { 128 set_mctrl: system3_set_mctrl, 129 get_mctrl: system3_get_mctrl, 130 pm: system3_uart_pm, 131}; 132 133static struct irqaction system3_irq = { 134 name: "PT Digital Board SA1111 IRQ", 135 handler: system3_IRQ_demux, 136 flags: SA_INTERRUPT 137}; 138 139static struct notifier_block system3_clkchg_block = { 140 notifier_call: sdram_notifier, 141}; 142 143/********************************************************************** 144 * Static functions 145 */ 146 147static void __init system3_map_io(void) 148{ 149 DPRINTK( "%s\n", "START" ); 150 sa1100_map_io(); 151 iotable_init(system3_io_desc); 152 153 sa1100_register_uart_fns(&system3_port_fns); 154 sa1100_register_uart(0, 1); /* com port */ 155 sa1100_register_uart(1, 2); 156 sa1100_register_uart(2, 3); /* radio module */ 157 158 Ser1SDCR0 |= SDCR0_SUS; 159} 160 161 162/********************************************************************* 163 * Install IRQ handler 164 */ 165static void system3_IRQ_demux( int irq, void *dev_id, struct pt_regs *regs ) 166{ 167 u_char irr; 168 169 for(;;){ 170 //irr = PTCPLD_REG_IRQSR & (PT_IRQ_LAN | PT_IRQ_USAR | PT_IRQ_SA1111); 171 irr = PT_IRQSR & (PT_IRQ_LAN | PT_IRQ_SA1111); 172 173 irr ^= (PT_IRQ_LAN); 174 if (!irr) break; 175 176 if( irr & PT_IRQ_LAN ) 177 do_IRQ(IRQ_SYSTEM3_SMC9196, regs); 178 179 180 if( irr & PT_IRQ_SA1111 ) 181 sa1111_IRQ_demux(irq, dev_id, regs); 182 } 183} 184 185 186static void __init system3_init_irq(void) 187{ 188 int irq; 189 190 DPRINTK( "%s\n", "START" ); 191 192 /* SA1111 IRQ not routed to a GPIO. */ 193 sa1111_init_irq(-1); 194 195 /* setup extra IRQs */ 196 irq = IRQ_SYSTEM3_SMC9196; 197 irq_desc[irq].valid = 1; 198 irq_desc[irq].probe_ok = 1; 199 200 201 /* IRQ by CPLD */ 202 set_GPIO_IRQ_edge( GPIO_GPIO(25), GPIO_RISING_EDGE ); 203 setup_arm_irq( IRQ_GPIO25, &system3_irq ); 204} 205 206/********************************************************************** 207 * On system 3 limit cpu frequency to 206 Mhz 208 */ 209static int sdram_notifier(struct notifier_block *nb, unsigned long event, 210 void *data) 211{ 212 switch (event) { 213 case CPUFREQ_MINMAX: 214 cpufreq_updateminmax(data, 147500, 206000); 215 break; 216 217 } 218 return 0; 219} 220 221/** 222 * fixup_system3 - fixup function for system 3 board 223 * @desc: machine description 224 * @param: kernel params 225 * @cmdline: kernel cmdline 226 * @mi: memory info struct 227 * 228 */ 229static void __init fixup_system3(struct machine_desc *desc, 230 struct param_struct *params, char **cmdline, struct meminfo *mi) 231{ 232 DPRINTK( "%s\n", "START" ); 233 234 ROOT_DEV = MKDEV(RAMDISK_MAJOR,0); 235 setup_ramdisk( 1, 0, 0, 8192 ); 236 setup_initrd( 0xc0800000, 8*1024*1024 ); 237} 238 239 240/** 241 * system3_uart_pm - powermgmt callback function for system 3 UART 242 * @port: uart port structure 243 * @state: pm state 244 * @oldstate: old pm state 245 * 246 */ 247static void system3_uart_pm(struct uart_port *port, u_int state, u_int oldstate) 248{ 249 /* TODO: switch on/off uart in powersave mode */ 250} 251 252static void system3_set_mctrl(struct uart_port *port, u_int mctrl) 253{ 254 if (port->mapbase == _Ser1UTCR0) { 255 u_int set = 0, clear = 0; 256 257 if (mctrl & TIOCM_RTS) 258 set |= PT_CTRL2_RS1_RTS; 259 else 260 clear |= PT_CTRL2_RS1_RTS; 261 262 if (mctrl & TIOCM_DTR) 263 set |= PT_CTRL2_RS1_DTR; 264 else 265 clear |= PT_CTRL2_RS1_DTR; 266 267 PTCTRL2_clear(clear); 268 PTCTRL2_set(set); 269 } 270} 271 272static int system3_get_mctrl(struct uart_port *port) 273{ 274 u_int ret = 0; 275 u_int irqsr = PT_IRQSR; 276 277 /* need 2 reads to read current value */ 278 irqsr = PT_IRQSR; 279 280 /* TODO: check IRQ source register for modem/com 281 status lines and set them correctly. */ 282 283 ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR; 284 285 return ret; 286} 287 288static int __init system3_init(void) 289{ 290 int ret = 0; 291 DPRINTK( "%s\n", "START" ); 292 293 if ( !machine_is_pt_system3() ) { 294 ret = -EINVAL; 295 goto DONE; 296 } 297 298 /* init control register */ 299 PT_CTRL0 = PT_CTRL0_INIT; 300 PT_CTRL1 = 0x02; 301 PT_CTRL2 = 0x00; 302 DPRINTK( "CTRL[0]=0x%02x\n", PT_CTRL0 ); 303 DPRINTK( "CTRL[1]=0x%02x\n", PT_CTRL1 ); 304 DPRINTK( "CTRL[2]=0x%02x\n", PT_CTRL2 ); 305 306 /* 307 * Ensure that the memory bus request/grant signals are setup, 308 * and the grant is held in its inactive state. 309 */ 310 sa1110_mb_disable(); 311 312 /* 313 * Probe for a SA1111. 314 */ 315 ret = sa1111_probe(PT_SA1111_BASE); 316 if (ret < 0) { 317 printk( KERN_WARNING"PT Digital Board: no SA1111 found!\n" ); 318 goto DONE; 319 } 320 321 /* 322 * We found it. Wake the chip up. 323 */ 324 sa1111_wake(); 325 326 /* 327 * The SDRAM configuration of the SA1110 and the SA1111 must 328 * match. This is very important to ensure that SA1111 accesses 329 * don't corrupt the SDRAM. Note that this ungates the SA1111's 330 * MBGNT signal, so we must have called sa1110_mb_disable() 331 * beforehand. 332 */ 333 sa1111_configure_smc(1, 334 FExtr(MDCNFG, MDCNFG_SA1110_DRAC0), 335 FExtr(MDCNFG, MDCNFG_SA1110_TDL0)); 336 337 /* 338 * We only need to turn on DCLK whenever we want to use the 339 * DMA. It can otherwise be held firmly in the off position. 340 */ 341 SKPCR |= SKPCR_DCLKEN; 342 343 /* 344 * Enable the SA1110 memory bus request and grant signals. 345 */ 346 sa1110_mb_enable(); 347 348 system3_init_irq(); 349 350#if defined(CONFIG_CPU_FREQ) 351 ret = cpufreq_register_notifier(&system3_clkchg_block); 352 if ( ret != 0 ) { 353 printk( KERN_WARNING"PT Digital Board: could not register clock scale callback\n" ); 354 goto DONE; 355 } 356#endif 357 358 ret = 0; 359DONE: 360 DPRINTK( "ret=%d\n", ret ); 361 return ret; 362} 363 364/********************************************************************** 365 * Exported Functions 366 */ 367 368/********************************************************************** 369 * kernel magic macros 370 */ 371__initcall(system3_init); 372 373MACHINE_START(PT_SYSTEM3, "PT System 3") 374 BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) 375 BOOT_PARAMS(0xc0000100) 376 FIXUP(fixup_system3) 377 MAPIO(system3_map_io) 378 INITIRQ(sa1100_init_irq) 379MACHINE_END 380