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/mfd/syscon.h> 17 #include <linux/module.h> 18 #include <linux/of_device.h> 19 #include <linux/platform_device.h> 20 #include <linux/pm.h> 21 #include <linux/regmap.h> 22 23 #include "ahci.h" 24 25 #define DRV_NAME "ahci-dwc" 26 27 #define AHCI_DWC_FBS_PMPN_MAX 15 28 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) 36 37 #define AHCI_DWC_HOST_GPCR 0xd0 38 #define AHCI_DWC_HOST_GPSR 0xd4 39 40 #define AHCI_DWC_HOST_TIMER1MS 0xe0 41 #define AHCI_DWC_HOST_TIMV_MASK GENMASK(19, 0) 42 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) 58 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) 71 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) 79 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) 83 84 #define AHCI_DWC_HOST_VERSIONR 0xf8 85 #define AHCI_DWC_HOST_IDR 0xfc 86 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 94 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) 104 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) 108 109 struct ahci_dwc_plat_data { 110 unsigned int pflags; 111 unsigned int hflags; 112 int (*init)(struct ahci_host_priv *hpriv); 113 int (*reinit)(struct ahci_host_priv *hpriv); 114 void (*clear)(struct ahci_host_priv *hpriv); 115 }; 116 117 struct ahci_dwc_host_priv { 118 const struct ahci_dwc_plat_data *pdata; 119 struct platform_device *pdev; 120 121 u32 timv; 122 u32 dmacr[AHCI_MAX_PORTS]; 123 }; 124 125 static int ahci_bt1_init(struct ahci_host_priv *hpriv) 126 { 127 struct ahci_dwc_host_priv *dpriv = hpriv->plat_data; 128 int ret; 129 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"); 135 return -EINVAL; 136 } 137 138 /* 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. 142 */ 143 ret = ahci_platform_assert_rsts(hpriv); 144 if (ret) { 145 dev_err(&dpriv->pdev->dev, "Couldn't assert the resets\n"); 146 return ret; 147 } 148 149 ret = ahci_platform_deassert_rsts(hpriv); 150 if (ret) { 151 dev_err(&dpriv->pdev->dev, "Couldn't de-assert the resets\n"); 152 return ret; 153 } 154 155 return 0; 156 } 157 158 static struct ahci_host_priv *ahci_dwc_get_resources(struct platform_device *pdev) 159 { 160 struct ahci_dwc_host_priv *dpriv; 161 struct ahci_host_priv *hpriv; 162 163 dpriv = devm_kzalloc(&pdev->dev, sizeof(*dpriv), GFP_KERNEL); 164 if (!dpriv) 165 return ERR_PTR(-ENOMEM); 166 167 dpriv->pdev = pdev; 168 dpriv->pdata = device_get_match_data(&pdev->dev); 169 if (!dpriv->pdata) 170 return ERR_PTR(-EINVAL); 171 172 hpriv = ahci_platform_get_resources(pdev, dpriv->pdata->pflags); 173 if (IS_ERR(hpriv)) 174 return hpriv; 175 176 hpriv->flags |= dpriv->pdata->hflags; 177 hpriv->plat_data = (void *)dpriv; 178 179 return hpriv; 180 } 181 182 static void ahci_dwc_check_cap(struct ahci_host_priv *hpriv) 183 { 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; 188 u32 param; 189 int i; 190 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); 196 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; 200 } 201 202 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", 205 fbs_pmp); 206 } 207 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; 212 } 213 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; 217 } 218 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; 222 } 223 } 224 } 225 226 static void ahci_dwc_init_timer(struct ahci_host_priv *hpriv) 227 { 228 struct ahci_dwc_host_priv *dpriv = hpriv->plat_data; 229 unsigned long rate; 230 struct clk *aclk; 231 u32 cap, cap2; 232 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)) 237 return; 238 239 /* 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. 242 */ 243 aclk = ahci_platform_find_clk(hpriv, "aclk"); 244 if (!aclk) 245 return; 246 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) 252 return; 253 254 dev_info(&dpriv->pdev->dev, "Update CCC/DevSlp timer for Fapp %lu MHz\n", 255 rate / 1000UL); 256 dpriv->timv = FIELD_PREP(AHCI_DWC_HOST_TIMV_MASK, rate); 257 writel(dpriv->timv, hpriv->mmio + AHCI_DWC_HOST_TIMER1MS); 258 } 259 260 static int ahci_dwc_init_dmacr(struct ahci_host_priv *hpriv) 261 { 262 struct ahci_dwc_host_priv *dpriv = hpriv->plat_data; 263 struct device_node *child; 264 void __iomem *port_mmio; 265 u32 port, dmacr, ts; 266 267 /* 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 272 * next system reset. 273 */ 274 for_each_child_of_node(dpriv->pdev->dev.of_node, child) { 275 if (!of_device_is_available(child)) 276 continue; 277 278 if (of_property_read_u32(child, "reg", &port)) { 279 of_node_put(child); 280 return -EINVAL; 281 } 282 283 port_mmio = __ahci_port_base(hpriv, port); 284 dmacr = readl(port_mmio + AHCI_DWC_PORT_DMACR); 285 286 if (!of_property_read_u32(child, "snps,tx-ts-max", &ts)) { 287 ts = ilog2(ts); 288 dmacr &= ~AHCI_DWC_PORT_TXTS_MASK; 289 dmacr |= FIELD_PREP(AHCI_DWC_PORT_TXTS_MASK, ts); 290 } 291 292 if (!of_property_read_u32(child, "snps,rx-ts-max", &ts)) { 293 ts = ilog2(ts); 294 dmacr &= ~AHCI_DWC_PORT_RXTS_MASK; 295 dmacr |= FIELD_PREP(AHCI_DWC_PORT_RXTS_MASK, ts); 296 } 297 298 writel(dmacr, port_mmio + AHCI_DWC_PORT_DMACR); 299 dpriv->dmacr[port] = dmacr; 300 } 301 302 return 0; 303 } 304 305 static int ahci_dwc_init_host(struct ahci_host_priv *hpriv) 306 { 307 struct ahci_dwc_host_priv *dpriv = hpriv->plat_data; 308 int rc; 309 310 rc = ahci_platform_enable_resources(hpriv); 311 if (rc) 312 return rc; 313 314 if (dpriv->pdata->init) { 315 rc = dpriv->pdata->init(hpriv); 316 if (rc) 317 goto err_disable_resources; 318 } 319 320 ahci_dwc_check_cap(hpriv); 321 322 ahci_dwc_init_timer(hpriv); 323 324 rc = ahci_dwc_init_dmacr(hpriv); 325 if (rc) 326 goto err_clear_platform; 327 328 return 0; 329 330 err_clear_platform: 331 if (dpriv->pdata->clear) 332 dpriv->pdata->clear(hpriv); 333 334 err_disable_resources: 335 ahci_platform_disable_resources(hpriv); 336 337 return rc; 338 } 339 340 static int ahci_dwc_reinit_host(struct ahci_host_priv *hpriv) 341 { 342 struct ahci_dwc_host_priv *dpriv = hpriv->plat_data; 343 unsigned long port_map = hpriv->port_map; 344 void __iomem *port_mmio; 345 int i, rc; 346 347 rc = ahci_platform_enable_resources(hpriv); 348 if (rc) 349 return rc; 350 351 if (dpriv->pdata->reinit) { 352 rc = dpriv->pdata->reinit(hpriv); 353 if (rc) 354 goto err_disable_resources; 355 } 356 357 writel(dpriv->timv, hpriv->mmio + AHCI_DWC_HOST_TIMER1MS); 358 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); 362 } 363 364 return 0; 365 366 err_disable_resources: 367 ahci_platform_disable_resources(hpriv); 368 369 return rc; 370 } 371 372 static void ahci_dwc_clear_host(struct ahci_host_priv *hpriv) 373 { 374 struct ahci_dwc_host_priv *dpriv = hpriv->plat_data; 375 376 if (dpriv->pdata->clear) 377 dpriv->pdata->clear(hpriv); 378 379 ahci_platform_disable_resources(hpriv); 380 } 381 382 static void ahci_dwc_stop_host(struct ata_host *host) 383 { 384 struct ahci_host_priv *hpriv = host->private_data; 385 386 ahci_dwc_clear_host(hpriv); 387 } 388 389 static struct ata_port_operations ahci_dwc_port_ops = { 390 .inherits = &ahci_platform_ops, 391 .host_stop = ahci_dwc_stop_host, 392 }; 393 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, 399 }; 400 401 static const struct scsi_host_template ahci_dwc_scsi_info = { 402 AHCI_SHT(DRV_NAME), 403 }; 404 405 static int ahci_dwc_probe(struct platform_device *pdev) 406 { 407 struct ahci_host_priv *hpriv; 408 int rc; 409 410 hpriv = ahci_dwc_get_resources(pdev); 411 if (IS_ERR(hpriv)) 412 return PTR_ERR(hpriv); 413 414 rc = ahci_dwc_init_host(hpriv); 415 if (rc) 416 return rc; 417 418 rc = ahci_platform_init_host(pdev, hpriv, &ahci_dwc_port_info, 419 &ahci_dwc_scsi_info); 420 if (rc) 421 goto err_clear_host; 422 423 return 0; 424 425 err_clear_host: 426 ahci_dwc_clear_host(hpriv); 427 428 return rc; 429 } 430 431 static int ahci_dwc_suspend(struct device *dev) 432 { 433 struct ata_host *host = dev_get_drvdata(dev); 434 struct ahci_host_priv *hpriv = host->private_data; 435 int rc; 436 437 rc = ahci_platform_suspend_host(dev); 438 if (rc) 439 return rc; 440 441 ahci_dwc_clear_host(hpriv); 442 443 return 0; 444 } 445 446 static int ahci_dwc_resume(struct device *dev) 447 { 448 struct ata_host *host = dev_get_drvdata(dev); 449 struct ahci_host_priv *hpriv = host->private_data; 450 int rc; 451 452 rc = ahci_dwc_reinit_host(hpriv); 453 if (rc) 454 return rc; 455 456 return ahci_platform_resume_host(dev); 457 } 458 459 static DEFINE_SIMPLE_DEV_PM_OPS(ahci_dwc_pm_ops, ahci_dwc_suspend, 460 ahci_dwc_resume); 461 462 static struct ahci_dwc_plat_data ahci_dwc_plat = { 463 .pflags = AHCI_PLATFORM_GET_RESETS, 464 }; 465 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, 469 }; 470 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 }, 475 {}, 476 }; 477 MODULE_DEVICE_TABLE(of, ahci_dwc_of_match); 478 479 static struct platform_driver ahci_dwc_driver = { 480 .probe = ahci_dwc_probe, 481 .remove = ata_platform_remove_one, 482 .shutdown = ahci_platform_shutdown, 483 .driver = { 484 .name = DRV_NAME, 485 .of_match_table = ahci_dwc_of_match, 486 .pm = &ahci_dwc_pm_ops, 487 }, 488 }; 489 module_platform_driver(ahci_dwc_driver); 490 491 MODULE_DESCRIPTION("DWC AHCI SATA platform driver"); 492 MODULE_AUTHOR("Serge Semin <Sergey.Semin@baikalelectronics.ru>"); 493 MODULE_LICENSE("GPL"); 494