1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Driver for Amlogic A1 SPI flash controller (SPIFC) 4 * 5 * Copyright (c) 2023, SberDevices. All Rights Reserved. 6 * 7 * Author: Martin Kurbanov <mmkurbanov@sberdevices.ru> 8 */ 9 10 #include <linux/bitfield.h> 11 #include <linux/clk.h> 12 #include <linux/device.h> 13 #include <linux/io.h> 14 #include <linux/iopoll.h> 15 #include <linux/kernel.h> 16 #include <linux/module.h> 17 #include <linux/of.h> 18 #include <linux/platform_device.h> 19 #include <linux/pm_runtime.h> 20 #include <linux/spi/spi.h> 21 #include <linux/spi/spi-mem.h> 22 #include <linux/types.h> 23 24 #define SPIFC_A1_AHB_CTRL_REG 0x0 25 #define SPIFC_A1_AHB_BUS_EN BIT(31) 26 27 #define SPIFC_A1_USER_CTRL0_REG 0x200 28 #define SPIFC_A1_USER_REQUEST_ENABLE BIT(31) 29 #define SPIFC_A1_USER_REQUEST_FINISH BIT(30) 30 #define SPIFC_A1_USER_DATA_UPDATED BIT(0) 31 32 #define SPIFC_A1_USER_CTRL1_REG 0x204 33 #define SPIFC_A1_USER_CMD_ENABLE BIT(30) 34 #define SPIFC_A1_USER_CMD_MODE GENMASK(29, 28) 35 #define SPIFC_A1_USER_CMD_CODE GENMASK(27, 20) 36 #define SPIFC_A1_USER_ADDR_ENABLE BIT(19) 37 #define SPIFC_A1_USER_ADDR_MODE GENMASK(18, 17) 38 #define SPIFC_A1_USER_ADDR_BYTES GENMASK(16, 15) 39 #define SPIFC_A1_USER_DOUT_ENABLE BIT(14) 40 #define SPIFC_A1_USER_DOUT_MODE GENMASK(11, 10) 41 #define SPIFC_A1_USER_DOUT_BYTES GENMASK(9, 0) 42 43 #define SPIFC_A1_USER_CTRL2_REG 0x208 44 #define SPIFC_A1_USER_DUMMY_ENABLE BIT(31) 45 #define SPIFC_A1_USER_DUMMY_MODE GENMASK(30, 29) 46 #define SPIFC_A1_USER_DUMMY_CLK_SYCLES GENMASK(28, 23) 47 48 #define SPIFC_A1_USER_CTRL3_REG 0x20c 49 #define SPIFC_A1_USER_DIN_ENABLE BIT(31) 50 #define SPIFC_A1_USER_DIN_MODE GENMASK(28, 27) 51 #define SPIFC_A1_USER_DIN_BYTES GENMASK(25, 16) 52 53 #define SPIFC_A1_USER_ADDR_REG 0x210 54 55 #define SPIFC_A1_AHB_REQ_CTRL_REG 0x214 56 #define SPIFC_A1_AHB_REQ_ENABLE BIT(31) 57 58 #define SPIFC_A1_ACTIMING0_REG (0x0088 << 2) 59 #define SPIFC_A1_TSLCH GENMASK(31, 30) 60 #define SPIFC_A1_TCLSH GENMASK(29, 28) 61 #define SPIFC_A1_TSHWL GENMASK(20, 16) 62 #define SPIFC_A1_TSHSL2 GENMASK(15, 12) 63 #define SPIFC_A1_TSHSL1 GENMASK(11, 8) 64 #define SPIFC_A1_TWHSL GENMASK(7, 0) 65 66 #define SPIFC_A1_DBUF_CTRL_REG 0x240 67 #define SPIFC_A1_DBUF_DIR BIT(31) 68 #define SPIFC_A1_DBUF_AUTO_UPDATE_ADDR BIT(30) 69 #define SPIFC_A1_DBUF_ADDR GENMASK(7, 0) 70 71 #define SPIFC_A1_DBUF_DATA_REG 0x244 72 73 #define SPIFC_A1_USER_DBUF_ADDR_REG 0x248 74 75 #define SPIFC_A1_BUFFER_SIZE 512 76 77 #define SPIFC_A1_MAX_HZ 200000000 78 #define SPIFC_A1_MIN_HZ 1000000 79 80 #define SPIFC_A1_USER_CMD(op) ( \ 81 SPIFC_A1_USER_CMD_ENABLE | \ 82 FIELD_PREP(SPIFC_A1_USER_CMD_CODE, (op)->cmd.opcode) | \ 83 FIELD_PREP(SPIFC_A1_USER_CMD_MODE, ilog2((op)->cmd.buswidth))) 84 85 #define SPIFC_A1_USER_ADDR(op) ( \ 86 SPIFC_A1_USER_ADDR_ENABLE | \ 87 FIELD_PREP(SPIFC_A1_USER_ADDR_MODE, ilog2((op)->addr.buswidth)) | \ 88 FIELD_PREP(SPIFC_A1_USER_ADDR_BYTES, (op)->addr.nbytes - 1)) 89 90 #define SPIFC_A1_USER_DUMMY(op) ( \ 91 SPIFC_A1_USER_DUMMY_ENABLE | \ 92 FIELD_PREP(SPIFC_A1_USER_DUMMY_MODE, ilog2((op)->dummy.buswidth)) | \ 93 FIELD_PREP(SPIFC_A1_USER_DUMMY_CLK_SYCLES, (op)->dummy.nbytes << 3)) 94 95 #define SPIFC_A1_TSLCH_VAL FIELD_PREP(SPIFC_A1_TSLCH, 1) 96 #define SPIFC_A1_TCLSH_VAL FIELD_PREP(SPIFC_A1_TCLSH, 1) 97 #define SPIFC_A1_TSHWL_VAL FIELD_PREP(SPIFC_A1_TSHWL, 7) 98 #define SPIFC_A1_TSHSL2_VAL FIELD_PREP(SPIFC_A1_TSHSL2, 7) 99 #define SPIFC_A1_TSHSL1_VAL FIELD_PREP(SPIFC_A1_TSHSL1, 7) 100 #define SPIFC_A1_TWHSL_VAL FIELD_PREP(SPIFC_A1_TWHSL, 2) 101 #define SPIFC_A1_ACTIMING0_VAL (SPIFC_A1_TSLCH_VAL | SPIFC_A1_TCLSH_VAL | \ 102 SPIFC_A1_TSHWL_VAL | SPIFC_A1_TSHSL2_VAL | \ 103 SPIFC_A1_TSHSL1_VAL | SPIFC_A1_TWHSL_VAL) 104 105 struct amlogic_spifc_a1 { 106 struct spi_controller *ctrl; 107 struct clk *clk; 108 struct device *dev; 109 void __iomem *base; 110 }; 111 112 static int amlogic_spifc_a1_request(struct amlogic_spifc_a1 *spifc, bool read) 113 { 114 u32 mask = SPIFC_A1_USER_REQUEST_FINISH | 115 (read ? SPIFC_A1_USER_DATA_UPDATED : 0); 116 u32 val; 117 118 writel(SPIFC_A1_USER_REQUEST_ENABLE, 119 spifc->base + SPIFC_A1_USER_CTRL0_REG); 120 121 return readl_poll_timeout(spifc->base + SPIFC_A1_USER_CTRL0_REG, 122 val, (val & mask) == mask, 0, 123 200 * USEC_PER_MSEC); 124 } 125 126 static void amlogic_spifc_a1_drain_buffer(struct amlogic_spifc_a1 *spifc, 127 char *buf, u32 len) 128 { 129 u32 data; 130 const u32 count = len / sizeof(data); 131 const u32 pad = len % sizeof(data); 132 133 writel(SPIFC_A1_DBUF_AUTO_UPDATE_ADDR, 134 spifc->base + SPIFC_A1_DBUF_CTRL_REG); 135 ioread32_rep(spifc->base + SPIFC_A1_DBUF_DATA_REG, buf, count); 136 137 if (pad) { 138 data = readl(spifc->base + SPIFC_A1_DBUF_DATA_REG); 139 memcpy(buf + len - pad, &data, pad); 140 } 141 } 142 143 static void amlogic_spifc_a1_fill_buffer(struct amlogic_spifc_a1 *spifc, 144 const char *buf, u32 len) 145 { 146 u32 data; 147 const u32 count = len / sizeof(data); 148 const u32 pad = len % sizeof(data); 149 150 writel(SPIFC_A1_DBUF_DIR | SPIFC_A1_DBUF_AUTO_UPDATE_ADDR, 151 spifc->base + SPIFC_A1_DBUF_CTRL_REG); 152 iowrite32_rep(spifc->base + SPIFC_A1_DBUF_DATA_REG, buf, count); 153 154 if (pad) { 155 memcpy(&data, buf + len - pad, pad); 156 writel(data, spifc->base + SPIFC_A1_DBUF_DATA_REG); 157 } 158 } 159 160 static void amlogic_spifc_a1_user_init(struct amlogic_spifc_a1 *spifc) 161 { 162 writel(0, spifc->base + SPIFC_A1_USER_CTRL0_REG); 163 writel(0, spifc->base + SPIFC_A1_USER_CTRL1_REG); 164 writel(0, spifc->base + SPIFC_A1_USER_CTRL2_REG); 165 writel(0, spifc->base + SPIFC_A1_USER_CTRL3_REG); 166 } 167 168 static void amlogic_spifc_a1_set_cmd(struct amlogic_spifc_a1 *spifc, 169 u32 cmd_cfg) 170 { 171 u32 val; 172 173 val = readl(spifc->base + SPIFC_A1_USER_CTRL1_REG); 174 val &= ~(SPIFC_A1_USER_CMD_MODE | SPIFC_A1_USER_CMD_CODE); 175 val |= cmd_cfg; 176 writel(val, spifc->base + SPIFC_A1_USER_CTRL1_REG); 177 } 178 179 static void amlogic_spifc_a1_set_addr(struct amlogic_spifc_a1 *spifc, u32 addr, 180 u32 addr_cfg) 181 { 182 u32 val; 183 184 writel(addr, spifc->base + SPIFC_A1_USER_ADDR_REG); 185 186 val = readl(spifc->base + SPIFC_A1_USER_CTRL1_REG); 187 val &= ~(SPIFC_A1_USER_ADDR_MODE | SPIFC_A1_USER_ADDR_BYTES); 188 val |= addr_cfg; 189 writel(val, spifc->base + SPIFC_A1_USER_CTRL1_REG); 190 } 191 192 static void amlogic_spifc_a1_set_dummy(struct amlogic_spifc_a1 *spifc, 193 u32 dummy_cfg) 194 { 195 u32 val = readl(spifc->base + SPIFC_A1_USER_CTRL2_REG); 196 197 val &= ~(SPIFC_A1_USER_DUMMY_MODE | SPIFC_A1_USER_DUMMY_CLK_SYCLES); 198 val |= dummy_cfg; 199 writel(val, spifc->base + SPIFC_A1_USER_CTRL2_REG); 200 } 201 202 static int amlogic_spifc_a1_read(struct amlogic_spifc_a1 *spifc, void *buf, 203 u32 size, u32 mode) 204 { 205 u32 val = readl(spifc->base + SPIFC_A1_USER_CTRL3_REG); 206 int ret; 207 208 val &= ~(SPIFC_A1_USER_DIN_MODE | SPIFC_A1_USER_DIN_BYTES); 209 val |= SPIFC_A1_USER_DIN_ENABLE; 210 val |= FIELD_PREP(SPIFC_A1_USER_DIN_MODE, mode); 211 val |= FIELD_PREP(SPIFC_A1_USER_DIN_BYTES, size); 212 writel(val, spifc->base + SPIFC_A1_USER_CTRL3_REG); 213 214 ret = amlogic_spifc_a1_request(spifc, true); 215 if (!ret) 216 amlogic_spifc_a1_drain_buffer(spifc, buf, size); 217 218 return ret; 219 } 220 221 static int amlogic_spifc_a1_write(struct amlogic_spifc_a1 *spifc, 222 const void *buf, u32 size, u32 mode) 223 { 224 u32 val; 225 226 amlogic_spifc_a1_fill_buffer(spifc, buf, size); 227 228 val = readl(spifc->base + SPIFC_A1_USER_CTRL1_REG); 229 val &= ~(SPIFC_A1_USER_DOUT_MODE | SPIFC_A1_USER_DOUT_BYTES); 230 val |= FIELD_PREP(SPIFC_A1_USER_DOUT_MODE, mode); 231 val |= FIELD_PREP(SPIFC_A1_USER_DOUT_BYTES, size); 232 val |= SPIFC_A1_USER_DOUT_ENABLE; 233 writel(val, spifc->base + SPIFC_A1_USER_CTRL1_REG); 234 235 return amlogic_spifc_a1_request(spifc, false); 236 } 237 238 static int amlogic_spifc_a1_exec_op(struct spi_mem *mem, 239 const struct spi_mem_op *op) 240 { 241 struct amlogic_spifc_a1 *spifc = 242 spi_controller_get_devdata(mem->spi->controller); 243 size_t off, nbytes = op->data.nbytes; 244 u32 cmd_cfg, addr_cfg, dummy_cfg, dmode; 245 int ret; 246 247 amlogic_spifc_a1_user_init(spifc); 248 249 cmd_cfg = SPIFC_A1_USER_CMD(op); 250 amlogic_spifc_a1_set_cmd(spifc, cmd_cfg); 251 252 if (op->addr.nbytes) { 253 addr_cfg = SPIFC_A1_USER_ADDR(op); 254 amlogic_spifc_a1_set_addr(spifc, op->addr.val, addr_cfg); 255 } 256 257 if (op->dummy.nbytes) { 258 dummy_cfg = SPIFC_A1_USER_DUMMY(op); 259 amlogic_spifc_a1_set_dummy(spifc, dummy_cfg); 260 } 261 262 if (!op->data.nbytes) 263 return amlogic_spifc_a1_request(spifc, false); 264 265 dmode = ilog2(op->data.buswidth); 266 off = 0; 267 268 do { 269 size_t block_size = min_t(size_t, nbytes, SPIFC_A1_BUFFER_SIZE); 270 271 amlogic_spifc_a1_set_cmd(spifc, cmd_cfg); 272 273 if (op->addr.nbytes) 274 amlogic_spifc_a1_set_addr(spifc, op->addr.val + off, 275 addr_cfg); 276 277 if (op->dummy.nbytes) 278 amlogic_spifc_a1_set_dummy(spifc, dummy_cfg); 279 280 writel(0, spifc->base + SPIFC_A1_USER_DBUF_ADDR_REG); 281 282 if (op->data.dir == SPI_MEM_DATA_IN) 283 ret = amlogic_spifc_a1_read(spifc, 284 op->data.buf.in + off, 285 block_size, dmode); 286 else 287 ret = amlogic_spifc_a1_write(spifc, 288 op->data.buf.out + off, 289 block_size, dmode); 290 291 nbytes -= block_size; 292 off += block_size; 293 } while (nbytes != 0 && !ret); 294 295 return ret; 296 } 297 298 static void amlogic_spifc_a1_hw_init(struct amlogic_spifc_a1 *spifc) 299 { 300 u32 regv; 301 302 regv = readl(spifc->base + SPIFC_A1_AHB_REQ_CTRL_REG); 303 regv &= ~(SPIFC_A1_AHB_REQ_ENABLE); 304 writel(regv, spifc->base + SPIFC_A1_AHB_REQ_CTRL_REG); 305 306 regv = readl(spifc->base + SPIFC_A1_AHB_CTRL_REG); 307 regv &= ~(SPIFC_A1_AHB_BUS_EN); 308 writel(regv, spifc->base + SPIFC_A1_AHB_CTRL_REG); 309 310 writel(SPIFC_A1_ACTIMING0_VAL, spifc->base + SPIFC_A1_ACTIMING0_REG); 311 312 writel(0, spifc->base + SPIFC_A1_USER_DBUF_ADDR_REG); 313 } 314 315 static const struct spi_controller_mem_ops amlogic_spifc_a1_mem_ops = { 316 .exec_op = amlogic_spifc_a1_exec_op, 317 }; 318 319 static int amlogic_spifc_a1_probe(struct platform_device *pdev) 320 { 321 struct spi_controller *ctrl; 322 struct amlogic_spifc_a1 *spifc; 323 int ret; 324 325 ctrl = devm_spi_alloc_master(&pdev->dev, sizeof(*spifc)); 326 if (!ctrl) 327 return -ENOMEM; 328 329 spifc = spi_controller_get_devdata(ctrl); 330 platform_set_drvdata(pdev, spifc); 331 332 spifc->dev = &pdev->dev; 333 spifc->ctrl = ctrl; 334 335 spifc->base = devm_platform_ioremap_resource(pdev, 0); 336 if (IS_ERR(spifc->base)) 337 return PTR_ERR(spifc->base); 338 339 spifc->clk = devm_clk_get_enabled(spifc->dev, NULL); 340 if (IS_ERR(spifc->clk)) 341 return dev_err_probe(spifc->dev, PTR_ERR(spifc->clk), 342 "unable to get clock\n"); 343 344 amlogic_spifc_a1_hw_init(spifc); 345 346 pm_runtime_set_autosuspend_delay(spifc->dev, 500); 347 pm_runtime_use_autosuspend(spifc->dev); 348 devm_pm_runtime_enable(spifc->dev); 349 350 ctrl->num_chipselect = 1; 351 ctrl->dev.of_node = pdev->dev.of_node; 352 ctrl->bits_per_word_mask = SPI_BPW_MASK(8); 353 ctrl->auto_runtime_pm = true; 354 ctrl->mem_ops = &amlogic_spifc_a1_mem_ops; 355 ctrl->min_speed_hz = SPIFC_A1_MIN_HZ; 356 ctrl->max_speed_hz = SPIFC_A1_MAX_HZ; 357 ctrl->mode_bits = (SPI_RX_DUAL | SPI_TX_DUAL | 358 SPI_RX_QUAD | SPI_TX_QUAD); 359 360 ret = devm_spi_register_controller(spifc->dev, ctrl); 361 if (ret) 362 return dev_err_probe(spifc->dev, ret, 363 "failed to register spi controller\n"); 364 365 return 0; 366 } 367 368 #ifdef CONFIG_PM_SLEEP 369 static int amlogic_spifc_a1_suspend(struct device *dev) 370 { 371 struct amlogic_spifc_a1 *spifc = dev_get_drvdata(dev); 372 int ret; 373 374 ret = spi_controller_suspend(spifc->ctrl); 375 if (ret) 376 return ret; 377 378 if (!pm_runtime_suspended(dev)) 379 clk_disable_unprepare(spifc->clk); 380 381 return 0; 382 } 383 384 static int amlogic_spifc_a1_resume(struct device *dev) 385 { 386 struct amlogic_spifc_a1 *spifc = dev_get_drvdata(dev); 387 int ret = 0; 388 389 if (!pm_runtime_suspended(dev)) { 390 ret = clk_prepare_enable(spifc->clk); 391 if (ret) 392 return ret; 393 } 394 395 amlogic_spifc_a1_hw_init(spifc); 396 397 ret = spi_controller_resume(spifc->ctrl); 398 if (ret) 399 clk_disable_unprepare(spifc->clk); 400 401 return ret; 402 } 403 #endif /* CONFIG_PM_SLEEP */ 404 405 #ifdef CONFIG_PM 406 static int amlogic_spifc_a1_runtime_suspend(struct device *dev) 407 { 408 struct amlogic_spifc_a1 *spifc = dev_get_drvdata(dev); 409 410 clk_disable_unprepare(spifc->clk); 411 412 return 0; 413 } 414 415 static int amlogic_spifc_a1_runtime_resume(struct device *dev) 416 { 417 struct amlogic_spifc_a1 *spifc = dev_get_drvdata(dev); 418 int ret; 419 420 ret = clk_prepare_enable(spifc->clk); 421 if (!ret) 422 amlogic_spifc_a1_hw_init(spifc); 423 424 return ret; 425 } 426 #endif /* CONFIG_PM */ 427 428 static const struct dev_pm_ops amlogic_spifc_a1_pm_ops = { 429 SET_SYSTEM_SLEEP_PM_OPS(amlogic_spifc_a1_suspend, 430 amlogic_spifc_a1_resume) 431 SET_RUNTIME_PM_OPS(amlogic_spifc_a1_runtime_suspend, 432 amlogic_spifc_a1_runtime_resume, 433 NULL) 434 }; 435 436 #ifdef CONFIG_OF 437 static const struct of_device_id amlogic_spifc_a1_dt_match[] = { 438 { .compatible = "amlogic,a1-spifc", }, 439 { }, 440 }; 441 MODULE_DEVICE_TABLE(of, amlogic_spifc_a1_dt_match); 442 #endif /* CONFIG_OF */ 443 444 static struct platform_driver amlogic_spifc_a1_driver = { 445 .probe = amlogic_spifc_a1_probe, 446 .driver = { 447 .name = "amlogic-spifc-a1", 448 .of_match_table = of_match_ptr(amlogic_spifc_a1_dt_match), 449 .pm = &amlogic_spifc_a1_pm_ops, 450 }, 451 }; 452 module_platform_driver(amlogic_spifc_a1_driver); 453 454 MODULE_AUTHOR("Martin Kurbanov <mmkurbanov@sberdevices.ru>"); 455 MODULE_DESCRIPTION("Amlogic A1 SPIFC driver"); 456 MODULE_LICENSE("GPL"); 457