mach-smdk6400.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  1. /***********************************************************************
  2. *
  3. * linux/arch/arm/mach-s3c64xx/smdk6400.c
  4. *
  5. * $Id: mach-smdk6400.c,v 1.52 2008/07/17 01:51:09 yujiun Exp $
  6. *
  7. * Copyright (C) 2005, Sean Choi <sh428.choi@samsung.com>
  8. * All rights reserved
  9. *
  10. * This program is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU General Public License as
  12. * published by the Free Software Foundation; either version 2 of
  13. * the License, or (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with this program; if not, write to the Free Software
  22. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  23. * MA 02111-1307 USA
  24. *
  25. * derived from linux/arch/arm/mach-s3c2410/devs.c, written by
  26. * Ben Dooks <ben@simtec.co.uk>
  27. *
  28. ***********************************************************************/
  29. #include <linux/kernel.h>
  30. #include <linux/types.h>
  31. #include <linux/interrupt.h>
  32. #include <linux/list.h>
  33. #include <linux/timer.h>
  34. #include <linux/init.h>
  35. #include <linux/platform_device.h>
  36. #include <linux/mtd/mtd.h>
  37. #include <linux/mtd/partitions.h>
  38. #include <asm/setup.h>
  39. #include <asm/mach/arch.h>
  40. #include <asm/mach/map.h>
  41. #include <asm/mach/irq.h>
  42. #include <asm/mach/flash.h>
  43. #include <asm/hardware.h>
  44. #include <asm/io.h>
  45. #include <asm/irq.h>
  46. #include <asm/mach-types.h>
  47. #include <asm/arch/regs-serial.h>
  48. #include <asm/arch/regs-gpio.h>
  49. #include <asm/arch/regs-mem.h>
  50. #include <asm/arch/nand.h>
  51. #include <asm/plat-s3c24xx/s3c6400.h>
  52. #include <asm/plat-s3c24xx/devs.h>
  53. #include <asm/plat-s3c24xx/cpu.h>
  54. #include <asm/arch/hsmmc.h>
  55. #include <asm/plat-s3c24xx/common-smdk.h>
  56. #include <asm/arch-s3c2410/reserved_mem.h>
  57. #if defined(CONFIG_MACH_SANJOSE2)
  58. #include <asm/arch/regs-irq.h>
  59. #endif
  60. extern struct sys_timer s3c_timer;
  61. static struct map_desc smdk6400_iodesc[] __initdata = {
  62. IODESC_ENT(CS8900),
  63. };
  64. #define DEF_UCON S3C_UCON_DEFAULT
  65. #define DEF_ULCON S3C_LCON_CS8 | S3C_LCON_PNONE
  66. #define DEF_UFCON S3C_UFCON_RXTRIG8 | S3C_UFCON_FIFOMODE
  67. static struct s3c24xx_uart_clksrc smdk6400_serial_clocks[] = {
  68. /* UART Clock with MPLL by Boyko */
  69. [0] = {
  70. .name = "mpll_clk_uart",
  71. .divisor = 1,
  72. .min_baud = 0,
  73. .max_baud = 0,
  74. },
  75. #if 0 /* HS UART Source is changed from epll to mpll */
  76. [1] = {
  77. .name = "pclk",
  78. .divisor = 1,
  79. .min_baud = 0,
  80. .max_baud = 0,
  81. },
  82. #if defined (CONFIG_SERIAL_S3C64XX_HS_UART)
  83. [2] = {
  84. .name = "epll_clk_uart_192m",
  85. .divisor = 1,
  86. .min_baud = 0,
  87. .max_baud = 4000000,
  88. }
  89. #endif
  90. #endif
  91. };
  92. static struct s3c2410_uartcfg smdk6400_uartcfgs[] = {
  93. [0] = {
  94. .hwport = 0,
  95. .flags = 0,
  96. .ucon = DEF_UCON,
  97. .ulcon = DEF_ULCON,
  98. .ufcon = DEF_UFCON,
  99. .clocks = smdk6400_serial_clocks,
  100. .clocks_size = ARRAY_SIZE(smdk6400_serial_clocks),
  101. },
  102. [1] = {
  103. .hwport = 1,
  104. .flags = 0,
  105. .ucon = DEF_UCON,
  106. .ulcon = DEF_ULCON,
  107. .ufcon = DEF_UFCON,
  108. .clocks = smdk6400_serial_clocks,
  109. .clocks_size = ARRAY_SIZE(smdk6400_serial_clocks),
  110. },
  111. [2] = {
  112. .hwport = 2,
  113. .flags = 0,
  114. .ucon = DEF_UCON,
  115. .ulcon = DEF_ULCON,
  116. .ufcon = DEF_UFCON,
  117. .clocks = smdk6400_serial_clocks,
  118. .clocks_size = ARRAY_SIZE(smdk6400_serial_clocks),
  119. },
  120. [3] = {
  121. .hwport = 3,
  122. .flags = 0,
  123. .ucon = DEF_UCON,
  124. .ulcon = DEF_ULCON,
  125. .ufcon = DEF_UFCON,
  126. .clocks = smdk6400_serial_clocks,
  127. .clocks_size = ARRAY_SIZE(smdk6400_serial_clocks),
  128. }
  129. };
  130. /*add devices as drivers are integrated*/
  131. static struct platform_device *smdk6400_devices[] __initdata = {
  132. &s3c_device_lcd,
  133. &s3c_device_rtc,
  134. &s3c_device_ac97,
  135. &s3c_device_iis,
  136. &s3c_device_adc,
  137. &s3c_device_i2c,
  138. &s3c_device_usb,
  139. &s3c_device_usbgadget,
  140. &s3c_device_tvenc,
  141. &s3c_device_tvscaler,
  142. &s3c_device_hsmmc0,
  143. &s3c_device_hsmmc1,
  144. &s3c_device_hsmmc2,
  145. &s3c_device_wdt,
  146. &s3c_device_jpeg,
  147. &s3c_device_vpp,
  148. &s3c_device_ide,
  149. &s3c_device_mfc,
  150. &s3c_device_spi0,
  151. &s3c_device_spi1,
  152. &s3c_device_2d,
  153. &s3c_device_keypad,
  154. &s3c_device_camif,
  155. };
  156. static struct s3c24xx_board smdk6400_board __initdata = {
  157. .devices = smdk6400_devices,
  158. .devices_count = ARRAY_SIZE(smdk6400_devices)
  159. };
  160. static void __init smdk6400_map_io(void)
  161. {
  162. s3c24xx_init_io(smdk6400_iodesc, ARRAY_SIZE(smdk6400_iodesc));
  163. s3c24xx_init_clocks(0);
  164. s3c24xx_init_uarts(smdk6400_uartcfgs, ARRAY_SIZE(smdk6400_uartcfgs));
  165. s3c24xx_set_board(&smdk6400_board);
  166. }
  167. void smdk6400_cs89x0_set(void)
  168. {
  169. unsigned int tmp;
  170. tmp = __raw_readl(S3C_SROM_BW);
  171. tmp &=~(0xF<<4);
  172. tmp |= (1<<7) | (1<<6) | (1<<4);
  173. __raw_writel(tmp, S3C_SROM_BW);
  174. __raw_writel((0x0<<28)|(0x4<<24)|(0xd<<16)|(0x1<<12)|(0x4<<8)|(0x6<<4)|(0x0<<0), S3C_SROM_BC1);
  175. #if defined(CONFIG_MACH_SANJOSE2)
  176. __raw_writel(0, S3C_GPPPU);
  177. __raw_writel((__raw_readl(S3C_GPPCON) & ~(0x3 << 14)) | (0x1 << 14), S3C_GPPCON);
  178. #endif
  179. }
  180. static void __init smdk6400_fixup (struct machine_desc *desc, struct tag *tags,
  181. char **cmdline, struct meminfo *mi)
  182. {
  183. /*
  184. * Bank start addresses are not present in the information
  185. * passed in from the boot loader. We could potentially
  186. * detect them, but instead we hard-code them.
  187. */
  188. mi->bank[0].start = 0x50000000;
  189. #if defined(CONFIG_RESERVED_MEM_JPEG)
  190. mi->bank[0].size = 120*1024*1024;
  191. #elif defined(CONFIG_RESERVED_MEM_JPEG_POST)
  192. mi->bank[0].size = 112*1024*1024;
  193. #elif defined(CONFIG_RESERVED_MEM_MFC)
  194. mi->bank[0].size = 122*1024*1024;
  195. #elif defined(CONFIG_RESERVED_MEM_MFC_POST)
  196. mi->bank[0].size = 114*1024*1024;
  197. #elif defined(CONFIG_RESERVED_MEM_JPEG_MFC_POST)
  198. mi->bank[0].size = 106*1024*1024;
  199. #elif defined(CONFIG_RESERVED_MEM_JPEG_CAMERA)
  200. mi->bank[0].size = 105*1024*1024;
  201. #elif defined(CONFIG_RESERVED_MEM_JPEG_POST_CAMERA)
  202. mi->bank[0].size = 97*1024*1024;
  203. #elif defined(CONFIG_RESERVED_MEM_MFC_CAMERA)
  204. mi->bank[0].size = 107*1024*1024;
  205. #elif defined(CONFIG_RESERVED_MEM_MFC_POST_CAMERA)
  206. mi->bank[0].size = 99*1024*1024;
  207. #elif defined(CONFIG_RESERVED_MEM_JPEG_MFC_POST_CAMERA)
  208. mi->bank[0].size = 91*1024*1024;
  209. #elif defined(CONFIG_RESERVED_MEM_CMM_MFC_POST)
  210. mi->bank[0].size = 106*1024*1024;
  211. #elif defined(CONFIG_RESERVED_MEM_CMM_JPEG_MFC_POST_CAMERA)
  212. mi->bank[0].size = 83*1024*1024;
  213. #elif defined(CONFIG_RESERVED_MEM_TV_MFC_POST_CAMERA)
  214. mi->bank[0].size = 91*1024*1024;
  215. #elif defined(CONFIG_VIDEO_SAMSUNG)
  216. mi->bank[0].size = 113*1024*1024;
  217. #else
  218. mi->bank[0].size = 128*1024*1024;
  219. #endif
  220. mi->bank[0].node = 0;
  221. mi->nr_banks = 1;
  222. }
  223. static void smdk6400_hsmmc_init (void)
  224. {
  225. /* jsgood: hsmmc0/1 card detect pin should be high before setup gpio. (GPG6 to Input) */
  226. writel(readl(S3C_GPGCON) & 0xf0ffffff, S3C_GPGCON);
  227. #if defined(CONFIG_MACH_SANJOSE2)
  228. /* for hsmmc ch2 */
  229. writel(0, S3C_GPNPU);
  230. writel((readl(S3C_GPNCON) & ~(0x3 << 24)) | (0x2 << 24), S3C_GPNCON); /* GPN12 to EINT */
  231. writel(readl(S3C_EINT0CON0) | (0x3 << 25), S3C_EINT0CON0); /* EINT12 to both edge triggered */
  232. writel(readl(S3C_EINT0MASK) & ~(0x1 << 12), S3C_EINT0MASK); /* EINT12 unmask */
  233. writel(readl(S3C_VIC1INTENABLE) | (0x1 << 0), S3C_VIC1INTENABLE); /* EINT12 enable */
  234. #if 0
  235. /* smdk6400 */
  236. writel((readl(S3C_GPNCON) & ~(0x3 << 30)) | (0x2 << 30), S3C_GPNCON); /* GPN15 to EINT */
  237. writel(readl(S3C_EINT0CON0) | (0x3 << 29), S3C_EINT0CON0); /* EINT15 to both edge triggered */
  238. writel(readl(S3C_EINT0MASK) & ~(0x1 << 15), S3C_EINT0MASK); /* EINT15 unmask */
  239. writel(readl(S3C_VIC1INTENABLE) | (0x1 << 4), S3C_VIC1INTENABLE); /* EINT15 enable */
  240. #endif
  241. /* GPC7 to high for usb power up */
  242. s3c_gpio_cfgpin(S3C_GPC7, S3C_GPC7_OUTP);
  243. s3c_gpio_setpin(S3C_GPC7, 1);
  244. #endif
  245. }
  246. static void __init smdk6400_machine_init (void)
  247. {
  248. smdk6400_cs89x0_set();
  249. smdk_machine_init();
  250. smdk6400_hsmmc_init();
  251. }
  252. MACHINE_START(SMDK6400, "SMDK6400")
  253. /* Maintainer: Samsung Electronics */
  254. .phys_io = S3C24XX_PA_UART,
  255. .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
  256. .boot_params = S3C_SDRAM_PA + 0x100,
  257. .init_irq = s3c_init_irq,
  258. .map_io = smdk6400_map_io,
  259. .fixup = smdk6400_fixup,
  260. .timer = &s3c_timer,
  261. .init_machine = smdk6400_machine_init,
  262. MACHINE_END
  263. /*--------------------------------------------------------------
  264. * HS-MMC GPIO Set function
  265. * the location of this function must be re-considered.
  266. * by scsuh
  267. *--------------------------------------------------------------*/
  268. void hsmmc_set_gpio (uint channel, uint width)
  269. {
  270. u32 reg;
  271. switch (channel) {
  272. /* can supports 1 and 4 bit bus */
  273. case 0:
  274. if (width == 1) {
  275. /* MMC CLK0, MMC CMD0, MMC DATA0[0], MMC CDn0 0~2,6 */
  276. reg = readl(S3C_GPGCON) & 0xf0fff000;
  277. writel(reg | 0x02000222, S3C_GPGCON);
  278. reg = readl(S3C_GPGPU) & 0xffffcfc0;
  279. writel(reg, S3C_GPGPU);
  280. }
  281. else if (width == 4) {
  282. /* MMC CLK0, MMC CMD0, MMC DATA0[0-3], MMC CDn0 0~6 */
  283. reg = readl(S3C_GPGCON) & 0xf0000000;
  284. writel(reg | 0x02222222, S3C_GPGCON);
  285. reg = readl(S3C_GPGPU) & 0xfffff000;
  286. writel(reg, S3C_GPGPU);
  287. }
  288. break;
  289. /* can supports 1, 4, and 8 bit bus */
  290. case 1:
  291. /* MMC CDn1 - 6 */
  292. reg = readl(S3C_GPGCON) & 0xf0ffffff;
  293. writel(reg | 0x03000000, S3C_GPGCON);
  294. reg = readl(S3C_GPGPU) & 0xffffcfff;
  295. writel(reg, S3C_GPGPU);
  296. if (width == 1) {
  297. /* MMC CLK1, MMC CMD1, MMC DATA1[0] - 0~2 */
  298. reg = readl(S3C_GPH0CON) & 0xfffff000;
  299. writel(reg | 0x222, S3C_GPH0CON);
  300. reg = readl(S3C_GPHPU) & 0xffffffc0;
  301. writel(reg, S3C_GPHPU);
  302. }
  303. else if (width == 4) {
  304. /* MMC CLK1, MMC CMD1, MMC DATA1[0-3] - 0~5 */
  305. reg = readl(S3C_GPH0CON) & 0xff000000;
  306. writel(reg | 0x00222222, S3C_GPH0CON);
  307. reg = readl(S3C_GPHPU) & 0xfffff000;
  308. writel(reg, S3C_GPHPU);
  309. }
  310. else if (width == 8) {
  311. /* MMC CLK1, MMC CMD1, MMC DATA1[0-5] - 0~7 */
  312. writel(0x22222222, S3C_GPH0CON);
  313. /* MMC DATA1[6-7] 8~9 */
  314. writel(0x00000022, S3C_GPH1CON);
  315. reg = readl(S3C_GPHPU) & 0xfff00000;
  316. writel(reg, S3C_GPHPU);
  317. }
  318. break;
  319. /* can supports 1 and 4 bit bus, no irq_cd */
  320. case 2:
  321. /* MMC CLK2, MMC CMD2 */
  322. reg = readl(S3C_GPCCON) & 0xff00ffff;
  323. writel(reg | 0x00330000, S3C_GPCCON);
  324. reg = readl(S3C_GPCPU) & 0xfffff0ff;
  325. writel(reg, S3C_GPCPU);
  326. if (width == 1) {
  327. /* MMC DATA2[0] */
  328. reg = readl(S3C_GPH0CON) & 0xf0ffffff;
  329. writel(reg | 0x03000000, S3C_GPH0CON);
  330. reg = readl(S3C_GPHPU) & 0xfffff3ff;
  331. writel(reg, S3C_GPHPU);
  332. }
  333. else if (width == 4) {
  334. /* MMC DATA2[1] */
  335. reg = readl(S3C_GPH0CON) & 0x00ffffff;
  336. writel(reg | 0x33000000, S3C_GPH0CON);
  337. /* MMC DATA2[2-3] */
  338. writel(0x00000033, S3C_GPH1CON);
  339. reg = readl(S3C_GPHPU) & 0xfff00fff;
  340. writel(reg, S3C_GPHPU);
  341. }
  342. break;
  343. default:
  344. break;
  345. }
  346. }
  347. /* For host controller's capabilities */
  348. #define HOST_CAPS (MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE | \
  349. MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED)
  350. struct s3c_hsmmc_cfg s3c_hsmmc0_platform = {
  351. .hwport = 0,
  352. .enabled = 0,
  353. .host_caps = HOST_CAPS,
  354. .bus_width = 4,
  355. .highspeed = 0,
  356. /* ctrl for mmc */
  357. .fd_ctrl[MMC_MODE_MMC] = {
  358. .ctrl2 = 0xC0004100, /* ctrl2 for mmc */
  359. .ctrl3[SPEED_NORMAL] = 0x80808080, /* ctrl3 for low speed */
  360. .ctrl3[SPEED_HIGH] = 0x00000080, /* ctrl3 for high speed */
  361. .ctrl4 = 0,
  362. },
  363. /* ctrl for sd */
  364. .fd_ctrl[MMC_MODE_SD] = {
  365. .ctrl2 = 0xC0000100, /* ctrl2 for sd */
  366. .ctrl3[SPEED_NORMAL] = 0, /* ctrl3 for low speed */
  367. .ctrl3[SPEED_HIGH] = 0, /* ctrl3 for high speed */
  368. .ctrl4 = 0,
  369. },
  370. .clk_name[0] = "hsmmc0", /* 1st clock source */
  371. .clk_name[1] = "", /* 2nd clock source */
  372. .clk_name[2] = "sclk_48m_mmc0", /* 3rd clock source */
  373. };
  374. struct s3c_hsmmc_cfg s3c_hsmmc1_platform = {
  375. .hwport = 1,
  376. .enabled = 1,
  377. .host_caps = HOST_CAPS | MMC_CAP_8_BIT_DATA,
  378. .bus_width = 8,
  379. .highspeed = 0,
  380. /* ctrl for mmc */
  381. .fd_ctrl[MMC_MODE_MMC] = {
  382. .ctrl2 = 0xC0004100, /* ctrl2 for mmc */
  383. .ctrl3[SPEED_NORMAL] = 0x80808080, /* ctrl3 for low speed */
  384. .ctrl3[SPEED_HIGH] = 0x00000080, /* ctrl3 for high speed */
  385. .ctrl4 = 0,
  386. },
  387. /* ctrl for sd */
  388. .fd_ctrl[MMC_MODE_SD] = {
  389. .ctrl2 = 0xC0000100, /* ctrl2 for sd */
  390. .ctrl3[SPEED_NORMAL] = 0, /* ctrl3 for low speed */
  391. .ctrl3[SPEED_HIGH] = 0, /* ctrl3 for high speed */
  392. .ctrl4 = 0,
  393. },
  394. .clk_name[0] = "hsmmc1", /* 1st clock source */
  395. .clk_name[1] = "", /* 2nd clock source */
  396. .clk_name[2] = "sclk_48m_mmc1", /* 3rd clock source */
  397. };
  398. struct s3c_hsmmc_cfg s3c_hsmmc2_platform = {
  399. .hwport = 2,
  400. .enabled = 0,
  401. .host_caps = HOST_CAPS,
  402. .bus_width = 4,
  403. .highspeed = 0,
  404. /* ctrl for mmc */
  405. .fd_ctrl[MMC_MODE_MMC] = {
  406. .ctrl2 = 0xC0004100, /* ctrl2 for mmc */
  407. .ctrl3[SPEED_NORMAL] = 0x80808080, /* ctrl3 for low speed */
  408. .ctrl3[SPEED_HIGH] = 0x00000080, /* ctrl3 for high speed */
  409. .ctrl4 = 0,
  410. },
  411. /* ctrl for sd */
  412. .fd_ctrl[MMC_MODE_SD] = {
  413. .ctrl2 = 0xC0000100, /* ctrl2 for sd */
  414. .ctrl3[SPEED_NORMAL] = 0, /* ctrl3 for low speed */
  415. .ctrl3[SPEED_HIGH] = 0, /* ctrl3 for high speed */
  416. .ctrl4 = 0,
  417. },
  418. .clk_name[0] = "hsmmc2", /* 1st clock source */
  419. .clk_name[1] = "", /* 2nd clock source */
  420. .clk_name[2] = "sclk_48m_mmc2", /* 3rd clock source */
  421. };