2 * Support for Gemini PATA
4 * Copyright (C) 2009 Janos Laube <janos.dev@gmail.com>
5 * Copyright (C) 2010 Frederic Pecourt <opengemini@free.fr>
6 * Copyright (C) 2011 Tobias Waldvogel <tobias.waldvogel@gmail.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 * 26:24 bits is "IDE IO Select"
26 * 011 - ata0 <-> sata0, sata1; bring out ata1
27 * 010 - ata1 <-> sata1, sata0; bring out ata0
28 * 001 - ata0 <-> sata0, ata1 <-> sata1; bring out ata1
29 * 000 - ata0 <-> sata0, ata1 <-> sata1; bring out ata0
33 #include <linux/platform_device.h>
34 #include <linux/module.h>
35 #include <linux/moduleparam.h>
36 #include <linux/libata.h>
37 #include <linux/leds.h>
39 #include <mach/hardware.h>
40 #include <mach/global_reg.h>
42 #define DRV_NAME "pata-gemini"
44 #define PATA_GEMINI_PORTS 1
46 #define PIO_TIMING_REG 0x10
47 #define MDMA_TIMING_REG 0x11
48 #define UDMA_TIMING0_REG 0x12
49 #define UDMA_TIMING1_REG 0x13
50 #define CLK_MOD_REG 0x14
52 #define CLK_MOD_66M_DEV0_BIT 0
53 #define CLK_MOD_66M_DEV1_BIT 1
54 #define CLK_MOD_UDMA_DEV0_BIT 4
55 #define CLK_MOD_UDMA_DEV1_BIT 5
57 #define CLK_MOD_66M_DEV0 (1 << CLK_MOD_66M_DEV0_BIT)
58 #define CLK_MOD_66M_DEV1 (1 << CLK_MOD_66M_DEV1_BIT)
59 #define CLK_MOD_UDMA_DEV0 (1 << CLK_MOD_UDMA_DEV0_BIT)
60 #define CLK_MOD_UDMA_DEV1 (1 << CLK_MOD_UDMA_DEV1_BIT)
62 #define SATA_ENABLE_PDEV_MASK 0x01
63 #define SATA_ENABLE_PDEV_PM 0x02
64 #define SATA_ENABLE_PDEV_ADDED 0x04
65 #define SATA_ENABLE_PDEV_REMOVED 0x08
66 #define SATA_ENABLE_SDEV_MASK 0x10
67 #define SATA_ENABLE_SDEV_PM 0x20
68 #define SATA_ENABLE_SDEV_ADDED 0x40
69 #define SATA_ENABLE_SDEV_REMOVED 0x80
71 MODULE_AUTHOR("Janos Laube <janos.dev@gmail.com>");
72 MODULE_LICENSE("GPL");
73 MODULE_ALIAS("platform:" DRV_NAME
);
75 static unsigned char PIO_TIMING
[5] = {
76 0xaa, 0xa3, 0xa1, 0x33, 0x31
79 static unsigned char TIMING_MW_DMA
[4][2] = {
80 { 0x44, 1 }, // 480 4.2
81 { 0x42, 1 }, // 150 13.3
82 { 0x31, 1 }, // 120 16.7
83 { 0x21, 1 }, // 100 20
86 static unsigned char TIMING_UDMA
[7][2] = {
87 { 0x33, 0 }, //240 16.7
89 { 0x21, 0 }, //120 33.3
90 { 0x21, 1 }, //90 44.4
91 { 0x11, 1 }, //60 66.7
92 { 0x11 | 0x80, 0 }, //40 100
93 { 0x11 | 0x80, 1 }, //30 133
96 static struct scsi_host_template pata_gemini_sht
= {
97 ATA_NCQ_SHT(DRV_NAME
),
100 .dma_boundary
= 0xffffU
,
103 static void gemini_set_dmamode(struct ata_port
*ap
, struct ata_device
*adev
)
105 void __iomem
*clk_reg
= ap
->ioaddr
.bmdma_addr
+ CLK_MOD_REG
;
106 void __iomem
*tim_reg
= ap
->ioaddr
.bmdma_addr
+ UDMA_TIMING0_REG
;
107 unsigned short udma
= adev
->dma_mode
;
108 unsigned short speed
= udma
;
109 unsigned short devno
= adev
->devno
& 1;
111 u8 mod_udma_mask
= 1 << (CLK_MOD_UDMA_DEV0_BIT
+ devno
);
112 u8 mod_66m_mask
= 1 << (CLK_MOD_66M_DEV0_BIT
+ devno
);
116 clk_mod
= ioread8(clk_reg
);
117 clk_mod
&= ~mod_udma_mask
;
119 if (speed
& XFER_UDMA_0
) {
120 i
= speed
& ~XFER_UDMA_0
;
121 timing
= TIMING_UDMA
[i
][0];
122 clk_mod
|= mod_udma_mask
;
123 if (TIMING_UDMA
[i
][1])
124 clk_mod
|= mod_66m_mask
;
126 i
= speed
& ~XFER_MW_DMA_0
;
127 timing
= TIMING_MW_DMA
[i
][0];
128 clk_mod
|= mod_udma_mask
;
129 if (TIMING_MW_DMA
[i
][1])
130 clk_mod
|= mod_66m_mask
;
133 iowrite8(clk_mod
, clk_reg
);
134 iowrite8(timing
, tim_reg
+ devno
);
138 static void gemini_set_piomode(struct ata_port
*ap
, struct ata_device
*adev
)
140 void __iomem
*pio_reg
= ap
->ioaddr
.bmdma_addr
+ PIO_TIMING_REG
;
141 unsigned int pio
= adev
->pio_mode
- XFER_PIO_0
;
143 iowrite8(PIO_TIMING
[pio
], pio_reg
);
146 unsigned int gemini_qc_issue(struct ata_queued_cmd
*qc
)
148 ledtrig_ide_activity();
149 return ata_bmdma_qc_issue(qc
);
152 static struct ata_port_operations pata_gemini_port_ops
= {
153 .inherits
= &ata_bmdma_port_ops
,
154 .set_dmamode
= gemini_set_dmamode
,
155 .set_piomode
= gemini_set_piomode
,
156 .qc_issue
= gemini_qc_issue
,
159 static struct ata_port_info pata_gemini_portinfo
= {
161 .udma_mask
= ATA_UDMA6
,
162 .pio_mask
= ATA_PIO4
,
163 .port_ops
= &pata_gemini_port_ops
,
166 static const struct ata_port_info
*pata_gemini_ports
= &pata_gemini_portinfo
;
168 static int pata_gemini_probe(struct platform_device
*pdev
)
170 struct ata_host
*host
;
171 struct resource
*res
;
173 void __iomem
*mmio_base
;
175 /* standard bdma init */
176 irq
= platform_get_irq(pdev
, 0);
180 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
184 pr_info(DRV_NAME
": irq %d, io base 0x%08x\n", irq
, res
->start
);
186 mmio_base
= devm_ioremap(&pdev
->dev
, res
->start
, resource_size(res
));
188 host
= ata_host_alloc_pinfo(&pdev
->dev
, &pata_gemini_ports
, 1);
192 for (i
= 0; i
< host
->n_ports
; i
++) {
193 struct ata_port
*ap
= host
->ports
[i
];
194 struct ata_ioports
*ioaddr
= &ap
->ioaddr
;
196 ioaddr
->bmdma_addr
= mmio_base
;
197 ioaddr
->cmd_addr
= mmio_base
+ 0x20;
198 ioaddr
->ctl_addr
= mmio_base
+ 0x36;
199 ioaddr
->altstatus_addr
= ioaddr
->ctl_addr
;
200 ata_sff_std_ports(ioaddr
);
201 host
->ports
[i
]->cbl
= ATA_CBL_SATA
;
204 return ata_host_activate(host
, irq
, ata_bmdma_interrupt
,
205 IRQF_SHARED
, &pata_gemini_sht
);
208 static int pata_gemini_remove(struct platform_device
*pdev
)
210 struct device
*dev
= &pdev
->dev
;
211 struct ata_host
*host
= dev_get_drvdata(dev
);
212 ata_host_detach(host
);
216 static struct platform_driver pata_gemini_driver
= {
217 .probe
= pata_gemini_probe
,
218 .remove
= pata_gemini_remove
,
219 .driver
.owner
= THIS_MODULE
,
220 .driver
.name
= DRV_NAME
,
223 static int __init
pata_gemini_module_init(void)
225 return platform_driver_probe(&pata_gemini_driver
, pata_gemini_probe
);
228 static void __exit
pata_gemini_module_exit(void)
230 platform_driver_unregister(&pata_gemini_driver
);
233 module_init(pata_gemini_module_init
);
234 module_exit(pata_gemini_module_exit
);