1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Memory-mapped interface driver for DW SPI Core 4 * 5 * Copyright (c) 2010, Octasic semiconductor. 6 */ 7 8 #include <linux/clk.h> 9 #include <linux/err.h> 10 #include <linux/platform_device.h> 11 #include <linux/pm_runtime.h> 12 #include <linux/slab.h> 13 #include <linux/spi/spi.h> 14 #include <linux/scatterlist.h> 15 #include <linux/mfd/syscon.h> 16 #include <linux/module.h> 17 #include <linux/of.h> 18 #include <linux/of_platform.h> 19 #include <linux/acpi.h> 20 #include <linux/property.h> 21 #include <linux/regmap.h> 22 #include <linux/reset.h> 23 24 #include "spi-dw.h" 25 26 #define DRIVER_NAME "dw_spi_mmio" 27 28 struct dw_spi_mmio { 29 struct dw_spi dws; 30 struct clk *clk; 31 struct clk *pclk; 32 void *priv; 33 struct reset_control *rstc; 34 }; 35 36 #define MSCC_CPU_SYSTEM_CTRL_GENERAL_CTRL 0x24 37 #define OCELOT_IF_SI_OWNER_OFFSET 4 38 #define JAGUAR2_IF_SI_OWNER_OFFSET 6 39 #define MSCC_IF_SI_OWNER_MASK GENMASK(1, 0) 40 #define MSCC_IF_SI_OWNER_SISL 0 41 #define MSCC_IF_SI_OWNER_SIBM 1 42 #define MSCC_IF_SI_OWNER_SIMC 2 43 44 #define MSCC_SPI_MST_SW_MODE 0x14 45 #define MSCC_SPI_MST_SW_MODE_SW_PIN_CTRL_MODE BIT(13) 46 #define MSCC_SPI_MST_SW_MODE_SW_SPI_CS(x) (x << 5) 47 48 #define SPARX5_FORCE_ENA 0xa4 49 #define SPARX5_FORCE_VAL 0xa8 50 51 struct dw_spi_mscc { 52 struct regmap *syscon; 53 void __iomem *spi_mst; /* Not sparx5 */ 54 }; 55 56 /* 57 * Elba SoC does not use ssi, pin override is used for cs 0,1 and 58 * gpios for cs 2,3 as defined in the device tree. 59 * 60 * cs: | 1 0 61 * bit: |---3-------2-------1-------0 62 * | cs1 cs1_ovr cs0 cs0_ovr 63 */ 64 #define ELBA_SPICS_REG 0x2468 65 #define ELBA_SPICS_OFFSET(cs) ((cs) << 1) 66 #define ELBA_SPICS_MASK(cs) (GENMASK(1, 0) << ELBA_SPICS_OFFSET(cs)) 67 #define ELBA_SPICS_SET(cs, val) \ 68 ((((val) << 1) | BIT(0)) << ELBA_SPICS_OFFSET(cs)) 69 70 /* 71 * The Designware SPI controller (referred to as master in the documentation) 72 * automatically deasserts chip select when the tx fifo is empty. The chip 73 * selects then needs to be either driven as GPIOs or, for the first 4 using 74 * the SPI boot controller registers. the final chip select is an OR gate 75 * between the Designware SPI controller and the SPI boot controller. 76 */ 77 static void dw_spi_mscc_set_cs(struct spi_device *spi, bool enable) 78 { 79 struct dw_spi *dws = spi_controller_get_devdata(spi->controller); 80 struct dw_spi_mmio *dwsmmio = container_of(dws, struct dw_spi_mmio, dws); 81 struct dw_spi_mscc *dwsmscc = dwsmmio->priv; 82 u32 cs = spi_get_chipselect(spi, 0); 83 84 if (cs < 4) { 85 u32 sw_mode = MSCC_SPI_MST_SW_MODE_SW_PIN_CTRL_MODE; 86 87 if (!enable) 88 sw_mode |= MSCC_SPI_MST_SW_MODE_SW_SPI_CS(BIT(cs)); 89 90 writel(sw_mode, dwsmscc->spi_mst + MSCC_SPI_MST_SW_MODE); 91 } 92 93 dw_spi_set_cs(spi, enable); 94 } 95 96 static int dw_spi_mscc_init(struct platform_device *pdev, 97 struct dw_spi_mmio *dwsmmio, 98 const char *cpu_syscon, u32 if_si_owner_offset) 99 { 100 struct dw_spi_mscc *dwsmscc; 101 102 dwsmscc = devm_kzalloc(&pdev->dev, sizeof(*dwsmscc), GFP_KERNEL); 103 if (!dwsmscc) 104 return -ENOMEM; 105 106 dwsmscc->spi_mst = devm_platform_ioremap_resource(pdev, 1); 107 if (IS_ERR(dwsmscc->spi_mst)) 108 return PTR_ERR(dwsmscc->spi_mst); 109 110 dwsmscc->syscon = syscon_regmap_lookup_by_compatible(cpu_syscon); 111 if (IS_ERR(dwsmscc->syscon)) 112 return PTR_ERR(dwsmscc->syscon); 113 114 /* Deassert all CS */ 115 writel(0, dwsmscc->spi_mst + MSCC_SPI_MST_SW_MODE); 116 117 /* Select the owner of the SI interface */ 118 regmap_update_bits(dwsmscc->syscon, MSCC_CPU_SYSTEM_CTRL_GENERAL_CTRL, 119 MSCC_IF_SI_OWNER_MASK << if_si_owner_offset, 120 MSCC_IF_SI_OWNER_SIMC << if_si_owner_offset); 121 122 dwsmmio->dws.set_cs = dw_spi_mscc_set_cs; 123 dwsmmio->priv = dwsmscc; 124 125 return 0; 126 } 127 128 static int dw_spi_mscc_ocelot_init(struct platform_device *pdev, 129 struct dw_spi_mmio *dwsmmio) 130 { 131 return dw_spi_mscc_init(pdev, dwsmmio, "mscc,ocelot-cpu-syscon", 132 OCELOT_IF_SI_OWNER_OFFSET); 133 } 134 135 static int dw_spi_mscc_jaguar2_init(struct platform_device *pdev, 136 struct dw_spi_mmio *dwsmmio) 137 { 138 return dw_spi_mscc_init(pdev, dwsmmio, "mscc,jaguar2-cpu-syscon", 139 JAGUAR2_IF_SI_OWNER_OFFSET); 140 } 141 142 /* 143 * The Designware SPI controller (referred to as master in the 144 * documentation) automatically deasserts chip select when the tx fifo 145 * is empty. The chip selects then needs to be driven by a CS override 146 * register. enable is an active low signal. 147 */ 148 static void dw_spi_sparx5_set_cs(struct spi_device *spi, bool enable) 149 { 150 struct dw_spi *dws = spi_controller_get_devdata(spi->controller); 151 struct dw_spi_mmio *dwsmmio = container_of(dws, struct dw_spi_mmio, dws); 152 struct dw_spi_mscc *dwsmscc = dwsmmio->priv; 153 u8 cs = spi_get_chipselect(spi, 0); 154 155 if (!enable) { 156 /* CS override drive enable */ 157 regmap_write(dwsmscc->syscon, SPARX5_FORCE_ENA, 1); 158 /* Now set CSx enabled */ 159 regmap_write(dwsmscc->syscon, SPARX5_FORCE_VAL, ~BIT(cs)); 160 /* Allow settle */ 161 usleep_range(1, 5); 162 } else { 163 /* CS value */ 164 regmap_write(dwsmscc->syscon, SPARX5_FORCE_VAL, ~0); 165 /* Allow settle */ 166 usleep_range(1, 5); 167 /* CS override drive disable */ 168 regmap_write(dwsmscc->syscon, SPARX5_FORCE_ENA, 0); 169 } 170 171 dw_spi_set_cs(spi, enable); 172 } 173 174 static int dw_spi_mscc_sparx5_init(struct platform_device *pdev, 175 struct dw_spi_mmio *dwsmmio) 176 { 177 const char *syscon_name = "microchip,sparx5-cpu-syscon"; 178 struct device *dev = &pdev->dev; 179 struct dw_spi_mscc *dwsmscc; 180 181 if (!IS_ENABLED(CONFIG_SPI_MUX)) { 182 dev_err(dev, "This driver needs CONFIG_SPI_MUX\n"); 183 return -EOPNOTSUPP; 184 } 185 186 dwsmscc = devm_kzalloc(dev, sizeof(*dwsmscc), GFP_KERNEL); 187 if (!dwsmscc) 188 return -ENOMEM; 189 190 dwsmscc->syscon = 191 syscon_regmap_lookup_by_compatible(syscon_name); 192 if (IS_ERR(dwsmscc->syscon)) { 193 dev_err(dev, "No syscon map %s\n", syscon_name); 194 return PTR_ERR(dwsmscc->syscon); 195 } 196 197 dwsmmio->dws.set_cs = dw_spi_sparx5_set_cs; 198 dwsmmio->priv = dwsmscc; 199 200 return 0; 201 } 202 203 static int dw_spi_alpine_init(struct platform_device *pdev, 204 struct dw_spi_mmio *dwsmmio) 205 { 206 dwsmmio->dws.caps = DW_SPI_CAP_CS_OVERRIDE; 207 208 return 0; 209 } 210 211 static int dw_spi_pssi_init(struct platform_device *pdev, 212 struct dw_spi_mmio *dwsmmio) 213 { 214 dw_spi_dma_setup_generic(&dwsmmio->dws); 215 216 return 0; 217 } 218 219 static int dw_spi_hssi_init(struct platform_device *pdev, 220 struct dw_spi_mmio *dwsmmio) 221 { 222 dwsmmio->dws.ip = DW_HSSI_ID; 223 224 dw_spi_dma_setup_generic(&dwsmmio->dws); 225 226 return 0; 227 } 228 229 static int dw_spi_intel_init(struct platform_device *pdev, 230 struct dw_spi_mmio *dwsmmio) 231 { 232 dwsmmio->dws.ip = DW_HSSI_ID; 233 234 return 0; 235 } 236 237 /* 238 * DMA-based mem ops are not configured for this device and are not tested. 239 */ 240 static int dw_spi_mountevans_imc_init(struct platform_device *pdev, 241 struct dw_spi_mmio *dwsmmio) 242 { 243 /* 244 * The Intel Mount Evans SoC's Integrated Management Complex DW 245 * apb_ssi_v4.02a controller has an errata where a full TX FIFO can 246 * result in data corruption. The suggested workaround is to never 247 * completely fill the FIFO. The TX FIFO has a size of 32 so the 248 * fifo_len is set to 31. 249 */ 250 dwsmmio->dws.fifo_len = 31; 251 252 return 0; 253 } 254 255 static int dw_spi_canaan_k210_init(struct platform_device *pdev, 256 struct dw_spi_mmio *dwsmmio) 257 { 258 /* 259 * The Canaan Kendryte K210 SoC DW apb_ssi v4 spi controller is 260 * documented to have a 32 word deep TX and RX FIFO, which 261 * spi_hw_init() detects. However, when the RX FIFO is filled up to 262 * 32 entries (RXFLR = 32), an RX FIFO overrun error occurs. Avoid this 263 * problem by force setting fifo_len to 31. 264 */ 265 dwsmmio->dws.fifo_len = 31; 266 267 return 0; 268 } 269 270 static void dw_spi_elba_override_cs(struct regmap *syscon, int cs, int enable) 271 { 272 regmap_update_bits(syscon, ELBA_SPICS_REG, ELBA_SPICS_MASK(cs), 273 ELBA_SPICS_SET(cs, enable)); 274 } 275 276 static void dw_spi_elba_set_cs(struct spi_device *spi, bool enable) 277 { 278 struct dw_spi *dws = spi_controller_get_devdata(spi->controller); 279 struct dw_spi_mmio *dwsmmio = container_of(dws, struct dw_spi_mmio, dws); 280 struct regmap *syscon = dwsmmio->priv; 281 u8 cs; 282 283 cs = spi_get_chipselect(spi, 0); 284 if (cs < 2) 285 dw_spi_elba_override_cs(syscon, spi_get_chipselect(spi, 0), enable); 286 287 /* 288 * The DW SPI controller needs a native CS bit selected to start 289 * the serial engine. 290 */ 291 spi_set_chipselect(spi, 0, 0); 292 dw_spi_set_cs(spi, enable); 293 spi_set_chipselect(spi, 0, cs); 294 } 295 296 static int dw_spi_elba_init(struct platform_device *pdev, 297 struct dw_spi_mmio *dwsmmio) 298 { 299 struct regmap *syscon; 300 301 syscon = syscon_regmap_lookup_by_phandle(dev_of_node(&pdev->dev), 302 "amd,pensando-elba-syscon"); 303 if (IS_ERR(syscon)) 304 return dev_err_probe(&pdev->dev, PTR_ERR(syscon), 305 "syscon regmap lookup failed\n"); 306 307 dwsmmio->priv = syscon; 308 dwsmmio->dws.set_cs = dw_spi_elba_set_cs; 309 310 return 0; 311 } 312 313 static int dw_spi_mmio_probe(struct platform_device *pdev) 314 { 315 int (*init_func)(struct platform_device *pdev, 316 struct dw_spi_mmio *dwsmmio); 317 struct dw_spi_mmio *dwsmmio; 318 struct resource *mem; 319 struct dw_spi *dws; 320 int ret; 321 322 dwsmmio = devm_kzalloc(&pdev->dev, sizeof(struct dw_spi_mmio), 323 GFP_KERNEL); 324 if (!dwsmmio) 325 return -ENOMEM; 326 327 dws = &dwsmmio->dws; 328 329 /* Get basic io resource and map it */ 330 dws->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &mem); 331 if (IS_ERR(dws->regs)) 332 return PTR_ERR(dws->regs); 333 334 dws->paddr = mem->start; 335 336 dws->irq = platform_get_irq(pdev, 0); 337 if (dws->irq < 0) 338 return dws->irq; /* -ENXIO */ 339 340 dwsmmio->clk = devm_clk_get_enabled(&pdev->dev, NULL); 341 if (IS_ERR(dwsmmio->clk)) 342 return PTR_ERR(dwsmmio->clk); 343 344 /* Optional clock needed to access the registers */ 345 dwsmmio->pclk = devm_clk_get_optional_enabled(&pdev->dev, "pclk"); 346 if (IS_ERR(dwsmmio->pclk)) 347 return PTR_ERR(dwsmmio->pclk); 348 349 /* find an optional reset controller */ 350 dwsmmio->rstc = devm_reset_control_get_optional_exclusive(&pdev->dev, "spi"); 351 if (IS_ERR(dwsmmio->rstc)) 352 return PTR_ERR(dwsmmio->rstc); 353 354 ret = reset_control_deassert(dwsmmio->rstc); 355 if (ret) 356 return dev_err_probe(&pdev->dev, ret, "Failed to deassert resets\n"); 357 358 dws->bus_num = pdev->id; 359 360 dws->max_freq = clk_get_rate(dwsmmio->clk); 361 362 if (device_property_read_u32(&pdev->dev, "reg-io-width", 363 &dws->reg_io_width)) 364 dws->reg_io_width = 4; 365 366 /* Rely on the auto-detection if no property specified */ 367 device_property_read_u32(&pdev->dev, "num-cs", &dws->num_cs); 368 369 init_func = device_get_match_data(&pdev->dev); 370 if (init_func) { 371 ret = init_func(pdev, dwsmmio); 372 if (ret) 373 goto out_reset; 374 } 375 376 pm_runtime_enable(&pdev->dev); 377 378 ret = dw_spi_add_controller(&pdev->dev, dws); 379 if (ret) 380 goto out; 381 382 platform_set_drvdata(pdev, dwsmmio); 383 return 0; 384 385 out: 386 pm_runtime_disable(&pdev->dev); 387 out_reset: 388 reset_control_assert(dwsmmio->rstc); 389 390 return ret; 391 } 392 393 static int dw_spi_mmio_suspend(struct device *dev) 394 { 395 struct dw_spi_mmio *dwsmmio = dev_get_drvdata(dev); 396 int ret; 397 398 ret = dw_spi_suspend_controller(&dwsmmio->dws); 399 if (ret) 400 return ret; 401 402 reset_control_assert(dwsmmio->rstc); 403 404 clk_disable_unprepare(dwsmmio->pclk); 405 clk_disable_unprepare(dwsmmio->clk); 406 407 return 0; 408 } 409 410 static int dw_spi_mmio_resume(struct device *dev) 411 { 412 struct dw_spi_mmio *dwsmmio = dev_get_drvdata(dev); 413 414 clk_prepare_enable(dwsmmio->clk); 415 clk_prepare_enable(dwsmmio->pclk); 416 417 reset_control_deassert(dwsmmio->rstc); 418 419 return dw_spi_resume_controller(&dwsmmio->dws); 420 } 421 422 static DEFINE_SIMPLE_DEV_PM_OPS(dw_spi_mmio_pm_ops, 423 dw_spi_mmio_suspend, dw_spi_mmio_resume); 424 425 static void dw_spi_mmio_remove(struct platform_device *pdev) 426 { 427 struct dw_spi_mmio *dwsmmio = platform_get_drvdata(pdev); 428 429 dw_spi_remove_controller(&dwsmmio->dws); 430 pm_runtime_disable(&pdev->dev); 431 reset_control_assert(dwsmmio->rstc); 432 } 433 434 static const struct of_device_id dw_spi_mmio_of_match[] = { 435 { .compatible = "snps,dw-apb-ssi", .data = dw_spi_pssi_init}, 436 { .compatible = "mscc,ocelot-spi", .data = dw_spi_mscc_ocelot_init}, 437 { .compatible = "mscc,jaguar2-spi", .data = dw_spi_mscc_jaguar2_init}, 438 { .compatible = "amazon,alpine-dw-apb-ssi", .data = dw_spi_alpine_init}, 439 { .compatible = "renesas,rzn1-spi", .data = dw_spi_pssi_init}, 440 { .compatible = "snps,dwc-ssi-1.01a", .data = dw_spi_hssi_init}, 441 { .compatible = "intel,keembay-ssi", .data = dw_spi_intel_init}, 442 { 443 .compatible = "intel,mountevans-imc-ssi", 444 .data = dw_spi_mountevans_imc_init, 445 }, 446 { .compatible = "microchip,sparx5-spi", dw_spi_mscc_sparx5_init}, 447 { .compatible = "canaan,k210-spi", dw_spi_canaan_k210_init}, 448 { .compatible = "amd,pensando-elba-spi", .data = dw_spi_elba_init}, 449 { /* end of table */} 450 }; 451 MODULE_DEVICE_TABLE(of, dw_spi_mmio_of_match); 452 453 #ifdef CONFIG_ACPI 454 static const struct acpi_device_id dw_spi_mmio_acpi_match[] = { 455 {"HISI0173", (kernel_ulong_t)dw_spi_pssi_init}, 456 {}, 457 }; 458 MODULE_DEVICE_TABLE(acpi, dw_spi_mmio_acpi_match); 459 #endif 460 461 static struct platform_driver dw_spi_mmio_driver = { 462 .probe = dw_spi_mmio_probe, 463 .remove = dw_spi_mmio_remove, 464 .driver = { 465 .name = DRIVER_NAME, 466 .of_match_table = dw_spi_mmio_of_match, 467 .acpi_match_table = ACPI_PTR(dw_spi_mmio_acpi_match), 468 .pm = pm_sleep_ptr(&dw_spi_mmio_pm_ops), 469 }, 470 }; 471 module_platform_driver(dw_spi_mmio_driver); 472 473 MODULE_AUTHOR("Jean-Hugues Deschenes <jean-hugues.deschenes@octasic.com>"); 474 MODULE_DESCRIPTION("Memory-mapped I/O interface driver for DW SPI Core"); 475 MODULE_LICENSE("GPL v2"); 476 MODULE_IMPORT_NS("SPI_DW_CORE"); 477