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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  *  arch/mips/ddb5476/setup.c -- NEC DDB Vrc-5476 setup routines
  3.  *
  4.  *  Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
  5.  *                     Sony Software Development Center Europe (SDCE), Brussels
  6.  */
  7. #include <linux/config.h>
  8. #include <linux/init.h>
  9. #include <linux/kbd_ll.h>
  10. #include <linux/kernel.h>
  11. #include <linux/kdev_t.h>
  12. #include <linux/types.h>
  13. #include <linux/console.h>
  14. #include <linux/sched.h>
  15. #include <linux/mc146818rtc.h>
  16. #include <linux/pc_keyb.h>
  17. #include <linux/pci.h>
  18. #include <linux/ide.h>
  19. #include <asm/addrspace.h>
  20. #include <asm/bcache.h>
  21. #include <asm/keyboard.h>
  22. #include <asm/irq.h>
  23. #include <asm/reboot.h>
  24. #include <asm/gdb-stub.h>
  25. #include <asm/nile4.h>
  26. #include <asm/time.h>
  27. #ifdef CONFIG_REMOTE_DEBUG
  28. extern void rs_kgdb_hook(int);
  29. extern void breakpoint(void);
  30. #endif
  31. #if defined(CONFIG_SERIAL_CONSOLE)
  32. extern void console_setup(char *);
  33. #endif
  34. extern struct ide_ops std_ide_ops;
  35. extern struct rtc_ops ddb_rtc_ops;
  36. extern struct kbd_ops std_kbd_ops;
  37. static void (*back_to_prom) (void) = (void (*)(void)) 0xbfc00000;
  38. static void ddb_machine_restart(char *command)
  39. {
  40. u32 t;
  41. /* PCI cold reset */
  42. t = nile4_in32(NILE4_PCICTRL + 4);
  43. t |= 0x40000000;
  44. nile4_out32(NILE4_PCICTRL + 4, t);
  45. /* CPU cold reset */
  46. t = nile4_in32(NILE4_CPUSTAT);
  47. t |= 1;
  48. nile4_out32(NILE4_CPUSTAT, t);
  49. /* Call the PROM */
  50. back_to_prom();
  51. }
  52. static void ddb_machine_halt(void)
  53. {
  54. printk("DDB Vrc-5476 halted.n");
  55. while (1);
  56. }
  57. static void ddb_machine_power_off(void)
  58. {
  59. printk("DDB Vrc-5476 halted. Please turn off the power.n");
  60. while (1);
  61. }
  62. extern void ddb_irq_setup(void);
  63. static void __init ddb_time_init(struct irqaction *irq)
  64. {
  65. printk("ddb_time_init invoked.n");
  66. mips_counter_frequency = 83000000;
  67. }
  68. static void __init ddb_timer_setup(struct irqaction *irq)
  69. {
  70. unsigned int count;
  71. /* we are using the cpu counter for timer interrupts */
  72. i8259_setup_irq(0, irq);
  73. set_cp0_status(IE_IRQ5);
  74. /* to generate the first timer interrupt */
  75. count = read_32bit_cp0_register(CP0_COUNT);
  76. write_32bit_cp0_register(CP0_COMPARE, count + 1000);
  77. #if 0 /* the old way to do timer interrupt */
  78. /* set the clock to 100 Hz */
  79. nile4_out32(NILE4_T2CTRL, 830000);
  80. /* enable the General-Purpose Timer */
  81. nile4_out32(NILE4_T2CTRL + 4, 0x00000001);
  82. /* reset timer */
  83. nile4_out32(NILE4_T2CNTR, 0);
  84. /* enable interrupt */
  85. nile4_enable_irq(NILE4_INT_GPT);
  86. i8259_setup_irq(nile4_to_irq(NILE4_INT_GPT), irq);
  87. #endif
  88. }
  89. static struct {
  90. struct resource dma1;
  91. struct resource pic1;
  92. struct resource timer;
  93. struct resource rtc;
  94. struct resource dma_page_reg;
  95. struct resource pic2;
  96. struct resource dma2;
  97. } ddb5476_ioport = {
  98. {
  99. "dma1", 0x00, 0x1f, IORESOURCE_BUSY}, {
  100. "pic1", 0x20, 0x3f, IORESOURCE_BUSY}, {
  101. "timer", 0x40, 0x5f, IORESOURCE_BUSY}, {
  102. "rtc", 0x70, 0x7f, IORESOURCE_BUSY}, {
  103. "dma page reg", 0x80, 0x8f, IORESOURCE_BUSY}, {
  104. "pic2", 0xa0, 0xbf, IORESOURCE_BUSY}, {
  105. "dma2", 0xc0, 0xdf, IORESOURCE_BUSY}
  106. };
  107. static struct {
  108. struct resource nile4;
  109. } ddb5476_iomem = {
  110. { "Nile 4", NILE4_BASE, NILE4_BASE + NILE4_SIZE - 1, IORESOURCE_BUSY}
  111. };
  112. void __init ddb_setup(void)
  113. {
  114. extern int panic_timeout;
  115. irq_setup = ddb_irq_setup;
  116. mips_io_port_base = NILE4_PCI_IO_BASE;
  117. isa_slot_offset = NILE4_PCI_MEM_BASE;
  118. board_time_init = ddb_time_init;
  119. board_timer_setup = ddb_timer_setup;
  120. _machine_restart = ddb_machine_restart;
  121. _machine_halt = ddb_machine_halt;
  122. _machine_power_off = ddb_machine_power_off;
  123. /* request io port/mem resources  */
  124. if (request_resource(&ioport_resource, &ddb5476_ioport.dma1) ||
  125.     request_resource(&ioport_resource, &ddb5476_ioport.pic1) ||
  126.     request_resource(&ioport_resource, &ddb5476_ioport.timer) ||
  127.     request_resource(&ioport_resource, &ddb5476_ioport.rtc) ||
  128.     request_resource(&ioport_resource,
  129.      &ddb5476_ioport.dma_page_reg)
  130.     || request_resource(&ioport_resource, &ddb5476_ioport.pic2)
  131.     || request_resource(&ioport_resource, &ddb5476_ioport.dma2)
  132.     || request_resource(&iomem_resource, &ddb5476_iomem.nile4)) {
  133. printk
  134.     ("ddb_setup - requesting oo port resources failed.n");
  135. for (;;);
  136. }
  137. #ifdef CONFIG_BLK_DEV_IDE
  138. ide_ops = &std_ide_ops;
  139. #endif
  140. rtc_ops = &ddb_rtc_ops;
  141. #ifdef CONFIG_PC_KEYB
  142. kbd_ops = &std_kbd_ops;
  143. #endif
  144. /* Reboot on panic */
  145. panic_timeout = 180;
  146. /* [jsun] we need to set BAR0 so that SDRAM 0 appears at 0x0 in PCI */
  147. /* *(long*)0xbfa00218 = 0x8; */
  148. #ifdef CONFIG_FB
  149. conswitchp = &dummy_con;
  150. #endif
  151. /* board initialization stuff - non-fundamental, but need to be set
  152.  * before kernel runs */
  153. /* setup I/O space */
  154. nile4_set_pdar(NILE4_PCIW0,
  155.        PHYSADDR(NILE4_PCI_IO_BASE), 0x02000000, 32, 0, 0);
  156. nile4_set_pmr(NILE4_PCIINIT0, NILE4_PCICMD_IO, 0);
  157. /* map config space to 0xa8000000, 128MB */
  158. nile4_set_pdar(NILE4_PCIW1,
  159.        PHYSADDR(NILE4_PCI_CFG_BASE), 0x08000000, 32, 0, 0);
  160. nile4_set_pmr(NILE4_PCIINIT1, NILE4_PCICMD_CFG, 0x0);
  161. /* ----- M1543 PCI setup ------ */
  162. /* we know M1543 PCI-ISA controller is at addr:18 */
  163. /* xxxx1010 makes USB at addr:13 and PMU at addr:14 */
  164. *(volatile unsigned char *) 0xa8040072 &= 0xf0;
  165. *(volatile unsigned char *) 0xa8040072 |= 0xa;
  166. /* setup USB interrupt to IRQ 9, (bit 0:3 - 0001)
  167.  * no IOCHRDY signal, (bit 7 - 1)
  168.  * M1543C & M7101 VID and Subsys Device ID are read-only (bit 6 - 1)
  169.  * Bypass USB Master INTAJ level to edge conversion (bit 4 - 0)
  170.  */
  171. *(unsigned char *) 0xa8040074 = 0xc1;
  172. /* setup PMU(SCI to IRQ 10 (bit 0:3 - 0011)
  173.  * SCI routing to IRQ 13 disabled (bit 7 - 1)
  174.  * SCI interrupt level to edge conversion bypassed (bit 4 - 0)
  175.  */
  176. *(unsigned char *) 0xa8040076 = 0x83;
  177. /* setup IDE controller
  178.  * enable IDE controller (bit 6 - 1)
  179.  * IDE IDSEL to be addr:24 (bit 4:5 - 11)
  180.  * no IDE ATA Secondary Bus Signal Pad Control (bit 3 - 0)
  181.  * no IDE ATA Primary Bus Signal Pad Control (bit 2 - 0)
  182.  * primary IRQ is 14, secondary is 15 (bit 1:0 - 01
  183.  */
  184. // *(unsigned char*)0xa8040058 = 0x71;
  185. // *(unsigned char*)0xa8040058 = 0x79;
  186. // *(unsigned char*)0xa8040058 = 0x74;              // use SIRQ, primary tri-state
  187. *(unsigned char *) 0xa8040058 = 0x75; // primary tri-state
  188. #if 0
  189. /* this is not necessary if M5229 does not use SIRQ */
  190. *(unsigned char *) 0xa8040044 = 0x0d; // primary to IRQ 14
  191. *(unsigned char *) 0xa8040075 = 0x0d; // secondary to IRQ 14
  192. #endif
  193. /* enable IDE in the M5229 config register 0x50 (bit 0 - 1) */
  194. /* M5229 IDSEL is addr:24; see above setting */
  195. *(unsigned char *) 0xa9000050 |= 0x1;
  196. /* enable bus master (bit 2)  and IO decoding  (bit 0) */
  197. *(unsigned char *) 0xa9000004 |= 0x5;
  198. /* enable native, copied from arch/ppc/k2boot/head.S */
  199. /* TODO - need volatile, need to be portable */
  200. *(unsigned char *) 0xa9000009 = 0xff;
  201. /* ----- end of M1543 PCI setup ------ */
  202. /* ----- reset on-board ether chip  ------ */
  203. *((volatile u32 *) 0xa8020004) |= 1; /* decode I/O */
  204. *((volatile u32 *) 0xa8020010) = 0; /* set BAR address */
  205. /* send reset command */
  206. *((volatile u32 *) 0xa6000000) = 1; /* do a soft reset */
  207. /* disable ether chip */
  208. *((volatile u32 *) 0xa8020004) = 0; /* disable any decoding */
  209. /* put it into sleep */
  210. *((volatile u32 *) 0xa8020040) = 0x80000000;
  211. /* ----- end of reset on-board ether chip  ------ */
  212. /* ----- set pci window 1 to pci memory space -------- */
  213. nile4_set_pdar(NILE4_PCIW1,
  214.        PHYSADDR(NILE4_PCI_MEM_BASE), 0x08000000, 32, 0, 0);
  215. // nile4_set_pmr(NILE4_PCIINIT1, NILE4_PCICMD_MEM, 0);
  216. nile4_set_pmr(NILE4_PCIINIT1, NILE4_PCICMD_MEM, 0x08000000);
  217. }
  218. #define USE_NILE4_SERIAL 0
  219. #if USE_NILE4_SERIAL
  220. #define ns16550_in(reg) nile4_in8((reg)*8)
  221. #define ns16550_out(reg, val) nile4_out8((reg)*8, (val))
  222. #else
  223. #define NS16550_BASE (NILE4_PCI_IO_BASE+0x03f8)
  224. static inline u8 ns16550_in(u32 reg)
  225. {
  226. return *(volatile u8 *) (NS16550_BASE + reg);
  227. }
  228. static inline void ns16550_out(u32 reg, u8 val)
  229. {
  230. *(volatile u8 *) (NS16550_BASE + reg) = val;
  231. }
  232. #endif
  233. #define NS16550_RBR 0
  234. #define NS16550_THR 0
  235. #define NS16550_DLL 0
  236. #define NS16550_IER 1
  237. #define NS16550_DLM 1
  238. #define NS16550_FCR 2
  239. #define NS16550_IIR 2
  240. #define NS16550_LCR 3
  241. #define NS16550_MCR 4
  242. #define NS16550_LSR 5
  243. #define NS16550_MSR 6
  244. #define NS16550_SCR 7
  245. #define NS16550_LSR_DR 0x01 /* Data ready */
  246. #define NS16550_LSR_OE 0x02 /* Overrun */
  247. #define NS16550_LSR_PE 0x04 /* Parity error */
  248. #define NS16550_LSR_FE 0x08 /* Framing error */
  249. #define NS16550_LSR_BI 0x10 /* Break */
  250. #define NS16550_LSR_THRE 0x20 /* Xmit holding register empty */
  251. #define NS16550_LSR_TEMT 0x40 /* Xmitter empty */
  252. #define NS16550_LSR_ERR 0x80 /* Error */
  253. void _serinit(void)
  254. {
  255. #if USE_NILE4_SERIAL
  256. ns16550_out(NS16550_LCR, 0x80);
  257. ns16550_out(NS16550_DLM, 0x00);
  258. ns16550_out(NS16550_DLL, 0x36); /* 9600 baud */
  259. ns16550_out(NS16550_LCR, 0x00);
  260. ns16550_out(NS16550_LCR, 0x03);
  261. ns16550_out(NS16550_FCR, 0x47);
  262. #else
  263. /* done by PMON */
  264. #endif
  265. }
  266. void _putc(char c)
  267. {
  268. while (!(ns16550_in(NS16550_LSR) & NS16550_LSR_THRE));
  269. ns16550_out(NS16550_THR, c);
  270. if (c == 'n') {
  271. while (!(ns16550_in(NS16550_LSR) & NS16550_LSR_THRE));
  272. ns16550_out(NS16550_THR, 'r');
  273. }
  274. }
  275. void _puts(const char *s)
  276. {
  277. char c;
  278. while ((c = *s++))
  279. _putc(c);
  280. }
  281. char _getc(void)
  282. {
  283. while (!(ns16550_in(NS16550_LSR) & NS16550_LSR_DR));
  284. return ns16550_in(NS16550_RBR);
  285. }
  286. int _testc(void)
  287. {
  288. return (ns16550_in(NS16550_LSR) & NS16550_LSR_DR) != 0;
  289. }
  290. /*
  291.  *  Hexadecimal 7-segment LED
  292.  */
  293. void ddb5476_led_hex(int hex)
  294. {
  295. outb(hex, 0x80);
  296. }
  297. /*
  298.  *  LEDs D2 and D3, connected to the GPIO pins of the PMU in the ALi M1543
  299.  */
  300. struct pci_dev *pci_pmu = NULL;
  301. void ddb5476_led_d2(int on)
  302. {
  303. u8 t;
  304. if (pci_pmu) {
  305. pci_read_config_byte(pci_pmu, 0x7e, &t);
  306. if (on)
  307. t &= 0x7f;
  308. else
  309. t |= 0x80;
  310. pci_write_config_byte(pci_pmu, 0x7e, t);
  311. }
  312. }
  313. void ddb5476_led_d3(int on)
  314. {
  315. u8 t;
  316. if (pci_pmu) {
  317. pci_read_config_byte(pci_pmu, 0x7e, &t);
  318. if (on)
  319. t &= 0xbf;
  320. else
  321. t |= 0x40;
  322. pci_write_config_byte(pci_pmu, 0x7e, t);
  323. }
  324. }