1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2015 Xilinx, Inc.
4 * CEVA AHCI SATA platform driver
6 * based on the AHCI SATA platform driver by Jeff Garzik and Anton Vorontsov
9 #include <linux/ahci_platform.h>
10 #include <linux/kernel.h>
11 #include <linux/libata.h>
12 #include <linux/module.h>
14 #include <linux/platform_device.h>
15 #include <linux/reset.h>
18 /* Vendor Specific Register Offsets */
19 #define AHCI_VEND_PCFG 0xA4
20 #define AHCI_VEND_PPCFG 0xA8
21 #define AHCI_VEND_PP2C 0xAC
22 #define AHCI_VEND_PP3C 0xB0
23 #define AHCI_VEND_PP4C 0xB4
24 #define AHCI_VEND_PP5C 0xB8
25 #define AHCI_VEND_AXICC 0xBC
26 #define AHCI_VEND_PAXIC 0xC0
27 #define AHCI_VEND_PTC 0xC8
29 /* Vendor Specific Register bit definitions */
30 #define PAXIC_ADBW_BW64 0x1
31 #define PAXIC_MAWID(i) (((i) * 2) << 4)
32 #define PAXIC_MARID(i) (((i) * 2) << 12)
33 #define PAXIC_MARIDD(i) ((((i) * 2) + 1) << 16)
34 #define PAXIC_MAWIDD(i) ((((i) * 2) + 1) << 8)
35 #define PAXIC_OTL (0x4 << 20)
37 /* Register bit definitions for cache control */
38 #define AXICC_ARCA_VAL (0xF << 0)
39 #define AXICC_ARCF_VAL (0xF << 4)
40 #define AXICC_ARCH_VAL (0xF << 8)
41 #define AXICC_ARCP_VAL (0xF << 12)
42 #define AXICC_AWCFD_VAL (0xF << 16)
43 #define AXICC_AWCD_VAL (0xF << 20)
44 #define AXICC_AWCF_VAL (0xF << 24)
46 #define PCFG_TPSS_VAL (0x32 << 16)
47 #define PCFG_TPRS_VAL (0x2 << 12)
48 #define PCFG_PAD_VAL 0x2
50 #define PPCFG_TTA 0x1FFFE
51 #define PPCFG_PSSO_EN (1 << 28)
52 #define PPCFG_PSS_EN (1 << 29)
53 #define PPCFG_ESDF_EN (1 << 31)
55 #define PP5C_RIT 0x60216
56 #define PP5C_RCT (0x7f0 << 20)
58 #define PTC_RX_WM_VAL 0x40
59 #define PTC_RSVD (1 << 27)
61 #define PORT0_BASE 0x100
62 #define PORT1_BASE 0x180
64 /* Port Control Register Bit Definitions */
65 #define PORT_SCTL_SPD_GEN3 (0x3 << 4)
66 #define PORT_SCTL_SPD_GEN2 (0x2 << 4)
67 #define PORT_SCTL_SPD_GEN1 (0x1 << 4)
68 #define PORT_SCTL_IPM (0x3 << 8)
70 #define PORT_BASE 0x100
71 #define PORT_OFFSET 0x80
73 #define DRV_NAME "ahci-ceva"
74 #define CEVA_FLAG_BROKEN_GEN2 1
76 static unsigned int rx_watermark
= PTC_RX_WM_VAL
;
77 module_param(rx_watermark
, uint
, 0644);
78 MODULE_PARM_DESC(rx_watermark
, "RxWaterMark value (0 - 0x80)");
80 struct ceva_ahci_priv
{
81 struct platform_device
*ahci_pdev
;
82 /* Port Phy2Cfg Register */
87 /* Axi Cache Control Register */
93 static unsigned int ceva_ahci_read_id(struct ata_device
*dev
,
94 struct ata_taskfile
*tf
, __le16
*id
)
98 err_mask
= ata_do_dev_read_id(dev
, tf
, id
);
102 * Since CEVA controller does not support device sleep feature, we
103 * need to clear DEVSLP (bit 8) in word78 of the IDENTIFY DEVICE data.
105 id
[ATA_ID_FEATURE_SUPP
] &= cpu_to_le16(~(1 << 8));
110 static struct ata_port_operations ahci_ceva_ops
= {
111 .inherits
= &ahci_platform_ops
,
112 .read_id
= ceva_ahci_read_id
,
115 static const struct ata_port_info ahci_ceva_port_info
= {
116 .flags
= AHCI_FLAG_COMMON
,
117 .pio_mask
= ATA_PIO4
,
118 .udma_mask
= ATA_UDMA6
,
119 .port_ops
= &ahci_ceva_ops
,
122 static void ahci_ceva_setup(struct ahci_host_priv
*hpriv
)
124 void __iomem
*mmio
= hpriv
->mmio
;
125 struct ceva_ahci_priv
*cevapriv
= hpriv
->plat_data
;
129 /* Set AHCI Enable */
130 tmp
= readl(mmio
+ HOST_CTL
);
132 writel(tmp
, mmio
+ HOST_CTL
);
134 for (i
= 0; i
< NR_PORTS
; i
++) {
135 /* TPSS TPRS scalars, CISE and Port Addr */
136 tmp
= PCFG_TPSS_VAL
| PCFG_TPRS_VAL
| (PCFG_PAD_VAL
+ i
);
137 writel(tmp
, mmio
+ AHCI_VEND_PCFG
);
140 * AXI Data bus width to 64
141 * Set Mem Addr Read, Write ID for data transfers
142 * Set Mem Addr Read ID, Write ID for non-data transfers
143 * Transfer limit to 72 DWord
145 tmp
= PAXIC_ADBW_BW64
| PAXIC_MAWIDD(i
) | PAXIC_MARIDD(i
) |
146 PAXIC_MAWID(i
) | PAXIC_MARID(i
) | PAXIC_OTL
;
147 writel(tmp
, mmio
+ AHCI_VEND_PAXIC
);
149 /* Set AXI cache control register if CCi is enabled */
150 if (cevapriv
->is_cci_enabled
) {
151 tmp
= readl(mmio
+ AHCI_VEND_AXICC
);
152 tmp
|= AXICC_ARCA_VAL
| AXICC_ARCF_VAL
|
153 AXICC_ARCH_VAL
| AXICC_ARCP_VAL
|
154 AXICC_AWCFD_VAL
| AXICC_AWCD_VAL
|
156 writel(tmp
, mmio
+ AHCI_VEND_AXICC
);
159 /* Port Phy Cfg register enables */
160 tmp
= PPCFG_TTA
| PPCFG_PSS_EN
| PPCFG_ESDF_EN
;
161 writel(tmp
, mmio
+ AHCI_VEND_PPCFG
);
163 /* Phy Control OOB timing parameters COMINIT */
164 writel(cevapriv
->pp2c
[i
], mmio
+ AHCI_VEND_PP2C
);
166 /* Phy Control OOB timing parameters COMWAKE */
167 writel(cevapriv
->pp3c
[i
], mmio
+ AHCI_VEND_PP3C
);
169 /* Phy Control Burst timing setting */
170 writel(cevapriv
->pp4c
[i
], mmio
+ AHCI_VEND_PP4C
);
172 /* Rate Change Timer and Retry Interval Timer setting */
173 writel(cevapriv
->pp5c
[i
], mmio
+ AHCI_VEND_PP5C
);
175 /* Rx Watermark setting */
176 tmp
= rx_watermark
| PTC_RSVD
;
177 writel(tmp
, mmio
+ AHCI_VEND_PTC
);
179 /* Default to Gen 3 Speed and Gen 1 if Gen2 is broken */
180 tmp
= PORT_SCTL_SPD_GEN3
| PORT_SCTL_IPM
;
181 if (cevapriv
->flags
& CEVA_FLAG_BROKEN_GEN2
)
182 tmp
= PORT_SCTL_SPD_GEN1
| PORT_SCTL_IPM
;
183 writel(tmp
, mmio
+ PORT_SCR_CTL
+ PORT_BASE
+ PORT_OFFSET
* i
);
187 static const struct scsi_host_template ahci_platform_sht
= {
191 static int ceva_ahci_platform_enable_resources(struct ahci_host_priv
*hpriv
)
195 rc
= ahci_platform_enable_regulators(hpriv
);
199 rc
= ahci_platform_enable_clks(hpriv
);
201 goto disable_regulator
;
203 /* Assert the controller reset */
204 rc
= ahci_platform_assert_rsts(hpriv
);
208 for (i
= 0; i
< hpriv
->nports
; i
++) {
209 rc
= phy_init(hpriv
->phys
[i
]);
214 /* De-assert the controller reset */
215 ahci_platform_deassert_rsts(hpriv
);
217 for (i
= 0; i
< hpriv
->nports
; i
++) {
218 rc
= phy_power_on(hpriv
->phys
[i
]);
220 phy_exit(hpriv
->phys
[i
]);
228 ahci_platform_deassert_rsts(hpriv
);
232 phy_power_off(hpriv
->phys
[i
]);
233 phy_exit(hpriv
->phys
[i
]);
237 ahci_platform_disable_clks(hpriv
);
240 ahci_platform_disable_regulators(hpriv
);
245 static int ceva_ahci_probe(struct platform_device
*pdev
)
247 struct device_node
*np
= pdev
->dev
.of_node
;
248 struct device
*dev
= &pdev
->dev
;
249 struct ahci_host_priv
*hpriv
;
250 struct ceva_ahci_priv
*cevapriv
;
251 enum dev_dma_attr attr
;
254 cevapriv
= devm_kzalloc(dev
, sizeof(*cevapriv
), GFP_KERNEL
);
258 cevapriv
->ahci_pdev
= pdev
;
259 hpriv
= ahci_platform_get_resources(pdev
, 0);
261 return PTR_ERR(hpriv
);
263 hpriv
->rsts
= devm_reset_control_get_optional_exclusive(&pdev
->dev
,
265 if (IS_ERR(hpriv
->rsts
))
266 return dev_err_probe(&pdev
->dev
, PTR_ERR(hpriv
->rsts
),
267 "failed to get reset\n");
269 rc
= ceva_ahci_platform_enable_resources(hpriv
);
273 if (of_property_read_bool(np
, "ceva,broken-gen2"))
274 cevapriv
->flags
= CEVA_FLAG_BROKEN_GEN2
;
276 /* Read OOB timing value for COMINIT from device-tree */
277 if (of_property_read_u8_array(np
, "ceva,p0-cominit-params",
278 (u8
*)&cevapriv
->pp2c
[0], 4) < 0) {
279 dev_warn(dev
, "ceva,p0-cominit-params property not defined\n");
281 goto disable_resources
;
284 if (of_property_read_u8_array(np
, "ceva,p1-cominit-params",
285 (u8
*)&cevapriv
->pp2c
[1], 4) < 0) {
286 dev_warn(dev
, "ceva,p1-cominit-params property not defined\n");
288 goto disable_resources
;
291 /* Read OOB timing value for COMWAKE from device-tree*/
292 if (of_property_read_u8_array(np
, "ceva,p0-comwake-params",
293 (u8
*)&cevapriv
->pp3c
[0], 4) < 0) {
294 dev_warn(dev
, "ceva,p0-comwake-params property not defined\n");
296 goto disable_resources
;
299 if (of_property_read_u8_array(np
, "ceva,p1-comwake-params",
300 (u8
*)&cevapriv
->pp3c
[1], 4) < 0) {
301 dev_warn(dev
, "ceva,p1-comwake-params property not defined\n");
303 goto disable_resources
;
306 /* Read phy BURST timing value from device-tree */
307 if (of_property_read_u8_array(np
, "ceva,p0-burst-params",
308 (u8
*)&cevapriv
->pp4c
[0], 4) < 0) {
309 dev_warn(dev
, "ceva,p0-burst-params property not defined\n");
311 goto disable_resources
;
314 if (of_property_read_u8_array(np
, "ceva,p1-burst-params",
315 (u8
*)&cevapriv
->pp4c
[1], 4) < 0) {
316 dev_warn(dev
, "ceva,p1-burst-params property not defined\n");
318 goto disable_resources
;
321 /* Read phy RETRY interval timing value from device-tree */
322 if (of_property_read_u16_array(np
, "ceva,p0-retry-params",
323 (u16
*)&cevapriv
->pp5c
[0], 2) < 0) {
324 dev_warn(dev
, "ceva,p0-retry-params property not defined\n");
326 goto disable_resources
;
329 if (of_property_read_u16_array(np
, "ceva,p1-retry-params",
330 (u16
*)&cevapriv
->pp5c
[1], 2) < 0) {
331 dev_warn(dev
, "ceva,p1-retry-params property not defined\n");
333 goto disable_resources
;
337 * Check if CCI is enabled for SATA. The DEV_DMA_COHERENT is returned
338 * if CCI is enabled, so check for DEV_DMA_COHERENT.
340 attr
= device_get_dma_attr(dev
);
341 cevapriv
->is_cci_enabled
= (attr
== DEV_DMA_COHERENT
);
343 hpriv
->plat_data
= cevapriv
;
345 /* CEVA specific initialization */
346 ahci_ceva_setup(hpriv
);
348 rc
= ahci_platform_init_host(pdev
, hpriv
, &ahci_ceva_port_info
,
351 goto disable_resources
;
356 ahci_platform_disable_resources(hpriv
);
360 static int __maybe_unused
ceva_ahci_suspend(struct device
*dev
)
362 return ahci_platform_suspend(dev
);
365 static int __maybe_unused
ceva_ahci_resume(struct device
*dev
)
367 struct ata_host
*host
= dev_get_drvdata(dev
);
368 struct ahci_host_priv
*hpriv
= host
->private_data
;
371 rc
= ceva_ahci_platform_enable_resources(hpriv
);
375 /* Configure CEVA specific config before resuming HBA */
376 ahci_ceva_setup(hpriv
);
378 rc
= ahci_platform_resume_host(dev
);
380 goto disable_resources
;
382 /* We resumed so update PM runtime state */
383 pm_runtime_disable(dev
);
384 pm_runtime_set_active(dev
);
385 pm_runtime_enable(dev
);
390 ahci_platform_disable_resources(hpriv
);
395 static SIMPLE_DEV_PM_OPS(ahci_ceva_pm_ops
, ceva_ahci_suspend
, ceva_ahci_resume
);
397 static const struct of_device_id ceva_ahci_of_match
[] = {
398 { .compatible
= "ceva,ahci-1v84" },
401 MODULE_DEVICE_TABLE(of
, ceva_ahci_of_match
);
403 static struct platform_driver ceva_ahci_driver
= {
404 .probe
= ceva_ahci_probe
,
405 .remove
= ata_platform_remove_one
,
408 .of_match_table
= ceva_ahci_of_match
,
409 .pm
= &ahci_ceva_pm_ops
,
412 module_platform_driver(ceva_ahci_driver
);
414 MODULE_DESCRIPTION("CEVA AHCI SATA platform driver");
415 MODULE_AUTHOR("Xilinx Inc.");
416 MODULE_LICENSE("GPL v2");