system3.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:9k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

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