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 512U 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 105struct amlogic_spifc_a1 { 106 struct spi_controller *ctrl; 107 struct clk *clk; 108 struct device *dev; 109 void __iomem *base; 110 u32 curr_speed_hz; 111}; 112 113static int amlogic_spifc_a1_request(struct amlogic_spifc_a1 *spifc, bool read) 114{ 115 u32 mask = SPIFC_A1_USER_REQUEST_FINISH | 116 (read ? SPIFC_A1_USER_DATA_UPDATED : 0); 117 u32 val; 118 119 writel(SPIFC_A1_USER_REQUEST_ENABLE, 120 spifc->base + SPIFC_A1_USER_CTRL0_REG); 121 122 return readl_poll_timeout(spifc->base + SPIFC_A1_USER_CTRL0_REG, 123 val, (val & mask) == mask, 0, 124 200 * USEC_PER_MSEC); 125} 126 127static void amlogic_spifc_a1_drain_buffer(struct amlogic_spifc_a1 *spifc, 128 char *buf, u32 len) 129{ 130 u32 data; 131 const u32 count = len / sizeof(data); 132 const u32 pad = len % sizeof(data); 133 134 writel(SPIFC_A1_DBUF_AUTO_UPDATE_ADDR, 135 spifc->base + SPIFC_A1_DBUF_CTRL_REG); 136 ioread32_rep(spifc->base + SPIFC_A1_DBUF_DATA_REG, buf, count); 137 138 if (pad) { 139 data = readl(spifc->base + SPIFC_A1_DBUF_DATA_REG); 140 memcpy(buf + len - pad, &data, pad); 141 } 142} 143 144static void amlogic_spifc_a1_fill_buffer(struct amlogic_spifc_a1 *spifc, 145 const char *buf, u32 len) 146{ 147 u32 data; 148 const u32 count = len / sizeof(data); 149 const u32 pad = len % sizeof(data); 150 151 writel(SPIFC_A1_DBUF_DIR | SPIFC_A1_DBUF_AUTO_UPDATE_ADDR, 152 spifc->base + SPIFC_A1_DBUF_CTRL_REG); 153 iowrite32_rep(spifc->base + SPIFC_A1_DBUF_DATA_REG, buf, count); 154 155 if (pad) { 156 memcpy(&data, buf + len - pad, pad); 157 writel(data, spifc->base + SPIFC_A1_DBUF_DATA_REG); 158 } 159} 160 161static void amlogic_spifc_a1_user_init(struct amlogic_spifc_a1 *spifc) 162{ 163 writel(0, spifc->base + SPIFC_A1_USER_CTRL0_REG); 164 writel(0, spifc->base + SPIFC_A1_USER_CTRL1_REG); 165 writel(0, spifc->base + SPIFC_A1_USER_CTRL2_REG); 166 writel(0, spifc->base + SPIFC_A1_USER_CTRL3_REG); 167} 168 169static void amlogic_spifc_a1_set_cmd(struct amlogic_spifc_a1 *spifc, 170 u32 cmd_cfg) 171{ 172 u32 val; 173 174 val = readl(spifc->base + SPIFC_A1_USER_CTRL1_REG); 175 val &= ~(SPIFC_A1_USER_CMD_MODE | SPIFC_A1_USER_CMD_CODE); 176 val |= cmd_cfg; 177 writel(val, spifc->base + SPIFC_A1_USER_CTRL1_REG); 178} 179 180static void amlogic_spifc_a1_set_addr(struct amlogic_spifc_a1 *spifc, u32 addr, 181 u32 addr_cfg) 182{ 183 u32 val; 184 185 writel(addr, spifc->base + SPIFC_A1_USER_ADDR_REG); 186 187 val = readl(spifc->base + SPIFC_A1_USER_CTRL1_REG); 188 val &= ~(SPIFC_A1_USER_ADDR_MODE | SPIFC_A1_USER_ADDR_BYTES); 189 val |= addr_cfg; 190 writel(val, spifc->base + SPIFC_A1_USER_CTRL1_REG); 191} 192 193static void amlogic_spifc_a1_set_dummy(struct amlogic_spifc_a1 *spifc, 194 u32 dummy_cfg) 195{ 196 u32 val = readl(spifc->base + SPIFC_A1_USER_CTRL2_REG); 197 198 val &= ~(SPIFC_A1_USER_DUMMY_MODE | SPIFC_A1_USER_DUMMY_CLK_SYCLES); 199 val |= dummy_cfg; 200 writel(val, spifc->base + SPIFC_A1_USER_CTRL2_REG); 201} 202 203static int amlogic_spifc_a1_read(struct amlogic_spifc_a1 *spifc, void *buf, 204 u32 size, u32 mode) 205{ 206 u32 val = readl(spifc->base + SPIFC_A1_USER_CTRL3_REG); 207 int ret; 208 209 val &= ~(SPIFC_A1_USER_DIN_MODE | SPIFC_A1_USER_DIN_BYTES); 210 val |= SPIFC_A1_USER_DIN_ENABLE; 211 val |= FIELD_PREP(SPIFC_A1_USER_DIN_MODE, mode); 212 val |= FIELD_PREP(SPIFC_A1_USER_DIN_BYTES, size); 213 writel(val, spifc->base + SPIFC_A1_USER_CTRL3_REG); 214 215 ret = amlogic_spifc_a1_request(spifc, true); 216 if (!ret) 217 amlogic_spifc_a1_drain_buffer(spifc, buf, size); 218 219 return ret; 220} 221 222static int amlogic_spifc_a1_write(struct amlogic_spifc_a1 *spifc, 223 const void *buf, u32 size, u32 mode) 224{ 225 u32 val; 226 227 amlogic_spifc_a1_fill_buffer(spifc, buf, size); 228 229 val = readl(spifc->base + SPIFC_A1_USER_CTRL1_REG); 230 val &= ~(SPIFC_A1_USER_DOUT_MODE | SPIFC_A1_USER_DOUT_BYTES); 231 val |= FIELD_PREP(SPIFC_A1_USER_DOUT_MODE, mode); 232 val |= FIELD_PREP(SPIFC_A1_USER_DOUT_BYTES, size); 233 val |= SPIFC_A1_USER_DOUT_ENABLE; 234 writel(val, spifc->base + SPIFC_A1_USER_CTRL1_REG); 235 236 return amlogic_spifc_a1_request(spifc, false); 237} 238 239static int amlogic_spifc_a1_set_freq(struct amlogic_spifc_a1 *spifc, u32 freq) 240{ 241 int ret; 242 243 if (freq == spifc->curr_speed_hz) 244 return 0; 245 246 ret = clk_set_rate(spifc->clk, freq); 247 if (ret) 248 return ret; 249 250 spifc->curr_speed_hz = freq; 251 return 0; 252} 253 254static int amlogic_spifc_a1_exec_op(struct spi_mem *mem, 255 const struct spi_mem_op *op) 256{ 257 struct amlogic_spifc_a1 *spifc = 258 spi_controller_get_devdata(mem->spi->controller); 259 size_t data_size = op->data.nbytes; 260 int ret; 261 262 ret = amlogic_spifc_a1_set_freq(spifc, mem->spi->max_speed_hz); 263 if (ret) 264 return ret; 265 266 amlogic_spifc_a1_user_init(spifc); 267 amlogic_spifc_a1_set_cmd(spifc, SPIFC_A1_USER_CMD(op)); 268 269 if (op->addr.nbytes) 270 amlogic_spifc_a1_set_addr(spifc, op->addr.val, 271 SPIFC_A1_USER_ADDR(op)); 272 273 if (op->dummy.nbytes) 274 amlogic_spifc_a1_set_dummy(spifc, SPIFC_A1_USER_DUMMY(op)); 275 276 if (data_size) { 277 u32 mode = ilog2(op->data.buswidth); 278 279 writel(0, spifc->base + SPIFC_A1_USER_DBUF_ADDR_REG); 280 281 if (op->data.dir == SPI_MEM_DATA_IN) 282 ret = amlogic_spifc_a1_read(spifc, op->data.buf.in, 283 data_size, mode); 284 else 285 ret = amlogic_spifc_a1_write(spifc, op->data.buf.out, 286 data_size, mode); 287 } else { 288 ret = amlogic_spifc_a1_request(spifc, false); 289 } 290 291 return ret; 292} 293 294static int amlogic_spifc_a1_adjust_op_size(struct spi_mem *mem, 295 struct spi_mem_op *op) 296{ 297 op->data.nbytes = min(op->data.nbytes, SPIFC_A1_BUFFER_SIZE); 298 return 0; 299} 300 301static void amlogic_spifc_a1_hw_init(struct amlogic_spifc_a1 *spifc) 302{ 303 u32 regv; 304 305 regv = readl(spifc->base + SPIFC_A1_AHB_REQ_CTRL_REG); 306 regv &= ~(SPIFC_A1_AHB_REQ_ENABLE); 307 writel(regv, spifc->base + SPIFC_A1_AHB_REQ_CTRL_REG); 308 309 regv = readl(spifc->base + SPIFC_A1_AHB_CTRL_REG); 310 regv &= ~(SPIFC_A1_AHB_BUS_EN); 311 writel(regv, spifc->base + SPIFC_A1_AHB_CTRL_REG); 312 313 writel(SPIFC_A1_ACTIMING0_VAL, spifc->base + SPIFC_A1_ACTIMING0_REG); 314 315 writel(0, spifc->base + SPIFC_A1_USER_DBUF_ADDR_REG); 316} 317 318static const struct spi_controller_mem_ops amlogic_spifc_a1_mem_ops = { 319 .exec_op = amlogic_spifc_a1_exec_op, 320 .adjust_op_size = amlogic_spifc_a1_adjust_op_size, 321}; 322 323static int amlogic_spifc_a1_probe(struct platform_device *pdev) 324{ 325 struct spi_controller *ctrl; 326 struct amlogic_spifc_a1 *spifc; 327 int ret; 328 329 ctrl = devm_spi_alloc_host(&pdev->dev, sizeof(*spifc)); 330 if (!ctrl) 331 return -ENOMEM; 332 333 spifc = spi_controller_get_devdata(ctrl); 334 platform_set_drvdata(pdev, spifc); 335 336 spifc->dev = &pdev->dev; 337 spifc->ctrl = ctrl; 338 339 spifc->base = devm_platform_ioremap_resource(pdev, 0); 340 if (IS_ERR(spifc->base)) 341 return PTR_ERR(spifc->base); 342 343 spifc->clk = devm_clk_get_enabled(spifc->dev, NULL); 344 if (IS_ERR(spifc->clk)) 345 return dev_err_probe(spifc->dev, PTR_ERR(spifc->clk), 346 "unable to get clock\n"); 347 348 amlogic_spifc_a1_hw_init(spifc); 349 350 pm_runtime_set_autosuspend_delay(spifc->dev, 500); 351 pm_runtime_use_autosuspend(spifc->dev); 352 devm_pm_runtime_enable(spifc->dev); 353 354 ctrl->num_chipselect = 1; 355 ctrl->dev.of_node = pdev->dev.of_node; 356 ctrl->bits_per_word_mask = SPI_BPW_MASK(8); 357 ctrl->auto_runtime_pm = true; 358 ctrl->mem_ops = &amlogic_spifc_a1_mem_ops; 359 ctrl->min_speed_hz = SPIFC_A1_MIN_HZ; 360 ctrl->max_speed_hz = SPIFC_A1_MAX_HZ; 361 ctrl->mode_bits = (SPI_RX_DUAL | SPI_TX_DUAL | 362 SPI_RX_QUAD | SPI_TX_QUAD); 363 364 ret = devm_spi_register_controller(spifc->dev, ctrl); 365 if (ret) 366 return dev_err_probe(spifc->dev, ret, 367 "failed to register spi controller\n"); 368 369 return 0; 370} 371 372#ifdef CONFIG_PM_SLEEP 373static int amlogic_spifc_a1_suspend(struct device *dev) 374{ 375 struct amlogic_spifc_a1 *spifc = dev_get_drvdata(dev); 376 int ret; 377 378 ret = spi_controller_suspend(spifc->ctrl); 379 if (ret) 380 return ret; 381 382 if (!pm_runtime_suspended(dev)) 383 clk_disable_unprepare(spifc->clk); 384 385 return 0; 386} 387 388static int amlogic_spifc_a1_resume(struct device *dev) 389{ 390 struct amlogic_spifc_a1 *spifc = dev_get_drvdata(dev); 391 int ret = 0; 392 393 if (!pm_runtime_suspended(dev)) { 394 ret = clk_prepare_enable(spifc->clk); 395 if (ret) 396 return ret; 397 } 398 399 amlogic_spifc_a1_hw_init(spifc); 400 401 ret = spi_controller_resume(spifc->ctrl); 402 if (ret) 403 clk_disable_unprepare(spifc->clk); 404 405 return ret; 406} 407#endif /* CONFIG_PM_SLEEP */ 408 409#ifdef CONFIG_PM 410static int amlogic_spifc_a1_runtime_suspend(struct device *dev) 411{ 412 struct amlogic_spifc_a1 *spifc = dev_get_drvdata(dev); 413 414 clk_disable_unprepare(spifc->clk); 415 416 return 0; 417} 418 419static int amlogic_spifc_a1_runtime_resume(struct device *dev) 420{ 421 struct amlogic_spifc_a1 *spifc = dev_get_drvdata(dev); 422 int ret; 423 424 ret = clk_prepare_enable(spifc->clk); 425 if (!ret) 426 amlogic_spifc_a1_hw_init(spifc); 427 428 return ret; 429} 430#endif /* CONFIG_PM */ 431 432static const struct dev_pm_ops amlogic_spifc_a1_pm_ops = { 433 SET_SYSTEM_SLEEP_PM_OPS(amlogic_spifc_a1_suspend, 434 amlogic_spifc_a1_resume) 435 SET_RUNTIME_PM_OPS(amlogic_spifc_a1_runtime_suspend, 436 amlogic_spifc_a1_runtime_resume, 437 NULL) 438}; 439 440#ifdef CONFIG_OF 441static const struct of_device_id amlogic_spifc_a1_dt_match[] = { 442 { .compatible = "amlogic,a1-spifc", }, 443 { }, 444}; 445MODULE_DEVICE_TABLE(of, amlogic_spifc_a1_dt_match); 446#endif /* CONFIG_OF */ 447 448static struct platform_driver amlogic_spifc_a1_driver = { 449 .probe = amlogic_spifc_a1_probe, 450 .driver = { 451 .name = "amlogic-spifc-a1", 452 .of_match_table = of_match_ptr(amlogic_spifc_a1_dt_match), 453 .pm = &amlogic_spifc_a1_pm_ops, 454 }, 455}; 456module_platform_driver(amlogic_spifc_a1_driver); 457 458MODULE_AUTHOR("Martin Kurbanov <mmkurbanov@sberdevices.ru>"); 459MODULE_DESCRIPTION("Amlogic A1 SPIFC driver"); 460MODULE_LICENSE("GPL"); 461