aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafal Prylowski <prylowski@metasoft.pl>2012-04-12 08:13:16 -0400
committerJeff Garzik <jgarzik@redhat.com>2012-05-22 16:02:34 -0400
commit2fff27512600f9ad91335577e485a8552edb0abf (patch)
treeeba9659d44dfef5d36c15e41cae91cb45e6a66f1
parentd70e551c8e1ecb6f20422f8db6bfe6a0049edcb8 (diff)
PATA host controller driver for ep93xx
Add PATA host controller driver for ep93xx. Signed-off-by: Rafal Prylowski <prylowski@metasoft.pl> Cc: Joao Ramos <joao.ramos@inov.pt> Cc: H Hartley Sweeten <hsweeten@visionengravers.com> Cc: Ryan Mallon <rmallon@gmail.com> Cc: Sergei Shtylyov <sshtylyov@mvista.com> Cc: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
-rw-r--r--drivers/ata/Kconfig9
-rw-r--r--drivers/ata/Makefile1
-rw-r--r--drivers/ata/pata_ep93xx.c1044
3 files changed, 1054 insertions, 0 deletions
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 6bdedd7cca2c..2be8ef1d3093 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -416,6 +416,15 @@ config PATA_EFAR
416 416
417 If unsure, say N. 417 If unsure, say N.
418 418
419config PATA_EP93XX
420 tristate "Cirrus Logic EP93xx PATA support"
421 depends on ARCH_EP93XX
422 help
423 This option enables support for the PATA controller in
424 the Cirrus Logic EP9312 and EP9315 ARM CPU.
425
426 If unsure, say N.
427
419config PATA_HPT366 428config PATA_HPT366
420 tristate "HPT 366/368 PATA support" 429 tristate "HPT 366/368 PATA support"
421 depends on PCI 430 depends on PCI
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index 6ece5b7231a3..a454a139b1d2 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -43,6 +43,7 @@ obj-$(CONFIG_PATA_CS5535) += pata_cs5535.o
43obj-$(CONFIG_PATA_CS5536) += pata_cs5536.o 43obj-$(CONFIG_PATA_CS5536) += pata_cs5536.o
44obj-$(CONFIG_PATA_CYPRESS) += pata_cypress.o 44obj-$(CONFIG_PATA_CYPRESS) += pata_cypress.o
45obj-$(CONFIG_PATA_EFAR) += pata_efar.o 45obj-$(CONFIG_PATA_EFAR) += pata_efar.o
46obj-$(CONFIG_PATA_EP93XX) += pata_ep93xx.o
46obj-$(CONFIG_PATA_HPT366) += pata_hpt366.o 47obj-$(CONFIG_PATA_HPT366) += pata_hpt366.o
47obj-$(CONFIG_PATA_HPT37X) += pata_hpt37x.o 48obj-$(CONFIG_PATA_HPT37X) += pata_hpt37x.o
48obj-$(CONFIG_PATA_HPT3X2N) += pata_hpt3x2n.o 49obj-$(CONFIG_PATA_HPT3X2N) += pata_hpt3x2n.o
diff --git a/drivers/ata/pata_ep93xx.c b/drivers/ata/pata_ep93xx.c
new file mode 100644
index 000000000000..6ef2e3741f76
--- /dev/null
+++ b/drivers/ata/pata_ep93xx.c
@@ -0,0 +1,1044 @@
1/*
2 * EP93XX PATA controller driver.
3 *
4 * Copyright (c) 2012, Metasoft s.c.
5 * Rafal Prylowski <prylowski@metasoft.pl>
6 *
7 * Based on pata_scc.c, pata_icside.c and on earlier version of EP93XX
8 * PATA driver by Lennert Buytenhek and Alessandro Zummo.
9 * Read/Write timings, resource management and other improvements
10 * from driver by Joao Ramos and Bartlomiej Zolnierkiewicz.
11 * DMA engine support based on spi-ep93xx.c by Mika Westerberg.
12 *
13 * Original copyrights:
14 *
15 * Support for Cirrus Logic's EP93xx (EP9312, EP9315) CPUs
16 * PATA host controller driver.
17 *
18 * Copyright (c) 2009, Bartlomiej Zolnierkiewicz
19 *
20 * Heavily based on the ep93xx-ide.c driver:
21 *
22 * Copyright (c) 2009, Joao Ramos <joao.ramos@inov.pt>
23 * INESC Inovacao (INOV)
24 *
25 * EP93XX PATA controller driver.
26 * Copyright (C) 2007 Lennert Buytenhek <buytenh@wantstofly.org>
27 *
28 * An ATA driver for the Cirrus Logic EP93xx PATA controller.
29 *
30 * Based on an earlier version by Alessandro Zummo, which is:
31 * Copyright (C) 2006 Tower Technologies
32 */
33
34#include <linux/kernel.h>
35#include <linux/module.h>
36#include <linux/init.h>
37#include <linux/blkdev.h>
38#include <scsi/scsi_host.h>
39#include <linux/ata.h>
40#include <linux/libata.h>
41#include <linux/platform_device.h>
42#include <linux/delay.h>
43#include <linux/dmaengine.h>
44#include <linux/ktime.h>
45
46#include <mach/dma.h>
47#include <mach/platform.h>
48
49#define DRV_NAME "ep93xx-ide"
50#define DRV_VERSION "1.0"
51
52enum {
53 /* IDE Control Register */
54 IDECTRL = 0x00,
55 IDECTRL_CS0N = (1 << 0),
56 IDECTRL_CS1N = (1 << 1),
57 IDECTRL_DIORN = (1 << 5),
58 IDECTRL_DIOWN = (1 << 6),
59 IDECTRL_INTRQ = (1 << 9),
60 IDECTRL_IORDY = (1 << 10),
61 /*
62 * the device IDE register to be accessed is selected through
63 * IDECTRL register's specific bitfields 'DA', 'CS1N' and 'CS0N':
64 * b4 b3 b2 b1 b0
65 * A2 A1 A0 CS1N CS0N
66 * the values filled in this structure allows the value to be directly
67 * ORed to the IDECTRL register, hence giving directly the A[2:0] and
68 * CS1N/CS0N values for each IDE register.
69 * The values correspond to the transformation:
70 * ((real IDE address) << 2) | CS1N value << 1 | CS0N value
71 */
72 IDECTRL_ADDR_CMD = 0 + 2, /* CS1 */
73 IDECTRL_ADDR_DATA = (ATA_REG_DATA << 2) + 2,
74 IDECTRL_ADDR_ERROR = (ATA_REG_ERR << 2) + 2,
75 IDECTRL_ADDR_FEATURE = (ATA_REG_FEATURE << 2) + 2,
76 IDECTRL_ADDR_NSECT = (ATA_REG_NSECT << 2) + 2,
77 IDECTRL_ADDR_LBAL = (ATA_REG_LBAL << 2) + 2,
78 IDECTRL_ADDR_LBAM = (ATA_REG_LBAM << 2) + 2,
79 IDECTRL_ADDR_LBAH = (ATA_REG_LBAH << 2) + 2,
80 IDECTRL_ADDR_DEVICE = (ATA_REG_DEVICE << 2) + 2,
81 IDECTRL_ADDR_STATUS = (ATA_REG_STATUS << 2) + 2,
82 IDECTRL_ADDR_COMMAND = (ATA_REG_CMD << 2) + 2,
83 IDECTRL_ADDR_ALTSTATUS = (0x06 << 2) + 1, /* CS0 */
84 IDECTRL_ADDR_CTL = (0x06 << 2) + 1, /* CS0 */
85
86 /* IDE Configuration Register */
87 IDECFG = 0x04,
88 IDECFG_IDEEN = (1 << 0),
89 IDECFG_PIO = (1 << 1),
90 IDECFG_MDMA = (1 << 2),
91 IDECFG_UDMA = (1 << 3),
92 IDECFG_MODE_SHIFT = 4,
93 IDECFG_MODE_MASK = (0xf << 4),
94 IDECFG_WST_SHIFT = 8,
95 IDECFG_WST_MASK = (0x3 << 8),
96
97 /* MDMA Operation Register */
98 IDEMDMAOP = 0x08,
99
100 /* UDMA Operation Register */
101 IDEUDMAOP = 0x0c,
102 IDEUDMAOP_UEN = (1 << 0),
103 IDEUDMAOP_RWOP = (1 << 1),
104
105 /* PIO/MDMA/UDMA Data Registers */
106 IDEDATAOUT = 0x10,
107 IDEDATAIN = 0x14,
108 IDEMDMADATAOUT = 0x18,
109 IDEMDMADATAIN = 0x1c,
110 IDEUDMADATAOUT = 0x20,
111 IDEUDMADATAIN = 0x24,
112
113 /* UDMA Status Register */
114 IDEUDMASTS = 0x28,
115 IDEUDMASTS_DMAIDE = (1 << 16),
116 IDEUDMASTS_INTIDE = (1 << 17),
117 IDEUDMASTS_SBUSY = (1 << 18),
118 IDEUDMASTS_NDO = (1 << 24),
119 IDEUDMASTS_NDI = (1 << 25),
120 IDEUDMASTS_N4X = (1 << 26),
121
122 /* UDMA Debug Status Register */
123 IDEUDMADEBUG = 0x2c,
124};
125
126struct ep93xx_pata_data {
127 const struct platform_device *pdev;
128 void __iomem *ide_base;
129 struct ata_timing t;
130 bool iordy;
131
132 unsigned long udma_in_phys;
133 unsigned long udma_out_phys;
134
135 struct dma_chan *dma_rx_channel;
136 struct ep93xx_dma_data dma_rx_data;
137 struct dma_chan *dma_tx_channel;
138 struct ep93xx_dma_data dma_tx_data;
139};
140
141static void ep93xx_pata_clear_regs(void __iomem *base)
142{
143 writel(IDECTRL_CS0N | IDECTRL_CS1N | IDECTRL_DIORN |
144 IDECTRL_DIOWN, base + IDECTRL);
145
146 writel(0, base + IDECFG);
147 writel(0, base + IDEMDMAOP);
148 writel(0, base + IDEUDMAOP);
149 writel(0, base + IDEDATAOUT);
150 writel(0, base + IDEDATAIN);
151 writel(0, base + IDEMDMADATAOUT);
152 writel(0, base + IDEMDMADATAIN);
153 writel(0, base + IDEUDMADATAOUT);
154 writel(0, base + IDEUDMADATAIN);
155 writel(0, base + IDEUDMADEBUG);
156}
157
158static bool ep93xx_pata_check_iordy(void __iomem *base)
159{