1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * DWC AHCI SATA Platform driver
5 * Copyright (C) 2021 BAIKAL ELECTRONICS, JSC
8 #include <linux/ahci_platform.h>
9 #include <linux/bitfield.h>
10 #include <linux/bits.h>
11 #include <linux/clk.h>
12 #include <linux/device.h>
13 #include <linux/kernel.h>
14 #include <linux/libata.h>
15 #include <linux/log2.h>
16 #include <linux/mfd/syscon.h>
17 #include <linux/module.h>
19 #include <linux/platform_device.h>
21 #include <linux/regmap.h>
25 #define DRV_NAME "ahci-dwc"
27 #define AHCI_DWC_FBS_PMPN_MAX 15
29 /* DWC AHCI SATA controller specific registers */
30 #define AHCI_DWC_HOST_OOBR 0xbc
31 #define AHCI_DWC_HOST_OOB_WE BIT(31)
32 #define AHCI_DWC_HOST_CWMIN_MASK GENMASK(30, 24)
33 #define AHCI_DWC_HOST_CWMAX_MASK GENMASK(23, 16)
34 #define AHCI_DWC_HOST_CIMIN_MASK GENMASK(15, 8)
35 #define AHCI_DWC_HOST_CIMAX_MASK GENMASK(7, 0)
37 #define AHCI_DWC_HOST_GPCR 0xd0
38 #define AHCI_DWC_HOST_GPSR 0xd4
40 #define AHCI_DWC_HOST_TIMER1MS 0xe0
41 #define AHCI_DWC_HOST_TIMV_MASK GENMASK(19, 0)
43 #define AHCI_DWC_HOST_GPARAM1R 0xe8
44 #define AHCI_DWC_HOST_ALIGN_M BIT(31)
45 #define AHCI_DWC_HOST_RX_BUFFER BIT(30)
46 #define AHCI_DWC_HOST_PHY_DATA_MASK GENMASK(29, 28)
47 #define AHCI_DWC_HOST_PHY_RST BIT(27)
48 #define AHCI_DWC_HOST_PHY_CTRL_MASK GENMASK(26, 21)
49 #define AHCI_DWC_HOST_PHY_STAT_MASK GENMASK(20, 15)
50 #define AHCI_DWC_HOST_LATCH_M BIT(14)
51 #define AHCI_DWC_HOST_PHY_TYPE_MASK GENMASK(13, 11)
52 #define AHCI_DWC_HOST_RET_ERR BIT(10)
53 #define AHCI_DWC_HOST_AHB_ENDIAN_MASK GENMASK(9, 8)
54 #define AHCI_DWC_HOST_S_HADDR BIT(7)
55 #define AHCI_DWC_HOST_M_HADDR BIT(6)
56 #define AHCI_DWC_HOST_S_HDATA_MASK GENMASK(5, 3)
57 #define AHCI_DWC_HOST_M_HDATA_MASK GENMASK(2, 0)
59 #define AHCI_DWC_HOST_GPARAM2R 0xec
60 #define AHCI_DWC_HOST_FBS_MEM_S BIT(19)
61 #define AHCI_DWC_HOST_FBS_PMPN_MASK GENMASK(17, 16)
62 #define AHCI_DWC_HOST_FBS_SUP BIT(15)
63 #define AHCI_DWC_HOST_DEV_CP BIT(14)
64 #define AHCI_DWC_HOST_DEV_MP BIT(13)
65 #define AHCI_DWC_HOST_ENCODE_M BIT(12)
66 #define AHCI_DWC_HOST_RXOOB_CLK_M BIT(11)
67 #define AHCI_DWC_HOST_RXOOB_M BIT(10)
68 #define AHCI_DWC_HOST_TXOOB_M BIT(9)
69 #define AHCI_DWC_HOST_RXOOB_M BIT(10)
70 #define AHCI_DWC_HOST_RXOOB_CLK_MASK GENMASK(8, 0)
72 #define AHCI_DWC_HOST_PPARAMR 0xf0
73 #define AHCI_DWC_HOST_TX_MEM_M BIT(11)
74 #define AHCI_DWC_HOST_TX_MEM_S BIT(10)
75 #define AHCI_DWC_HOST_RX_MEM_M BIT(9)
76 #define AHCI_DWC_HOST_RX_MEM_S BIT(8)
77 #define AHCI_DWC_HOST_TXFIFO_DEPTH GENMASK(7, 4)
78 #define AHCI_DWC_HOST_RXFIFO_DEPTH GENMASK(3, 0)
80 #define AHCI_DWC_HOST_TESTR 0xf4
81 #define AHCI_DWC_HOST_PSEL_MASK GENMASK(18, 16)
82 #define AHCI_DWC_HOST_TEST_IF BIT(0)
84 #define AHCI_DWC_HOST_VERSIONR 0xf8
85 #define AHCI_DWC_HOST_IDR 0xfc
87 #define AHCI_DWC_PORT_DMACR 0x70
88 #define AHCI_DWC_PORT_RXABL_MASK GENMASK(15, 12)
89 #define AHCI_DWC_PORT_TXABL_MASK GENMASK(11, 8)
90 #define AHCI_DWC_PORT_RXTS_MASK GENMASK(7, 4)
91 #define AHCI_DWC_PORT_TXTS_MASK GENMASK(3, 0)
92 #define AHCI_DWC_PORT_PHYCR 0x74
93 #define AHCI_DWC_PORT_PHYSR 0x78
95 /* Baikal-T1 AHCI SATA specific registers */
96 #define AHCI_BT1_HOST_PHYCR AHCI_DWC_HOST_GPCR
97 #define AHCI_BT1_HOST_MPLM_MASK GENMASK(29, 23)
98 #define AHCI_BT1_HOST_LOSDT_MASK GENMASK(22, 20)
99 #define AHCI_BT1_HOST_CRR BIT(19)
100 #define AHCI_BT1_HOST_CRW BIT(18)
101 #define AHCI_BT1_HOST_CRCD BIT(17)
102 #define AHCI_BT1_HOST_CRCA BIT(16)
103 #define AHCI_BT1_HOST_CRDI_MASK GENMASK(15, 0)
105 #define AHCI_BT1_HOST_PHYSR AHCI_DWC_HOST_GPSR
106 #define AHCI_BT1_HOST_CRA BIT(16)
107 #define AHCI_BT1_HOST_CRDO_MASK GENMASK(15, 0)
109 struct ahci_dwc_plat_data
{
112 int (*init
)(struct ahci_host_priv
*hpriv
);
113 int (*reinit
)(struct ahci_host_priv
*hpriv
);
114 void (*clear
)(struct ahci_host_priv
*hpriv
);
117 struct ahci_dwc_host_priv
{
118 const struct ahci_dwc_plat_data
*pdata
;
119 struct platform_device
*pdev
;
122 u32 dmacr
[AHCI_MAX_PORTS
];
125 static int ahci_bt1_init(struct ahci_host_priv
*hpriv
)
127 struct ahci_dwc_host_priv
*dpriv
= hpriv
->plat_data
;
130 /* APB, application and reference clocks are required */
131 if (!ahci_platform_find_clk(hpriv
, "pclk") ||
132 !ahci_platform_find_clk(hpriv
, "aclk") ||
133 !ahci_platform_find_clk(hpriv
, "ref")) {
134 dev_err(&dpriv
->pdev
->dev
, "No system clocks specified\n");
139 * Fully reset the SATA AXI and ref clocks domain to ensure the state
140 * machine is working from scratch especially if the reference clocks
141 * source has been changed.
143 ret
= ahci_platform_assert_rsts(hpriv
);
145 dev_err(&dpriv
->pdev
->dev
, "Couldn't assert the resets\n");
149 ret
= ahci_platform_deassert_rsts(hpriv
);
151 dev_err(&dpriv
->pdev
->dev
, "Couldn't de-assert the resets\n");
158 static struct ahci_host_priv
*ahci_dwc_get_resources(struct platform_device
*pdev
)
160 struct ahci_dwc_host_priv
*dpriv
;
161 struct ahci_host_priv
*hpriv
;
163 dpriv
= devm_kzalloc(&pdev
->dev
, sizeof(*dpriv
), GFP_KERNEL
);
165 return ERR_PTR(-ENOMEM
);
168 dpriv
->pdata
= device_get_match_data(&pdev
->dev
);
170 return ERR_PTR(-EINVAL
);
172 hpriv
= ahci_platform_get_resources(pdev
, dpriv
->pdata
->pflags
);
176 hpriv
->flags
|= dpriv
->pdata
->hflags
;
177 hpriv
->plat_data
= (void *)dpriv
;
182 static void ahci_dwc_check_cap(struct ahci_host_priv
*hpriv
)
184 unsigned long port_map
= hpriv
->saved_port_map
| hpriv
->mask_port_map
;
185 struct ahci_dwc_host_priv
*dpriv
= hpriv
->plat_data
;
186 bool dev_mp
, dev_cp
, fbs_sup
;
187 unsigned int fbs_pmp
;
191 param
= readl(hpriv
->mmio
+ AHCI_DWC_HOST_GPARAM2R
);
192 dev_mp
= !!(param
& AHCI_DWC_HOST_DEV_MP
);
193 dev_cp
= !!(param
& AHCI_DWC_HOST_DEV_CP
);
194 fbs_sup
= !!(param
& AHCI_DWC_HOST_FBS_SUP
);
195 fbs_pmp
= 5 * FIELD_GET(AHCI_DWC_HOST_FBS_PMPN_MASK
, param
);
197 if (!dev_mp
&& hpriv
->saved_cap
& HOST_CAP_MPS
) {
198 dev_warn(&dpriv
->pdev
->dev
, "MPS is unsupported\n");
199 hpriv
->saved_cap
&= ~HOST_CAP_MPS
;
203 if (fbs_sup
&& fbs_pmp
< AHCI_DWC_FBS_PMPN_MAX
) {
204 dev_warn(&dpriv
->pdev
->dev
, "PMPn is limited up to %u ports\n",
208 for_each_set_bit(i
, &port_map
, AHCI_MAX_PORTS
) {
209 if (!dev_mp
&& hpriv
->saved_port_cap
[i
] & PORT_CMD_MPSP
) {
210 dev_warn(&dpriv
->pdev
->dev
, "MPS incapable port %d\n", i
);
211 hpriv
->saved_port_cap
[i
] &= ~PORT_CMD_MPSP
;
214 if (!dev_cp
&& hpriv
->saved_port_cap
[i
] & PORT_CMD_CPD
) {
215 dev_warn(&dpriv
->pdev
->dev
, "CPD incapable port %d\n", i
);
216 hpriv
->saved_port_cap
[i
] &= ~PORT_CMD_CPD
;
219 if (!fbs_sup
&& hpriv
->saved_port_cap
[i
] & PORT_CMD_FBSCP
) {
220 dev_warn(&dpriv
->pdev
->dev
, "FBS incapable port %d\n", i
);
221 hpriv
->saved_port_cap
[i
] &= ~PORT_CMD_FBSCP
;
226 static void ahci_dwc_init_timer(struct ahci_host_priv
*hpriv
)
228 struct ahci_dwc_host_priv
*dpriv
= hpriv
->plat_data
;
233 /* 1ms tick is generated only for the CCC or DevSleep features */
234 cap
= readl(hpriv
->mmio
+ HOST_CAP
);
235 cap2
= readl(hpriv
->mmio
+ HOST_CAP2
);
236 if (!(cap
& HOST_CAP_CCC
) && !(cap2
& HOST_CAP2_SDS
))
240 * Tick is generated based on the AXI/AHB application clocks signal
241 * so we need to be sure in the clock we are going to use.
243 aclk
= ahci_platform_find_clk(hpriv
, "aclk");
247 /* 1ms timer interval is set as TIMV = AMBA_FREQ[MHZ] * 1000 */
248 dpriv
->timv
= readl(hpriv
->mmio
+ AHCI_DWC_HOST_TIMER1MS
);
249 dpriv
->timv
= FIELD_GET(AHCI_DWC_HOST_TIMV_MASK
, dpriv
->timv
);
250 rate
= clk_get_rate(aclk
) / 1000UL;
251 if (rate
== dpriv
->timv
)
254 dev_info(&dpriv
->pdev
->dev
, "Update CCC/DevSlp timer for Fapp %lu MHz\n",
256 dpriv
->timv
= FIELD_PREP(AHCI_DWC_HOST_TIMV_MASK
, rate
);
257 writel(dpriv
->timv
, hpriv
->mmio
+ AHCI_DWC_HOST_TIMER1MS
);
260 static int ahci_dwc_init_dmacr(struct ahci_host_priv
*hpriv
)
262 struct ahci_dwc_host_priv
*dpriv
= hpriv
->plat_data
;
263 struct device_node
*child
;
264 void __iomem
*port_mmio
;
268 * Update the DMA Tx/Rx transaction sizes in accordance with the
269 * platform setup. Note values exceeding maximal or minimal limits will
270 * be automatically clamped. Also note the register isn't affected by
271 * the HBA global reset so we can freely initialize it once until the
274 for_each_child_of_node(dpriv
->pdev
->dev
.of_node
, child
) {
275 if (!of_device_is_available(child
))
278 if (of_property_read_u32(child
, "reg", &port
)) {
283 port_mmio
= __ahci_port_base(hpriv
, port
);
284 dmacr
= readl(port_mmio
+ AHCI_DWC_PORT_DMACR
);
286 if (!of_property_read_u32(child
, "snps,tx-ts-max", &ts
)) {
288 dmacr
&= ~AHCI_DWC_PORT_TXTS_MASK
;
289 dmacr
|= FIELD_PREP(AHCI_DWC_PORT_TXTS_MASK
, ts
);
292 if (!of_property_read_u32(child
, "snps,rx-ts-max", &ts
)) {
294 dmacr
&= ~AHCI_DWC_PORT_RXTS_MASK
;
295 dmacr
|= FIELD_PREP(AHCI_DWC_PORT_RXTS_MASK
, ts
);
298 writel(dmacr
, port_mmio
+ AHCI_DWC_PORT_DMACR
);
299 dpriv
->dmacr
[port
] = dmacr
;
305 static int ahci_dwc_init_host(struct ahci_host_priv
*hpriv
)
307 struct ahci_dwc_host_priv
*dpriv
= hpriv
->plat_data
;
310 rc
= ahci_platform_enable_resources(hpriv
);
314 if (dpriv
->pdata
->init
) {
315 rc
= dpriv
->pdata
->init(hpriv
);
317 goto err_disable_resources
;
320 ahci_dwc_check_cap(hpriv
);
322 ahci_dwc_init_timer(hpriv
);
324 rc
= ahci_dwc_init_dmacr(hpriv
);
326 goto err_clear_platform
;
331 if (dpriv
->pdata
->clear
)
332 dpriv
->pdata
->clear(hpriv
);
334 err_disable_resources
:
335 ahci_platform_disable_resources(hpriv
);
340 static int ahci_dwc_reinit_host(struct ahci_host_priv
*hpriv
)
342 struct ahci_dwc_host_priv
*dpriv
= hpriv
->plat_data
;
343 unsigned long port_map
= hpriv
->port_map
;
344 void __iomem
*port_mmio
;
347 rc
= ahci_platform_enable_resources(hpriv
);
351 if (dpriv
->pdata
->reinit
) {
352 rc
= dpriv
->pdata
->reinit(hpriv
);
354 goto err_disable_resources
;
357 writel(dpriv
->timv
, hpriv
->mmio
+ AHCI_DWC_HOST_TIMER1MS
);
359 for_each_set_bit(i
, &port_map
, AHCI_MAX_PORTS
) {
360 port_mmio
= __ahci_port_base(hpriv
, i
);
361 writel(dpriv
->dmacr
[i
], port_mmio
+ AHCI_DWC_PORT_DMACR
);
366 err_disable_resources
:
367 ahci_platform_disable_resources(hpriv
);
372 static void ahci_dwc_clear_host(struct ahci_host_priv
*hpriv
)
374 struct ahci_dwc_host_priv
*dpriv
= hpriv
->plat_data
;
376 if (dpriv
->pdata
->clear
)
377 dpriv
->pdata
->clear(hpriv
);
379 ahci_platform_disable_resources(hpriv
);
382 static void ahci_dwc_stop_host(struct ata_host
*host
)
384 struct ahci_host_priv
*hpriv
= host
->private_data
;
386 ahci_dwc_clear_host(hpriv
);
389 static struct ata_port_operations ahci_dwc_port_ops
= {
390 .inherits
= &ahci_platform_ops
,
391 .host_stop
= ahci_dwc_stop_host
,
394 static const struct ata_port_info ahci_dwc_port_info
= {
395 .flags
= AHCI_FLAG_COMMON
,
396 .pio_mask
= ATA_PIO4
,
397 .udma_mask
= ATA_UDMA6
,
398 .port_ops
= &ahci_dwc_port_ops
,
401 static const struct scsi_host_template ahci_dwc_scsi_info
= {
405 static int ahci_dwc_probe(struct platform_device
*pdev
)
407 struct ahci_host_priv
*hpriv
;
410 hpriv
= ahci_dwc_get_resources(pdev
);
412 return PTR_ERR(hpriv
);
414 rc
= ahci_dwc_init_host(hpriv
);
418 rc
= ahci_platform_init_host(pdev
, hpriv
, &ahci_dwc_port_info
,
419 &ahci_dwc_scsi_info
);
426 ahci_dwc_clear_host(hpriv
);
431 static int ahci_dwc_suspend(struct device
*dev
)
433 struct ata_host
*host
= dev_get_drvdata(dev
);
434 struct ahci_host_priv
*hpriv
= host
->private_data
;
437 rc
= ahci_platform_suspend_host(dev
);
441 ahci_dwc_clear_host(hpriv
);
446 static int ahci_dwc_resume(struct device
*dev
)
448 struct ata_host
*host
= dev_get_drvdata(dev
);
449 struct ahci_host_priv
*hpriv
= host
->private_data
;
452 rc
= ahci_dwc_reinit_host(hpriv
);
456 return ahci_platform_resume_host(dev
);
459 static DEFINE_SIMPLE_DEV_PM_OPS(ahci_dwc_pm_ops
, ahci_dwc_suspend
,
462 static struct ahci_dwc_plat_data ahci_dwc_plat
= {
463 .pflags
= AHCI_PLATFORM_GET_RESETS
,
466 static struct ahci_dwc_plat_data ahci_bt1_plat
= {
467 .pflags
= AHCI_PLATFORM_GET_RESETS
| AHCI_PLATFORM_RST_TRIGGER
,
468 .init
= ahci_bt1_init
,
471 static const struct of_device_id ahci_dwc_of_match
[] = {
472 { .compatible
= "snps,dwc-ahci", &ahci_dwc_plat
},
473 { .compatible
= "snps,spear-ahci", &ahci_dwc_plat
},
474 { .compatible
= "baikal,bt1-ahci", &ahci_bt1_plat
},
477 MODULE_DEVICE_TABLE(of
, ahci_dwc_of_match
);
479 static struct platform_driver ahci_dwc_driver
= {
480 .probe
= ahci_dwc_probe
,
481 .remove_new
= ata_platform_remove_one
,
482 .shutdown
= ahci_platform_shutdown
,
485 .of_match_table
= ahci_dwc_of_match
,
486 .pm
= &ahci_dwc_pm_ops
,
489 module_platform_driver(ahci_dwc_driver
);
491 MODULE_DESCRIPTION("DWC AHCI SATA platform driver");
492 MODULE_AUTHOR("Serge Semin <Sergey.Semin@baikalelectronics.ru>");
493 MODULE_LICENSE("GPL");