palm_bk3710.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  1. /*
  2. * Palmchip bk3710 IDE controller
  3. *
  4. * Copyright (C) 2006 Texas Instruments.
  5. * Copyright (C) 2007 MontaVista Software, Inc., <source@mvista.com>
  6. *
  7. * ----------------------------------------------------------------------------
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; either version 2 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, write to the Free Software
  21. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  22. * ----------------------------------------------------------------------------
  23. *
  24. */
  25. #include <linux/types.h>
  26. #include <linux/module.h>
  27. #include <linux/kernel.h>
  28. #include <linux/ioport.h>
  29. #include <linux/hdreg.h>
  30. #include <linux/ide.h>
  31. #include <linux/delay.h>
  32. #include <linux/init.h>
  33. #include <linux/clk.h>
  34. #include <linux/platform_device.h>
  35. /* Offset of the primary interface registers */
  36. #define IDE_PALM_ATA_PRI_REG_OFFSET 0x1F0
  37. /* Primary Control Offset */
  38. #define IDE_PALM_ATA_PRI_CTL_OFFSET 0x3F6
  39. /*
  40. * PalmChip 3710 IDE Controller UDMA timing structure Definition
  41. */
  42. struct palm_bk3710_udmatiming {
  43. unsigned int rptime; /* Ready to pause time */
  44. unsigned int cycletime; /* Cycle Time */
  45. };
  46. #define BK3710_BMICP 0x00
  47. #define BK3710_BMISP 0x02
  48. #define BK3710_BMIDTP 0x04
  49. #define BK3710_BMICS 0x08
  50. #define BK3710_BMISS 0x0A
  51. #define BK3710_BMIDTS 0x0C
  52. #define BK3710_IDETIMP 0x40
  53. #define BK3710_IDETIMS 0x42
  54. #define BK3710_SIDETIM 0x44
  55. #define BK3710_SLEWCTL 0x45
  56. #define BK3710_IDESTATUS 0x47
  57. #define BK3710_UDMACTL 0x48
  58. #define BK3710_UDMATIM 0x4A
  59. #define BK3710_MISCCTL 0x50
  60. #define BK3710_REGSTB 0x54
  61. #define BK3710_REGRCVR 0x58
  62. #define BK3710_DATSTB 0x5C
  63. #define BK3710_DATRCVR 0x60
  64. #define BK3710_DMASTB 0x64
  65. #define BK3710_DMARCVR 0x68
  66. #define BK3710_UDMASTB 0x6C
  67. #define BK3710_UDMATRP 0x70
  68. #define BK3710_UDMAENV 0x74
  69. #define BK3710_IORDYTMP 0x78
  70. #define BK3710_IORDYTMS 0x7C
  71. static unsigned ideclk_period; /* in nanoseconds */
  72. static const struct palm_bk3710_udmatiming palm_bk3710_udmatimings[6] = {
  73. {160, 240}, /* UDMA Mode 0 */
  74. {125, 160}, /* UDMA Mode 1 */
  75. {100, 120}, /* UDMA Mode 2 */
  76. {100, 90}, /* UDMA Mode 3 */
  77. {100, 60}, /* UDMA Mode 4 */
  78. {85, 40}, /* UDMA Mode 5 */
  79. };
  80. static void palm_bk3710_setudmamode(void __iomem *base, unsigned int dev,
  81. unsigned int mode)
  82. {
  83. u8 tenv, trp, t0;
  84. u32 val32;
  85. u16 val16;
  86. /* DMA Data Setup */
  87. t0 = DIV_ROUND_UP(palm_bk3710_udmatimings[mode].cycletime,
  88. ideclk_period) - 1;
  89. tenv = DIV_ROUND_UP(20, ideclk_period) - 1;
  90. trp = DIV_ROUND_UP(palm_bk3710_udmatimings[mode].rptime,
  91. ideclk_period) - 1;
  92. /* udmatim Register */
  93. val16 = readw(base + BK3710_UDMATIM) & (dev ? 0xFF0F : 0xFFF0);
  94. val16 |= (mode << (dev ? 4 : 0));
  95. writew(val16, base + BK3710_UDMATIM);
  96. /* udmastb Ultra DMA Access Strobe Width */
  97. val32 = readl(base + BK3710_UDMASTB) & (0xFF << (dev ? 0 : 8));
  98. val32 |= (t0 << (dev ? 8 : 0));
  99. writel(val32, base + BK3710_UDMASTB);
  100. /* udmatrp Ultra DMA Ready to Pause Time */
  101. val32 = readl(base + BK3710_UDMATRP) & (0xFF << (dev ? 0 : 8));
  102. val32 |= (trp << (dev ? 8 : 0));
  103. writel(val32, base + BK3710_UDMATRP);
  104. /* udmaenv Ultra DMA envelop Time */
  105. val32 = readl(base + BK3710_UDMAENV) & (0xFF << (dev ? 0 : 8));
  106. val32 |= (tenv << (dev ? 8 : 0));
  107. writel(val32, base + BK3710_UDMAENV);
  108. /* Enable UDMA for Device */
  109. val16 = readw(base + BK3710_UDMACTL) | (1 << dev);
  110. writew(val16, base + BK3710_UDMACTL);
  111. }
  112. static void palm_bk3710_setdmamode(void __iomem *base, unsigned int dev,
  113. unsigned short min_cycle,
  114. unsigned int mode)
  115. {
  116. u8 td, tkw, t0;
  117. u32 val32;
  118. u16 val16;
  119. struct ide_timing *t;
  120. int cycletime;
  121. t = ide_timing_find_mode(mode);
  122. cycletime = max_t(int, t->cycle, min_cycle);
  123. /* DMA Data Setup */
  124. t0 = DIV_ROUND_UP(cycletime, ideclk_period);
  125. td = DIV_ROUND_UP(t->active, ideclk_period);
  126. tkw = t0 - td - 1;
  127. td -= 1;
  128. val32 = readl(base + BK3710_DMASTB) & (0xFF << (dev ? 0 : 8));
  129. val32 |= (td << (dev ? 8 : 0));
  130. writel(val32, base + BK3710_DMASTB);
  131. val32 = readl(base + BK3710_DMARCVR) & (0xFF << (dev ? 0 : 8));
  132. val32 |= (tkw << (dev ? 8 : 0));
  133. writel(val32, base + BK3710_DMARCVR);
  134. /* Disable UDMA for Device */
  135. val16 = readw(base + BK3710_UDMACTL) & ~(1 << dev);
  136. writew(val16, base + BK3710_UDMACTL);
  137. }
  138. static void palm_bk3710_setpiomode(void __iomem *base, ide_drive_t *mate,
  139. unsigned int dev, unsigned int cycletime,
  140. unsigned int mode)
  141. {
  142. u8 t2, t2i, t0;
  143. u32 val32;
  144. struct ide_timing *t;
  145. /* PIO Data Setup */
  146. t0 = DIV_ROUND_UP(cycletime, ideclk_period);
  147. t2 = DIV_ROUND_UP(ide_timing_find_mode(XFER_PIO_0 + mode)->active,
  148. ideclk_period);
  149. t2i = t0 - t2 - 1;
  150. t2 -= 1;
  151. val32 = readl(base + BK3710_DATSTB) & (0xFF << (dev ? 0 : 8));
  152. val32 |= (t2 << (dev ? 8 : 0));
  153. writel(val32, base + BK3710_DATSTB);
  154. val32 = readl(base + BK3710_DATRCVR) & (0xFF << (dev ? 0 : 8));
  155. val32 |= (t2i << (dev ? 8 : 0));
  156. writel(val32, base + BK3710_DATRCVR);
  157. if (mate && mate->present) {
  158. u8 mode2 = ide_get_best_pio_mode(mate, 255, 4);
  159. if (mode2 < mode)
  160. mode = mode2;
  161. }
  162. /* TASKFILE Setup */
  163. t = ide_timing_find_mode(XFER_PIO_0 + mode);
  164. t0 = DIV_ROUND_UP(t->cyc8b, ideclk_period);
  165. t2 = DIV_ROUND_UP(t->act8b, ideclk_period);
  166. t2i = t0 - t2 - 1;
  167. t2 -= 1;
  168. val32 = readl(base + BK3710_REGSTB) & (0xFF << (dev ? 0 : 8));
  169. val32 |= (t2 << (dev ? 8 : 0));
  170. writel(val32, base + BK3710_REGSTB);
  171. val32 = readl(base + BK3710_REGRCVR) & (0xFF << (dev ? 0 : 8));
  172. val32 |= (t2i << (dev ? 8 : 0));
  173. writel(val32, base + BK3710_REGRCVR);
  174. }
  175. static void palm_bk3710_set_dma_mode(ide_drive_t *drive, u8 xferspeed)
  176. {
  177. int is_slave = drive->dn & 1;
  178. void __iomem *base = (void *)drive->hwif->dma_base;
  179. if (xferspeed >= XFER_UDMA_0) {
  180. palm_bk3710_setudmamode(base, is_slave,
  181. xferspeed - XFER_UDMA_0);
  182. } else {
  183. palm_bk3710_setdmamode(base, is_slave, drive->id->eide_dma_min,
  184. xferspeed);
  185. }
  186. }
  187. static void palm_bk3710_set_pio_mode(ide_drive_t *drive, u8 pio)
  188. {
  189. unsigned int cycle_time;
  190. int is_slave = drive->dn & 1;
  191. ide_drive_t *mate;
  192. void __iomem *base = (void *)drive->hwif->dma_base;
  193. /*
  194. * Obtain the drive PIO data for tuning the Palm Chip registers
  195. */
  196. cycle_time = ide_pio_cycle_time(drive, pio);
  197. mate = ide_get_paired_drive(drive);
  198. palm_bk3710_setpiomode(base, mate, is_slave, cycle_time, pio);
  199. }
  200. static void __devinit palm_bk3710_chipinit(void __iomem *base)
  201. {
  202. /*
  203. * enable the reset_en of ATA controller so that when ata signals
  204. * are brought out, by writing into device config. at that
  205. * time por_n signal should not be 'Z' and have a stable value.
  206. */
  207. writel(0x0300, base + BK3710_MISCCTL);
  208. /* wait for some time and deassert the reset of ATA Device. */
  209. mdelay(100);
  210. /* Deassert the Reset */
  211. writel(0x0200, base + BK3710_MISCCTL);
  212. /*
  213. * Program the IDETIMP Register Value based on the following assumptions
  214. *
  215. * (ATA_IDETIMP_IDEEN , ENABLE ) |
  216. * (ATA_IDETIMP_SLVTIMEN , DISABLE) |
  217. * (ATA_IDETIMP_RDYSMPL , 70NS) |
  218. * (ATA_IDETIMP_RDYRCVRY , 50NS) |
  219. * (ATA_IDETIMP_DMAFTIM1 , PIOCOMP) |
  220. * (ATA_IDETIMP_PREPOST1 , DISABLE) |
  221. * (ATA_IDETIMP_RDYSEN1 , DISABLE) |
  222. * (ATA_IDETIMP_PIOFTIM1 , DISABLE) |
  223. * (ATA_IDETIMP_DMAFTIM0 , PIOCOMP) |
  224. * (ATA_IDETIMP_PREPOST0 , DISABLE) |
  225. * (ATA_IDETIMP_RDYSEN0 , DISABLE) |
  226. * (ATA_IDETIMP_PIOFTIM0 , DISABLE)
  227. */
  228. writew(0xB388, base + BK3710_IDETIMP);
  229. /*
  230. * Configure SIDETIM Register
  231. * (ATA_SIDETIM_RDYSMPS1 ,120NS ) |
  232. * (ATA_SIDETIM_RDYRCYS1 ,120NS )
  233. */
  234. writeb(0, base + BK3710_SIDETIM);
  235. /*
  236. * UDMACTL Ultra-ATA DMA Control
  237. * (ATA_UDMACTL_UDMAP1 , 0 ) |
  238. * (ATA_UDMACTL_UDMAP0 , 0 )
  239. *
  240. */
  241. writew(0, base + BK3710_UDMACTL);
  242. /*
  243. * MISCCTL Miscellaneous Conrol Register
  244. * (ATA_MISCCTL_RSTMODEP , 1) |
  245. * (ATA_MISCCTL_RESETP , 0) |
  246. * (ATA_MISCCTL_TIMORIDE , 1)
  247. */
  248. writel(0x201, base + BK3710_MISCCTL);
  249. /*
  250. * IORDYTMP IORDY Timer for Primary Register
  251. * (ATA_IORDYTMP_IORDYTMP , 0xffff )
  252. */
  253. writel(0xFFFF, base + BK3710_IORDYTMP);
  254. /*
  255. * Configure BMISP Register
  256. * (ATA_BMISP_DMAEN1 , DISABLE ) |
  257. * (ATA_BMISP_DMAEN0 , DISABLE ) |
  258. * (ATA_BMISP_IORDYINT , CLEAR) |
  259. * (ATA_BMISP_INTRSTAT , CLEAR) |
  260. * (ATA_BMISP_DMAERROR , CLEAR)
  261. */
  262. writew(0, base + BK3710_BMISP);
  263. palm_bk3710_setpiomode(base, NULL, 0, 600, 0);
  264. palm_bk3710_setpiomode(base, NULL, 1, 600, 0);
  265. }
  266. static u8 palm_bk3710_cable_detect(ide_hwif_t *hwif)
  267. {
  268. return ATA_CBL_PATA80;
  269. }
  270. static int __devinit palm_bk3710_init_dma(ide_hwif_t *hwif,
  271. const struct ide_port_info *d)
  272. {
  273. printk(KERN_INFO " %s: MMIO-DMA\n", hwif->name);
  274. if (ide_allocate_dma_engine(hwif))
  275. return -1;
  276. hwif->dma_base = hwif->io_ports.data_addr - IDE_PALM_ATA_PRI_REG_OFFSET;
  277. hwif->dma_ops = &sff_dma_ops;
  278. return 0;
  279. }
  280. static const struct ide_port_ops palm_bk3710_ports_ops = {
  281. .set_pio_mode = palm_bk3710_set_pio_mode,
  282. .set_dma_mode = palm_bk3710_set_dma_mode,
  283. .cable_detect = palm_bk3710_cable_detect,
  284. };
  285. static struct ide_port_info __devinitdata palm_bk3710_port_info = {
  286. .init_dma = palm_bk3710_init_dma,
  287. .port_ops = &palm_bk3710_ports_ops,
  288. .host_flags = IDE_HFLAG_MMIO,
  289. .pio_mask = ATA_PIO4,
  290. .mwdma_mask = ATA_MWDMA2,
  291. };
  292. static int __init palm_bk3710_probe(struct platform_device *pdev)
  293. {
  294. struct clk *clk;
  295. struct resource *mem, *irq;
  296. unsigned long base, rate;
  297. int i, rc;
  298. hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
  299. clk = clk_get(&pdev->dev, "IDECLK");
  300. if (IS_ERR(clk))
  301. return -ENODEV;
  302. clk_enable(clk);
  303. rate = clk_get_rate(clk);
  304. ideclk_period = 1000000000UL / rate;
  305. /* Register the IDE interface with Linux ATA Interface */
  306. memset(&hw, 0, sizeof(hw));
  307. mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  308. if (mem == NULL) {
  309. printk(KERN_ERR "failed to get memory region resource\n");
  310. return -ENODEV;
  311. }
  312. irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
  313. if (irq == NULL) {
  314. printk(KERN_ERR "failed to get IRQ resource\n");
  315. return -ENODEV;
  316. }
  317. if (request_mem_region(mem->start, mem->end - mem->start + 1,
  318. "palm_bk3710") == NULL) {
  319. printk(KERN_ERR "failed to request memory region\n");
  320. return -EBUSY;
  321. }
  322. base = IO_ADDRESS(mem->start);
  323. /* Configure the Palm Chip controller */
  324. palm_bk3710_chipinit((void __iomem *)base);
  325. for (i = 0; i < IDE_NR_PORTS - 2; i++)
  326. hw.io_ports_array[i] = base + IDE_PALM_ATA_PRI_REG_OFFSET + i;
  327. hw.io_ports.ctl_addr = base + IDE_PALM_ATA_PRI_CTL_OFFSET;
  328. hw.irq = irq->start;
  329. hw.dev = &pdev->dev;
  330. hw.chipset = ide_palm3710;
  331. palm_bk3710_port_info.udma_mask = rate < 100000000 ? ATA_UDMA4 :
  332. ATA_UDMA5;
  333. rc = ide_host_add(&palm_bk3710_port_info, hws, NULL);
  334. if (rc)
  335. goto out;
  336. return 0;
  337. out:
  338. printk(KERN_WARNING "Palm Chip BK3710 IDE Register Fail\n");
  339. return rc;
  340. }
  341. /* work with hotplug and coldplug */
  342. MODULE_ALIAS("platform:palm_bk3710");
  343. static struct platform_driver platform_bk_driver = {
  344. .driver = {
  345. .name = "palm_bk3710",
  346. .owner = THIS_MODULE,
  347. },
  348. };
  349. static int __init palm_bk3710_init(void)
  350. {
  351. return platform_driver_probe(&platform_bk_driver, palm_bk3710_probe);
  352. }
  353. module_init(palm_bk3710_init);
  354. MODULE_LICENSE("GPL");