aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVladimir Zapolskiy <vz@mleia.com>2016-11-08 19:56:37 -0500
committerTejun Heo <tj@kernel.org>2016-11-09 11:48:57 -0500
commitfab43e14347e510b5872515a47200914182c15f9 (patch)
tree412ddfe5b3b51377185ec110c6d806e15cc822cd
parent65a443ea54832cdf221c03c285930f0089c03f9a (diff)
pata: imx: add support of setting timings for PIO modes
The controller is capable to operate in up to PIO4 mode, however before the change the driver relies on timing settings done by a bootloader for PIO0 mode only. The change adds more flexibility in PIO mode selection at runtime and makes the driver to work even if bootloader does not preset ATA timings. Signed-off-by: Vladimir Zapolskiy <vz@mleia.com> Signed-off-by: Tejun Heo <tj@kernel.org>
-rw-r--r--drivers/ata/pata_imx.c47
1 files changed, 46 insertions, 1 deletions
diff --git a/drivers/ata/pata_imx.c b/drivers/ata/pata_imx.c
index 00df18b07fa6..8f13c9f27c8c 100644
--- a/drivers/ata/pata_imx.c
+++ b/drivers/ata/pata_imx.c
@@ -11,7 +11,6 @@
11 * 11 *
12 * TODO: 12 * TODO:
13 * - dmaengine support 13 * - dmaengine support
14 * - check if timing stuff needed
15 */ 14 */
16 15
17#include <linux/ata.h> 16#include <linux/ata.h>
@@ -22,6 +21,16 @@
22 21
23#define DRV_NAME "pata_imx" 22#define DRV_NAME "pata_imx"
24 23
24#define PATA_IMX_ATA_TIME_OFF 0x00
25#define PATA_IMX_ATA_TIME_ON 0x01
26#define PATA_IMX_ATA_TIME_1 0x02
27#define PATA_IMX_ATA_TIME_2W 0x03
28#define PATA_IMX_ATA_TIME_2R 0x04
29#define PATA_IMX_ATA_TIME_AX 0x05
30#define PATA_IMX_ATA_TIME_PIO_RDX 0x06
31#define PATA_IMX_ATA_TIME_4 0x07
32#define PATA_IMX_ATA_TIME_9 0x08
33
25#define PATA_IMX_ATA_CONTROL 0x24 34#define PATA_IMX_ATA_CONTROL 0x24
26#define PATA_IMX_ATA_CTRL_FIFO_RST_B (1<<7) 35#define PATA_IMX_ATA_CTRL_FIFO_RST_B (1<<7)
27#define PATA_IMX_ATA_CTRL_ATA_RST_B (1<<6) 36#define PATA_IMX_ATA_CTRL_ATA_RST_B (1<<6)
@@ -31,6 +40,10 @@
31#define PATA_IMX_DRIVE_DATA 0xA0 40#define PATA_IMX_DRIVE_DATA 0xA0
32#define PATA_IMX_DRIVE_CONTROL 0xD8 41#define PATA_IMX_DRIVE_CONTROL 0xD8
33 42
43static u32 pio_t4[] = { 30, 20, 15, 10, 10 };
44static u32 pio_t9[] = { 20, 15, 10, 10, 10 };
45static u32 pio_tA[] = { 35, 35, 35, 35, 35 };
46
34struct pata_imx_priv { 47struct pata_imx_priv {
35 struct clk *clk; 48 struct clk *clk;
36 /* timings/interrupt/control regs */ 49 /* timings/interrupt/control regs */
@@ -38,11 +51,43 @@ struct pata_imx_priv {
38 u32 ata_ctl; 51 u32 ata_ctl;
39}; 52};
40 53
54static void pata_imx_set_timing(struct ata_device *adev,
55 struct pata_imx_priv *priv)
56{
57 struct ata_timing timing;
58 unsigned long clkrate;
59 u32 T, mode;
60
61 clkrate = clk_get_rate(priv->clk);
62
63 if (adev->pio_mode < XFER_PIO_0 || adev->pio_mode > XFER_PIO_4 ||
64 !clkrate)
65 return;
66
67 T = 1000000000 / clkrate;
68 ata_timing_compute(adev, adev->pio_mode, &timing, T * 1000, 0);
69
70 mode = adev->pio_mode - XFER_PIO_0;
71
72 writeb(3, priv->host_regs + PATA_IMX_ATA_TIME_OFF);
73 writeb(3, priv->host_regs + PATA_IMX_ATA_TIME_ON);
74 writeb(timing.setup, priv->host_regs + PATA_IMX_ATA_TIME_1);
75 writeb(timing.act8b, priv->host_regs + PATA_IMX_ATA_TIME_2W);
76 writeb(timing.act8b, priv->host_regs + PATA_IMX_ATA_TIME_2R);
77 writeb(1, priv->host_regs + PATA_IMX_ATA_TIME_PIO_RDX);
78
79 writeb(pio_t4[mode] / T + 1, priv->host_regs + PATA_IMX_ATA_TIME_4);
80 writeb(pio_t9[mode] / T + 1, priv->host_regs + PATA_IMX_ATA_TIME_9);
81 writeb(pio_tA[mode] / T + 1, priv->host_regs + PATA_IMX_ATA_TIME_AX);
82}
83
41static void pata_imx_set_piomode(struct ata_port *ap, struct ata_device *adev) 84static void pata_imx_set_piomode(struct ata_port *ap, struct ata_device *adev)
42{ 85{
43 struct pata_imx_priv *priv = ap->host->private_data; 86 struct pata_imx_priv *priv = ap->host->private_data;
44 u32 val; 87 u32 val;
45 88
89 pata_imx_set_timing(adev, priv);
90
46 val = __raw_readl(priv->host_regs + PATA_IMX_ATA_CONTROL); 91 val = __raw_readl(priv->host_regs + PATA_IMX_ATA_CONTROL);
47 if (ata_pio_need_iordy(adev)) 92 if (ata_pio_need_iordy(adev))
48 val |= PATA_IMX_ATA_CTRL_IORDY_EN; 93 val |= PATA_IMX_ATA_CTRL_IORDY_EN;