1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * DWC AHCI SATA Platform driver 4 * 5 * Copyright (C) 2021 BAIKAL ELECTRONICS, JSC 6 */ 7 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/module.h> 17 #include <linux/of.h> 18 #include <linux/platform_device.h> 19 #include <linux/pm.h> 20 21 #include "ahci.h" 22 23 #define DRV_NAME "ahci-dwc" 24 25 #define AHCI_DWC_FBS_PMPN_MAX 15 26 27 /* DWC AHCI SATA controller specific registers */ 28 #define AHCI_DWC_HOST_OOBR 0xbc 29 #define AHCI_DWC_HOST_OOB_WE BIT(31) 30 #define AHCI_DWC_HOST_CWMIN_MASK GENMASK(30, 24) 31 #define AHCI_DWC_HOST_CWMAX_MASK GENMASK(23, 16) 32 #define AHCI_DWC_HOST_CIMIN_MASK GENMASK(15, 8) 33 #define AHCI_DWC_HOST_CIMAX_MASK GENMASK(7, 0) 34 35 #define AHCI_DWC_HOST_GPCR 0xd0 36 #define AHCI_DWC_HOST_GPSR 0xd4 37 38 #define AHCI_DWC_HOST_TIMER1MS 0xe0 39 #define AHCI_DWC_HOST_TIMV_MASK GENMASK(19, 0) 40 41 #define AHCI_DWC_HOST_GPARAM1R 0xe8 42 #define AHCI_DWC_HOST_ALIGN_M BIT(31) 43 #define AHCI_DWC_HOST_RX_BUFFER BIT(30) 44 #define AHCI_DWC_HOST_PHY_DATA_MASK GENMASK(29, 28) 45 #define AHCI_DWC_HOST_PHY_RST BIT(27) 46 #define AHCI_DWC_HOST_PHY_CTRL_MASK GENMASK(26, 21) 47 #define AHCI_DWC_HOST_PHY_STAT_MASK GENMASK(20, 15) 48 #define AHCI_DWC_HOST_LATCH_M BIT(14) 49 #define AHCI_DWC_HOST_PHY_TYPE_MASK GENMASK(13, 11) 50 #define AHCI_DWC_HOST_RET_ERR BIT(10) 51 #define AHCI_DWC_HOST_AHB_ENDIAN_MASK GENMASK(9, 8) 52 #define AHCI_DWC_HOST_S_HADDR BIT(7) 53 #define AHCI_DWC_HOST_M_HADDR BIT(6) 54 #define AHCI_DWC_HOST_S_HDATA_MASK GENMASK(5, 3) 55 #define AHCI_DWC_HOST_M_HDATA_MASK GENMASK(2, 0) 56 57 #define AHCI_DWC_HOST_GPARAM2R 0xec 58 #define AHCI_DWC_HOST_FBS_MEM_S BIT(19) 59 #define AHCI_DWC_HOST_FBS_PMPN_MASK GENMASK(17, 16) 60 #define AHCI_DWC_HOST_FBS_SUP BIT(15) 61 #define AHCI_DWC_HOST_DEV_CP BIT(14) 62 #define AHCI_DWC_HOST_DEV_MP BIT(13) 63 #define AHCI_DWC_HOST_ENCODE_M BIT(12) 64 #define AHCI_DWC_HOST_RXOOB_CLK_M BIT(11) 65 #define AHCI_DWC_HOST_RXOOB_M BIT(10) 66 #define AHCI_DWC_HOST_TXOOB_M BIT(9) 67 #define AHCI_DWC_HOST_RXOOB_M BIT(10) 68 #define AHCI_DWC_HOST_RXOOB_CLK_MASK GENMASK(8, 0) 69 70 #define AHCI_DWC_HOST_PPARAMR 0xf0 71 #define AHCI_DWC_HOST_TX_MEM_M BIT(11) 72 #define AHCI_DWC_HOST_TX_MEM_S BIT(10) 73 #define AHCI_DWC_HOST_RX_MEM_M BIT(9) 74 #define AHCI_DWC_HOST_RX_MEM_S BIT(8) 75 #define AHCI_DWC_HOST_TXFIFO_DEPTH GENMASK(7, 4) 76 #define AHCI_DWC_HOST_RXFIFO_DEPTH GENMASK(3, 0) 77 78 #define AHCI_DWC_HOST_TESTR 0xf4 79 #define AHCI_DWC_HOST_PSEL_MASK GENMASK(18, 16) 80 #define AHCI_DWC_HOST_TEST_IF BIT(0) 81 82 #define AHCI_DWC_HOST_VERSIONR 0xf8 83 #define AHCI_DWC_HOST_IDR 0xfc 84 85 #define AHCI_DWC_PORT_DMACR 0x70 86 #define AHCI_DWC_PORT_RXABL_MASK GENMASK(15, 12) 87 #define AHCI_DWC_PORT_TXABL_MASK GENMASK(11, 8) 88 #define AHCI_DWC_PORT_RXTS_MASK GENMASK(7, 4) 89 #define AHCI_DWC_PORT_TXTS_MASK GENMASK(3, 0) 90 #define AHCI_DWC_PORT_PHYCR 0x74 91 #define AHCI_DWC_PORT_PHYSR 0x78 92 93 struct ahci_dwc_plat_data { 94 unsigned int pflags; 95 unsigned int hflags; 96 int (*init)(struct ahci_host_priv *hpriv); 97 int (*reinit)(struct ahci_host_priv *hpriv); 98 void (*clear)(struct ahci_host_priv *hpriv); 99 }; 100 101 struct ahci_dwc_host_priv { 102 const struct ahci_dwc_plat_data *pdata; 103 struct platform_device *pdev; 104 105 u32 timv; 106 u32 dmacr[AHCI_MAX_PORTS]; 107 }; 108 109 static struct ahci_host_priv *ahci_dwc_get_resources(struct platform_device *pdev) 110 { 111 struct ahci_dwc_host_priv *dpriv; 112 struct ahci_host_priv *hpriv; 113 114 dpriv = devm_kzalloc(&pdev->dev, sizeof(*dpriv), GFP_KERNEL); 115 if (!dpriv) 116 return ERR_PTR(-ENOMEM); 117 118 dpriv->pdev = pdev; 119 dpriv->pdata = device_get_match_data(&pdev->dev); 120 if (!dpriv->pdata) 121 return ERR_PTR(-EINVAL); 122 123 hpriv = ahci_platform_get_resources(pdev, dpriv->pdata->pflags); 124 if (IS_ERR(hpriv)) 125 return hpriv; 126 127 hpriv->flags |= dpriv->pdata->hflags; 128 hpriv->plat_data = (void *)dpriv; 129 130 return hpriv; 131 } 132 133 static void ahci_dwc_check_cap(struct ahci_host_priv *hpriv) 134 { 135 unsigned long port_map = hpriv->saved_port_map | hpriv->mask_port_map; 136 struct ahci_dwc_host_priv *dpriv = hpriv->plat_data; 137 bool dev_mp, dev_cp, fbs_sup; 138 unsigned int fbs_pmp; 139 u32 param; 140 int i; 141 142 param = readl(hpriv->mmio + AHCI_DWC_HOST_GPARAM2R); 143 dev_mp = !!(param & AHCI_DWC_HOST_DEV_MP); 144 dev_cp = !!(param & AHCI_DWC_HOST_DEV_CP); 145 fbs_sup = !!(param & AHCI_DWC_HOST_FBS_SUP); 146 fbs_pmp = 5 * FIELD_GET(AHCI_DWC_HOST_FBS_PMPN_MASK, param); 147 148 if (!dev_mp && hpriv->saved_cap & HOST_CAP_MPS) { 149 dev_warn(&dpriv->pdev->dev, "MPS is unsupported\n"); 150 hpriv->saved_cap &= ~HOST_CAP_MPS; 151 } 152 153 154 if (fbs_sup && fbs_pmp < AHCI_DWC_FBS_PMPN_MAX) { 155 dev_warn(&dpriv->pdev->dev, "PMPn is limited up to %u ports\n", 156 fbs_pmp); 157 } 158 159 for_each_set_bit(i, &port_map, AHCI_MAX_PORTS) { 160 if (!dev_mp && hpriv->saved_port_cap[i] & PORT_CMD_MPSP) { 161 dev_warn(&dpriv->pdev->dev, "MPS incapable port %d\n", i); 162 hpriv->saved_port_cap[i] &= ~PORT_CMD_MPSP; 163 } 164 165 if (!dev_cp && hpriv->saved_port_cap[i] & PORT_CMD_CPD) { 166 dev_warn(&dpriv->pdev->dev, "CPD incapable port %d\n", i); 167 hpriv->saved_port_cap[i] &= ~PORT_CMD_CPD; 168 } 169 170 if (!fbs_sup && hpriv->saved_port_cap[i] & PORT_CMD_FBSCP) { 171 dev_warn(&dpriv->pdev->dev, "FBS incapable port %d\n", i); 172 hpriv->saved_port_cap[i] &= ~PORT_CMD_FBSCP; 173 } 174 } 175 } 176 177 static void ahci_dwc_init_timer(struct ahci_host_priv *hpriv) 178 { 179 struct ahci_dwc_host_priv *dpriv = hpriv->plat_data; 180 unsigned long rate; 181 struct clk *aclk; 182 u32 cap, cap2; 183 184 /* 1ms tick is generated only for the CCC or DevSleep features */ 185 cap = readl(hpriv->mmio + HOST_CAP); 186 cap2 = readl(hpriv->mmio + HOST_CAP2); 187 if (!(cap & HOST_CAP_CCC) && !(cap2 & HOST_CAP2_SDS)) 188 return; 189 190 /* 191 * Tick is generated based on the AXI/AHB application clocks signal 192 * so we need to be sure in the clock we are going to use. 193 */ 194 aclk = ahci_platform_find_clk(hpriv, "aclk"); 195 if (!aclk) 196 return; 197 198 /* 1ms timer interval is set as TIMV = AMBA_FREQ[MHZ] * 1000 */ 199 dpriv->timv = readl(hpriv->mmio + AHCI_DWC_HOST_TIMER1MS); 200 dpriv->timv = FIELD_GET(AHCI_DWC_HOST_TIMV_MASK, dpriv->timv); 201 rate = clk_get_rate(aclk) / 1000UL; 202 if (rate == dpriv->timv) 203 return; 204 205 dev_info(&dpriv->pdev->dev, "Update CCC/DevSlp timer for Fapp %lu MHz\n", 206 rate / 1000UL); 207 dpriv->timv = FIELD_PREP(AHCI_DWC_HOST_TIMV_MASK, rate); 208 writel(dpriv->timv, hpriv->mmio + AHCI_DWC_HOST_TIMER1MS); 209 } 210 211 static int ahci_dwc_init_dmacr(struct ahci_host_priv *hpriv) 212 { 213 struct ahci_dwc_host_priv *dpriv = hpriv->plat_data; 214 void __iomem *port_mmio; 215 u32 port, dmacr, ts; 216 217 /* 218 * Update the DMA Tx/Rx transaction sizes in accordance with the 219 * platform setup. Note values exceeding maximal or minimal limits will 220 * be automatically clamped. Also note the register isn't affected by 221 * the HBA global reset so we can freely initialize it once until the 222 * next system reset. 223 */ 224 for_each_available_child_of_node_scoped(dpriv->pdev->dev.of_node, child) { 225 if (of_property_read_u32(child, "reg", &port)) 226 return -EINVAL; 227 228 port_mmio = __ahci_port_base(hpriv, port); 229 dmacr = readl(port_mmio + AHCI_DWC_PORT_DMACR); 230 231 if (!of_property_read_u32(child, "snps,tx-ts-max", &ts)) { 232 ts = ilog2(ts); 233 dmacr &= ~AHCI_DWC_PORT_TXTS_MASK; 234 dmacr |= FIELD_PREP(AHCI_DWC_PORT_TXTS_MASK, ts); 235 } 236 237 if (!of_property_read_u32(child, "snps,rx-ts-max", &ts)) { 238 ts = ilog2(ts); 239 dmacr &= ~AHCI_DWC_PORT_RXTS_MASK; 240 dmacr |= FIELD_PREP(AHCI_DWC_PORT_RXTS_MASK, ts); 241 } 242 243 writel(dmacr, port_mmio + AHCI_DWC_PORT_DMACR); 244 dpriv->dmacr[port] = dmacr; 245 } 246 247 return 0; 248 } 249 250 static int ahci_dwc_init_host(struct ahci_host_priv *hpriv) 251 { 252 struct ahci_dwc_host_priv *dpriv = hpriv->plat_data; 253 int rc; 254 255 rc = ahci_platform_enable_resources(hpriv); 256 if (rc) 257 return rc; 258 259 if (dpriv->pdata->init) { 260 rc = dpriv->pdata->init(hpriv); 261 if (rc) 262 goto err_disable_resources; 263 } 264 265 ahci_dwc_check_cap(hpriv); 266 267 ahci_dwc_init_timer(hpriv); 268 269 rc = ahci_dwc_init_dmacr(hpriv); 270 if (rc) 271 goto err_clear_platform; 272 273 return 0; 274 275 err_clear_platform: 276 if (dpriv->pdata->clear) 277 dpriv->pdata->clear(hpriv); 278 279 err_disable_resources: 280 ahci_platform_disable_resources(hpriv); 281 282 return rc; 283 } 284 285 static int ahci_dwc_reinit_host(struct ahci_host_priv *hpriv) 286 { 287 struct ahci_dwc_host_priv *dpriv = hpriv->plat_data; 288 unsigned long port_map = hpriv->port_map; 289 void __iomem *port_mmio; 290 int i, rc; 291 292 rc = ahci_platform_enable_resources(hpriv); 293 if (rc) 294 return rc; 295 296 if (dpriv->pdata->reinit) { 297 rc = dpriv->pdata->reinit(hpriv); 298 if (rc) 299 goto err_disable_resources; 300 } 301 302 writel(dpriv->timv, hpriv->mmio + AHCI_DWC_HOST_TIMER1MS); 303 304 for_each_set_bit(i, &port_map, AHCI_MAX_PORTS) { 305 port_mmio = __ahci_port_base(hpriv, i); 306 writel(dpriv->dmacr[i], port_mmio + AHCI_DWC_PORT_DMACR); 307 } 308 309 return 0; 310 311 err_disable_resources: 312 ahci_platform_disable_resources(hpriv); 313 314 return rc; 315 } 316 317 static void ahci_dwc_clear_host(struct ahci_host_priv *hpriv) 318 { 319 struct ahci_dwc_host_priv *dpriv = hpriv->plat_data; 320 321 if (dpriv->pdata->clear) 322 dpriv->pdata->clear(hpriv); 323 324 ahci_platform_disable_resources(hpriv); 325 } 326 327 static void ahci_dwc_stop_host(struct ata_host *host) 328 { 329 struct ahci_host_priv *hpriv = host->private_data; 330 331 ahci_dwc_clear_host(hpriv); 332 } 333 334 static struct ata_port_operations ahci_dwc_port_ops = { 335 .inherits = &ahci_platform_ops, 336 .host_stop = ahci_dwc_stop_host, 337 }; 338 339 static const struct ata_port_info ahci_dwc_port_info = { 340 .flags = AHCI_FLAG_COMMON, 341 .pio_mask = ATA_PIO4, 342 .udma_mask = ATA_UDMA6, 343 .port_ops = &ahci_dwc_port_ops, 344 }; 345 346 static const struct scsi_host_template ahci_dwc_scsi_info = { 347 AHCI_SHT(DRV_NAME), 348 }; 349 350 static int ahci_dwc_probe(struct platform_device *pdev) 351 { 352 struct ahci_host_priv *hpriv; 353 int rc; 354 355 hpriv = ahci_dwc_get_resources(pdev); 356 if (IS_ERR(hpriv)) 357 return PTR_ERR(hpriv); 358 359 rc = ahci_dwc_init_host(hpriv); 360 if (rc) 361 return rc; 362 363 rc = ahci_platform_init_host(pdev, hpriv, &ahci_dwc_port_info, 364 &ahci_dwc_scsi_info); 365 if (rc) 366 goto err_clear_host; 367 368 return 0; 369 370 err_clear_host: 371 ahci_dwc_clear_host(hpriv); 372 373 return rc; 374 } 375 376 static int ahci_dwc_suspend(struct device *dev) 377 { 378 struct ata_host *host = dev_get_drvdata(dev); 379 struct ahci_host_priv *hpriv = host->private_data; 380 int rc; 381 382 rc = ahci_platform_suspend_host(dev); 383 if (rc) 384 return rc; 385 386 ahci_dwc_clear_host(hpriv); 387 388 return 0; 389 } 390 391 static int ahci_dwc_resume(struct device *dev) 392 { 393 struct ata_host *host = dev_get_drvdata(dev); 394 struct ahci_host_priv *hpriv = host->private_data; 395 int rc; 396 397 rc = ahci_dwc_reinit_host(hpriv); 398 if (rc) 399 return rc; 400 401 return ahci_platform_resume_host(dev); 402 } 403 404 static DEFINE_SIMPLE_DEV_PM_OPS(ahci_dwc_pm_ops, ahci_dwc_suspend, 405 ahci_dwc_resume); 406 407 static struct ahci_dwc_plat_data ahci_dwc_plat = { 408 .pflags = AHCI_PLATFORM_GET_RESETS, 409 }; 410 411 static const struct of_device_id ahci_dwc_of_match[] = { 412 { .compatible = "snps,dwc-ahci", &ahci_dwc_plat }, 413 { .compatible = "snps,spear-ahci", &ahci_dwc_plat }, 414 {}, 415 }; 416 MODULE_DEVICE_TABLE(of, ahci_dwc_of_match); 417 418 static struct platform_driver ahci_dwc_driver = { 419 .probe = ahci_dwc_probe, 420 .remove = ata_platform_remove_one, 421 .shutdown = ahci_platform_shutdown, 422 .driver = { 423 .name = DRV_NAME, 424 .of_match_table = ahci_dwc_of_match, 425 .pm = &ahci_dwc_pm_ops, 426 }, 427 }; 428 module_platform_driver(ahci_dwc_driver); 429 430 MODULE_DESCRIPTION("DWC AHCI SATA platform driver"); 431 MODULE_AUTHOR("Serge Semin <Sergey.Semin@baikalelectronics.ru>"); 432 MODULE_LICENSE("GPL"); 433