Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

memory: renesas-rpc-if: Add RZ/G3E xSPI support

Add support for RZ/G3E xSPI. Compared to RPC-IF, it can support writes on
memory-mapped area. Introduce struct rpcif_impl for holding the function
pointers and data to handle the differences between xspi and rpc-if
interface.

Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
Link: https://lore.kernel.org/r/20250424090000.136804-7-biju.das.jz@bp.renesas.com
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>

authored by

Biju Das and committed by
Krzysztof Kozlowski
687cac95 e1c200a4

+542 -7
+433 -7
drivers/memory/renesas-rpc-if.c
··· 19 19 #include <memory/renesas-rpc-if.h> 20 20 21 21 #include "renesas-rpc-if-regs.h" 22 + #include "renesas-xspi-if-regs.h" 22 23 23 24 static const struct regmap_range rpcif_volatile_ranges[] = { 24 25 regmap_reg_range(RPCIF_SMRDR0, RPCIF_SMRDR1), ··· 32 31 .n_yes_ranges = ARRAY_SIZE(rpcif_volatile_ranges), 33 32 }; 34 33 34 + static const struct regmap_range xspi_volatile_ranges[] = { 35 + regmap_reg_range(XSPI_CDD0BUF0, XSPI_CDD0BUF0), 36 + }; 37 + 38 + static const struct regmap_access_table xspi_volatile_table = { 39 + .yes_ranges = xspi_volatile_ranges, 40 + .n_yes_ranges = ARRAY_SIZE(xspi_volatile_ranges), 41 + }; 42 + 43 + struct rpcif_priv; 44 + 45 + struct rpcif_impl { 46 + int (*hw_init)(struct rpcif_priv *rpc, bool hyperflash); 47 + void (*prepare)(struct rpcif_priv *rpc, const struct rpcif_op *op, 48 + u64 *offs, size_t *len); 49 + int (*manual_xfer)(struct rpcif_priv *rpc); 50 + size_t (*dirmap_read)(struct rpcif_priv *rpc, u64 offs, size_t len, 51 + void *buf); 52 + u32 status_reg; 53 + u32 status_mask; 54 + }; 55 + 35 56 struct rpcif_info { 36 57 const struct regmap_config *regmap_config; 58 + const struct rpcif_impl *impl; 37 59 enum rpcif_type type; 38 60 u8 strtim; 39 61 }; ··· 73 49 enum rpcif_data_dir dir; 74 50 u8 bus_size; 75 51 u8 xfer_size; 52 + u8 addr_nbytes; /* Specified for xSPI */ 53 + u32 proto; /* Specified for xSPI */ 76 54 void *buffer; 77 55 u32 xferlen; 78 56 u32 smcr; ··· 175 149 .volatile_table = &rpcif_volatile_table, 176 150 }; 177 151 152 + static int xspi_reg_read(void *context, unsigned int reg, unsigned int *val) 153 + { 154 + struct rpcif_priv *xspi = context; 155 + 156 + *val = readl(xspi->base + reg); 157 + return 0; 158 + } 159 + 160 + static int xspi_reg_write(void *context, unsigned int reg, unsigned int val) 161 + { 162 + struct rpcif_priv *xspi = context; 163 + 164 + writel(val, xspi->base + reg); 165 + return 0; 166 + } 167 + 168 + static const struct regmap_config xspi_regmap_config = { 169 + .reg_bits = 32, 170 + .val_bits = 32, 171 + .reg_stride = 4, 172 + .reg_read = xspi_reg_read, 173 + .reg_write = xspi_reg_write, 174 + .fast_io = true, 175 + .max_register = XSPI_INTE, 176 + .volatile_table = &xspi_volatile_table, 177 + }; 178 + 178 179 int rpcif_sw_init(struct rpcif *rpcif, struct device *dev) 179 180 { 180 181 struct rpcif_priv *rpc = dev_get_drvdata(dev); ··· 209 156 rpcif->dev = dev; 210 157 rpcif->dirmap = rpc->dirmap; 211 158 rpcif->size = rpc->size; 159 + rpcif->xspi = rpc->info->type == XSPI_RZ_G3E; 212 160 return 0; 213 161 } 214 162 EXPORT_SYMBOL(rpcif_sw_init); ··· 285 231 return 0; 286 232 } 287 233 234 + static int xspi_hw_init_impl(struct rpcif_priv *xspi, bool hyperflash) 235 + { 236 + int ret; 237 + 238 + ret = reset_control_reset(xspi->rstc); 239 + if (ret) 240 + return ret; 241 + 242 + regmap_write(xspi->regmap, XSPI_WRAPCFG, 0x0); 243 + 244 + regmap_update_bits(xspi->regmap, XSPI_LIOCFGCS0, 245 + XSPI_LIOCFG_PRTMD(0x3ff) | XSPI_LIOCFG_CSMIN(0xf) | 246 + XSPI_LIOCFG_CSASTEX | XSPI_LIOCFG_CSNEGEX, 247 + XSPI_LIOCFG_PRTMD(0) | XSPI_LIOCFG_CSMIN(0) | 248 + XSPI_LIOCFG_CSASTEX | XSPI_LIOCFG_CSNEGEX); 249 + 250 + regmap_update_bits(xspi->regmap, XSPI_CCCTL0CS0, XSPI_CCCTL0_CAEN, 0); 251 + 252 + regmap_update_bits(xspi->regmap, XSPI_CDCTL0, 253 + XSPI_CDCTL0_TRREQ | XSPI_CDCTL0_CSSEL, 0); 254 + 255 + regmap_update_bits(xspi->regmap, XSPI_INTE, XSPI_INTE_CMDCMPE, 256 + XSPI_INTE_CMDCMPE); 257 + 258 + return 0; 259 + } 260 + 288 261 int rpcif_hw_init(struct device *dev, bool hyperflash) 289 262 { 290 263 struct rpcif_priv *rpc = dev_get_drvdata(dev); ··· 321 240 if (ret) 322 241 return ret; 323 242 324 - ret = rpcif_hw_init_impl(rpc, hyperflash); 243 + ret = rpc->info->impl->hw_init(rpc, hyperflash); 325 244 326 245 pm_runtime_put(dev); 327 246 ··· 333 252 { 334 253 u32 sts; 335 254 336 - return regmap_read_poll_timeout(rpc->regmap, RPCIF_CMNSR, sts, 337 - sts & RPCIF_CMNSR_TEND, 0, 338 - USEC_PER_SEC); 255 + return regmap_read_poll_timeout(rpc->regmap, rpc->info->impl->status_reg, 256 + sts, sts & rpc->info->impl->status_mask, 257 + 0, USEC_PER_SEC); 339 258 } 340 259 341 260 static u8 rpcif_bits_set(struct rpcif_priv *rpc, u32 nbytes) ··· 435 354 } 436 355 } 437 356 357 + static void xspi_prepare_impl(struct rpcif_priv *xspi, const struct rpcif_op *op, 358 + u64 *offs, size_t *len) 359 + { 360 + xspi->smadr = 0; 361 + xspi->addr_nbytes = 0; 362 + xspi->command = 0; 363 + xspi->option = 0; 364 + xspi->dummy = 0; 365 + xspi->xferlen = 0; 366 + xspi->proto = 0; 367 + 368 + if (op->cmd.buswidth) 369 + xspi->command = op->cmd.opcode; 370 + 371 + if (op->ocmd.buswidth) 372 + xspi->command = (xspi->command << 8) | op->ocmd.opcode; 373 + 374 + if (op->addr.buswidth) { 375 + xspi->addr_nbytes = op->addr.nbytes; 376 + if (offs && len) 377 + xspi->smadr = *offs; 378 + else 379 + xspi->smadr = op->addr.val; 380 + } 381 + 382 + if (op->dummy.buswidth) 383 + xspi->dummy = op->dummy.ncycles; 384 + 385 + xspi->dir = op->data.dir; 386 + if (op->data.buswidth) { 387 + u32 nbytes; 388 + 389 + xspi->buffer = op->data.buf.in; 390 + 391 + if (offs && len) 392 + nbytes = *len; 393 + else 394 + nbytes = op->data.nbytes; 395 + xspi->xferlen = nbytes; 396 + } 397 + 398 + if (op->cmd.buswidth == 1) { 399 + if (op->addr.buswidth == 2 || op->data.buswidth == 2) 400 + xspi->proto = PROTO_1S_2S_2S; 401 + else if (op->addr.buswidth == 4 || op->data.buswidth == 4) 402 + xspi->proto = PROTO_1S_4S_4S; 403 + } else if (op->cmd.buswidth == 2 && 404 + (op->addr.buswidth == 2 || op->data.buswidth == 2)) { 405 + xspi->proto = PROTO_2S_2S_2S; 406 + } else if (op->cmd.buswidth == 4 && 407 + (op->addr.buswidth == 4 || op->data.buswidth == 4)) { 408 + xspi->proto = PROTO_4S_4S_4S; 409 + } 410 + } 411 + 438 412 void rpcif_prepare(struct device *dev, const struct rpcif_op *op, u64 *offs, 439 413 size_t *len) 440 414 { 441 415 struct rpcif_priv *rpc = dev_get_drvdata(dev); 442 416 443 - rpcif_prepare_impl(rpc, op, offs, len); 417 + rpc->info->impl->prepare(rpc, op, offs, len); 444 418 } 445 419 EXPORT_SYMBOL(rpcif_prepare); 446 420 ··· 620 484 return ret; 621 485 } 622 486 487 + static int xspi_manual_xfer_impl(struct rpcif_priv *xspi) 488 + { 489 + u32 pos = 0, max = 8; 490 + int ret = 0; 491 + 492 + regmap_update_bits(xspi->regmap, XSPI_CDCTL0, XSPI_CDCTL0_TRNUM(0x3), 493 + XSPI_CDCTL0_TRNUM(0)); 494 + 495 + regmap_update_bits(xspi->regmap, XSPI_CDCTL0, XSPI_CDCTL0_TRREQ, 0); 496 + 497 + regmap_write(xspi->regmap, XSPI_CDTBUF0, 498 + XSPI_CDTBUF_CMDSIZE(0x1) | XSPI_CDTBUF_CMD_FIELD(xspi->command)); 499 + 500 + regmap_write(xspi->regmap, XSPI_CDABUF0, 0); 501 + 502 + regmap_update_bits(xspi->regmap, XSPI_CDTBUF0, XSPI_CDTBUF_ADDSIZE(0x7), 503 + XSPI_CDTBUF_ADDSIZE(xspi->addr_nbytes)); 504 + 505 + regmap_write(xspi->regmap, XSPI_CDABUF0, xspi->smadr); 506 + 507 + regmap_update_bits(xspi->regmap, XSPI_LIOCFGCS0, XSPI_LIOCFG_PRTMD(0x3ff), 508 + XSPI_LIOCFG_PRTMD(xspi->proto)); 509 + 510 + switch (xspi->dir) { 511 + case RPCIF_DATA_OUT: 512 + while (pos < xspi->xferlen) { 513 + u32 bytes_left = xspi->xferlen - pos; 514 + u32 nbytes, data[2], *p = data; 515 + 516 + regmap_update_bits(xspi->regmap, XSPI_CDTBUF0, 517 + XSPI_CDTBUF_TRTYPE, XSPI_CDTBUF_TRTYPE); 518 + 519 + nbytes = bytes_left >= max ? max : bytes_left; 520 + 521 + regmap_update_bits(xspi->regmap, XSPI_CDTBUF0, 522 + XSPI_CDTBUF_DATASIZE(0xf), 523 + XSPI_CDTBUF_DATASIZE(nbytes)); 524 + 525 + regmap_update_bits(xspi->regmap, XSPI_CDTBUF0, 526 + XSPI_CDTBUF_ADDSIZE(0x7), 527 + XSPI_CDTBUF_ADDSIZE(xspi->addr_nbytes)); 528 + 529 + memcpy(data, xspi->buffer + pos, nbytes); 530 + 531 + if (nbytes > 4) { 532 + regmap_write(xspi->regmap, XSPI_CDD0BUF0, *p++); 533 + regmap_write(xspi->regmap, XSPI_CDD1BUF0, *p); 534 + } else { 535 + regmap_write(xspi->regmap, XSPI_CDD0BUF0, *p); 536 + } 537 + 538 + regmap_write(xspi->regmap, XSPI_CDABUF0, xspi->smadr + pos); 539 + 540 + regmap_update_bits(xspi->regmap, XSPI_CDCTL0, 541 + XSPI_CDCTL0_TRREQ, XSPI_CDCTL0_TRREQ); 542 + 543 + ret = wait_msg_xfer_end(xspi); 544 + if (ret) 545 + goto err_out; 546 + 547 + regmap_update_bits(xspi->regmap, XSPI_INTC, 548 + XSPI_INTC_CMDCMPC, XSPI_INTC_CMDCMPC); 549 + 550 + pos += nbytes; 551 + } 552 + regmap_update_bits(xspi->regmap, XSPI_CDCTL0, XSPI_CDCTL0_TRREQ, 0); 553 + break; 554 + case RPCIF_DATA_IN: 555 + while (pos < xspi->xferlen) { 556 + u32 bytes_left = xspi->xferlen - pos; 557 + u32 nbytes, data[2], *p = data; 558 + 559 + regmap_update_bits(xspi->regmap, XSPI_CDTBUF0, 560 + XSPI_CDTBUF_TRTYPE, 561 + ~(u32)XSPI_CDTBUF_TRTYPE); 562 + 563 + /* nbytes can be up to 8 bytes */ 564 + nbytes = bytes_left >= max ? max : bytes_left; 565 + 566 + regmap_update_bits(xspi->regmap, XSPI_CDTBUF0, 567 + XSPI_CDTBUF_DATASIZE(0xf), 568 + XSPI_CDTBUF_DATASIZE(nbytes)); 569 + 570 + regmap_update_bits(xspi->regmap, XSPI_CDTBUF0, 571 + XSPI_CDTBUF_ADDSIZE(0x7), 572 + XSPI_CDTBUF_ADDSIZE(xspi->addr_nbytes)); 573 + 574 + if (xspi->addr_nbytes) 575 + regmap_write(xspi->regmap, XSPI_CDABUF0, 576 + xspi->smadr + pos); 577 + 578 + regmap_update_bits(xspi->regmap, XSPI_CDTBUF0, 579 + XSPI_CDTBUF_LATE(0x1f), 580 + XSPI_CDTBUF_LATE(xspi->dummy)); 581 + 582 + regmap_update_bits(xspi->regmap, XSPI_CDCTL0, 583 + XSPI_CDCTL0_TRREQ, XSPI_CDCTL0_TRREQ); 584 + 585 + ret = wait_msg_xfer_end(xspi); 586 + if (ret) 587 + goto err_out; 588 + 589 + if (nbytes > 4) { 590 + regmap_read(xspi->regmap, XSPI_CDD0BUF0, p++); 591 + regmap_read(xspi->regmap, XSPI_CDD1BUF0, p); 592 + } else { 593 + regmap_read(xspi->regmap, XSPI_CDD0BUF0, p); 594 + } 595 + 596 + memcpy(xspi->buffer + pos, data, nbytes); 597 + 598 + regmap_update_bits(xspi->regmap, XSPI_INTC, 599 + XSPI_INTC_CMDCMPC, XSPI_INTC_CMDCMPC); 600 + 601 + pos += nbytes; 602 + } 603 + regmap_update_bits(xspi->regmap, XSPI_CDCTL0, 604 + XSPI_CDCTL0_TRREQ, 0); 605 + break; 606 + default: 607 + regmap_update_bits(xspi->regmap, XSPI_CDTBUF0, 608 + XSPI_CDTBUF_TRTYPE, XSPI_CDTBUF_TRTYPE); 609 + regmap_update_bits(xspi->regmap, XSPI_CDCTL0, 610 + XSPI_CDCTL0_TRREQ, XSPI_CDCTL0_TRREQ); 611 + 612 + ret = wait_msg_xfer_end(xspi); 613 + if (ret) 614 + goto err_out; 615 + 616 + regmap_update_bits(xspi->regmap, XSPI_INTC, 617 + XSPI_INTC_CMDCMPC, XSPI_INTC_CMDCMPC); 618 + } 619 + 620 + return ret; 621 + 622 + err_out: 623 + xspi_hw_init_impl(xspi, false); 624 + return ret; 625 + } 626 + 623 627 int rpcif_manual_xfer(struct device *dev) 624 628 { 625 629 struct rpcif_priv *rpc = dev_get_drvdata(dev); ··· 769 493 if (ret) 770 494 return ret; 771 495 772 - ret = rpcif_manual_xfer_impl(rpc); 496 + ret = rpc->info->impl->manual_xfer(rpc); 773 497 774 498 pm_runtime_put(dev); 775 499 ··· 847 571 return len; 848 572 } 849 573 574 + static size_t xspi_dirmap_read_impl(struct rpcif_priv *xspi, u64 offs, 575 + size_t len, void *buf) 576 + { 577 + loff_t from = offs & (xspi->size - 1); 578 + size_t size = xspi->size - from; 579 + u8 addsize = xspi->addr_nbytes - 1; 580 + 581 + if (len > size) 582 + len = size; 583 + 584 + regmap_update_bits(xspi->regmap, XSPI_CMCFG0CS0, 585 + XSPI_CMCFG0_FFMT(0x3) | XSPI_CMCFG0_ADDSIZE(0x3), 586 + XSPI_CMCFG0_FFMT(0) | XSPI_CMCFG0_ADDSIZE(addsize)); 587 + 588 + regmap_update_bits(xspi->regmap, XSPI_CMCFG1CS0, 589 + XSPI_CMCFG1_RDCMD(0xffff) | XSPI_CMCFG1_RDLATE(0x1f), 590 + XSPI_CMCFG1_RDCMD_UPPER_BYTE(xspi->command) | 591 + XSPI_CMCFG1_RDLATE(xspi->dummy)); 592 + 593 + regmap_update_bits(xspi->regmap, XSPI_BMCTL0, XSPI_BMCTL0_CS0ACC(0xff), 594 + XSPI_BMCTL0_CS0ACC(0x01)); 595 + 596 + regmap_update_bits(xspi->regmap, XSPI_BMCFG, 597 + XSPI_BMCFG_WRMD | XSPI_BMCFG_MWRCOMB | 598 + XSPI_BMCFG_MWRSIZE(0xff) | XSPI_BMCFG_PREEN, 599 + 0 | XSPI_BMCFG_MWRCOMB | XSPI_BMCFG_MWRSIZE(0x0f) | 600 + XSPI_BMCFG_PREEN); 601 + 602 + regmap_update_bits(xspi->regmap, XSPI_LIOCFGCS0, XSPI_LIOCFG_PRTMD(0x3ff), 603 + XSPI_LIOCFG_PRTMD(xspi->proto)); 604 + 605 + memcpy_fromio(buf, xspi->dirmap + from, len); 606 + 607 + return len; 608 + } 609 + 850 610 ssize_t rpcif_dirmap_read(struct device *dev, u64 offs, size_t len, void *buf) 851 611 { 852 612 struct rpcif_priv *rpc = dev_get_drvdata(dev); ··· 893 581 if (ret) 894 582 return ret; 895 583 896 - read = rpcif_dirmap_read_impl(rpc, offs, len, buf); 584 + read = rpc->info->impl->dirmap_read(rpc, offs, len, buf); 897 585 898 586 pm_runtime_put(dev); 899 587 900 588 return read; 901 589 } 902 590 EXPORT_SYMBOL(rpcif_dirmap_read); 591 + 592 + /** 593 + * xspi_dirmap_write - Write data to xspi memory. 594 + * @dev: xspi device 595 + * @offs: offset 596 + * @len: Number of bytes to be written. 597 + * @buf: Buffer holding write data. 598 + * 599 + * This function writes data into xspi memory. 600 + * 601 + * Returns number of bytes written on success, else negative errno. 602 + */ 603 + ssize_t xspi_dirmap_write(struct device *dev, u64 offs, size_t len, const void *buf) 604 + { 605 + struct rpcif_priv *xspi = dev_get_drvdata(dev); 606 + loff_t from = offs & (xspi->size - 1); 607 + u8 addsize = xspi->addr_nbytes - 1; 608 + size_t size = xspi->size - from; 609 + ssize_t writebytes; 610 + int ret; 611 + 612 + ret = pm_runtime_resume_and_get(dev); 613 + if (ret) 614 + return ret; 615 + 616 + if (len > size) 617 + len = size; 618 + 619 + if (len > MWRSIZE_MAX) 620 + writebytes = MWRSIZE_MAX; 621 + else 622 + writebytes = len; 623 + 624 + regmap_update_bits(xspi->regmap, XSPI_CMCFG0CS0, 625 + XSPI_CMCFG0_FFMT(0x3) | XSPI_CMCFG0_ADDSIZE(0x3), 626 + XSPI_CMCFG0_FFMT(0) | XSPI_CMCFG0_ADDSIZE(addsize)); 627 + 628 + regmap_update_bits(xspi->regmap, XSPI_CMCFG2CS0, 629 + XSPI_CMCFG2_WRCMD_UPPER(0xff) | XSPI_CMCFG2_WRLATE(0x1f), 630 + XSPI_CMCFG2_WRCMD_UPPER(xspi->command) | 631 + XSPI_CMCFG2_WRLATE(xspi->dummy)); 632 + 633 + regmap_update_bits(xspi->regmap, XSPI_BMCTL0, 634 + XSPI_BMCTL0_CS0ACC(0xff), XSPI_BMCTL0_CS0ACC(0x03)); 635 + 636 + regmap_update_bits(xspi->regmap, XSPI_BMCFG, 637 + XSPI_BMCFG_WRMD | XSPI_BMCFG_MWRCOMB | 638 + XSPI_BMCFG_MWRSIZE(0xff) | XSPI_BMCFG_PREEN, 639 + 0 | XSPI_BMCFG_MWRCOMB | XSPI_BMCFG_MWRSIZE(0x0f) | 640 + XSPI_BMCFG_PREEN); 641 + 642 + regmap_update_bits(xspi->regmap, XSPI_LIOCFGCS0, XSPI_LIOCFG_PRTMD(0x3ff), 643 + XSPI_LIOCFG_PRTMD(xspi->proto)); 644 + 645 + memcpy_toio(xspi->dirmap + from, buf, writebytes); 646 + 647 + /* Request to push the pending data */ 648 + if (writebytes < MWRSIZE_MAX) 649 + regmap_update_bits(xspi->regmap, XSPI_BMCTL1, 650 + XSPI_BMCTL1_MWRPUSH, XSPI_BMCTL1_MWRPUSH); 651 + 652 + pm_runtime_put(dev); 653 + 654 + return writebytes; 655 + } 656 + EXPORT_SYMBOL_GPL(xspi_dirmap_write); 903 657 904 658 static int rpcif_probe(struct platform_device *pdev) 905 659 { ··· 1019 641 if (IS_ERR(rpc->rstc)) 1020 642 return PTR_ERR(rpc->rstc); 1021 643 644 + /* 645 + * The enabling/disabling of spi/spix2 clocks at runtime leading to 646 + * flash write failure. So, enable these clocks during probe() and 647 + * disable it in remove(). 648 + */ 649 + if (rpc->info->type == XSPI_RZ_G3E) { 650 + struct clk *spi_clk; 651 + 652 + spi_clk = devm_clk_get_enabled(dev, "spix2"); 653 + if (IS_ERR(spi_clk)) 654 + return dev_err_probe(dev, PTR_ERR(spi_clk), 655 + "cannot get enabled spix2 clk\n"); 656 + 657 + spi_clk = devm_clk_get_enabled(dev, "spi"); 658 + if (IS_ERR(spi_clk)) 659 + return dev_err_probe(dev, PTR_ERR(spi_clk), 660 + "cannot get enabled spi clk\n"); 661 + } 662 + 1022 663 vdev = platform_device_alloc(name, pdev->id); 1023 664 if (!vdev) 1024 665 return -ENOMEM; ··· 1063 666 platform_device_unregister(rpc->vdev); 1064 667 } 1065 668 669 + struct rpcif_impl rpcif_impl = { 670 + .hw_init = rpcif_hw_init_impl, 671 + .prepare = rpcif_prepare_impl, 672 + .manual_xfer = rpcif_manual_xfer_impl, 673 + .dirmap_read = rpcif_dirmap_read_impl, 674 + .status_reg = RPCIF_CMNSR, 675 + .status_mask = RPCIF_CMNSR_TEND, 676 + }; 677 + 678 + struct rpcif_impl xspi_impl = { 679 + .hw_init = xspi_hw_init_impl, 680 + .prepare = xspi_prepare_impl, 681 + .manual_xfer = xspi_manual_xfer_impl, 682 + .dirmap_read = xspi_dirmap_read_impl, 683 + .status_reg = XSPI_INTS, 684 + .status_mask = XSPI_INTS_CMDCMP, 685 + }; 686 + 1066 687 static const struct rpcif_info rpcif_info_r8a7796 = { 1067 688 .regmap_config = &rpcif_regmap_config, 689 + .impl = &rpcif_impl, 1068 690 .type = RPCIF_RCAR_GEN3, 1069 691 .strtim = 6, 1070 692 }; 1071 693 1072 694 static const struct rpcif_info rpcif_info_gen3 = { 1073 695 .regmap_config = &rpcif_regmap_config, 696 + .impl = &rpcif_impl, 1074 697 .type = RPCIF_RCAR_GEN3, 1075 698 .strtim = 7, 1076 699 }; 1077 700 1078 701 static const struct rpcif_info rpcif_info_rz_g2l = { 1079 702 .regmap_config = &rpcif_regmap_config, 703 + .impl = &rpcif_impl, 1080 704 .type = RPCIF_RZ_G2L, 1081 705 .strtim = 7, 1082 706 }; 1083 707 1084 708 static const struct rpcif_info rpcif_info_gen4 = { 1085 709 .regmap_config = &rpcif_regmap_config, 710 + .impl = &rpcif_impl, 1086 711 .type = RPCIF_RCAR_GEN4, 1087 712 .strtim = 15, 1088 713 }; 1089 714 715 + static const struct rpcif_info xspi_info_r9a09g047 = { 716 + .regmap_config = &xspi_regmap_config, 717 + .impl = &xspi_impl, 718 + .type = XSPI_RZ_G3E, 719 + }; 720 + 1090 721 static const struct of_device_id rpcif_of_match[] = { 1091 722 { .compatible = "renesas,r8a7796-rpc-if", .data = &rpcif_info_r8a7796 }, 723 + { .compatible = "renesas,r9a09g047-xspi", .data = &xspi_info_r9a09g047 }, 1092 724 { .compatible = "renesas,rcar-gen3-rpc-if", .data = &rpcif_info_gen3 }, 1093 725 { .compatible = "renesas,rcar-gen4-rpc-if", .data = &rpcif_info_gen4 }, 1094 726 { .compatible = "renesas,rzg2l-rpc-if", .data = &rpcif_info_rz_g2l },
+105
drivers/memory/renesas-xspi-if-regs.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * RZ xSPI Interface Registers Definitions 4 + * 5 + * Copyright (C) 2025 Renesas Electronics Corporation 6 + */ 7 + 8 + #ifndef __RENESAS_XSPI_IF_REGS_H__ 9 + #define __RENESAS_XSPI_IF_REGS_H__ 10 + 11 + #include <linux/bits.h> 12 + 13 + /* xSPI Wrapper Configuration Register */ 14 + #define XSPI_WRAPCFG 0x0000 15 + 16 + /* xSPI Bridge Configuration Register */ 17 + #define XSPI_BMCFG 0x0008 18 + #define XSPI_BMCFG_WRMD BIT(0) 19 + #define XSPI_BMCFG_MWRCOMB BIT(7) 20 + #define XSPI_BMCFG_MWRSIZE(val) (((val) & 0xff) << 8) 21 + #define XSPI_BMCFG_PREEN BIT(16) 22 + 23 + /* xSPI Command Map Configuration Register 0 CS0 */ 24 + #define XSPI_CMCFG0CS0 0x0010 25 + #define XSPI_CMCFG0_FFMT(val) (((val) & 0x03) << 0) 26 + #define XSPI_CMCFG0_ADDSIZE(val) (((val) & 0x03) << 2) 27 + 28 + /* xSPI Command Map Configuration Register 1 CS0 */ 29 + #define XSPI_CMCFG1CS0 0x0014 30 + #define XSPI_CMCFG1_RDCMD(val) (((val) & 0xffff) << 0) 31 + #define XSPI_CMCFG1_RDCMD_UPPER_BYTE(val) (((val) & 0xff) << 8) 32 + #define XSPI_CMCFG1_RDLATE(val) (((val) & 0x1f) << 16) 33 + 34 + /* xSPI Command Map Configuration Register 2 CS0 */ 35 + #define XSPI_CMCFG2CS0 0x0018 36 + #define XSPI_CMCFG2_WRCMD(val) (((val) & 0xffff) << 0) 37 + #define XSPI_CMCFG2_WRCMD_UPPER(val) (((val) & 0xff) << 8) 38 + #define XSPI_CMCFG2_WRLATE(val) (((val) & 0x1f) << 16) 39 + 40 + /* xSPI Link I/O Configuration Register CS0 */ 41 + #define XSPI_LIOCFGCS0 0x0050 42 + #define XSPI_LIOCFG_PRTMD(val) (((val) & 0x3ff) << 0) 43 + #define XSPI_LIOCFG_CSMIN(val) (((val) & 0x0f) << 16) 44 + #define XSPI_LIOCFG_CSASTEX BIT(20) 45 + #define XSPI_LIOCFG_CSNEGEX BIT(21) 46 + 47 + /* xSPI Bridge Map Control Register 0 */ 48 + #define XSPI_BMCTL0 0x0060 49 + #define XSPI_BMCTL0_CS0ACC(val) (((val) & 0x03) << 0) 50 + 51 + /* xSPI Bridge Map Control Register 1 */ 52 + #define XSPI_BMCTL1 0x0064 53 + #define XSPI_BMCTL1_MWRPUSH BIT(8) 54 + 55 + /* xSPI Command Manual Control Register 0 */ 56 + #define XSPI_CDCTL0 0x0070 57 + #define XSPI_CDCTL0_TRREQ BIT(0) 58 + #define XSPI_CDCTL0_CSSEL BIT(3) 59 + #define XSPI_CDCTL0_TRNUM(val) (((val) & 0x03) << 4) 60 + 61 + /* xSPI Command Manual Type Buf */ 62 + #define XSPI_CDTBUF0 0x0080 63 + #define XSPI_CDTBUF_CMDSIZE(val) (((val) & 0x03) << 0) 64 + #define XSPI_CDTBUF_ADDSIZE(val) (((val) & 0x07) << 2) 65 + #define XSPI_CDTBUF_DATASIZE(val) (((val) & 0x0f) << 5) 66 + #define XSPI_CDTBUF_LATE(val) (((val) & 0x1f) << 9) 67 + #define XSPI_CDTBUF_TRTYPE BIT(15) 68 + #define XSPI_CDTBUF_CMD(val) (((val) & 0xffff) << 16) 69 + #define XSPI_CDTBUF_CMD_FIELD(val) (((val) & 0xff) << 24) 70 + 71 + /* xSPI Command Manual Address Buff */ 72 + #define XSPI_CDABUF0 0x0084 73 + 74 + /* xSPI Command Manual Data 0 Buf */ 75 + #define XSPI_CDD0BUF0 0x0088 76 + 77 + /* xSPI Command Manual Data 1 Buf */ 78 + #define XSPI_CDD1BUF0 0x008c 79 + 80 + /* xSPI Command Calibration Control Register 0 CS0 */ 81 + #define XSPI_CCCTL0CS0 0x0130 82 + #define XSPI_CCCTL0_CAEN BIT(0) 83 + 84 + /* xSPI Interrupt Status Register */ 85 + #define XSPI_INTS 0x0190 86 + #define XSPI_INTS_CMDCMP BIT(0) 87 + 88 + /* xSPI Interrupt Clear Register */ 89 + #define XSPI_INTC 0x0194 90 + #define XSPI_INTC_CMDCMPC BIT(0) 91 + 92 + /* xSPI Interrupt Enable Register */ 93 + #define XSPI_INTE 0x0198 94 + #define XSPI_INTE_CMDCMPE BIT(0) 95 + 96 + /* Maximum data size of MWRSIZE*/ 97 + #define MWRSIZE_MAX 64 98 + 99 + /* xSPI Protocol mode */ 100 + #define PROTO_1S_2S_2S 0x48 101 + #define PROTO_2S_2S_2S 0x49 102 + #define PROTO_1S_4S_4S 0x090 103 + #define PROTO_4S_4S_4S 0x092 104 + 105 + #endif /* __RENESAS_XSPI_IF_REGS_H__ */
+4
include/memory/renesas-rpc-if.h
··· 61 61 RPCIF_RCAR_GEN3, 62 62 RPCIF_RCAR_GEN4, 63 63 RPCIF_RZ_G2L, 64 + XSPI_RZ_G3E, 64 65 }; 65 66 66 67 struct rpcif { 67 68 struct device *dev; 68 69 void __iomem *dirmap; 69 70 size_t size; 71 + bool xspi; 70 72 }; 71 73 72 74 int rpcif_sw_init(struct rpcif *rpc, struct device *dev); ··· 77 75 size_t *len); 78 76 int rpcif_manual_xfer(struct device *dev); 79 77 ssize_t rpcif_dirmap_read(struct device *dev, u64 offs, size_t len, void *buf); 78 + ssize_t xspi_dirmap_write(struct device *dev, u64 offs, size_t len, 79 + const void *buf); 80 80 81 81 #endif // __RENESAS_RPC_IF_H