1 /* 2 * Driver for Amlogic Meson SPI flash controller (SPIFC) 3 * 4 * Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com> 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * version 2 as published by the Free Software Foundation. 9 * 10 * You should have received a copy of the GNU General Public License 11 * along with this program. If not, see <http://www.gnu.org/licenses/>. 12 */ 13 14 #include <linux/clk.h> 15 #include <linux/delay.h> 16 #include <linux/device.h> 17 #include <linux/io.h> 18 #include <linux/kernel.h> 19 #include <linux/module.h> 20 #include <linux/of.h> 21 #include <linux/platform_device.h> 22 #include <linux/pm_runtime.h> 23 #include <linux/regmap.h> 24 #include <linux/spi/spi.h> 25 #include <linux/types.h> 26 27 /* register map */ 28 #define REG_CMD 0x00 29 #define REG_ADDR 0x04 30 #define REG_CTRL 0x08 31 #define REG_CTRL1 0x0c 32 #define REG_STATUS 0x10 33 #define REG_CTRL2 0x14 34 #define REG_CLOCK 0x18 35 #define REG_USER 0x1c 36 #define REG_USER1 0x20 37 #define REG_USER2 0x24 38 #define REG_USER3 0x28 39 #define REG_USER4 0x2c 40 #define REG_SLAVE 0x30 41 #define REG_SLAVE1 0x34 42 #define REG_SLAVE2 0x38 43 #define REG_SLAVE3 0x3c 44 #define REG_C0 0x40 45 #define REG_B8 0x60 46 #define REG_MAX 0x7c 47 48 /* register fields */ 49 #define CMD_USER BIT(18) 50 #define CTRL_ENABLE_AHB BIT(17) 51 #define CLOCK_SOURCE BIT(31) 52 #define CLOCK_DIV_SHIFT 12 53 #define CLOCK_DIV_MASK (0x3f << CLOCK_DIV_SHIFT) 54 #define CLOCK_CNT_HIGH_SHIFT 6 55 #define CLOCK_CNT_HIGH_MASK (0x3f << CLOCK_CNT_HIGH_SHIFT) 56 #define CLOCK_CNT_LOW_SHIFT 0 57 #define CLOCK_CNT_LOW_MASK (0x3f << CLOCK_CNT_LOW_SHIFT) 58 #define USER_DIN_EN_MS BIT(0) 59 #define USER_CMP_MODE BIT(2) 60 #define USER_UC_DOUT_SEL BIT(27) 61 #define USER_UC_DIN_SEL BIT(28) 62 #define USER_UC_MASK ((BIT(5) - 1) << 27) 63 #define USER1_BN_UC_DOUT_SHIFT 17 64 #define USER1_BN_UC_DOUT_MASK (0xff << 16) 65 #define USER1_BN_UC_DIN_SHIFT 8 66 #define USER1_BN_UC_DIN_MASK (0xff << 8) 67 #define USER4_CS_ACT BIT(30) 68 #define SLAVE_TRST_DONE BIT(4) 69 #define SLAVE_OP_MODE BIT(30) 70 #define SLAVE_SW_RST BIT(31) 71 72 #define SPIFC_BUFFER_SIZE 64 73 74 /** 75 * struct meson_spifc 76 * @master: the SPI master 77 * @regmap: regmap for device registers 78 * @clk: input clock of the built-in baud rate generator 79 * @device: the device structure 80 */ 81 struct meson_spifc { 82 struct spi_master *master; 83 struct regmap *regmap; 84 struct clk *clk; 85 struct device *dev; 86 }; 87 88 static const struct regmap_config spifc_regmap_config = { 89 .reg_bits = 32, 90 .val_bits = 32, 91 .reg_stride = 4, 92 .max_register = REG_MAX, 93 }; 94 95 /** 96 * meson_spifc_wait_ready() - wait for the current operation to terminate 97 * @spifc: the Meson SPI device 98 * Return: 0 on success, a negative value on error 99 */ 100 static int meson_spifc_wait_ready(struct meson_spifc *spifc) 101 { 102 unsigned long deadline = jiffies + msecs_to_jiffies(5); 103 u32 data; 104 105 do { 106 regmap_read(spifc->regmap, REG_SLAVE, &data); 107 if (data & SLAVE_TRST_DONE) 108 return 0; 109 cond_resched(); 110 } while (!time_after(jiffies, deadline)); 111 112 return -ETIMEDOUT; 113 } 114 115 /** 116 * meson_spifc_drain_buffer() - copy data from device buffer to memory 117 * @spifc: the Meson SPI device 118 * @buf: the destination buffer 119 * @len: number of bytes to copy 120 */ 121 static void meson_spifc_drain_buffer(struct meson_spifc *spifc, u8 *buf, 122 int len) 123 { 124 u32 data; 125 int i = 0; 126 127 while (i < len) { 128 regmap_read(spifc->regmap, REG_C0 + i, &data); 129 130 if (len - i >= 4) { 131 *((u32 *)buf) = data; 132 buf += 4; 133 } else { 134 memcpy(buf, &data, len - i); 135 break; 136 } 137 i += 4; 138 } 139 } 140 141 /** 142 * meson_spifc_fill_buffer() - copy data from memory to device buffer 143 * @spifc: the Meson SPI device 144 * @buf: the source buffer 145 * @len: number of bytes to copy 146 */ 147 static void meson_spifc_fill_buffer(struct meson_spifc *spifc, const u8 *buf, 148 int len) 149 { 150 u32 data; 151 int i = 0; 152 153 while (i < len) { 154 if (len - i >= 4) 155 data = *(u32 *)buf; 156 else 157 memcpy(&data, buf, len - i); 158 159 regmap_write(spifc->regmap, REG_C0 + i, data); 160 161 buf += 4; 162 i += 4; 163 } 164 } 165 166 /** 167 * meson_spifc_setup_speed() - program the clock divider 168 * @spifc: the Meson SPI device 169 * @speed: desired speed in Hz 170 */ 171 static void meson_spifc_setup_speed(struct meson_spifc *spifc, u32 speed) 172 { 173 unsigned long parent, value; 174 int n; 175 176 parent = clk_get_rate(spifc->clk); 177 n = max_t(int, parent / speed - 1, 1); 178 179 dev_dbg(spifc->dev, "parent %lu, speed %u, n %d\n", parent, 180 speed, n); 181 182 value = (n << CLOCK_DIV_SHIFT) & CLOCK_DIV_MASK; 183 value |= (n << CLOCK_CNT_LOW_SHIFT) & CLOCK_CNT_LOW_MASK; 184 value |= (((n + 1) / 2 - 1) << CLOCK_CNT_HIGH_SHIFT) & 185 CLOCK_CNT_HIGH_MASK; 186 187 regmap_write(spifc->regmap, REG_CLOCK, value); 188 } 189 190 /** 191 * meson_spifc_txrx() - transfer a chunk of data 192 * @spifc: the Meson SPI device 193 * @xfer: the current SPI transfer 194 * @offset: offset of the data to transfer 195 * @len: length of the data to transfer 196 * @last_xfer: whether this is the last transfer of the message 197 * @last_chunk: whether this is the last chunk of the transfer 198 * Return: 0 on success, a negative value on error 199 */ 200 static int meson_spifc_txrx(struct meson_spifc *spifc, 201 struct spi_transfer *xfer, 202 int offset, int len, bool last_xfer, 203 bool last_chunk) 204 { 205 bool keep_cs = true; 206 int ret; 207 208 if (xfer->tx_buf) 209 meson_spifc_fill_buffer(spifc, xfer->tx_buf + offset, len); 210 211 /* enable DOUT stage */ 212 regmap_update_bits(spifc->regmap, REG_USER, USER_UC_MASK, 213 USER_UC_DOUT_SEL); 214 regmap_write(spifc->regmap, REG_USER1, 215 (8 * len - 1) << USER1_BN_UC_DOUT_SHIFT); 216 217 /* enable data input during DOUT */ 218 regmap_update_bits(spifc->regmap, REG_USER, USER_DIN_EN_MS, 219 USER_DIN_EN_MS); 220 221 if (last_chunk) { 222 if (last_xfer) 223 keep_cs = xfer->cs_change; 224 else 225 keep_cs = !xfer->cs_change; 226 } 227 228 regmap_update_bits(spifc->regmap, REG_USER4, USER4_CS_ACT, 229 keep_cs ? USER4_CS_ACT : 0); 230 231 /* clear transition done bit */ 232 regmap_update_bits(spifc->regmap, REG_SLAVE, SLAVE_TRST_DONE, 0); 233 /* start transfer */ 234 regmap_update_bits(spifc->regmap, REG_CMD, CMD_USER, CMD_USER); 235 236 ret = meson_spifc_wait_ready(spifc); 237 238 if (!ret && xfer->rx_buf) 239 meson_spifc_drain_buffer(spifc, xfer->rx_buf + offset, len); 240 241 return ret; 242 } 243 244 /** 245 * meson_spifc_transfer_one() - perform a single transfer 246 * @master: the SPI master 247 * @spi: the SPI device 248 * @xfer: the current SPI transfer 249 * Return: 0 on success, a negative value on error 250 */ 251 static int meson_spifc_transfer_one(struct spi_master *master, 252 struct spi_device *spi, 253 struct spi_transfer *xfer) 254 { 255 struct meson_spifc *spifc = spi_master_get_devdata(master); 256 int len, done = 0, ret = 0; 257 258 meson_spifc_setup_speed(spifc, xfer->speed_hz); 259 260 regmap_update_bits(spifc->regmap, REG_CTRL, CTRL_ENABLE_AHB, 0); 261 262 while (done < xfer->len && !ret) { 263 len = min_t(int, xfer->len - done, SPIFC_BUFFER_SIZE); 264 ret = meson_spifc_txrx(spifc, xfer, done, len, 265 spi_transfer_is_last(master, xfer), 266 done + len >= xfer->len); 267 done += len; 268 } 269 270 regmap_update_bits(spifc->regmap, REG_CTRL, CTRL_ENABLE_AHB, 271 CTRL_ENABLE_AHB); 272 273 return ret; 274 } 275 276 /** 277 * meson_spifc_hw_init() - reset and initialize the SPI controller 278 * @spifc: the Meson SPI device 279 */ 280 static void meson_spifc_hw_init(struct meson_spifc *spifc) 281 { 282 /* reset device */ 283 regmap_update_bits(spifc->regmap, REG_SLAVE, SLAVE_SW_RST, 284 SLAVE_SW_RST); 285 /* disable compatible mode */ 286 regmap_update_bits(spifc->regmap, REG_USER, USER_CMP_MODE, 0); 287 /* set master mode */ 288 regmap_update_bits(spifc->regmap, REG_SLAVE, SLAVE_OP_MODE, 0); 289 } 290 291 static int meson_spifc_probe(struct platform_device *pdev) 292 { 293 struct spi_master *master; 294 struct meson_spifc *spifc; 295 struct resource *res; 296 void __iomem *base; 297 unsigned int rate; 298 int ret = 0; 299 300 master = spi_alloc_master(&pdev->dev, sizeof(struct meson_spifc)); 301 if (!master) 302 return -ENOMEM; 303 304 platform_set_drvdata(pdev, master); 305 306 spifc = spi_master_get_devdata(master); 307 spifc->dev = &pdev->dev; 308 309 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 310 base = devm_ioremap_resource(spifc->dev, res); 311 if (IS_ERR(base)) { 312 ret = PTR_ERR(base); 313 goto out_err; 314 } 315 316 spifc->regmap = devm_regmap_init_mmio(spifc->dev, base, 317 &spifc_regmap_config); 318 if (IS_ERR(spifc->regmap)) { 319 ret = PTR_ERR(spifc->regmap); 320 goto out_err; 321 } 322 323 spifc->clk = devm_clk_get(spifc->dev, NULL); 324 if (IS_ERR(spifc->clk)) { 325 dev_err(spifc->dev, "missing clock\n"); 326 ret = PTR_ERR(spifc->clk); 327 goto out_err; 328 } 329 330 ret = clk_prepare_enable(spifc->clk); 331 if (ret) { 332 dev_err(spifc->dev, "can't prepare clock\n"); 333 goto out_err; 334 } 335 336 rate = clk_get_rate(spifc->clk); 337 338 master->num_chipselect = 1; 339 master->dev.of_node = pdev->dev.of_node; 340 master->bits_per_word_mask = SPI_BPW_MASK(8); 341 master->auto_runtime_pm = true; 342 master->transfer_one = meson_spifc_transfer_one; 343 master->min_speed_hz = rate >> 6; 344 master->max_speed_hz = rate >> 1; 345 346 meson_spifc_hw_init(spifc); 347 348 pm_runtime_set_active(spifc->dev); 349 pm_runtime_enable(spifc->dev); 350 351 ret = devm_spi_register_master(spifc->dev, master); 352 if (ret) { 353 dev_err(spifc->dev, "failed to register spi master\n"); 354 goto out_clk; 355 } 356 357 return 0; 358 out_clk: 359 clk_disable_unprepare(spifc->clk); 360 out_err: 361 spi_master_put(master); 362 return ret; 363 } 364 365 static int meson_spifc_remove(struct platform_device *pdev) 366 { 367 struct spi_master *master = platform_get_drvdata(pdev); 368 struct meson_spifc *spifc = spi_master_get_devdata(master); 369 370 pm_runtime_get_sync(&pdev->dev); 371 clk_disable_unprepare(spifc->clk); 372 pm_runtime_disable(&pdev->dev); 373 374 return 0; 375 } 376 377 #ifdef CONFIG_PM_SLEEP 378 static int meson_spifc_suspend(struct device *dev) 379 { 380 struct spi_master *master = dev_get_drvdata(dev); 381 struct meson_spifc *spifc = spi_master_get_devdata(master); 382 int ret; 383 384 ret = spi_master_suspend(master); 385 if (ret) 386 return ret; 387 388 if (!pm_runtime_suspended(dev)) 389 clk_disable_unprepare(spifc->clk); 390 391 return 0; 392 } 393 394 static int meson_spifc_resume(struct device *dev) 395 { 396 struct spi_master *master = dev_get_drvdata(dev); 397 struct meson_spifc *spifc = spi_master_get_devdata(master); 398 int ret; 399 400 if (!pm_runtime_suspended(dev)) { 401 ret = clk_prepare_enable(spifc->clk); 402 if (ret) 403 return ret; 404 } 405 406 meson_spifc_hw_init(spifc); 407 408 ret = spi_master_resume(master); 409 if (ret) 410 clk_disable_unprepare(spifc->clk); 411 412 return ret; 413 } 414 #endif /* CONFIG_PM_SLEEP */ 415 416 #ifdef CONFIG_PM 417 static int meson_spifc_runtime_suspend(struct device *dev) 418 { 419 struct spi_master *master = dev_get_drvdata(dev); 420 struct meson_spifc *spifc = spi_master_get_devdata(master); 421 422 clk_disable_unprepare(spifc->clk); 423 424 return 0; 425 } 426 427 static int meson_spifc_runtime_resume(struct device *dev) 428 { 429 struct spi_master *master = dev_get_drvdata(dev); 430 struct meson_spifc *spifc = spi_master_get_devdata(master); 431 432 return clk_prepare_enable(spifc->clk); 433 } 434 #endif /* CONFIG_PM */ 435 436 static const struct dev_pm_ops meson_spifc_pm_ops = { 437 SET_SYSTEM_SLEEP_PM_OPS(meson_spifc_suspend, meson_spifc_resume) 438 SET_RUNTIME_PM_OPS(meson_spifc_runtime_suspend, 439 meson_spifc_runtime_resume, 440 NULL) 441 }; 442 443 static const struct of_device_id meson_spifc_dt_match[] = { 444 { .compatible = "amlogic,meson6-spifc", }, 445 { }, 446 }; 447 MODULE_DEVICE_TABLE(of, meson_spifc_dt_match); 448 449 static struct platform_driver meson_spifc_driver = { 450 .probe = meson_spifc_probe, 451 .remove = meson_spifc_remove, 452 .driver = { 453 .name = "meson-spifc", 454 .of_match_table = of_match_ptr(meson_spifc_dt_match), 455 .pm = &meson_spifc_pm_ops, 456 }, 457 }; 458 459 module_platform_driver(meson_spifc_driver); 460 461 MODULE_AUTHOR("Beniamino Galvani <b.galvani@gmail.com>"); 462 MODULE_DESCRIPTION("Amlogic Meson SPIFC driver"); 463 MODULE_LICENSE("GPL v2"); 464