trizeps4.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509
  1. /*
  2. * linux/arch/arm/mach-pxa/trizeps4.c
  3. *
  4. * Support for the Keith und Koep Trizeps4 Module Platform.
  5. *
  6. * Author: Jürgen Schindele
  7. * Created: 20 02, 2006
  8. * Copyright: Jürgen Schindele
  9. *
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License version 2 as
  12. * published by the Free Software Foundation.
  13. */
  14. #include <linux/init.h>
  15. #include <linux/kernel.h>
  16. #include <linux/platform_device.h>
  17. #include <linux/sysdev.h>
  18. #include <linux/interrupt.h>
  19. #include <linux/sched.h>
  20. #include <linux/bitops.h>
  21. #include <linux/fb.h>
  22. #include <linux/ioport.h>
  23. #include <linux/delay.h>
  24. #include <linux/serial_8250.h>
  25. #include <linux/mtd/mtd.h>
  26. #include <linux/mtd/physmap.h>
  27. #include <linux/mtd/partitions.h>
  28. #include <asm/types.h>
  29. #include <asm/setup.h>
  30. #include <asm/memory.h>
  31. #include <asm/mach-types.h>
  32. #include <asm/hardware.h>
  33. #include <asm/irq.h>
  34. #include <asm/sizes.h>
  35. #include <asm/mach/arch.h>
  36. #include <asm/mach/map.h>
  37. #include <asm/mach/irq.h>
  38. #include <asm/mach/flash.h>
  39. #include <asm/arch/pxa-regs.h>
  40. #include <asm/arch/trizeps4.h>
  41. #include <asm/arch/audio.h>
  42. #include <asm/arch/pxafb.h>
  43. #include <asm/arch/mmc.h>
  44. #include <asm/arch/irda.h>
  45. #include <asm/arch/ohci.h>
  46. #include "generic.h"
  47. #include "devices.h"
  48. /********************************************************************************************
  49. * ONBOARD FLASH
  50. ********************************************************************************************/
  51. static struct mtd_partition trizeps4_partitions[] = {
  52. {
  53. .name = "Bootloader",
  54. .offset = 0x00000000,
  55. .size = 0x00040000,
  56. .mask_flags = MTD_WRITEABLE /* force read-only */
  57. },{
  58. .name = "Backup",
  59. .offset = 0x00040000,
  60. .size = 0x00040000,
  61. },{
  62. .name = "Image",
  63. .offset = 0x00080000,
  64. .size = 0x01080000,
  65. },{
  66. .name = "IPSM",
  67. .offset = 0x01100000,
  68. .size = 0x00e00000,
  69. },{
  70. .name = "Registry",
  71. .offset = 0x01f00000,
  72. .size = MTDPART_SIZ_FULL,
  73. }
  74. };
  75. static struct physmap_flash_data trizeps4_flash_data[] = {
  76. {
  77. .width = 4, /* bankwidth in bytes */
  78. .parts = trizeps4_partitions,
  79. .nr_parts = ARRAY_SIZE(trizeps4_partitions)
  80. }
  81. };
  82. static struct resource flash_resource = {
  83. .start = PXA_CS0_PHYS,
  84. .end = PXA_CS0_PHYS + SZ_32M - 1,
  85. .flags = IORESOURCE_MEM,
  86. };
  87. static struct platform_device flash_device = {
  88. .name = "physmap-flash",
  89. .id = 0,
  90. .dev = {
  91. .platform_data = trizeps4_flash_data,
  92. },
  93. .resource = &flash_resource,
  94. .num_resources = 1,
  95. };
  96. /********************************************************************************************
  97. * DAVICOM DM9000 Ethernet
  98. ********************************************************************************************/
  99. static struct resource dm9000_resources[] = {
  100. [0] = {
  101. .start = TRIZEPS4_ETH_PHYS+0x300,
  102. .end = TRIZEPS4_ETH_PHYS+0x400-1,
  103. .flags = IORESOURCE_MEM,
  104. },
  105. [1] = {
  106. .start = TRIZEPS4_ETH_PHYS+0x8300,
  107. .end = TRIZEPS4_ETH_PHYS+0x8400-1,
  108. .flags = IORESOURCE_MEM,
  109. },
  110. [2] = {
  111. .start = TRIZEPS4_ETH_IRQ,
  112. .end = TRIZEPS4_ETH_IRQ,
  113. .flags = (IORESOURCE_IRQ | IRQT_RISING),
  114. },
  115. };
  116. static struct platform_device dm9000_device = {
  117. .name = "dm9000",
  118. .id = -1,
  119. .num_resources = ARRAY_SIZE(dm9000_resources),
  120. .resource = dm9000_resources,
  121. };
  122. /********************************************************************************************
  123. * PXA270 serial ports
  124. ********************************************************************************************/
  125. static struct plat_serial8250_port tri_serial_ports[] = {
  126. #ifdef CONFIG_SERIAL_PXA
  127. /* this uses the own PXA driver */
  128. {
  129. 0,
  130. },
  131. #else
  132. /* this uses the generic 8520 driver */
  133. [0] = {
  134. .membase = (void *)&FFUART,
  135. .irq = IRQ_FFUART,
  136. .flags = UPF_BOOT_AUTOCONF,
  137. .iotype = UPIO_MEM32,
  138. .regshift = 2,
  139. .uartclk = (921600*16),
  140. },
  141. [1] = {
  142. .membase = (void *)&BTUART,
  143. .irq = IRQ_BTUART,
  144. .flags = UPF_BOOT_AUTOCONF,
  145. .iotype = UPIO_MEM32,
  146. .regshift = 2,
  147. .uartclk = (921600*16),
  148. },
  149. {
  150. 0,
  151. },
  152. #endif
  153. };
  154. static struct platform_device uart_devices = {
  155. .name = "serial8250",
  156. .id = 0,
  157. .dev = {
  158. .platform_data = tri_serial_ports,
  159. },
  160. .num_resources = 0,
  161. .resource = NULL,
  162. };
  163. /********************************************************************************************
  164. * PXA270 ac97 sound codec
  165. ********************************************************************************************/
  166. static struct platform_device ac97_audio_device = {
  167. .name = "pxa2xx-ac97",
  168. .id = -1,
  169. };
  170. static struct platform_device * trizeps4_devices[] __initdata = {
  171. &flash_device,
  172. &uart_devices,
  173. &dm9000_device,
  174. &ac97_audio_device,
  175. };
  176. #ifdef CONFIG_MACH_TRIZEPS4_CONXS
  177. static short trizeps_conxs_bcr;
  178. /* PCCARD power switching supports only 3,3V */
  179. void board_pcmcia_power(int power)
  180. {
  181. if (power) {
  182. /* switch power on, put in reset and enable buffers */
  183. trizeps_conxs_bcr |= power;
  184. trizeps_conxs_bcr |= ConXS_BCR_CF_RESET;
  185. trizeps_conxs_bcr &= ~(ConXS_BCR_CF_BUF_EN);
  186. ConXS_BCR = trizeps_conxs_bcr;
  187. /* wait a little */
  188. udelay(2000);
  189. /* take reset away */
  190. trizeps_conxs_bcr &= ~(ConXS_BCR_CF_RESET);
  191. ConXS_BCR = trizeps_conxs_bcr;
  192. udelay(2000);
  193. } else {
  194. /* put in reset */
  195. trizeps_conxs_bcr |= ConXS_BCR_CF_RESET;
  196. ConXS_BCR = trizeps_conxs_bcr;
  197. udelay(1000);
  198. /* switch power off */
  199. trizeps_conxs_bcr &= ~(0xf);
  200. ConXS_BCR = trizeps_conxs_bcr;
  201. }
  202. pr_debug("%s: o%s 0x%x\n", __FUNCTION__, power ? "n": "ff", trizeps_conxs_bcr);
  203. }
  204. /* backlight power switching for LCD panel */
  205. static void board_backlight_power(int on)
  206. {
  207. if (on) {
  208. trizeps_conxs_bcr |= ConXS_BCR_L_DISP;
  209. } else {
  210. trizeps_conxs_bcr &= ~ConXS_BCR_L_DISP;
  211. }
  212. pr_debug("%s: o%s 0x%x\n", __FUNCTION__, on ? "n" : "ff", trizeps_conxs_bcr);
  213. ConXS_BCR = trizeps_conxs_bcr;
  214. }
  215. /* Powersupply for MMC/SD cardslot */
  216. static void board_mci_power(struct device *dev, unsigned int vdd)
  217. {
  218. struct pxamci_platform_data* p_d = dev->platform_data;
  219. if (( 1 << vdd) & p_d->ocr_mask) {
  220. pr_debug("%s: on\n", __FUNCTION__);
  221. /* FIXME fill in values here */
  222. } else {
  223. pr_debug("%s: off\n", __FUNCTION__);
  224. /* FIXME fill in values here */
  225. }
  226. }
  227. static short trizeps_conxs_ircr;
  228. /* Switch modes and Power for IRDA receiver */
  229. static void board_irda_mode(struct device *dev, int mode)
  230. {
  231. unsigned long flags;
  232. local_irq_save(flags);
  233. if (mode & IR_SIRMODE) {
  234. /* Slow mode */
  235. trizeps_conxs_ircr &= ~ConXS_IRCR_MODE;
  236. } else if (mode & IR_FIRMODE) {
  237. /* Fast mode */
  238. trizeps_conxs_ircr |= ConXS_IRCR_MODE;
  239. }
  240. if (mode & IR_OFF) {
  241. trizeps_conxs_ircr |= ConXS_IRCR_SD;
  242. } else {
  243. trizeps_conxs_ircr &= ~ConXS_IRCR_SD;
  244. }
  245. /* FIXME write values to register */
  246. local_irq_restore(flags);
  247. }
  248. #else
  249. /* for other baseboards define dummies */
  250. void board_pcmcia_power(int power) {;}
  251. #define board_backlight_power NULL
  252. #define board_mci_power NULL
  253. #define board_irda_mode NULL
  254. #endif /* CONFIG_MACH_TRIZEPS4_CONXS */
  255. EXPORT_SYMBOL(board_pcmcia_power);
  256. static int trizeps4_mci_init(struct device *dev, irq_handler_t mci_detect_int, void *data)
  257. {
  258. int err;
  259. /* setup GPIO for PXA27x MMC controller */
  260. pxa_gpio_mode(GPIO32_MMCCLK_MD);
  261. pxa_gpio_mode(GPIO112_MMCCMD_MD);
  262. pxa_gpio_mode(GPIO92_MMCDAT0_MD);
  263. pxa_gpio_mode(GPIO109_MMCDAT1_MD);
  264. pxa_gpio_mode(GPIO110_MMCDAT2_MD);
  265. pxa_gpio_mode(GPIO111_MMCDAT3_MD);
  266. pxa_gpio_mode(GPIO_MMC_DET | GPIO_IN);
  267. err = request_irq(TRIZEPS4_MMC_IRQ, mci_detect_int,
  268. IRQF_DISABLED | IRQF_TRIGGER_RISING,
  269. "MMC card detect", data);
  270. if (err)
  271. printk(KERN_ERR "trizeps4_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
  272. return err;
  273. }
  274. static void trizeps4_mci_exit(struct device *dev, void *data)
  275. {
  276. free_irq(TRIZEPS4_MMC_IRQ, data);
  277. }
  278. static struct pxamci_platform_data trizeps4_mci_platform_data = {
  279. .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
  280. .init = trizeps4_mci_init,
  281. .exit = trizeps4_mci_exit,
  282. .setpower = board_mci_power,
  283. };
  284. static struct pxaficp_platform_data trizeps4_ficp_platform_data = {
  285. .transceiver_cap = IR_SIRMODE | IR_FIRMODE | IR_OFF,
  286. .transceiver_mode = board_irda_mode,
  287. };
  288. static int trizeps4_ohci_init(struct device *dev)
  289. {
  290. /* setup Port1 GPIO pin. */
  291. pxa_gpio_mode( 88 | GPIO_ALT_FN_1_IN); /* USBHPWR1 */
  292. pxa_gpio_mode( 89 | GPIO_ALT_FN_2_OUT); /* USBHPEN1 */
  293. /* Set the Power Control Polarity Low and Power Sense
  294. Polarity Low to active low. */
  295. UHCHR = (UHCHR | UHCHR_PCPL | UHCHR_PSPL) &
  296. ~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE);
  297. return 0;
  298. }
  299. static void trizeps4_ohci_exit(struct device *dev)
  300. {
  301. ;
  302. }
  303. static struct pxaohci_platform_data trizeps4_ohci_platform_data = {
  304. .port_mode = PMM_PERPORT_MODE,
  305. .init = trizeps4_ohci_init,
  306. .exit = trizeps4_ohci_exit,
  307. };
  308. static struct map_desc trizeps4_io_desc[] __initdata = {
  309. { /* ConXS CFSR */
  310. .virtual = TRIZEPS4_CFSR_VIRT,
  311. .pfn = __phys_to_pfn(TRIZEPS4_CFSR_PHYS),
  312. .length = 0x00001000,
  313. .type = MT_DEVICE
  314. },
  315. { /* ConXS BCR */
  316. .virtual = TRIZEPS4_BOCR_VIRT,
  317. .pfn = __phys_to_pfn(TRIZEPS4_BOCR_PHYS),
  318. .length = 0x00001000,
  319. .type = MT_DEVICE
  320. },
  321. { /* ConXS IRCR */
  322. .virtual = TRIZEPS4_IRCR_VIRT,
  323. .pfn = __phys_to_pfn(TRIZEPS4_IRCR_PHYS),
  324. .length = 0x00001000,
  325. .type = MT_DEVICE
  326. },
  327. { /* ConXS DCR */
  328. .virtual = TRIZEPS4_DICR_VIRT,
  329. .pfn = __phys_to_pfn(TRIZEPS4_DICR_PHYS),
  330. .length = 0x00001000,
  331. .type = MT_DEVICE
  332. },
  333. { /* ConXS UPSR */
  334. .virtual = TRIZEPS4_UPSR_VIRT,
  335. .pfn = __phys_to_pfn(TRIZEPS4_UPSR_PHYS),
  336. .length = 0x00001000,
  337. .type = MT_DEVICE
  338. }
  339. };
  340. static struct pxafb_mode_info sharp_lcd_mode = {
  341. .pixclock = 78000,
  342. .xres = 640,
  343. .yres = 480,
  344. .bpp = 8,
  345. .hsync_len = 4,
  346. .left_margin = 4,
  347. .right_margin = 4,
  348. .vsync_len = 2,
  349. .upper_margin = 0,
  350. .lower_margin = 0,
  351. .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  352. .cmap_greyscale = 0,
  353. };
  354. static struct pxafb_mach_info sharp_lcd = {
  355. .modes = &sharp_lcd_mode,
  356. .num_modes = 1,
  357. .cmap_inverse = 0,
  358. .cmap_static = 0,
  359. .lccr0 = LCCR0_Color | LCCR0_Pas | LCCR0_Dual,
  360. .lccr3 = 0x0340ff02,
  361. .pxafb_backlight_power = board_backlight_power,
  362. };
  363. static struct pxafb_mode_info toshiba_lcd_mode = {
  364. .pixclock = 39720,
  365. .xres = 640,
  366. .yres = 480,
  367. .bpp = 8,
  368. .hsync_len = 63,
  369. .left_margin = 12,
  370. .right_margin = 12,
  371. .vsync_len = 4,
  372. .upper_margin = 32,
  373. .lower_margin = 10,
  374. .sync = 0,
  375. .cmap_greyscale = 0,
  376. };
  377. static struct pxafb_mach_info toshiba_lcd = {
  378. .modes = &toshiba_lcd_mode,
  379. .num_modes = 1,
  380. .cmap_inverse = 0,
  381. .cmap_static = 0,
  382. .lccr0 = LCCR0_Color | LCCR0_Act,
  383. .lccr3 = 0x03400002,
  384. .pxafb_backlight_power = board_backlight_power,
  385. };
  386. static void __init trizeps4_init(void)
  387. {
  388. platform_add_devices(trizeps4_devices, ARRAY_SIZE(trizeps4_devices));
  389. /* set_pxa_fb_info(&sharp_lcd); */
  390. set_pxa_fb_info(&toshiba_lcd);
  391. pxa_set_mci_info(&trizeps4_mci_platform_data);
  392. pxa_set_ficp_info(&trizeps4_ficp_platform_data);
  393. pxa_set_ohci_info(&trizeps4_ohci_platform_data);
  394. }
  395. static void __init trizeps4_map_io(void)
  396. {
  397. pxa_map_io();
  398. iotable_init(trizeps4_io_desc, ARRAY_SIZE(trizeps4_io_desc));
  399. /* for DiskOnChip */
  400. pxa_gpio_mode(GPIO15_nCS_1_MD);
  401. /* for off-module PIC on ConXS board */
  402. pxa_gpio_mode(GPIO_PIC | GPIO_IN);
  403. /* UCB1400 irq */
  404. pxa_gpio_mode(GPIO_UCB1400 | GPIO_IN);
  405. /* for DM9000 LAN */
  406. pxa_gpio_mode(GPIO78_nCS_2_MD);
  407. pxa_gpio_mode(GPIO_DM9000 | GPIO_IN);
  408. /* for PCMCIA device */
  409. pxa_gpio_mode(GPIO_PCD | GPIO_IN);
  410. pxa_gpio_mode(GPIO_PRDY | GPIO_IN);
  411. /* for I2C adapter */
  412. pxa_gpio_mode(GPIO117_I2CSCL_MD);
  413. pxa_gpio_mode(GPIO118_I2CSDA_MD);
  414. /* MMC_DET s.o. */
  415. pxa_gpio_mode(GPIO_MMC_DET | GPIO_IN);
  416. /* whats that for ??? */
  417. pxa_gpio_mode(GPIO79_nCS_3_MD);
  418. #ifdef CONFIG_LEDS
  419. pxa_gpio_mode( GPIO_SYS_BUSY_LED | GPIO_OUT); /* LED1 */
  420. pxa_gpio_mode( GPIO_HEARTBEAT_LED | GPIO_OUT); /* LED2 */
  421. #endif
  422. #ifdef CONFIG_MACH_TRIZEPS4_CONXS
  423. #ifdef CONFIG_IDE_PXA_CF
  424. /* if boot direct from compact flash dont disable power */
  425. trizeps_conxs_bcr = 0x0009;
  426. #else
  427. /* this is the reset value */
  428. trizeps_conxs_bcr = 0x00A0;
  429. #endif
  430. ConXS_BCR = trizeps_conxs_bcr;
  431. #endif
  432. PWER = 0x00000002;
  433. PFER = 0x00000000;
  434. PRER = 0x00000002;
  435. PGSR0 = 0x0158C000;
  436. PGSR1 = 0x00FF0080;
  437. PGSR2 = 0x0001C004;
  438. /* Stop 3.6MHz and drive HIGH to PCMCIA and CS */
  439. PCFR |= PCFR_OPDE;
  440. }
  441. MACHINE_START(TRIZEPS4, "Keith und Koep Trizeps IV module")
  442. /* MAINTAINER("Jürgen Schindele") */
  443. .phys_io = 0x40000000,
  444. .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
  445. .boot_params = TRIZEPS4_SDRAM_BASE + 0x100,
  446. .init_machine = trizeps4_init,
  447. .map_io = trizeps4_map_io,
  448. .init_irq = pxa27x_init_irq,
  449. .timer = &pxa_timer,
  450. MACHINE_END