037-Add-ColdFire-MCF54455-PATA-interface-support.patch 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934
  1. From 8e46c06091fd87904205a977be3c784e3ac61e95 Mon Sep 17 00:00:00 2001
  2. From: Jingchang Lu <[email protected]>
  3. Date: Thu, 4 Aug 2011 09:59:48 +0800
  4. Subject: [PATCH 37/52] Add ColdFire MCF54455 PATA interface support
  5. ColdFire MCF54455 parallel ATA controller support
  6. both uDMA and PIO mode, this driver implements all.
  7. Signed-off-by: Jingchang Lu <[email protected]>
  8. ---
  9. arch/m68k/include/asm/pata_fsl.h | 17 +
  10. drivers/ata/Kconfig | 23 +-
  11. drivers/ata/Makefile | 1 +
  12. drivers/ata/pata_fsl.c | 844 ++++++++++++++++++++++++++++++++++++++
  13. 4 files changed, 884 insertions(+), 1 deletions(-)
  14. create mode 100644 arch/m68k/include/asm/pata_fsl.h
  15. create mode 100644 drivers/ata/pata_fsl.c
  16. --- /dev/null
  17. +++ b/arch/m68k/include/asm/pata_fsl.h
  18. @@ -0,0 +1,17 @@
  19. +/*
  20. + * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
  21. + *
  22. + * This file is subject to the terms and conditions of the GNU General Public
  23. + * License. See the file COPYING in the main directory of this archive
  24. + * for more details.
  25. + */
  26. +
  27. +#ifndef _ASM_M68K_PATA_FSL_H
  28. +#define _ASM_M68K_PATA_FSL_H
  29. +
  30. +/* ATA mapped IO address translate function */
  31. +extern unsigned int io_ata_virt2phys(void *x);
  32. +extern void *io_ata_phys2virt(unsigned int x);
  33. +
  34. +
  35. +#endif
  36. --- a/drivers/ata/Kconfig
  37. +++ b/drivers/ata/Kconfig
  38. @@ -14,7 +14,7 @@ menuconfig ATA
  39. tristate "Serial ATA and Parallel ATA drivers"
  40. depends on HAS_IOMEM
  41. depends on BLOCK
  42. - depends on !(M32R || M68K) || BROKEN
  43. + depends on !(M32R) || BROKEN
  44. select SCSI
  45. ---help---
  46. If you want to use a ATA hard disk, ATA tape drive, ATA CD-ROM or
  47. @@ -687,6 +687,27 @@ config PATA_WINBOND
  48. If unsure, say N.
  49. +config PATA_FSL
  50. + tristate "Freescale on-chip PATA support"
  51. + depends on (ARCH_MX3 || ARCH_MX27 || PPC_512x || M54455)
  52. + help
  53. + Some Freescale processors SOC have parallel ATA controller,
  54. + such as ColdFire MCF54455.
  55. +
  56. + Say Y here if you wish to use the on-chip ATA interface.
  57. +
  58. + If you are unsure, say N to this.
  59. +
  60. +config FSL_PATA_USE_DMA
  61. + bool "Freescale PATA eDMA support"
  62. + depends on PATA_FSL && COLDFIRE_EDMA
  63. + default y
  64. + help
  65. + This option enables the uDMA support over PATA interface
  66. + which can improve performance than PIO mode for read and write.
  67. +
  68. + If unsure, say Y.
  69. +
  70. endif # ATA_BMDMA
  71. comment "PIO-only SFF controllers"
  72. --- a/drivers/ata/Makefile
  73. +++ b/drivers/ata/Makefile
  74. @@ -72,6 +72,7 @@ obj-$(CONFIG_PATA_TOSHIBA) += pata_picco
  75. obj-$(CONFIG_PATA_TRIFLEX) += pata_triflex.o
  76. obj-$(CONFIG_PATA_VIA) += pata_via.o
  77. obj-$(CONFIG_PATA_WINBOND) += pata_sl82c105.o
  78. +obj-$(CONFIG_PATA_FSL) += pata_fsl.o
  79. # SFF PIO only
  80. obj-$(CONFIG_PATA_AT32) += pata_at32.o
  81. --- /dev/null
  82. +++ b/drivers/ata/pata_fsl.c
  83. @@ -0,0 +1,844 @@
  84. +/*
  85. + * Freescale integrated PATA driver
  86. + *
  87. + * Copyright (C) 2007-2011 Freescale Semiconductor, Inc. All Rights Reserved.
  88. + *
  89. + * Description:
  90. + * This driver is for Coldfire MCF54455 on-chip ATA module.
  91. + *
  92. + * This is free software; you can redistribute it and/or modify it
  93. + * under the GNU General Public License as published by the Free
  94. + * Software Foundation; either version 2 of the License, or (at
  95. + * your option) any later version.
  96. + *
  97. + */
  98. +
  99. +#include <linux/kernel.h>
  100. +#include <linux/module.h>
  101. +#include <linux/init.h>
  102. +#include <linux/blkdev.h>
  103. +#include <scsi/scsi_host.h>
  104. +#include <linux/ata.h>
  105. +#include <linux/libata.h>
  106. +#include <linux/platform_device.h>
  107. +#include <linux/fsl_devices.h>
  108. +#ifdef CONFIG_FSL_PATA_USE_DMA
  109. +#include <asm/mcf_edma.h>
  110. +#endif
  111. +#include <asm/pata_fsl.h>
  112. +
  113. +#define DRV_NAME "pata_fsl"
  114. +#define DRV_VERSION "1.0"
  115. +
  116. +#ifdef CONFIG_M54455
  117. +#define WRITE_ATA8(val, reg) \
  118. + __raw_writeb(val, (ata_regs + reg));
  119. +#define WRITE_ATA16(val, reg) \
  120. + __raw_writew(val, (ata_regs + reg));
  121. +#else
  122. +#define WRITE_ATA8(val, reg) \
  123. + __raw_writel(val, (ata_regs + reg));
  124. +#define WRITE_ATA16(val, reg) \
  125. + __raw_writel(val, (ata_regs + reg));
  126. +#endif
  127. +
  128. +#define MAX_FSL_SG 256 /* MCF_EDMA_TCD_PER_CHAN */
  129. +
  130. +struct pata_fsl_priv {
  131. +#ifdef CONFIG_FSL_PATA_USE_DMA
  132. + int ultra;
  133. +#endif
  134. + u8 *fsl_ata_regs;
  135. +#ifdef CONFIG_FSL_PATA_USE_DMA
  136. + int dma_rchan;
  137. + int dma_wchan;
  138. + int dma_done;
  139. + int dma_dir;
  140. +#if 0
  141. + int nsg;
  142. + struct fsl_edma_requestbuf reqbuf[MAX_FSL_SG];
  143. +#endif
  144. +#endif
  145. +};
  146. +
  147. +enum {
  148. + /* various constants */
  149. +
  150. +#ifdef CONFIG_FSL_PATA_USE_DMA
  151. + FSL_ATA_MAX_SG_LEN = 65534,
  152. +#endif
  153. +
  154. + /* offsets to registers */
  155. +
  156. + FSL_ATA_TIMING_REGS = 0x00,
  157. + FSL_ATA_FIFO_FILL = 0x20,
  158. + FSL_ATA_CONTROL = 0x24,
  159. + FSL_ATA_INT_PEND = 0x28,
  160. + FSL_ATA_INT_EN = 0x2C,
  161. + FSL_ATA_INT_CLEAR = 0x30,
  162. + FSL_ATA_FIFO_ALARM = 0x34,
  163. + FSL_ATA_DRIVE_DATA = 0xA0,
  164. + FSL_ATA_DRIVE_CONTROL = 0xD8,
  165. +
  166. + /* bits within FSL_ATA_CONTROL */
  167. +
  168. + FSL_ATA_CTRL_FIFO_RST_B = 0x80,
  169. + FSL_ATA_CTRL_ATA_RST_B = 0x40,
  170. + FSL_ATA_CTRL_FIFO_TX_EN = 0x20,
  171. + FSL_ATA_CTRL_FIFO_RCV_EN = 0x10,
  172. + FSL_ATA_CTRL_DMA_PENDING = 0x08,
  173. + FSL_ATA_CTRL_DMA_ULTRA = 0x04,
  174. + FSL_ATA_CTRL_DMA_WRITE = 0x02,
  175. + FSL_ATA_CTRL_IORDY_EN = 0x01,
  176. +
  177. + /* bits within the interrupt control registers */
  178. +
  179. + FSL_ATA_INTR_ATA_INTRQ1 = 0x80,
  180. + FSL_ATA_INTR_FIFO_UNDERFLOW = 0x40,
  181. + FSL_ATA_INTR_FIFO_OVERFLOW = 0x20,
  182. + FSL_ATA_INTR_CTRL_IDLE = 0x10,
  183. + FSL_ATA_INTR_ATA_INTRQ2 = 0x08,
  184. +};
  185. +
  186. +/*
  187. + * This structure contains the timing parameters for
  188. + * ATA bus timing in the 5 PIO modes. The timings
  189. + * are in nanoseconds, and are converted to clock
  190. + * cycles before being stored in the ATA controller
  191. + * timing registers.
  192. + */
  193. +static struct {
  194. + short t0, t1, t2_8, t2_16, t2i, t4, t9, tA;
  195. +} pio_specs[] = {
  196. + [0] = {
  197. + .t0 = 600, .t1 = 70, .t2_8 = 290, .t2_16 = 165, .t2i = 0,
  198. + .t4 = 30, .t9 = 20, .tA = 50
  199. + },
  200. + [1] = {
  201. + .t0 = 383, .t1 = 50, .t2_8 = 290, .t2_16 = 125, .t2i = 0,
  202. + .t4 = 20, .t9 = 15, .tA = 50
  203. + },
  204. + [2] = {
  205. + .t0 = 240, .t1 = 30, .t2_8 = 290, .t2_16 = 100, .t2i = 0,
  206. + .t4 = 15, .t9 = 10, .tA = 50
  207. + },
  208. + [3] = {
  209. + .t0 = 180, .t1 = 30, .t2_8 = 80, .t2_16 = 80, .t2i = 0,
  210. + .t4 = 10, .t9 = 10, .tA = 50
  211. + },
  212. + [4] = {
  213. + .t0 = 120, .t1 = 25, .t2_8 = 70, .t2_16 = 70, .t2i = 0,
  214. + .t4 = 10, .t9 = 10, .tA = 50
  215. + },
  216. +};
  217. +
  218. +#define NR_PIO_SPECS (sizeof pio_specs / sizeof pio_specs[0])
  219. +
  220. +/*
  221. + * This structure contains the timing parameters for
  222. + * ATA bus timing in the 3 MDMA modes. The timings
  223. + * are in nanoseconds, and are converted to clock
  224. + * cycles before being stored in the ATA controller
  225. + * timing registers.
  226. + */
  227. +static struct {
  228. + short t0M, tD, tH, tJ, tKW, tM, tN, tJNH;
  229. +} mdma_specs[] = {
  230. + [0] = {
  231. + .t0M = 480, .tD = 215, .tH = 20, .tJ = 20, .tKW = 215,
  232. + .tM = 50, .tN = 15, .tJNH = 20
  233. + },
  234. + [1] = {
  235. + .t0M = 150, .tD = 80, .tH = 15, .tJ = 5, .tKW = 50,
  236. + .tM = 30, .tN = 10, .tJNH = 15
  237. + },
  238. + [2] = {
  239. + .t0M = 120, .tD = 70, .tH = 10, .tJ = 5, .tKW = 25,
  240. + .tM = 25, .tN = 10, .tJNH = 10
  241. + },
  242. +};
  243. +
  244. +#define NR_MDMA_SPECS (sizeof mdma_specs / sizeof mdma_specs[0])
  245. +
  246. +/*
  247. + * This structure contains the timing parameters for
  248. + * ATA bus timing in the 6 UDMA modes. The timings
  249. + * are in nanoseconds, and are converted to clock
  250. + * cycles before being stored in the ATA controller
  251. + * timing registers.
  252. + */
  253. +static struct {
  254. + short t2CYC, tCYC, tDS, tDH, tDVS, tDVH, tCVS, tCVH, tFS_min, tLI_max,
  255. + tMLI, tAZ, tZAH, tENV_min, tSR, tRFS, tRP, tACK, tSS, tDZFS;
  256. +} udma_specs[] = {
  257. + [0] = {
  258. + .t2CYC = 235, .tCYC = 114, .tDS = 15, .tDH = 5, .tDVS = 70,
  259. + .tDVH = 6, .tCVS = 70, .tCVH = 6, .tFS_min = 0,
  260. + .tLI_max = 100, .tMLI = 20, .tAZ = 10, .tZAH = 20,
  261. + .tENV_min = 20, .tSR = 50, .tRFS = 75, .tRP = 160,
  262. + .tACK = 20, .tSS = 50, .tDZFS = 80
  263. + },
  264. + [1] = {
  265. + .t2CYC = 156, .tCYC = 75, .tDS = 10, .tDH = 5, .tDVS = 48,
  266. + .tDVH = 6, .tCVS = 48, .tCVH = 6, .tFS_min = 0,
  267. + .tLI_max = 100, .tMLI = 20, .tAZ = 10, .tZAH = 20,
  268. + .tENV_min = 20, .tSR = 30, .tRFS = 70, .tRP = 125,
  269. + .tACK = 20, .tSS = 50, .tDZFS = 63
  270. + },
  271. + [2] = {
  272. + .t2CYC = 117, .tCYC = 55, .tDS = 7, .tDH = 5, .tDVS = 34,
  273. + .tDVH = 6, .tCVS = 34, .tCVH = 6, .tFS_min = 0,
  274. + .tLI_max = 100, .tMLI = 20, .tAZ = 10, .tZAH = 20,
  275. + .tENV_min = 20, .tSR = 20, .tRFS = 60, .tRP = 100,
  276. + .tACK = 20, .tSS = 50, .tDZFS = 47
  277. + },
  278. + [3] = {
  279. + .t2CYC = 86, .tCYC = 39, .tDS = 7, .tDH = 5, .tDVS = 20,
  280. + .tDVH = 6, .tCVS = 20, .tCVH = 6, .tFS_min = 0,
  281. + .tLI_max = 100, .tMLI = 20, .tAZ = 10, .tZAH = 20,
  282. + .tENV_min = 20, .tSR = 20, .tRFS = 60, .tRP = 100,
  283. + .tACK = 20, .tSS = 50, .tDZFS = 35
  284. + },
  285. + [4] = {
  286. + .t2CYC = 57, .tCYC = 25, .tDS = 5, .tDH = 5, .tDVS = 7,
  287. + .tDVH = 6, .tCVS = 7, .tCVH = 6, .tFS_min = 0,
  288. + .tLI_max = 100, .tMLI = 20, .tAZ = 10, .tZAH = 20,
  289. + .tENV_min = 20, .tSR = 50, .tRFS = 60, .tRP = 100,
  290. + .tACK = 20, .tSS = 50, .tDZFS = 25
  291. + },
  292. + [5] = {
  293. + .t2CYC = 38, .tCYC = 17, .tDS = 4, .tDH = 5, .tDVS = 5,
  294. + .tDVH = 6, .tCVS = 10, .tCVH = 10, .tFS_min = 0,
  295. + .tLI_max = 75, .tMLI = 20, .tAZ = 10, .tZAH = 20,
  296. + .tENV_min = 20, .tSR = 20, .tRFS = 50, .tRP = 85,
  297. + .tACK = 20, .tSS = 50, .tDZFS = 40
  298. + },
  299. +};
  300. +
  301. +#define NR_UDMA_SPECS (sizeof udma_specs / sizeof udma_specs[0])
  302. +
  303. +struct fsl_ata_time_regs {
  304. + u8 time_off, time_on, time_1, time_2w;
  305. + u8 time_2r, time_ax, time_pio_rdx, time_4;
  306. + u8 time_9, time_m, time_jn, time_d;
  307. + u8 time_k, time_ack, time_env, time_rpx;
  308. + u8 time_zah, time_mlix, time_dvh, time_dzfs;
  309. + u8 time_dvs, time_cvh, time_ss, time_cyc;
  310. +} __packed;
  311. +
  312. +
  313. +static void update_timing_config(struct fsl_ata_time_regs *tp,
  314. + struct ata_host *host)
  315. +{
  316. + u32 __iomem *lp = (u32 __iomem *)tp;
  317. + struct pata_fsl_priv *priv = host->private_data;
  318. + u32 __iomem *ctlp = (u32 __iomem *)priv->fsl_ata_regs;
  319. + int i;
  320. +
  321. + /*
  322. + * JKM - this could have endianess issues on BE depending
  323. + * on how the controller is glued to the bus -- probably
  324. + * should rewrite this to write byte at a time.
  325. + */
  326. + for (i = 0; i < 6; i++) {
  327. + __raw_writel(*lp, ctlp);
  328. + lp++;
  329. + ctlp++;
  330. + }
  331. +}
  332. +
  333. +/*!
  334. + * Calculate values for the ATA bus timing registers and store
  335. + * them into the hardware.
  336. + *
  337. + * @param xfer_mode specifies XFER xfer_mode
  338. + * @param pdev specifies platform_device
  339. + *
  340. + * @return EINVAL speed out of range, or illegal mode
  341. + */
  342. +static int set_ata_bus_timing(u8 xfer_mode, struct platform_device *pdev)
  343. +{
  344. + struct fsl_ata_platform_data *plat = (struct fsl_ata_platform_data *)
  345. + pdev->dev.platform_data;
  346. + struct ata_host *host = dev_get_drvdata(&pdev->dev);
  347. +
  348. + /* get the bus clock cycle time, in ns */
  349. + int T = 1 * 1000 * 1000 * 1000 / plat->get_clk_rate();
  350. + struct fsl_ata_time_regs tr = {0};
  351. + DPRINTK("clk_rate = %d T = %d\n", plat->get_clk_rate(), T);
  352. +
  353. + /*
  354. + * every mode gets the same t_off and t_on
  355. + */
  356. + tr.time_off = 3;
  357. + tr.time_on = 3;
  358. +
  359. + if (xfer_mode >= XFER_UDMA_0) {
  360. + int speed = xfer_mode - XFER_UDMA_0;
  361. + if (speed >= NR_UDMA_SPECS)
  362. + return -EINVAL;
  363. +
  364. + tr.time_ack = (udma_specs[speed].tACK + T) / T;
  365. + tr.time_env = (udma_specs[speed].tENV_min + T) / T;
  366. + tr.time_rpx = (udma_specs[speed].tRP + T) / T + 2;
  367. +
  368. + tr.time_zah = (udma_specs[speed].tZAH + T) / T;
  369. + tr.time_mlix = (udma_specs[speed].tMLI + T) / T;
  370. + tr.time_dvh = (udma_specs[speed].tDVH + T) / T + 1;
  371. + tr.time_dzfs = (udma_specs[speed].tDZFS + T) / T;
  372. +
  373. + tr.time_dvs = (udma_specs[speed].tDVS + T) / T;
  374. + tr.time_cvh = (udma_specs[speed].tCVH + T) / T;
  375. + tr.time_ss = (udma_specs[speed].tSS + T) / T;
  376. + tr.time_cyc = (udma_specs[speed].tCYC + T) / T;
  377. + } else if (xfer_mode >= XFER_MW_DMA_0) {
  378. + int speed = xfer_mode - XFER_MW_DMA_0;
  379. + if (speed >= NR_MDMA_SPECS)
  380. + return -EINVAL;
  381. +
  382. + tr.time_m = (mdma_specs[speed].tM + T) / T;
  383. + tr.time_jn = (mdma_specs[speed].tJNH + T) / T;
  384. + tr.time_d = (mdma_specs[speed].tD + T) / T;
  385. +
  386. + tr.time_k = (mdma_specs[speed].tKW + T) / T;
  387. + } else {
  388. + int speed = xfer_mode - XFER_PIO_0;
  389. + if (speed >= NR_PIO_SPECS)
  390. + return -EINVAL;
  391. +
  392. + tr.time_1 = (pio_specs[speed].t1 + T) / T;
  393. + tr.time_2w = (pio_specs[speed].t2_8 + T) / T;
  394. +
  395. + tr.time_2r = (pio_specs[speed].t2_8 + T) / T;
  396. + tr.time_ax = (pio_specs[speed].tA + T) / T + 2;
  397. + tr.time_pio_rdx = 1;
  398. + tr.time_4 = (pio_specs[speed].t4 + T) / T;
  399. +
  400. + tr.time_9 = (pio_specs[speed].t9 + T) / T;
  401. + }
  402. +
  403. + update_timing_config(&tr, host);
  404. +
  405. + return 0;
  406. +}
  407. +
  408. +static void pata_fsl_set_piomode(struct ata_port *ap, struct ata_device *adev)
  409. +{
  410. + set_ata_bus_timing(adev->pio_mode, to_platform_device(ap->dev));
  411. +}
  412. +
  413. +#ifdef CONFIG_FSL_PATA_USE_DMA
  414. +static void pata_fsl_set_dmamode(struct ata_port *ap, struct ata_device *adev)
  415. +{
  416. + struct pata_fsl_priv *priv = ap->host->private_data;
  417. +
  418. + priv->ultra = adev->dma_mode >= XFER_UDMA_0;
  419. +
  420. + set_ata_bus_timing(adev->dma_mode, to_platform_device(ap->dev));
  421. +}
  422. +#endif
  423. +
  424. +static int pata_fsl_port_start(struct ata_port *ap)
  425. +{
  426. + return 0;
  427. +}
  428. +
  429. +#ifdef CONFIG_FSL_PATA_USE_DMA
  430. +
  431. +static irqreturn_t dma_callback(int channel, void *arg)
  432. +{
  433. + struct ata_port *ap = arg;
  434. + struct pata_fsl_priv *priv = ap->host->private_data;
  435. + u8 __iomem *ata_regs = priv->fsl_ata_regs;
  436. +
  437. + mcf_edma_stop_transfer(channel);
  438. + priv->dma_done = 1;
  439. + /*
  440. + * DMA is finished, so unmask INTRQ from the drive to allow the
  441. + * normal ISR to fire.
  442. + */
  443. +#if 0
  444. + __raw_writel(FSL_ATA_INTR_ATA_INTRQ2, ata_regs + FSL_ATA_INT_EN);
  445. +#else
  446. + WRITE_ATA8(FSL_ATA_INTR_ATA_INTRQ2, FSL_ATA_INT_EN);
  447. + WRITE_ATA8(FSL_ATA_CTRL_ATA_RST_B, FSL_ATA_CONTROL);
  448. +#endif
  449. +
  450. + return IRQ_HANDLED;
  451. +}
  452. +
  453. +static void pata_fsl_bmdma_setup(struct ata_queued_cmd *qc)
  454. +{
  455. + int chan;
  456. + int dma_ultra;
  457. + u8 ata_control;
  458. + struct ata_port *ap = qc->ap;
  459. + struct pata_fsl_priv *priv = ap->host->private_data;
  460. + u8 __iomem *ata_regs = priv->fsl_ata_regs;
  461. +#if 0
  462. + struct scatterlist *sg;
  463. + struct fsl_edma_requestbuf *pbuf;
  464. + unsigned int si;
  465. +#endif
  466. + DPRINTK("ENTER\n");
  467. +
  468. + /* reset the ATA FIFO first */
  469. + /*
  470. + WRITE_ATA8(FSL_ATA_CTRL_ATA_RST_B,FSL_ATA_CONTROL);
  471. + */
  472. + priv->dma_dir = qc->dma_dir;
  473. +
  474. + /*
  475. + * Configure the on-chip ATA interface hardware.
  476. + */
  477. + dma_ultra = priv->ultra ?
  478. + FSL_ATA_CTRL_DMA_ULTRA : 0;
  479. +
  480. + ata_control = FSL_ATA_CTRL_FIFO_RST_B |
  481. + FSL_ATA_CTRL_ATA_RST_B |
  482. + FSL_ATA_CTRL_DMA_PENDING |
  483. + dma_ultra;
  484. +
  485. + if (qc->dma_dir == DMA_TO_DEVICE) {
  486. + chan = priv->dma_wchan;
  487. + ata_control |= FSL_ATA_CTRL_FIFO_TX_EN |
  488. + FSL_ATA_CTRL_DMA_WRITE;
  489. + } else {
  490. + chan = priv->dma_rchan;
  491. + ata_control |= FSL_ATA_CTRL_FIFO_RCV_EN;
  492. + }
  493. +#if 0
  494. + __raw_writel(ata_control, ata_regs + FSL_ATA_CONTROL);
  495. + __raw_writel(plat->fifo_alarm, ata_regs + FSL_ATA_FIFO_ALARM);
  496. + __raw_writel(FSL_ATA_INTR_ATA_INTRQ1, ata_regs + FSL_ATA_INT_EN);
  497. +#else
  498. + WRITE_ATA8(ata_control, FSL_ATA_CONTROL);
  499. + WRITE_ATA8(16/*plat->fifo_alarm*/, FSL_ATA_FIFO_ALARM);
  500. + WRITE_ATA8(FSL_ATA_INTR_ATA_INTRQ1, FSL_ATA_INT_EN);
  501. +#endif
  502. + /*mb();*/
  503. +
  504. + /*
  505. + * Set up the DMA completion callback.
  506. + */
  507. + /*
  508. + * Copy the sg list to an array.
  509. + */
  510. +#if 0
  511. + priv->nsg = 0;
  512. + pbuf = priv->reqbuf;
  513. +
  514. + for_each_sg(qc->sg, sg, qc->n_elem, si) {
  515. +
  516. + /*dma_map_sg(NULL, sg, 1, priv->dma_dir); */
  517. +
  518. + if (priv->dma_dir == DMA_TO_DEVICE) { /* WRITE */
  519. + pbuf->saddr = sg->dma_address;
  520. + pbuf->daddr = (dma_addr_t)(priv->fsl_ata_regs + 0x18);
  521. + pbuf->soff = 4;
  522. + pbuf->doff = 0;
  523. + } else { /* Read */
  524. + pbuf->daddr = sg->dma_address;
  525. + pbuf->saddr = (dma_addr_t)(priv->fsl_ata_regs + 0x18);
  526. + pbuf->doff = 4;
  527. + pbuf->soff = 0;
  528. + }
  529. + pbuf->attr = MCF_EDMA_TCD_ATTR_SSIZE_32BIT
  530. + |MCF_EDMA_TCD_ATTR_DSIZE_32BIT;
  531. + pbuf->minor_loop = 16*4; /* 16 longwords per request*/
  532. + pbuf->len = sg_dma_len(sg);
  533. +
  534. + pbuf++;
  535. + priv->nsg++;
  536. + }
  537. +
  538. + BUG_ON(*(unsigned char *)(ata_regs + FSL_ATA_FIFO_FILL));
  539. + mcf_edma_sg_config(chan, priv->reqbuf, priv->nsg);
  540. +#else
  541. + if (priv->dma_dir == DMA_TO_DEVICE) {
  542. + mcf_edma_sglist_config(chan, qc->sg, qc->n_elem, priv->dma_dir,
  543. + (dma_addr_t)
  544. + ((io_ata_virt2phys((void *)priv->fsl_ata_regs)) + 0x18),
  545. + MCF_EDMA_TCD_ATTR_SSIZE_32BIT
  546. + | MCF_EDMA_TCD_ATTR_DSIZE_32BIT,
  547. + 4, 0, 8*4);
  548. + } else {
  549. +
  550. + mcf_edma_sglist_config(chan, qc->sg, qc->n_elem, priv->dma_dir,
  551. + (dma_addr_t)
  552. + ((io_ata_virt2phys((void *)priv->fsl_ata_regs)) + 0x18),
  553. + MCF_EDMA_TCD_ATTR_SSIZE_32BIT
  554. + | MCF_EDMA_TCD_ATTR_DSIZE_32BIT,
  555. + 0, 4, 8*4);
  556. + }
  557. +
  558. +#endif
  559. + priv->dma_done = 0;
  560. +
  561. + DPRINTK("EXIT\n");
  562. +
  563. +}
  564. +
  565. +static void pata_fsl_bmdma_start(struct ata_queued_cmd *qc)
  566. +{
  567. + struct ata_port *ap = qc->ap;
  568. + struct pata_fsl_priv *priv = ap->host->private_data;
  569. + int chan;
  570. +
  571. + /*
  572. + * Start the channel.
  573. + */
  574. + chan = qc->dma_dir == DMA_TO_DEVICE ? priv->dma_wchan : priv->dma_rchan;
  575. +
  576. + mcf_edma_enable_transfer(chan);
  577. +
  578. + ap->ops->sff_exec_command(ap, &qc->tf);
  579. +}
  580. +
  581. +static void pata_fsl_bmdma_stop(struct ata_queued_cmd *qc)
  582. +{
  583. + struct ata_port *ap = qc->ap;
  584. +/*
  585. + int chan;
  586. +
  587. + chan = qc->dma_dir == DMA_TO_DEVICE ? priv->dma_wchan : priv->dma_rchan;
  588. + mcf_edma_stop_transfer(chan);
  589. +*/
  590. +/* do a dummy read as in ata_bmdma_stop */
  591. + ata_sff_dma_pause(ap);
  592. +}
  593. +
  594. +static u8 pata_fsl_bmdma_status(struct ata_port *ap)
  595. +{
  596. + struct pata_fsl_priv *priv = ap->host->private_data;
  597. +
  598. + return priv->dma_done ? ATA_DMA_INTR : 0;
  599. +}
  600. +
  601. +static void pata_fsl_dma_init(struct ata_port *ap)
  602. +{
  603. + struct pata_fsl_priv *priv = ap->host->private_data;
  604. +
  605. + priv->dma_rchan = -1;
  606. + priv->dma_wchan = -1;
  607. +
  608. + priv->dma_rchan = mcf_edma_request_channel(MCF_EDMA_CHAN_ATA_RX,
  609. + dma_callback,
  610. + NULL, 0x6,
  611. + (void *)ap,
  612. + NULL,
  613. + "MCF ATA RX");
  614. + if (priv->dma_rchan < 0) {
  615. + dev_printk(KERN_ERR, ap->dev, "couldn't get RX DMA channel\n");
  616. + goto err_out;
  617. + }
  618. +
  619. + priv->dma_wchan = mcf_edma_request_channel(MCF_EDMA_CHAN_ATA_TX,
  620. + dma_callback,
  621. + NULL, 0x6,
  622. + (void *)ap,
  623. + NULL,
  624. + "MCF ATA TX");
  625. + if (priv->dma_wchan < 0) {
  626. + dev_printk(KERN_ERR, ap->dev, "couldn't get TX DMA channel\n");
  627. + goto err_out;
  628. + }
  629. +
  630. + dev_printk(KERN_ERR, ap->dev, "rchan=%d wchan=%d\n", priv->dma_rchan,
  631. + priv->dma_wchan);
  632. + return;
  633. +
  634. +err_out:
  635. + ap->mwdma_mask = 0;
  636. + ap->udma_mask = 0;
  637. + mcf_edma_free_channel(priv->dma_rchan, ap);
  638. + mcf_edma_free_channel(priv->dma_wchan, ap);
  639. + kfree(priv);
  640. +}
  641. +#endif /* CONFIG_FSL_PATA_USE_DMA */
  642. +
  643. +static void ata_dummy_noret(struct ata_port *ap) { return; }
  644. +
  645. +static struct scsi_host_template pata_fsl_sht = {
  646. + ATA_BMDMA_SHT(DRV_NAME),
  647. +
  648. +#ifdef CONFIG_FSL_PATA_USE_DMA
  649. + .sg_tablesize = MAX_FSL_SG,
  650. + .dma_boundary = ATA_DMA_BOUNDARY,
  651. +#endif
  652. +};
  653. +
  654. +static struct ata_port_operations pata_fsl_port_ops = {
  655. +#ifdef CONFIG_FSL_PATA_USE_DMA
  656. + .inherits = &ata_bmdma_port_ops,
  657. +#else
  658. + .inherits = &ata_sff_port_ops,
  659. +#endif
  660. + .set_piomode = pata_fsl_set_piomode,
  661. +#ifdef CONFIG_FSL_PATA_USE_DMA
  662. + .set_dmamode = pata_fsl_set_dmamode,
  663. +#endif
  664. + .cable_detect = ata_cable_40wire,
  665. +
  666. +#ifdef CONFIG_FSL_PATA_USE_DMA
  667. + .bmdma_setup = pata_fsl_bmdma_setup,
  668. + .bmdma_start = pata_fsl_bmdma_start,
  669. +#endif
  670. +
  671. + .sff_data_xfer = ata_sff_data_xfer_noirq,
  672. + .qc_prep = ata_noop_qc_prep,
  673. +
  674. + .port_start = pata_fsl_port_start,
  675. +
  676. +#ifdef CONFIG_FSL_PATA_USE_DMA
  677. + .bmdma_stop = pata_fsl_bmdma_stop,
  678. + .bmdma_status = pata_fsl_bmdma_status,
  679. +#endif
  680. +};
  681. +
  682. +static void fsl_setup_port(struct ata_ioports *ioaddr)
  683. +{
  684. + unsigned int shift = 2;
  685. +
  686. + ioaddr->data_addr = ioaddr->cmd_addr + (ATA_REG_DATA << shift);
  687. + ioaddr->error_addr = ioaddr->cmd_addr + (ATA_REG_ERR << shift);
  688. + ioaddr->feature_addr = ioaddr->cmd_addr + (ATA_REG_FEATURE << shift);
  689. + ioaddr->nsect_addr = ioaddr->cmd_addr + (ATA_REG_NSECT << shift);
  690. + ioaddr->lbal_addr = ioaddr->cmd_addr + (ATA_REG_LBAL << shift);
  691. + ioaddr->lbam_addr = ioaddr->cmd_addr + (ATA_REG_LBAM << shift);
  692. + ioaddr->lbah_addr = ioaddr->cmd_addr + (ATA_REG_LBAH << shift);
  693. + ioaddr->device_addr = ioaddr->cmd_addr + (ATA_REG_DEVICE << shift);
  694. + ioaddr->status_addr = ioaddr->cmd_addr + (ATA_REG_STATUS << shift);
  695. + ioaddr->command_addr = ioaddr->cmd_addr + (ATA_REG_CMD << shift);
  696. +}
  697. +
  698. +/**
  699. + * pata_fsl_probe - attach a platform interface
  700. + * @pdev: platform device
  701. + *
  702. + * Register a platform bus integrated ATA host controller
  703. + *
  704. + * The 3 platform device resources are used as follows:
  705. + *
  706. + * - I/O Base (IORESOURCE_MEM) virt. addr. of ATA controller regs
  707. + * - CTL Base (IORESOURCE_MEM) unused
  708. + * - IRQ (IORESOURCE_IRQ) platform IRQ assigned to ATA
  709. + *
  710. + */
  711. +static int __devinit pata_fsl_probe(struct platform_device *pdev)
  712. +{
  713. + struct resource *io_res;
  714. + struct ata_host *host;
  715. + struct ata_port *ap;
  716. + struct fsl_ata_platform_data *plat = (struct fsl_ata_platform_data *)
  717. + pdev->dev.platform_data;
  718. + struct pata_fsl_priv *priv;
  719. + u8 *ata_regs;
  720. + int ret;
  721. +
  722. + DPRINTK("ENTER\n");
  723. + /*
  724. + * Get an ata_host structure for this device
  725. + */
  726. + host = ata_host_alloc(&pdev->dev, 1);
  727. + if (!host)
  728. + return -ENOMEM;
  729. + ap = host->ports[0];
  730. + /*
  731. + * Allocate private data
  732. + */
  733. + priv = kzalloc(sizeof(struct pata_fsl_priv), GFP_KERNEL);
  734. + if (priv == NULL) {
  735. + /* free(host); */
  736. + return -ENOMEM;
  737. + }
  738. + host->private_data = priv;
  739. +
  740. + /*
  741. + * Set up resources
  742. + */
  743. + if (unlikely(pdev->num_resources != 3)) {
  744. + dev_err(&pdev->dev, "invalid number of resources\n");
  745. + return -EINVAL;
  746. + }
  747. +
  748. + io_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  749. + ata_regs = (u8 *)io_res->start;
  750. + priv->fsl_ata_regs = ata_regs;
  751. + ap->ioaddr.cmd_addr = (void *)(ata_regs + FSL_ATA_DRIVE_DATA);
  752. + ap->ioaddr.ctl_addr = (void *)(ata_regs + FSL_ATA_DRIVE_CONTROL);
  753. + ap->ioaddr.altstatus_addr = ap->ioaddr.ctl_addr;
  754. + ap->ops = &pata_fsl_port_ops;
  755. + ap->pio_mask = 0x3F;
  756. +#ifdef CONFIG_FSL_PATA_USE_DMA
  757. + ap->mwdma_mask = 0x07;
  758. + ap->udma_mask = 0x1F;
  759. +/* ap->udma_mask = plat->udma_mask; */
  760. +/* pata_fsl_sht.sg_tablesize = plat->max_sg; */
  761. +#else
  762. + ap->mwdma_mask = 0x00;
  763. + ap->udma_mask = 0x00;
  764. +#endif
  765. + fsl_setup_port(&ap->ioaddr);
  766. +
  767. + /*
  768. + * Do platform-specific initialization (e.g. allocate pins,
  769. + * turn on clock). After this call it is assumed that
  770. + * plat->get_clk_rate() can be called to calculate
  771. + * timing.
  772. + */
  773. + if (plat->init && plat->init(pdev)) {
  774. + /* REVISIT: don't leak what ata_host_alloc() allocated */
  775. + return -ENODEV;
  776. + }
  777. +
  778. + /* Deassert the reset bit to enable the interface */
  779. + WRITE_ATA8(FSL_ATA_CTRL_ATA_RST_B, FSL_ATA_CONTROL);
  780. +
  781. + /* Set initial timing and mode */
  782. + set_ata_bus_timing(XFER_PIO_4, pdev);
  783. +
  784. +#ifdef CONFIG_FSL_PATA_USE_DMA
  785. + /* get DMA ready */
  786. + pata_fsl_dma_init(ap);
  787. +#endif
  788. +
  789. + /*
  790. + * Enable the ATA INTRQ interrupt from the bus, but
  791. + * only allow the CPU to see it (INTRQ2) at this point.
  792. + * INTRQ1, which goes to the DMA, will be enabled later.
  793. + */
  794. +#if 0
  795. + __raw_writel(FSL_ATA_INTR_ATA_INTRQ2, ata_regs + FSL_ATA_INT_EN);
  796. +#else
  797. + WRITE_ATA8(FSL_ATA_INTR_ATA_INTRQ2, FSL_ATA_INT_EN);
  798. +#endif
  799. +
  800. + /* activate */
  801. + ret = ata_host_activate(host, platform_get_irq(pdev, 0),
  802. + ata_sff_interrupt, 0, &pata_fsl_sht);
  803. + DPRINTK("EXIT ret=%d\n", ret);
  804. + return ret;
  805. +}
  806. +
  807. +/**
  808. + * pata_fsl_remove - unplug a platform interface
  809. + * @pdev: platform device
  810. + *
  811. + * A platform bus ATA device has been unplugged. Perform the needed
  812. + * cleanup. Also called on module unload for any active devices.
  813. + */
  814. +static int __devexit pata_fsl_remove(struct platform_device *pdev)
  815. +{
  816. + struct device *dev = &pdev->dev;
  817. + struct ata_host *host = dev_get_drvdata(dev);
  818. + struct pata_fsl_priv *priv = host->private_data;
  819. + struct fsl_ata_platform_data *plat = (struct fsl_ata_platform_data *)
  820. + pdev->dev.platform_data;
  821. + u8 *ata_regs = priv->fsl_ata_regs;
  822. +
  823. +#if 0
  824. + __raw_writel(0, ata_regs + FSL_ATA_INT_EN); /* Disable interrupts */
  825. +#else
  826. + WRITE_ATA8(0, FSL_ATA_INT_EN); /* Disable interrupts */
  827. +#endif
  828. +
  829. + ata_host_detach(host);
  830. +
  831. + if (plat->exit)
  832. + plat->exit();
  833. +
  834. + kfree(priv);
  835. +
  836. + return 0;
  837. +}
  838. +
  839. +#ifdef CONFIG_PM
  840. +static int pata_fsl_suspend(struct platform_device *pdev, pm_message_t state)
  841. +{
  842. + struct ata_host *host = dev_get_drvdata(&pdev->dev);
  843. + struct pata_fsl_priv *priv = host->private_data;
  844. + struct fsl_ata_platform_data *plat = (struct fsl_ata_platform_data *)
  845. + pdev->dev.platform_data;
  846. + u8 *ata_regs = priv->fsl_ata_regs;
  847. +
  848. + /* Disable interrupts. */
  849. +#if 0
  850. + __raw_writel(0, ata_regs + FSL_ATA_INT_EN);
  851. +#else
  852. + WRITE_ATA8(0, FSL_ATA_INT_EN);
  853. +#endif
  854. +
  855. + if (plat->exit)
  856. + plat->exit();
  857. +
  858. + return 0;
  859. +}
  860. +
  861. +static int pata_fsl_resume(struct platform_device *pdev)
  862. +{
  863. + struct ata_host *host = dev_get_drvdata(&pdev->dev);
  864. + struct pata_fsl_priv *priv = host->private_data;
  865. + struct fsl_ata_platform_data *plat = (struct fsl_ata_platform_data *)
  866. + pdev->dev.platform_data;
  867. + u8 *ata_regs = priv->fsl_ata_regs;
  868. +
  869. + if (plat->init && plat->init(pdev))
  870. + return -ENODEV;
  871. + /* Deassert the reset bit to enable the interface */
  872. +#if 0
  873. + __raw_writel(FSL_ATA_CTRL_ATA_RST_B, ata_regs + FSL_ATA_CONTROL);
  874. +#else
  875. + WRITE_ATA8(FSL_ATA_CTRL_ATA_RST_B, FSL_ATA_CONTROL);
  876. +#endif
  877. +
  878. + /* Set initial timing and mode */
  879. + set_ata_bus_timing(XFER_PIO_4, pdev);
  880. +
  881. + /*
  882. + * Enable hardware interrupts.
  883. + */
  884. +#if 0
  885. + __raw_writel(FSL_ATA_INTR_ATA_INTRQ2, ata_regs + FSL_ATA_INT_EN);
  886. +#else
  887. + WRITE_ATA8(FSL_ATA_INTR_ATA_INTRQ2, FSL_ATA_INT_EN);
  888. +#endif
  889. +
  890. + return 0;
  891. +}
  892. +#endif
  893. +
  894. +static struct platform_driver pata_fsl_driver = {
  895. + .probe = pata_fsl_probe,
  896. + .remove = __devexit_p(pata_fsl_remove),
  897. +#ifdef CONFIG_PM
  898. + .suspend = pata_fsl_suspend,
  899. + .resume = pata_fsl_resume,
  900. +#endif
  901. + .driver = {
  902. + .name = DRV_NAME,
  903. + .owner = THIS_MODULE,
  904. + },
  905. +};
  906. +
  907. +static int __init pata_fsl_init(void)
  908. +{
  909. + int ret;
  910. +
  911. + DPRINTK("ENTER\n");
  912. + ret = platform_driver_register(&pata_fsl_driver);
  913. + DPRINTK("EXIT ret=%d\n", ret);
  914. + return ret;
  915. +}
  916. +
  917. +static void __exit pata_fsl_exit(void)
  918. +{
  919. + platform_driver_unregister(&pata_fsl_driver);
  920. +}
  921. +module_init(pata_fsl_init);
  922. +module_exit(pata_fsl_exit);
  923. +
  924. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  925. +MODULE_DESCRIPTION("low-level driver for Freescale ATA");
  926. +MODULE_LICENSE("GPL");
  927. +MODULE_VERSION(DRV_VERSION);