s3c6400.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. /* linux/arch/arm/mach-s3c64xx/s3c6400.c
  2. *
  3. * Copyright (c) 2006, Samsung Electronics
  4. * All rights reserved.
  5. *
  6. * Samsung S3C6400 Mobile CPU support
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License version 2 as
  10. * published by the Free Software Foundation.
  11. *
  12. * derived from linux/arch/arm/mach-s3c2410/devs.c, written by
  13. * Ben Dooks <ben@simtec.co.uk>
  14. */
  15. #include <linux/kernel.h>
  16. #include <linux/types.h>
  17. #include <linux/interrupt.h>
  18. #include <linux/list.h>
  19. #include <linux/timer.h>
  20. #include <linux/init.h>
  21. #include <linux/platform_device.h>
  22. #include <linux/sysdev.h>
  23. #include <linux/delay.h>
  24. #include <linux/proc_fs.h>
  25. #include <linux/clk.h>
  26. #include <asm/mach/arch.h>
  27. #include <asm/mach/map.h>
  28. #include <asm/mach/irq.h>
  29. #include <asm/hardware.h>
  30. #include <asm/io.h>
  31. #include <asm/irq.h>
  32. #include <asm/proc-fns.h>
  33. #include <asm/arch/idle.h>
  34. #include <asm/arch/regs-s3c6400-clock.h>
  35. #include <asm/arch/regs-serial.h>
  36. #include <asm/arch/regs-gpio.h>
  37. #include <asm/arch/map.h>
  38. #include <asm/arch/nand.h>
  39. //#include <asm/plat-s3c24xx/clock.h>
  40. #include <asm/plat-s3c24xx/s3c6400.h>
  41. #include <asm/plat-s3c24xx/devs.h>
  42. #include <asm/plat-s3c24xx/cpu.h>
  43. #include "pm-s3c6400.h"
  44. /* Serial port registrations */
  45. static struct map_desc s3c6400_iodesc[] __initdata = {
  46. IODESC_ENT(TIMER),
  47. IODESC_ENT(LCD),
  48. IODESC_ENT(HOSTIFB),
  49. IODESC_ENT(IIS),
  50. IODESC_ENT(AC97),
  51. IODESC_ENT(OTG),
  52. IODESC_ENT(OTGSFR),
  53. IODESC_ENT(CAMIF),
  54. };
  55. /* s3c6400_idle
  56. *
  57. * use the standard idle call by ensuring the idle mode
  58. * in power config, then issuing the idle co-processor
  59. * instruction
  60. */
  61. static void s3c6400_idle(void)
  62. {
  63. unsigned long tmp;
  64. /* ensure our idle mode is to go to idle */
  65. /* Set WFI instruction to SLEEP mode */
  66. tmp = __raw_readl(S3C_PWR_CFG);
  67. tmp &= ~(0x3<<5);
  68. tmp |= (0x1<<5);
  69. __raw_writel(tmp, S3C_PWR_CFG);
  70. cpu_do_idle();
  71. }
  72. void __init s3c6400_init_uarts(struct s3c2410_uartcfg *cfg, int no)
  73. {
  74. s3c24xx_init_uartdevs("s3c-uart", s3c2410_uart_resources, cfg, no);
  75. #if defined (CONFIG_S3C_SIR)
  76. s3c24xx_uart_src[3]->name = "s3c-irda";
  77. #endif
  78. /* rename devices that are s3c2413/s3c2443/s3c6400 specific */
  79. s3c_device_lcd.name = "s3c-lcd";
  80. s3c_device_nand.name = "s3c-nand";
  81. s3c_device_tvenc.name = "s3c-tvenc";
  82. s3c_device_tvscaler.name = "s3c-tvscaler";
  83. }
  84. struct sysdev_class s3c6400_sysclass = {
  85. set_kset_name("s3c6400-core"),
  86. };
  87. static struct sys_device s3c6400_sysdev = {
  88. .cls = &s3c6400_sysclass,
  89. };
  90. static int __init s3c6400_core_init(void)
  91. {
  92. return sysdev_class_register(&s3c6400_sysclass);
  93. }
  94. core_initcall(s3c6400_core_init);
  95. void __init s3c6400_map_io(struct map_desc *mach_desc, int size)
  96. {
  97. /* register our io-tables */
  98. iotable_init(s3c6400_iodesc, ARRAY_SIZE(s3c6400_iodesc));
  99. iotable_init(mach_desc, size);
  100. /* rename any peripherals used differing from the s3c2412 */
  101. /* set our idle function */
  102. s3c24xx_idle = s3c6400_idle;
  103. }
  104. int __init s3c6400_init(void)
  105. {
  106. int ret;
  107. printk("s3c6400: Initialising architecture\n");
  108. ret = sysdev_register(&s3c6400_sysdev);
  109. if (ret != 0)
  110. printk(KERN_ERR "failed to register sysdev for s3c6400\n");
  111. return ret;
  112. }
  113. #define CAMDIV_val 20
  114. int s3c_camif_set_clock (unsigned int camclk)
  115. {
  116. unsigned int camclk_div, val, hclkcon;
  117. struct clk *src_clk = clk_get(NULL, "hclkx2");
  118. printk(KERN_INFO "External camera clock is set to %dHz\n", camclk);
  119. camclk_div = clk_get_rate(src_clk) / camclk;
  120. printk("Parent clk = %ld, CAMDIV = %d\n", clk_get_rate(src_clk), camclk_div);
  121. // CAMIF HCLK Enable
  122. hclkcon = __raw_readl(S3C_HCLK_GATE);
  123. hclkcon |= S3C_CLKCON_HCLK_CAMIF;
  124. __raw_writel(hclkcon, S3C_HCLK_GATE);
  125. /* CAMCLK Enable */
  126. val = readl(S3C_SCLK_GATE);
  127. val |= S3C_CLKCON_SCLK_CAM;
  128. writel(val, S3C_SCLK_GATE);
  129. val = readl(S3C_CLK_DIV0);
  130. val &= ~(0xf<<CAMDIV_val);
  131. writel(val, S3C_CLK_DIV0);
  132. /* CAM CLK DIVider Ratio = (EPLL clk)/(camclk_div) */
  133. val |= ((camclk_div - 1) << CAMDIV_val);
  134. writel(val, S3C_CLK_DIV0);
  135. val = readl(S3C_CLK_DIV0);
  136. return 0;
  137. }
  138. void s3c_camif_disable_clock (void)
  139. {
  140. unsigned int val;
  141. val = readl(S3C_SCLK_GATE);
  142. val &= ~S3C_CLKCON_SCLK_CAM;
  143. writel(val, S3C_SCLK_GATE);
  144. }
  145. static int mem_proc_read (
  146. char *buffer,
  147. char **buffer_location,
  148. off_t offset,
  149. int buffer_length,
  150. int *zero,
  151. void *ptr
  152. )
  153. {
  154. return 0;
  155. }
  156. static int mem_proc_write (
  157. struct file *file,
  158. const char *buffer,
  159. unsigned long count,
  160. void *data
  161. )
  162. {
  163. ulong address = 0, size = 0x100;
  164. ulong i = 0, j = 0;
  165. volatile uint *addr;
  166. char flag = 'b';
  167. uint temp=0;
  168. printk("buffers: %s\n", buffer);
  169. sscanf(buffer, "%lx %lx %c", &address, &size, &flag);
  170. switch (flag) {
  171. case 'b':
  172. for (i = address; i < address + size; i += 4 * 4) {
  173. printk("0x%08lx: %08x %08x %08x %08x\n",
  174. i,
  175. *(uint *) i,
  176. *(uint *) (i + 0x04),
  177. *(uint *) (i + 0x08),
  178. *(uint *) (i + 0x0c));
  179. }
  180. break;
  181. case 'l':
  182. for (i = address; i < address + size; i += 4 * 4) {
  183. printk("0x%08lx: %08x %08x %08x %08x\n",
  184. i,
  185. swab32(*(uint *) i),
  186. swab32(*(uint *) (i + 0x04)),
  187. swab32(*(uint *) (i + 0x08)),
  188. swab32(*(uint *) (i + 0x0c)));
  189. }
  190. break;
  191. case 'w':
  192. for (j = 0; j < 0x20000; j++) {
  193. temp = 0;
  194. for (i = address; i < address + size; i += 4) {
  195. addr = (volatile uint *)i;
  196. temp += *addr;
  197. // *(volatile uint *)i = temp+1;
  198. }
  199. if (!(j%0x1000)) {
  200. printk("%08x\n", temp);
  201. }
  202. }
  203. break;
  204. }
  205. return count;
  206. }
  207. static struct proc_dir_entry *evb_resource_dump;
  208. int __init mem_rw_proc (void)
  209. {
  210. evb_resource_dump = create_proc_entry("memory", 0666, &proc_root);
  211. evb_resource_dump->read_proc = mem_proc_read;
  212. evb_resource_dump->write_proc = mem_proc_write;
  213. evb_resource_dump->nlink = 1;
  214. return 0;
  215. }
  216. module_init(mem_rw_proc);