Lines Matching full:rpc

3  * Renesas RPC-IF core driver
19 #include <memory/renesas-rpc-if.h>
21 #include "renesas-rpc-if-regs.h"
47 int (*hw_init)(struct rpcif_priv *rpc, bool hyperflash);
48 void (*prepare)(struct rpcif_priv *rpc, const struct rpcif_op *op,
50 int (*manual_xfer)(struct rpcif_priv *rpc);
51 size_t (*dirmap_read)(struct rpcif_priv *rpc, u64 offs, size_t len,
97 struct rpcif_priv *rpc = context; in rpcif_reg_read() local
102 switch (rpc->xfer_size) { in rpcif_reg_read()
104 *val = readb(rpc->base + reg); in rpcif_reg_read()
108 *val = readw(rpc->base + reg); in rpcif_reg_read()
113 *val = readl(rpc->base + reg); in rpcif_reg_read()
122 if (rpc->xfer_size != 8) in rpcif_reg_read()
127 *val = readl(rpc->base + reg); in rpcif_reg_read()
133 struct rpcif_priv *rpc = context; in rpcif_reg_write() local
137 switch (rpc->xfer_size) { in rpcif_reg_write()
139 writeb(val, rpc->base + reg); in rpcif_reg_write()
143 writew(val, rpc->base + reg); in rpcif_reg_write()
148 writel(val, rpc->base + reg); in rpcif_reg_write()
156 if (rpc->xfer_size != 8) in rpcif_reg_write()
165 writel(val, rpc->base + reg); in rpcif_reg_write()
209 struct rpcif_priv *rpc = dev_get_drvdata(dev); in rpcif_sw_init() local
212 rpcif->dirmap = rpc->dirmap; in rpcif_sw_init()
213 rpcif->size = rpc->size; in rpcif_sw_init()
214 rpcif->xspi = rpc->info->type == XSPI_RZ_G3E; in rpcif_sw_init()
219 static void rpcif_rzg2l_timing_adjust_sdr(struct rpcif_priv *rpc) in rpcif_rzg2l_timing_adjust_sdr() argument
221 regmap_write(rpc->regmap, RPCIF_PHYWR, 0xa5390000); in rpcif_rzg2l_timing_adjust_sdr()
222 regmap_write(rpc->regmap, RPCIF_PHYADD, 0x80000000); in rpcif_rzg2l_timing_adjust_sdr()
223 regmap_write(rpc->regmap, RPCIF_PHYWR, 0x00008080); in rpcif_rzg2l_timing_adjust_sdr()
224 regmap_write(rpc->regmap, RPCIF_PHYADD, 0x80000022); in rpcif_rzg2l_timing_adjust_sdr()
225 regmap_write(rpc->regmap, RPCIF_PHYWR, 0x00008080); in rpcif_rzg2l_timing_adjust_sdr()
226 regmap_write(rpc->regmap, RPCIF_PHYADD, 0x80000024); in rpcif_rzg2l_timing_adjust_sdr()
227 regmap_update_bits(rpc->regmap, RPCIF_PHYCNT, RPCIF_PHYCNT_CKSEL(3), in rpcif_rzg2l_timing_adjust_sdr()
229 regmap_write(rpc->regmap, RPCIF_PHYWR, 0x00000030); in rpcif_rzg2l_timing_adjust_sdr()
230 regmap_write(rpc->regmap, RPCIF_PHYADD, 0x80000032); in rpcif_rzg2l_timing_adjust_sdr()
233 static int rpcif_hw_init_impl(struct rpcif_priv *rpc, bool hyperflash) in rpcif_hw_init_impl() argument
238 if (rpc->info->type == RPCIF_RZ_G2L) { in rpcif_hw_init_impl()
239 ret = reset_control_reset(rpc->rstc); in rpcif_hw_init_impl()
243 rpcif_rzg2l_timing_adjust_sdr(rpc); in rpcif_hw_init_impl()
246 regmap_update_bits(rpc->regmap, RPCIF_PHYCNT, RPCIF_PHYCNT_PHYMEM_MASK, in rpcif_hw_init_impl()
250 regmap_update_bits(rpc->regmap, RPCIF_PHYCNT, RPCIF_PHYCNT_HS, 0); in rpcif_hw_init_impl()
252 regmap_update_bits(rpc->regmap, RPCIF_PHYCNT, in rpcif_hw_init_impl()
254 RPCIF_PHYCNT_STRTIM(BIT(fls(rpc->info->strtim)) - 1), in rpcif_hw_init_impl()
255 RPCIF_PHYCNT_STRTIM(rpc->info->strtim)); in rpcif_hw_init_impl()
257 regmap_update_bits(rpc->regmap, RPCIF_PHYOFFSET1, RPCIF_PHYOFFSET1_DDRTMG(3), in rpcif_hw_init_impl()
259 regmap_update_bits(rpc->regmap, RPCIF_PHYOFFSET2, RPCIF_PHYOFFSET2_OCTTMG(7), in rpcif_hw_init_impl()
263 regmap_update_bits(rpc->regmap, RPCIF_PHYINT, in rpcif_hw_init_impl()
266 if (rpc->info->type == RPCIF_RZ_G2L) in rpcif_hw_init_impl()
267 regmap_update_bits(rpc->regmap, RPCIF_CMNCR, in rpcif_hw_init_impl()
273 regmap_update_bits(rpc->regmap, RPCIF_CMNCR, in rpcif_hw_init_impl()
279 regmap_write(rpc->regmap, RPCIF_DRCR, RPCIF_DRCR_RCF); in rpcif_hw_init_impl()
281 regmap_read(rpc->regmap, RPCIF_DRCR, &dummy); in rpcif_hw_init_impl()
282 regmap_write(rpc->regmap, RPCIF_SSLDR, RPCIF_SSLDR_SPNDL(7) | in rpcif_hw_init_impl()
285 rpc->bus_size = hyperflash ? 2 : 1; in rpcif_hw_init_impl()
319 struct rpcif_priv *rpc = dev_get_drvdata(dev); in rpcif_hw_init() local
326 ret = rpc->info->impl->hw_init(rpc, hyperflash); in rpcif_hw_init()
334 static int wait_msg_xfer_end(struct rpcif_priv *rpc) in wait_msg_xfer_end() argument
338 return regmap_read_poll_timeout(rpc->regmap, rpc->info->impl->status_reg, in wait_msg_xfer_end()
339 sts, sts & rpc->info->impl->status_mask, in wait_msg_xfer_end()
343 static u8 rpcif_bits_set(struct rpcif_priv *rpc, u32 nbytes) in rpcif_bits_set() argument
345 if (rpc->bus_size == 2) in rpcif_bits_set()
356 static void rpcif_prepare_impl(struct rpcif_priv *rpc, const struct rpcif_op *op, in rpcif_prepare_impl() argument
359 rpc->smcr = 0; in rpcif_prepare_impl()
360 rpc->smadr = 0; in rpcif_prepare_impl()
361 rpc->enable = 0; in rpcif_prepare_impl()
362 rpc->command = 0; in rpcif_prepare_impl()
363 rpc->option = 0; in rpcif_prepare_impl()
364 rpc->dummy = 0; in rpcif_prepare_impl()
365 rpc->ddr = 0; in rpcif_prepare_impl()
366 rpc->xferlen = 0; in rpcif_prepare_impl()
369 rpc->enable = RPCIF_SMENR_CDE | in rpcif_prepare_impl()
371 rpc->command = RPCIF_SMCMR_CMD(op->cmd.opcode); in rpcif_prepare_impl()
373 rpc->ddr = RPCIF_SMDRENR_HYPE(0x5); in rpcif_prepare_impl()
376 rpc->enable |= RPCIF_SMENR_OCDE | in rpcif_prepare_impl()
378 rpc->command |= RPCIF_SMCMR_OCMD(op->ocmd.opcode); in rpcif_prepare_impl()
382 rpc->enable |= in rpcif_prepare_impl()
385 rpc->enable |= RPCIF_SMENR_ADE(0xF); in rpcif_prepare_impl()
387 rpc->enable |= RPCIF_SMENR_ADE(GENMASK( in rpcif_prepare_impl()
390 rpc->ddr |= RPCIF_SMDRENR_ADDRE; in rpcif_prepare_impl()
393 rpc->smadr = *offs; in rpcif_prepare_impl()
395 rpc->smadr = op->addr.val; in rpcif_prepare_impl()
399 rpc->enable |= RPCIF_SMENR_DME; in rpcif_prepare_impl()
400 rpc->dummy = RPCIF_SMDMCR_DMCYC(op->dummy.ncycles); in rpcif_prepare_impl()
404 rpc->enable |= RPCIF_SMENR_OPDE( in rpcif_prepare_impl()
405 rpcif_bits_set(rpc, op->option.nbytes)) | in rpcif_prepare_impl()
408 rpc->ddr |= RPCIF_SMDRENR_OPDRE; in rpcif_prepare_impl()
409 rpc->option = op->option.val; in rpcif_prepare_impl()
412 rpc->dir = op->data.dir; in rpcif_prepare_impl()
416 rpc->buffer = op->data.buf.in; in rpcif_prepare_impl()
419 rpc->smcr = RPCIF_SMCR_SPIRE; in rpcif_prepare_impl()
422 rpc->smcr = RPCIF_SMCR_SPIWE; in rpcif_prepare_impl()
428 rpc->ddr |= RPCIF_SMDRENR_SPIDRE; in rpcif_prepare_impl()
434 rpc->xferlen = nbytes; in rpcif_prepare_impl()
436 rpc->enable |= RPCIF_SMENR_SPIDB(rpcif_bit_size(op->data.buswidth)); in rpcif_prepare_impl()
498 struct rpcif_priv *rpc = dev_get_drvdata(dev); in rpcif_prepare() local
500 rpc->info->impl->prepare(rpc, op, offs, len); in rpcif_prepare()
504 static int rpcif_manual_xfer_impl(struct rpcif_priv *rpc) in rpcif_manual_xfer_impl() argument
506 u32 smenr, smcr, pos = 0, max = rpc->bus_size == 2 ? 8 : 4; in rpcif_manual_xfer_impl()
509 regmap_update_bits(rpc->regmap, RPCIF_PHYCNT, in rpcif_manual_xfer_impl()
511 regmap_update_bits(rpc->regmap, RPCIF_CMNCR, in rpcif_manual_xfer_impl()
513 regmap_write(rpc->regmap, RPCIF_SMCMR, rpc->command); in rpcif_manual_xfer_impl()
514 regmap_write(rpc->regmap, RPCIF_SMOPR, rpc->option); in rpcif_manual_xfer_impl()
515 regmap_write(rpc->regmap, RPCIF_SMDMCR, rpc->dummy); in rpcif_manual_xfer_impl()
516 regmap_write(rpc->regmap, RPCIF_SMDRENR, rpc->ddr); in rpcif_manual_xfer_impl()
517 regmap_write(rpc->regmap, RPCIF_SMADR, rpc->smadr); in rpcif_manual_xfer_impl()
518 smenr = rpc->enable; in rpcif_manual_xfer_impl()
520 switch (rpc->dir) { in rpcif_manual_xfer_impl()
522 while (pos < rpc->xferlen) { in rpcif_manual_xfer_impl()
523 u32 bytes_left = rpc->xferlen - pos; in rpcif_manual_xfer_impl()
526 smcr = rpc->smcr | RPCIF_SMCR_SPIE; in rpcif_manual_xfer_impl()
533 smenr |= RPCIF_SMENR_SPIDE(rpcif_bits_set(rpc, nbytes)); in rpcif_manual_xfer_impl()
534 regmap_write(rpc->regmap, RPCIF_SMENR, smenr); in rpcif_manual_xfer_impl()
535 rpc->xfer_size = nbytes; in rpcif_manual_xfer_impl()
537 memcpy(data, rpc->buffer + pos, nbytes); in rpcif_manual_xfer_impl()
539 regmap_write(rpc->regmap, RPCIF_SMWDR1, *p++); in rpcif_manual_xfer_impl()
540 regmap_write(rpc->regmap, RPCIF_SMWDR0, *p); in rpcif_manual_xfer_impl()
542 regmap_write(rpc->regmap, RPCIF_SMCR, smcr); in rpcif_manual_xfer_impl()
543 ret = wait_msg_xfer_end(rpc); in rpcif_manual_xfer_impl()
548 smenr = rpc->enable & in rpcif_manual_xfer_impl()
554 * RPC-IF spoils the data for the commands without an address in rpcif_manual_xfer_impl()
559 if (!(smenr & RPCIF_SMENR_ADE(0xF)) && rpc->dirmap) { in rpcif_manual_xfer_impl()
562 regmap_update_bits(rpc->regmap, RPCIF_CMNCR, in rpcif_manual_xfer_impl()
564 regmap_write(rpc->regmap, RPCIF_DRCR, in rpcif_manual_xfer_impl()
566 regmap_write(rpc->regmap, RPCIF_DRCMR, rpc->command); in rpcif_manual_xfer_impl()
567 regmap_write(rpc->regmap, RPCIF_DREAR, in rpcif_manual_xfer_impl()
569 regmap_write(rpc->regmap, RPCIF_DROPR, rpc->option); in rpcif_manual_xfer_impl()
570 regmap_write(rpc->regmap, RPCIF_DRENR, in rpcif_manual_xfer_impl()
572 regmap_write(rpc->regmap, RPCIF_DRDMCR, rpc->dummy); in rpcif_manual_xfer_impl()
573 regmap_write(rpc->regmap, RPCIF_DRDRENR, rpc->ddr); in rpcif_manual_xfer_impl()
574 memcpy_fromio(rpc->buffer, rpc->dirmap, rpc->xferlen); in rpcif_manual_xfer_impl()
575 regmap_write(rpc->regmap, RPCIF_DRCR, RPCIF_DRCR_RCF); in rpcif_manual_xfer_impl()
577 regmap_read(rpc->regmap, RPCIF_DRCR, &dummy); in rpcif_manual_xfer_impl()
580 while (pos < rpc->xferlen) { in rpcif_manual_xfer_impl()
581 u32 bytes_left = rpc->xferlen - pos; in rpcif_manual_xfer_impl()
587 regmap_write(rpc->regmap, RPCIF_SMADR, in rpcif_manual_xfer_impl()
588 rpc->smadr + pos); in rpcif_manual_xfer_impl()
590 smenr |= RPCIF_SMENR_SPIDE(rpcif_bits_set(rpc, nbytes)); in rpcif_manual_xfer_impl()
591 regmap_write(rpc->regmap, RPCIF_SMENR, smenr); in rpcif_manual_xfer_impl()
592 regmap_write(rpc->regmap, RPCIF_SMCR, in rpcif_manual_xfer_impl()
593 rpc->smcr | RPCIF_SMCR_SPIE); in rpcif_manual_xfer_impl()
594 rpc->xfer_size = nbytes; in rpcif_manual_xfer_impl()
595 ret = wait_msg_xfer_end(rpc); in rpcif_manual_xfer_impl()
600 regmap_read(rpc->regmap, RPCIF_SMRDR1, p++); in rpcif_manual_xfer_impl()
601 regmap_read(rpc->regmap, RPCIF_SMRDR0, p); in rpcif_manual_xfer_impl()
602 memcpy(rpc->buffer + pos, data, nbytes); in rpcif_manual_xfer_impl()
608 regmap_write(rpc->regmap, RPCIF_SMENR, rpc->enable); in rpcif_manual_xfer_impl()
609 regmap_write(rpc->regmap, RPCIF_SMCR, in rpcif_manual_xfer_impl()
610 rpc->smcr | RPCIF_SMCR_SPIE); in rpcif_manual_xfer_impl()
611 ret = wait_msg_xfer_end(rpc); in rpcif_manual_xfer_impl()
619 if (reset_control_reset(rpc->rstc)) in rpcif_manual_xfer_impl()
620 dev_err(rpc->dev, "Failed to reset HW\n"); in rpcif_manual_xfer_impl()
621 rpcif_hw_init_impl(rpc, rpc->bus_size == 2); in rpcif_manual_xfer_impl()
767 struct rpcif_priv *rpc = dev_get_drvdata(dev); in rpcif_manual_xfer() local
774 ret = rpc->info->impl->manual_xfer(rpc); in rpcif_manual_xfer()
824 static size_t rpcif_dirmap_read_impl(struct rpcif_priv *rpc, u64 offs, in rpcif_dirmap_read_impl() argument
827 loff_t from = offs & (rpc->size - 1); in rpcif_dirmap_read_impl()
828 size_t size = rpc->size - from; in rpcif_dirmap_read_impl()
833 regmap_update_bits(rpc->regmap, RPCIF_CMNCR, RPCIF_CMNCR_MD, 0); in rpcif_dirmap_read_impl()
834 regmap_write(rpc->regmap, RPCIF_DRCR, 0); in rpcif_dirmap_read_impl()
835 regmap_write(rpc->regmap, RPCIF_DRCMR, rpc->command); in rpcif_dirmap_read_impl()
836 regmap_write(rpc->regmap, RPCIF_DREAR, in rpcif_dirmap_read_impl()
838 regmap_write(rpc->regmap, RPCIF_DROPR, rpc->option); in rpcif_dirmap_read_impl()
839 regmap_write(rpc->regmap, RPCIF_DRENR, in rpcif_dirmap_read_impl()
840 rpc->enable & ~RPCIF_SMENR_SPIDE(0xF)); in rpcif_dirmap_read_impl()
841 regmap_write(rpc->regmap, RPCIF_DRDMCR, rpc->dummy); in rpcif_dirmap_read_impl()
842 regmap_write(rpc->regmap, RPCIF_DRDRENR, rpc->ddr); in rpcif_dirmap_read_impl()
844 if (rpc->bus_size == 2) in rpcif_dirmap_read_impl()
845 memcpy_fromio_readw(buf, rpc->dirmap + from, len); in rpcif_dirmap_read_impl()
847 memcpy_fromio(buf, rpc->dirmap + from, len); in rpcif_dirmap_read_impl()
890 struct rpcif_priv *rpc = dev_get_drvdata(dev); in rpcif_dirmap_read() local
898 read = rpc->info->impl->dirmap_read(rpc, offs, len, buf); in rpcif_dirmap_read()
977 struct rpcif_priv *rpc; in rpcif_probe() local
989 name = "rpc-if-spi"; in rpcif_probe()
991 name = "rpc-if-hyperflash"; in rpcif_probe()
999 rpc = devm_kzalloc(dev, sizeof(*rpc), GFP_KERNEL); in rpcif_probe()
1000 if (!rpc) in rpcif_probe()
1003 rpc->base = devm_platform_ioremap_resource_byname(pdev, "regs"); in rpcif_probe()
1004 if (IS_ERR(rpc->base)) in rpcif_probe()
1005 return PTR_ERR(rpc->base); in rpcif_probe()
1006 rpc->info = of_device_get_match_data(dev); in rpcif_probe()
1007 rpc->regmap = devm_regmap_init(dev, NULL, rpc, rpc->info->regmap_config); in rpcif_probe()
1008 if (IS_ERR(rpc->regmap)) { in rpcif_probe()
1010 PTR_ERR(rpc->regmap)); in rpcif_probe()
1011 return PTR_ERR(rpc->regmap); in rpcif_probe()
1015 rpc->dirmap = devm_ioremap_resource(dev, res); in rpcif_probe()
1016 if (IS_ERR(rpc->dirmap)) in rpcif_probe()
1017 return PTR_ERR(rpc->dirmap); in rpcif_probe()
1019 rpc->size = resource_size(res); in rpcif_probe()
1020 rpc->rstc = devm_reset_control_array_get_exclusive(dev); in rpcif_probe()
1021 if (IS_ERR(rpc->rstc)) in rpcif_probe()
1022 return PTR_ERR(rpc->rstc); in rpcif_probe()
1029 rpc->spix2_clk = devm_clk_get_optional_enabled(dev, "spix2"); in rpcif_probe()
1030 if (IS_ERR(rpc->spix2_clk)) in rpcif_probe()
1031 return dev_err_probe(dev, PTR_ERR(rpc->spix2_clk), in rpcif_probe()
1034 rpc->spi_clk = devm_clk_get_optional_enabled(dev, "spi"); in rpcif_probe()
1035 if (IS_ERR(rpc->spi_clk)) in rpcif_probe()
1036 return dev_err_probe(dev, PTR_ERR(rpc->spi_clk), in rpcif_probe()
1044 rpc->dev = dev; in rpcif_probe()
1045 rpc->vdev = vdev; in rpcif_probe()
1046 platform_set_drvdata(pdev, rpc); in rpcif_probe()
1059 struct rpcif_priv *rpc = platform_get_drvdata(pdev); in rpcif_remove() local
1061 platform_device_unregister(rpc->vdev); in rpcif_remove()
1066 struct rpcif_priv *rpc = dev_get_drvdata(dev); in rpcif_suspend() local
1068 clk_disable_unprepare(rpc->spi_clk); in rpcif_suspend()
1069 clk_disable_unprepare(rpc->spix2_clk); in rpcif_suspend()
1076 struct rpcif_priv *rpc = dev_get_drvdata(dev); in rpcif_resume() local
1079 ret = clk_prepare_enable(rpc->spix2_clk); in rpcif_resume()
1085 ret = clk_prepare_enable(rpc->spi_clk); in rpcif_resume()
1087 clk_disable_unprepare(rpc->spix2_clk); in rpcif_resume()
1148 { .compatible = "renesas,r8a7796-rpc-if", .data = &rpcif_info_r8a7796 },
1150 { .compatible = "renesas,rcar-gen3-rpc-if", .data = &rpcif_info_gen3 },
1151 { .compatible = "renesas,rcar-gen4-rpc-if", .data = &rpcif_info_gen4 },
1152 { .compatible = "renesas,rzg2l-rpc-if", .data = &rpcif_info_rz_g2l },
1163 .name = "rpc-if",
1170 MODULE_DESCRIPTION("Renesas RPC-IF core driver");