Padmarao Begari | 32678b0 | 2022-10-27 11:32:01 +0530 | [diff] [blame] | 1 | // SPDX-License-Identifier: GPL-2.0+ |
| 2 | /* |
| 3 | * Copyright (C) 2022 Microchip Technology Inc. |
| 4 | * Padmarao Begari <padmarao.begari@microchip.com> |
| 5 | * Naga Sureshkumar Relli <nagasuresh.relli@microchip.com> |
| 6 | */ |
| 7 | |
Tom Rini | abb9a04 | 2024-05-18 20:20:43 -0600 | [diff] [blame] | 8 | #include <common.h> |
Padmarao Begari | 32678b0 | 2022-10-27 11:32:01 +0530 | [diff] [blame] | 9 | #include <clk.h> |
| 10 | #include <dm.h> |
| 11 | #include <log.h> |
| 12 | #include <malloc.h> |
| 13 | #include <spi.h> |
| 14 | #include <spi-mem.h> |
| 15 | #include <asm/io.h> |
| 16 | #include <linux/bitops.h> |
| 17 | #include <linux/delay.h> |
| 18 | #include <linux/types.h> |
| 19 | #include <linux/sizes.h> |
| 20 | |
| 21 | DECLARE_GLOBAL_DATA_PTR; |
| 22 | |
| 23 | /* |
| 24 | * QSPI Control register mask defines |
| 25 | */ |
| 26 | #define CONTROL_ENABLE BIT(0) |
| 27 | #define CONTROL_MASTER BIT(1) |
| 28 | #define CONTROL_XIP BIT(2) |
| 29 | #define CONTROL_XIPADDR BIT(3) |
| 30 | #define CONTROL_CLKIDLE BIT(10) |
| 31 | #define CONTROL_SAMPLE_MASK GENMASK(12, 11) |
| 32 | #define CONTROL_MODE0 BIT(13) |
| 33 | #define CONTROL_MODE12_MASK GENMASK(15, 14) |
| 34 | #define CONTROL_MODE12_EX_RO BIT(14) |
| 35 | #define CONTROL_MODE12_EX_RW BIT(15) |
| 36 | #define CONTROL_MODE12_FULL GENMASK(15, 14) |
| 37 | #define CONTROL_FLAGSX4 BIT(16) |
| 38 | #define CONTROL_CLKRATE_MASK GENMASK(27, 24) |
| 39 | #define CONTROL_CLKRATE_SHIFT 24 |
| 40 | |
| 41 | /* |
| 42 | * QSPI Frames register mask defines |
| 43 | */ |
| 44 | #define FRAMES_TOTALBYTES_MASK GENMASK(15, 0) |
| 45 | #define FRAMES_CMDBYTES_MASK GENMASK(24, 16) |
| 46 | #define FRAMES_CMDBYTES_SHIFT 16 |
| 47 | #define FRAMES_SHIFT 25 |
| 48 | #define FRAMES_IDLE_MASK GENMASK(29, 26) |
| 49 | #define FRAMES_IDLE_SHIFT 26 |
| 50 | #define FRAMES_FLAGBYTE BIT(30) |
| 51 | #define FRAMES_FLAGWORD BIT(31) |
| 52 | |
| 53 | /* |
| 54 | * QSPI Interrupt Enable register mask defines |
| 55 | */ |
| 56 | #define IEN_TXDONE BIT(0) |
| 57 | #define IEN_RXDONE BIT(1) |
| 58 | #define IEN_RXAVAILABLE BIT(2) |
| 59 | #define IEN_TXAVAILABLE BIT(3) |
| 60 | #define IEN_RXFIFOEMPTY BIT(4) |
| 61 | #define IEN_TXFIFOFULL BIT(5) |
| 62 | |
| 63 | /* |
| 64 | * QSPI Status register mask defines |
| 65 | */ |
| 66 | #define STATUS_TXDONE BIT(0) |
| 67 | #define STATUS_RXDONE BIT(1) |
| 68 | #define STATUS_RXAVAILABLE BIT(2) |
| 69 | #define STATUS_TXAVAILABLE BIT(3) |
| 70 | #define STATUS_RXFIFOEMPTY BIT(4) |
| 71 | #define STATUS_TXFIFOFULL BIT(5) |
| 72 | #define STATUS_READY BIT(7) |
| 73 | #define STATUS_FLAGSX4 BIT(8) |
| 74 | #define STATUS_MASK GENMASK(8, 0) |
| 75 | |
| 76 | #define BYTESUPPER_MASK GENMASK(31, 16) |
| 77 | #define BYTESLOWER_MASK GENMASK(15, 0) |
| 78 | |
| 79 | #define MAX_DIVIDER 16 |
| 80 | #define MIN_DIVIDER 0 |
| 81 | #define MAX_DATA_CMD_LEN 256 |
| 82 | |
| 83 | /* QSPI ready time out value */ |
| 84 | #define TIMEOUT_MS (1000 * 500) |
| 85 | |
| 86 | /* |
| 87 | * QSPI Register offsets. |
| 88 | */ |
| 89 | #define REG_CONTROL (0x00) |
| 90 | #define REG_FRAMES (0x04) |
| 91 | #define REG_IEN (0x0c) |
| 92 | #define REG_STATUS (0x10) |
| 93 | #define REG_DIRECT_ACCESS (0x14) |
| 94 | #define REG_UPPER_ACCESS (0x18) |
| 95 | #define REG_RX_DATA (0x40) |
| 96 | #define REG_TX_DATA (0x44) |
| 97 | #define REG_X4_RX_DATA (0x48) |
| 98 | #define REG_X4_TX_DATA (0x4c) |
| 99 | #define REG_FRAMESUP (0x50) |
| 100 | |
| 101 | /** |
| 102 | * struct mchp_coreqspi - Defines qspi driver instance |
| 103 | * @regs: Address of the QSPI controller registers |
| 104 | * @freq: QSPI Input frequency |
| 105 | * @txbuf: TX buffer |
| 106 | * @rxbuf: RX buffer |
| 107 | * @tx_len: Number of bytes left to transfer |
| 108 | * @rx_len: Number of bytes left to receive |
| 109 | */ |
| 110 | struct mchp_coreqspi { |
| 111 | void __iomem *regs; |
| 112 | u32 freq; |
| 113 | u8 *txbuf; |
| 114 | u8 *rxbuf; |
| 115 | int tx_len; |
| 116 | int rx_len; |
| 117 | }; |
| 118 | |
| 119 | static void mchp_coreqspi_init_hw(struct mchp_coreqspi *qspi) |
| 120 | { |
| 121 | u32 control; |
| 122 | |
| 123 | control = CONTROL_CLKIDLE | CONTROL_ENABLE; |
| 124 | |
| 125 | writel(control, qspi->regs + REG_CONTROL); |
| 126 | writel(0, qspi->regs + REG_IEN); |
| 127 | } |
| 128 | |
| 129 | static inline void mchp_coreqspi_read_op(struct mchp_coreqspi *qspi) |
| 130 | { |
| 131 | u32 control, data; |
| 132 | |
| 133 | if (!qspi->rx_len) |
| 134 | return; |
| 135 | |
| 136 | control = readl(qspi->regs + REG_CONTROL); |
| 137 | |
| 138 | /* |
| 139 | * Read 4-bytes from the SPI FIFO in single transaction and then read |
| 140 | * the reamaining data byte wise. |
| 141 | */ |
| 142 | control |= CONTROL_FLAGSX4; |
| 143 | writel(control, qspi->regs + REG_CONTROL); |
| 144 | |
| 145 | while (qspi->rx_len >= 4) { |
| 146 | while (readl(qspi->regs + REG_STATUS) & STATUS_RXFIFOEMPTY) |
| 147 | ; |
| 148 | data = readl(qspi->regs + REG_X4_RX_DATA); |
| 149 | *(u32 *)qspi->rxbuf = data; |
| 150 | qspi->rxbuf += 4; |
| 151 | qspi->rx_len -= 4; |
| 152 | } |
| 153 | |
| 154 | control &= ~CONTROL_FLAGSX4; |
| 155 | writel(control, qspi->regs + REG_CONTROL); |
| 156 | |
| 157 | while (qspi->rx_len--) { |
| 158 | while (readl(qspi->regs + REG_STATUS) & STATUS_RXFIFOEMPTY) |
| 159 | ; |
| 160 | data = readl(qspi->regs + REG_RX_DATA); |
| 161 | *qspi->rxbuf++ = (data & 0xFF); |
| 162 | } |
| 163 | } |
| 164 | |
| 165 | static inline void mchp_coreqspi_write_op(struct mchp_coreqspi *qspi, bool word) |
| 166 | { |
| 167 | u32 control, data; |
| 168 | |
| 169 | control = readl(qspi->regs + REG_CONTROL); |
| 170 | control |= CONTROL_FLAGSX4; |
| 171 | writel(control, qspi->regs + REG_CONTROL); |
| 172 | |
| 173 | while (qspi->tx_len >= 4) { |
| 174 | while (readl(qspi->regs + REG_STATUS) & STATUS_TXFIFOFULL) |
| 175 | ; |
| 176 | data = *(u32 *)qspi->txbuf; |
| 177 | qspi->txbuf += 4; |
| 178 | qspi->tx_len -= 4; |
| 179 | writel(data, qspi->regs + REG_X4_TX_DATA); |
| 180 | } |
| 181 | |
| 182 | control &= ~CONTROL_FLAGSX4; |
| 183 | writel(control, qspi->regs + REG_CONTROL); |
| 184 | |
| 185 | while (qspi->tx_len--) { |
| 186 | while (readl(qspi->regs + REG_STATUS) & STATUS_TXFIFOFULL) |
| 187 | ; |
| 188 | data = *qspi->txbuf++; |
| 189 | writel(data, qspi->regs + REG_TX_DATA); |
| 190 | } |
| 191 | } |
| 192 | |
| 193 | static inline void mchp_coreqspi_config_op(struct mchp_coreqspi *qspi, |
| 194 | const struct spi_mem_op *op) |
| 195 | { |
| 196 | u32 idle_cycles = 0; |
| 197 | int total_bytes, cmd_bytes, frames, ctrl; |
| 198 | |
| 199 | cmd_bytes = op->cmd.nbytes + op->addr.nbytes; |
| 200 | total_bytes = cmd_bytes + op->data.nbytes; |
| 201 | |
| 202 | /* |
| 203 | * As per the coreQSPI IP spec,the number of command and data bytes are |
| 204 | * controlled by the frames register for each SPI sequence. This supports |
| 205 | * the SPI flash memory read and writes sequences as below. so configure |
| 206 | * the cmd and total bytes accordingly. |
| 207 | * --------------------------------------------------------------------- |
| 208 | * TOTAL BYTES | CMD BYTES | What happens | |
| 209 | * ______________________________________________________________________ |
| 210 | * | | | |
| 211 | * 1 | 1 | The SPI core will transmit a single byte | |
| 212 | * | | and receive data is discarded | |
| 213 | * | | | |
| 214 | * 1 | 0 | The SPI core will transmit a single byte | |
| 215 | * | | and return a single byte | |
| 216 | * | | | |
| 217 | * 10 | 4 | The SPI core will transmit 4 command | |
| 218 | * | | bytes discarding the receive data and | |
| 219 | * | | transmits 6 dummy bytes returning the 6 | |
| 220 | * | | received bytes and return a single byte | |
| 221 | * | | | |
| 222 | * 10 | 10 | The SPI core will transmit 10 command | |
| 223 | * | | | |
| 224 | * 10 | 0 | The SPI core will transmit 10 command | |
| 225 | * | | bytes and returning 10 received bytes | |
| 226 | * ______________________________________________________________________ |
| 227 | */ |
| 228 | |
| 229 | if (!(op->data.dir == SPI_MEM_DATA_IN)) |
| 230 | cmd_bytes = total_bytes; |
| 231 | |
| 232 | frames = total_bytes & BYTESUPPER_MASK; |
| 233 | writel(frames, qspi->regs + REG_FRAMESUP); |
| 234 | frames = total_bytes & BYTESLOWER_MASK; |
| 235 | frames |= cmd_bytes << FRAMES_CMDBYTES_SHIFT; |
| 236 | |
| 237 | if (op->dummy.buswidth) |
| 238 | idle_cycles = op->dummy.nbytes * 8 / op->dummy.buswidth; |
| 239 | |
| 240 | frames |= idle_cycles << FRAMES_IDLE_SHIFT; |
| 241 | ctrl = readl(qspi->regs + REG_CONTROL); |
| 242 | |
| 243 | if (ctrl & CONTROL_MODE12_MASK) |
| 244 | frames |= (1 << FRAMES_SHIFT); |
| 245 | |
| 246 | frames |= FRAMES_FLAGWORD; |
| 247 | writel(frames, qspi->regs + REG_FRAMES); |
| 248 | } |
| 249 | |
| 250 | static int mchp_coreqspi_wait_for_ready(struct spi_slave *slave) |
| 251 | { |
| 252 | struct mchp_coreqspi *qspi = dev_get_priv(slave->dev->parent); |
| 253 | unsigned long count = 0; |
| 254 | |
| 255 | while (1) { |
| 256 | if (readl(qspi->regs + REG_STATUS) & STATUS_READY) |
| 257 | return 0; |
| 258 | |
| 259 | udelay(1); |
| 260 | count += 1; |
| 261 | if (count == TIMEOUT_MS) |
| 262 | return -ETIMEDOUT; |
| 263 | } |
| 264 | } |
| 265 | |
| 266 | static int mchp_coreqspi_set_operate_mode(struct mchp_coreqspi *qspi, |
| 267 | const struct spi_mem_op *op) |
| 268 | { |
| 269 | u32 control = readl(qspi->regs + REG_CONTROL); |
| 270 | |
| 271 | /* |
| 272 | * The operating mode can be configured based on the command that needs |
| 273 | * to be send. |
| 274 | * bits[15:14]: Sets whether multiple bit SPI operates in normal, |
| 275 | * extended or full modes. |
| 276 | * 00: Normal (single DQ0 TX and single DQ1 RX lines) |
| 277 | * 01: Extended RO (command and address bytes on DQ0 only) |
| 278 | * 10: Extended RW (command byte on DQ0 only) |
| 279 | * 11: Full. (command and address are on all DQ lines) |
| 280 | * bit[13]: Sets whether multiple bit SPI uses 2 or 4 bits of data |
| 281 | * 0: 2-bits (BSPI) |
| 282 | * 1: 4-bits (QSPI) |
| 283 | */ |
| 284 | if (op->data.buswidth == 4 || op->data.buswidth == 2) { |
| 285 | control &= ~CONTROL_MODE12_MASK; |
| 286 | if (op->cmd.buswidth == 1 && (op->addr.buswidth == 1 || |
| 287 | op->addr.buswidth == 0)) |
| 288 | control |= CONTROL_MODE12_EX_RO; |
| 289 | else if (op->cmd.buswidth == 1) |
| 290 | control |= CONTROL_MODE12_EX_RW; |
| 291 | else |
| 292 | control |= CONTROL_MODE12_FULL; |
| 293 | |
| 294 | control |= CONTROL_MODE0; |
| 295 | } else { |
| 296 | control &= ~(CONTROL_MODE12_MASK | CONTROL_MODE0); |
| 297 | } |
| 298 | |
| 299 | writel(control, qspi->regs + REG_CONTROL); |
| 300 | |
| 301 | return 0; |
| 302 | } |
| 303 | |
| 304 | static int mchp_coreqspi_exec_op(struct spi_slave *slave, |
| 305 | const struct spi_mem_op *op) |
| 306 | { |
| 307 | struct mchp_coreqspi *qspi = dev_get_priv(slave->dev->parent); |
| 308 | |
| 309 | u32 address = op->addr.val; |
| 310 | u8 opcode = op->cmd.opcode; |
| 311 | u8 opaddr[5]; |
| 312 | int err = 0, i; |
| 313 | |
| 314 | err = mchp_coreqspi_wait_for_ready(slave); |
| 315 | if (err) |
| 316 | return err; |
| 317 | |
| 318 | err = mchp_coreqspi_set_operate_mode(qspi, op); |
| 319 | if (err) |
| 320 | return err; |
| 321 | |
| 322 | mchp_coreqspi_config_op(qspi, op); |
| 323 | if (op->cmd.opcode) { |
| 324 | qspi->txbuf = &opcode; |
| 325 | qspi->rxbuf = NULL; |
| 326 | qspi->tx_len = op->cmd.nbytes; |
| 327 | qspi->rx_len = 0; |
| 328 | mchp_coreqspi_write_op(qspi, false); |
| 329 | } |
| 330 | |
| 331 | qspi->txbuf = &opaddr[0]; |
| 332 | if (op->addr.nbytes) { |
| 333 | for (i = 0; i < op->addr.nbytes; i++) |
| 334 | qspi->txbuf[i] = address >> (8 * (op->addr.nbytes - i - 1)); |
| 335 | |
| 336 | qspi->rxbuf = NULL; |
| 337 | qspi->tx_len = op->addr.nbytes; |
| 338 | qspi->rx_len = 0; |
| 339 | mchp_coreqspi_write_op(qspi, false); |
| 340 | } |
| 341 | |
| 342 | if (op->data.nbytes) { |
| 343 | if (op->data.dir == SPI_MEM_DATA_OUT) { |
| 344 | qspi->txbuf = (u8 *)op->data.buf.out; |
| 345 | qspi->rxbuf = NULL; |
| 346 | qspi->rx_len = 0; |
| 347 | qspi->tx_len = op->data.nbytes; |
| 348 | mchp_coreqspi_write_op(qspi, true); |
| 349 | } else { |
| 350 | qspi->txbuf = NULL; |
| 351 | qspi->rxbuf = (u8 *)op->data.buf.in; |
| 352 | qspi->rx_len = op->data.nbytes; |
| 353 | qspi->tx_len = 0; |
| 354 | mchp_coreqspi_read_op(qspi); |
| 355 | } |
| 356 | } |
| 357 | |
| 358 | return 0; |
| 359 | } |
| 360 | |
| 361 | static bool mchp_coreqspi_supports_op(struct spi_slave *slave, |
| 362 | const struct spi_mem_op *op) |
| 363 | { |
| 364 | if (!spi_mem_default_supports_op(slave, op)) |
| 365 | return false; |
| 366 | |
| 367 | if ((op->data.buswidth == 4 || op->data.buswidth == 2) && |
| 368 | (op->cmd.buswidth == 1 && (op->addr.buswidth == 1 || |
| 369 | op->addr.buswidth == 0))) { |
| 370 | /* |
| 371 | * If the command and address are on DQ0 only, then this |
| 372 | * controller doesn't support sending data on dual and |
| 373 | * quad lines. but it supports reading data on dual and |
| 374 | * quad lines with same configuration as command and |
| 375 | * address on DQ0. |
| 376 | * i.e. The control register[15:13] :EX_RO(read only) is |
| 377 | * meant only for the command and address are on DQ0 but |
| 378 | * not to write data, it is just to read. |
| 379 | * Ex: 0x34h is Quad Load Program Data which is not |
| 380 | * supported. Then the spi-mem layer will iterate over |
| 381 | * each command and it will chose the supported one. |
| 382 | */ |
| 383 | if (op->data.dir == SPI_MEM_DATA_OUT) |
| 384 | return false; |
| 385 | } |
| 386 | |
| 387 | return true; |
| 388 | } |
| 389 | |
| 390 | static int mchp_coreqspi_adjust_op_size(struct spi_slave *slave, |
| 391 | struct spi_mem_op *op) |
| 392 | { |
| 393 | if (op->data.dir == SPI_MEM_DATA_OUT) { |
| 394 | if (op->data.nbytes > MAX_DATA_CMD_LEN) |
| 395 | op->data.nbytes = MAX_DATA_CMD_LEN; |
| 396 | } |
| 397 | |
| 398 | return 0; |
| 399 | } |
| 400 | |
| 401 | static int mchp_coreqspi_set_speed(struct udevice *dev, uint speed) |
| 402 | { |
| 403 | struct mchp_coreqspi *qspi = dev_get_priv(dev); |
| 404 | u32 control, baud_rate_val = 0; |
| 405 | |
| 406 | if (speed > (qspi->freq / 2)) |
| 407 | speed = qspi->freq / 2; |
| 408 | |
| 409 | baud_rate_val = DIV_ROUND_UP(qspi->freq, 2 * speed); |
| 410 | if (baud_rate_val >= MAX_DIVIDER || baud_rate_val <= MIN_DIVIDER) |
| 411 | return -EINVAL; |
| 412 | |
| 413 | control = readl(qspi->regs + REG_CONTROL); |
| 414 | control &= ~CONTROL_CLKRATE_MASK; |
| 415 | control |= baud_rate_val << CONTROL_CLKRATE_SHIFT; |
| 416 | writel(control, qspi->regs + REG_CONTROL); |
| 417 | |
| 418 | return 0; |
| 419 | } |
| 420 | |
| 421 | static int mchp_coreqspi_set_mode(struct udevice *dev, uint mode) |
| 422 | { |
| 423 | struct mchp_coreqspi *qspi = dev_get_priv(dev); |
| 424 | u32 control; |
| 425 | |
| 426 | control = readl(qspi->regs + REG_CONTROL); |
| 427 | |
| 428 | if ((mode & SPI_CPOL) && (mode & SPI_CPHA)) |
| 429 | control |= CONTROL_CLKIDLE; |
| 430 | else |
| 431 | control &= ~CONTROL_CLKIDLE; |
| 432 | |
| 433 | writel(control, qspi->regs + REG_CONTROL); |
| 434 | |
| 435 | return 0; |
| 436 | } |
| 437 | |
| 438 | static int mchp_coreqspi_claim_bus(struct udevice *dev) |
| 439 | { |
| 440 | return 0; |
| 441 | } |
| 442 | |
| 443 | static int mchp_coreqspi_release_bus(struct udevice *dev) |
| 444 | { |
| 445 | return 0; |
| 446 | } |
| 447 | |
| 448 | static int mchp_coreqspi_probe(struct udevice *dev) |
| 449 | { |
| 450 | struct mchp_coreqspi *qspi = dev_get_priv(dev); |
| 451 | struct clk clk; |
| 452 | ulong clk_rate; |
| 453 | int ret; |
| 454 | |
| 455 | ret = clk_get_by_index(dev, 0, &clk); |
| 456 | if (ret) |
| 457 | return -EINVAL; |
| 458 | |
| 459 | ret = clk_enable(&clk); |
| 460 | if (ret) |
| 461 | return ret; |
| 462 | |
| 463 | clk_rate = clk_get_rate(&clk); |
| 464 | if (!clk_rate) |
| 465 | return -EINVAL; |
| 466 | qspi->freq = clk_rate; |
| 467 | |
| 468 | qspi->regs = dev_read_addr_ptr(dev); |
| 469 | if (!qspi->regs) |
| 470 | return -EINVAL; |
| 471 | |
| 472 | /* Init the mpfs qspi hw */ |
| 473 | mchp_coreqspi_init_hw(qspi); |
| 474 | |
| 475 | return 0; |
| 476 | } |
| 477 | |
| 478 | static const struct spi_controller_mem_ops mchp_coreqspi_mem_ops = { |
| 479 | .adjust_op_size = mchp_coreqspi_adjust_op_size, |
| 480 | .supports_op = mchp_coreqspi_supports_op, |
| 481 | .exec_op = mchp_coreqspi_exec_op, |
| 482 | }; |
| 483 | |
| 484 | static const struct dm_spi_ops mchp_coreqspi_ops = { |
| 485 | .claim_bus = mchp_coreqspi_claim_bus, |
| 486 | .release_bus = mchp_coreqspi_release_bus, |
| 487 | .set_speed = mchp_coreqspi_set_speed, |
| 488 | .set_mode = mchp_coreqspi_set_mode, |
| 489 | .mem_ops = &mchp_coreqspi_mem_ops, |
| 490 | }; |
| 491 | |
| 492 | static const struct udevice_id mchp_coreqspi_ids[] = { |
| 493 | { .compatible = "microchip,mpfs-coreqspi-rtl-v2" }, |
| 494 | { .compatible = "microchip,mpfs-qspi" }, |
| 495 | { } |
| 496 | }; |
| 497 | |
| 498 | U_BOOT_DRIVER(mchp_coreqspi) = { |
| 499 | .name = "mchp_coreqspi", |
| 500 | .id = UCLASS_SPI, |
| 501 | .of_match = mchp_coreqspi_ids, |
| 502 | .ops = &mchp_coreqspi_ops, |
| 503 | .priv_auto = sizeof(struct mchp_coreqspi), |
| 504 | .probe = mchp_coreqspi_probe, |
| 505 | }; |