Lines Matching +full:rpc +full:- +full:if
1 // SPDX-License-Identifier: GPL-2.0
3 * Renesas RPC-IF core driver
5 * Copyright (C) 2018-2019 Renesas Solutions Corp.
7 * Copyright (C) 2019-2020 Cogent Embedded, Inc.
19 #include <memory/renesas-rpc-if.h>
45 #define RPCIF_DRCR_RBURST(v) ((((v) - 1) & 0x1F) << 16)
113 #define RPCIF_DMDMCR_DMCYC(v) ((((v) - 1) & 0x1F) << 0)
122 #define RPCIF_SMDMCR_DMCYC(v) ((((v) - 1) & 0x1F) << 0)
171 struct rpcif *rpc = context; in rpcif_reg_read() local
173 if (reg == RPCIF_SMRDR0 || reg == RPCIF_SMWDR0) { in rpcif_reg_read()
174 u32 spide = readl(rpc->base + RPCIF_SMENR) & RPCIF_SMENR_SPIDE(0xF); in rpcif_reg_read()
176 if (spide == 0x8) { in rpcif_reg_read()
177 *val = readb(rpc->base + reg); in rpcif_reg_read()
179 } else if (spide == 0xC) { in rpcif_reg_read()
180 *val = readw(rpc->base + reg); in rpcif_reg_read()
182 } else if (spide != 0xF) { in rpcif_reg_read()
183 return -EILSEQ; in rpcif_reg_read()
187 *val = readl(rpc->base + reg); in rpcif_reg_read()
194 struct rpcif *rpc = context; in rpcif_reg_write() local
196 if (reg == RPCIF_SMRDR0 || reg == RPCIF_SMWDR0) { in rpcif_reg_write()
197 u32 spide = readl(rpc->base + RPCIF_SMENR) & RPCIF_SMENR_SPIDE(0xF); in rpcif_reg_write()
199 if (spide == 0x8) { in rpcif_reg_write()
200 writeb(val, rpc->base + reg); in rpcif_reg_write()
202 } else if (spide == 0xC) { in rpcif_reg_write()
203 writew(val, rpc->base + reg); in rpcif_reg_write()
205 } else if (spide != 0xF) { in rpcif_reg_write()
206 return -EILSEQ; in rpcif_reg_write()
210 writel(val, rpc->base + reg); in rpcif_reg_write()
225 int rpcif_sw_init(struct rpcif *rpc, struct device *dev) in rpcif_sw_init() argument
230 rpc->dev = dev; in rpcif_sw_init()
233 rpc->base = devm_ioremap_resource(&pdev->dev, res); in rpcif_sw_init()
234 if (IS_ERR(rpc->base)) in rpcif_sw_init()
235 return PTR_ERR(rpc->base); in rpcif_sw_init()
237 rpc->regmap = devm_regmap_init(&pdev->dev, NULL, rpc, &rpcif_regmap_config); in rpcif_sw_init()
238 if (IS_ERR(rpc->regmap)) { in rpcif_sw_init()
239 dev_err(&pdev->dev, in rpcif_sw_init()
241 PTR_ERR(rpc->regmap)); in rpcif_sw_init()
242 return PTR_ERR(rpc->regmap); in rpcif_sw_init()
246 rpc->dirmap = devm_ioremap_resource(&pdev->dev, res); in rpcif_sw_init()
247 if (IS_ERR(rpc->dirmap)) in rpcif_sw_init()
248 return PTR_ERR(rpc->dirmap); in rpcif_sw_init()
249 rpc->size = resource_size(res); in rpcif_sw_init()
251 rpc->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL); in rpcif_sw_init()
253 return PTR_ERR_OR_ZERO(rpc->rstc); in rpcif_sw_init()
257 void rpcif_enable_rpm(struct rpcif *rpc) in rpcif_enable_rpm() argument
259 pm_runtime_enable(rpc->dev); in rpcif_enable_rpm()
263 void rpcif_disable_rpm(struct rpcif *rpc) in rpcif_disable_rpm() argument
265 pm_runtime_disable(rpc->dev); in rpcif_disable_rpm()
269 void rpcif_hw_init(struct rpcif *rpc, bool hyperflash) in rpcif_hw_init() argument
273 pm_runtime_get_sync(rpc->dev); in rpcif_hw_init()
283 regmap_write(rpc->regmap, RPCIF_PHYCNT, RPCIF_PHYCNT_STRTIM(7) | in rpcif_hw_init()
292 regmap_write(rpc->regmap, RPCIF_PHYOFFSET1, 0x1511144 | in rpcif_hw_init()
294 regmap_write(rpc->regmap, RPCIF_PHYOFFSET2, 0x31 | in rpcif_hw_init()
297 if (hyperflash) in rpcif_hw_init()
298 regmap_update_bits(rpc->regmap, RPCIF_PHYINT, in rpcif_hw_init()
301 regmap_write(rpc->regmap, RPCIF_CMNCR, RPCIF_CMNCR_SFDE | in rpcif_hw_init()
305 regmap_write(rpc->regmap, RPCIF_DRCR, RPCIF_DRCR_RCF); in rpcif_hw_init()
307 regmap_read(rpc->regmap, RPCIF_DRCR, &dummy); in rpcif_hw_init()
308 regmap_write(rpc->regmap, RPCIF_SSLDR, RPCIF_SSLDR_SPNDL(7) | in rpcif_hw_init()
311 pm_runtime_put(rpc->dev); in rpcif_hw_init()
313 rpc->bus_size = hyperflash ? 2 : 1; in rpcif_hw_init()
317 static int wait_msg_xfer_end(struct rpcif *rpc) in wait_msg_xfer_end() argument
321 return regmap_read_poll_timeout(rpc->regmap, RPCIF_CMNSR, sts, in wait_msg_xfer_end()
326 static u8 rpcif_bits_set(struct rpcif *rpc, u32 nbytes) in rpcif_bits_set() argument
328 if (rpc->bus_size == 2) in rpcif_bits_set()
331 return GENMASK(3, 4 - nbytes); in rpcif_bits_set()
339 void rpcif_prepare(struct rpcif *rpc, const struct rpcif_op *op, u64 *offs, in rpcif_prepare() argument
342 rpc->smcr = 0; in rpcif_prepare()
343 rpc->smadr = 0; in rpcif_prepare()
344 rpc->enable = 0; in rpcif_prepare()
345 rpc->command = 0; in rpcif_prepare()
346 rpc->option = 0; in rpcif_prepare()
347 rpc->dummy = 0; in rpcif_prepare()
348 rpc->ddr = 0; in rpcif_prepare()
349 rpc->xferlen = 0; in rpcif_prepare()
351 if (op->cmd.buswidth) { in rpcif_prepare()
352 rpc->enable = RPCIF_SMENR_CDE | in rpcif_prepare()
353 RPCIF_SMENR_CDB(rpcif_bit_size(op->cmd.buswidth)); in rpcif_prepare()
354 rpc->command = RPCIF_SMCMR_CMD(op->cmd.opcode); in rpcif_prepare()
355 if (op->cmd.ddr) in rpcif_prepare()
356 rpc->ddr = RPCIF_SMDRENR_HYPE(0x5); in rpcif_prepare()
358 if (op->ocmd.buswidth) { in rpcif_prepare()
359 rpc->enable |= RPCIF_SMENR_OCDE | in rpcif_prepare()
360 RPCIF_SMENR_OCDB(rpcif_bit_size(op->ocmd.buswidth)); in rpcif_prepare()
361 rpc->command |= RPCIF_SMCMR_OCMD(op->ocmd.opcode); in rpcif_prepare()
364 if (op->addr.buswidth) { in rpcif_prepare()
365 rpc->enable |= in rpcif_prepare()
366 RPCIF_SMENR_ADB(rpcif_bit_size(op->addr.buswidth)); in rpcif_prepare()
367 if (op->addr.nbytes == 4) in rpcif_prepare()
368 rpc->enable |= RPCIF_SMENR_ADE(0xF); in rpcif_prepare()
370 rpc->enable |= RPCIF_SMENR_ADE(GENMASK( in rpcif_prepare()
371 2, 3 - op->addr.nbytes)); in rpcif_prepare()
372 if (op->addr.ddr) in rpcif_prepare()
373 rpc->ddr |= RPCIF_SMDRENR_ADDRE; in rpcif_prepare()
375 if (offs && len) in rpcif_prepare()
376 rpc->smadr = *offs; in rpcif_prepare()
378 rpc->smadr = op->addr.val; in rpcif_prepare()
381 if (op->dummy.buswidth) { in rpcif_prepare()
382 rpc->enable |= RPCIF_SMENR_DME; in rpcif_prepare()
383 rpc->dummy = RPCIF_SMDMCR_DMCYC(op->dummy.ncycles / in rpcif_prepare()
384 op->dummy.buswidth); in rpcif_prepare()
387 if (op->option.buswidth) { in rpcif_prepare()
388 rpc->enable |= RPCIF_SMENR_OPDE( in rpcif_prepare()
389 rpcif_bits_set(rpc, op->option.nbytes)) | in rpcif_prepare()
390 RPCIF_SMENR_OPDB(rpcif_bit_size(op->option.buswidth)); in rpcif_prepare()
391 if (op->option.ddr) in rpcif_prepare()
392 rpc->ddr |= RPCIF_SMDRENR_OPDRE; in rpcif_prepare()
393 rpc->option = op->option.val; in rpcif_prepare()
396 rpc->dir = op->data.dir; in rpcif_prepare()
397 if (op->data.buswidth) { in rpcif_prepare()
400 rpc->buffer = op->data.buf.in; in rpcif_prepare()
401 switch (op->data.dir) { in rpcif_prepare()
403 rpc->smcr = RPCIF_SMCR_SPIRE; in rpcif_prepare()
406 rpc->smcr = RPCIF_SMCR_SPIWE; in rpcif_prepare()
411 if (op->data.ddr) in rpcif_prepare()
412 rpc->ddr |= RPCIF_SMDRENR_SPIDRE; in rpcif_prepare()
414 if (offs && len) in rpcif_prepare()
417 nbytes = op->data.nbytes; in rpcif_prepare()
418 rpc->xferlen = nbytes; in rpcif_prepare()
420 rpc->enable |= RPCIF_SMENR_SPIDB(rpcif_bit_size(op->data.buswidth)); in rpcif_prepare()
425 int rpcif_manual_xfer(struct rpcif *rpc) in rpcif_manual_xfer() argument
427 u32 smenr, smcr, pos = 0, max = rpc->bus_size == 2 ? 8 : 4; in rpcif_manual_xfer()
430 pm_runtime_get_sync(rpc->dev); in rpcif_manual_xfer()
432 regmap_update_bits(rpc->regmap, RPCIF_PHYCNT, in rpcif_manual_xfer()
434 regmap_update_bits(rpc->regmap, RPCIF_CMNCR, in rpcif_manual_xfer()
436 regmap_write(rpc->regmap, RPCIF_SMCMR, rpc->command); in rpcif_manual_xfer()
437 regmap_write(rpc->regmap, RPCIF_SMOPR, rpc->option); in rpcif_manual_xfer()
438 regmap_write(rpc->regmap, RPCIF_SMDMCR, rpc->dummy); in rpcif_manual_xfer()
439 regmap_write(rpc->regmap, RPCIF_SMDRENR, rpc->ddr); in rpcif_manual_xfer()
440 regmap_write(rpc->regmap, RPCIF_SMADR, rpc->smadr); in rpcif_manual_xfer()
441 smenr = rpc->enable; in rpcif_manual_xfer()
443 switch (rpc->dir) { in rpcif_manual_xfer()
445 while (pos < rpc->xferlen) { in rpcif_manual_xfer()
446 u32 bytes_left = rpc->xferlen - pos; in rpcif_manual_xfer()
449 smcr = rpc->smcr | RPCIF_SMCR_SPIE; in rpcif_manual_xfer()
453 if (bytes_left > nbytes) in rpcif_manual_xfer()
456 smenr |= RPCIF_SMENR_SPIDE(rpcif_bits_set(rpc, nbytes)); in rpcif_manual_xfer()
457 regmap_write(rpc->regmap, RPCIF_SMENR, smenr); in rpcif_manual_xfer()
459 memcpy(data, rpc->buffer + pos, nbytes); in rpcif_manual_xfer()
460 if (nbytes == 8) { in rpcif_manual_xfer()
461 regmap_write(rpc->regmap, RPCIF_SMWDR1, in rpcif_manual_xfer()
463 regmap_write(rpc->regmap, RPCIF_SMWDR0, in rpcif_manual_xfer()
466 regmap_write(rpc->regmap, RPCIF_SMWDR0, in rpcif_manual_xfer()
470 regmap_write(rpc->regmap, RPCIF_SMCR, smcr); in rpcif_manual_xfer()
471 ret = wait_msg_xfer_end(rpc); in rpcif_manual_xfer()
472 if (ret) in rpcif_manual_xfer()
476 smenr = rpc->enable & in rpcif_manual_xfer()
482 * RPC-IF spoils the data for the commands without an address in rpcif_manual_xfer()
487 if (!(smenr & RPCIF_SMENR_ADE(0xF)) && rpc->dirmap) { in rpcif_manual_xfer()
490 regmap_update_bits(rpc->regmap, RPCIF_CMNCR, in rpcif_manual_xfer()
492 regmap_write(rpc->regmap, RPCIF_DRCR, in rpcif_manual_xfer()
494 regmap_write(rpc->regmap, RPCIF_DRCMR, rpc->command); in rpcif_manual_xfer()
495 regmap_write(rpc->regmap, RPCIF_DREAR, in rpcif_manual_xfer()
497 regmap_write(rpc->regmap, RPCIF_DROPR, rpc->option); in rpcif_manual_xfer()
498 regmap_write(rpc->regmap, RPCIF_DRENR, in rpcif_manual_xfer()
500 regmap_write(rpc->regmap, RPCIF_DRDMCR, rpc->dummy); in rpcif_manual_xfer()
501 regmap_write(rpc->regmap, RPCIF_DRDRENR, rpc->ddr); in rpcif_manual_xfer()
502 memcpy_fromio(rpc->buffer, rpc->dirmap, rpc->xferlen); in rpcif_manual_xfer()
503 regmap_write(rpc->regmap, RPCIF_DRCR, RPCIF_DRCR_RCF); in rpcif_manual_xfer()
505 regmap_read(rpc->regmap, RPCIF_DRCR, &dummy); in rpcif_manual_xfer()
508 while (pos < rpc->xferlen) { in rpcif_manual_xfer()
509 u32 bytes_left = rpc->xferlen - pos; in rpcif_manual_xfer()
515 regmap_write(rpc->regmap, RPCIF_SMADR, in rpcif_manual_xfer()
516 rpc->smadr + pos); in rpcif_manual_xfer()
518 smenr |= RPCIF_SMENR_SPIDE(rpcif_bits_set(rpc, nbytes)); in rpcif_manual_xfer()
519 regmap_write(rpc->regmap, RPCIF_SMENR, smenr); in rpcif_manual_xfer()
520 regmap_write(rpc->regmap, RPCIF_SMCR, in rpcif_manual_xfer()
521 rpc->smcr | RPCIF_SMCR_SPIE); in rpcif_manual_xfer()
522 ret = wait_msg_xfer_end(rpc); in rpcif_manual_xfer()
523 if (ret) in rpcif_manual_xfer()
526 if (nbytes == 8) { in rpcif_manual_xfer()
527 regmap_read(rpc->regmap, RPCIF_SMRDR1, in rpcif_manual_xfer()
529 regmap_read(rpc->regmap, RPCIF_SMRDR0, in rpcif_manual_xfer()
532 regmap_read(rpc->regmap, RPCIF_SMRDR0, in rpcif_manual_xfer()
535 memcpy(rpc->buffer + pos, data, nbytes); in rpcif_manual_xfer()
541 regmap_write(rpc->regmap, RPCIF_SMENR, rpc->enable); in rpcif_manual_xfer()
542 regmap_write(rpc->regmap, RPCIF_SMCR, in rpcif_manual_xfer()
543 rpc->smcr | RPCIF_SMCR_SPIE); in rpcif_manual_xfer()
544 ret = wait_msg_xfer_end(rpc); in rpcif_manual_xfer()
545 if (ret) in rpcif_manual_xfer()
550 pm_runtime_put(rpc->dev); in rpcif_manual_xfer()
554 if (reset_control_reset(rpc->rstc)) in rpcif_manual_xfer()
555 dev_err(rpc->dev, "Failed to reset HW\n"); in rpcif_manual_xfer()
556 rpcif_hw_init(rpc, rpc->bus_size == 2); in rpcif_manual_xfer()
561 ssize_t rpcif_dirmap_read(struct rpcif *rpc, u64 offs, size_t len, void *buf) in rpcif_dirmap_read() argument
563 loff_t from = offs & (RPCIF_DIRMAP_SIZE - 1); in rpcif_dirmap_read()
564 size_t size = RPCIF_DIRMAP_SIZE - from; in rpcif_dirmap_read()
566 if (len > size) in rpcif_dirmap_read()
569 pm_runtime_get_sync(rpc->dev); in rpcif_dirmap_read()
571 regmap_update_bits(rpc->regmap, RPCIF_CMNCR, RPCIF_CMNCR_MD, 0); in rpcif_dirmap_read()
572 regmap_write(rpc->regmap, RPCIF_DRCR, 0); in rpcif_dirmap_read()
573 regmap_write(rpc->regmap, RPCIF_DRCMR, rpc->command); in rpcif_dirmap_read()
574 regmap_write(rpc->regmap, RPCIF_DREAR, in rpcif_dirmap_read()
576 regmap_write(rpc->regmap, RPCIF_DROPR, rpc->option); in rpcif_dirmap_read()
577 regmap_write(rpc->regmap, RPCIF_DRENR, in rpcif_dirmap_read()
578 rpc->enable & ~RPCIF_SMENR_SPIDE(0xF)); in rpcif_dirmap_read()
579 regmap_write(rpc->regmap, RPCIF_DRDMCR, rpc->dummy); in rpcif_dirmap_read()
580 regmap_write(rpc->regmap, RPCIF_DRDRENR, rpc->ddr); in rpcif_dirmap_read()
582 memcpy_fromio(buf, rpc->dirmap + from, len); in rpcif_dirmap_read()
584 pm_runtime_put(rpc->dev); in rpcif_dirmap_read()
596 flash = of_get_next_child(pdev->dev.of_node, NULL); in rpcif_probe()
597 if (!flash) { in rpcif_probe()
598 dev_warn(&pdev->dev, "no flash node found\n"); in rpcif_probe()
599 return -ENODEV; in rpcif_probe()
602 if (of_device_is_compatible(flash, "jedec,spi-nor")) { in rpcif_probe()
603 name = "rpc-if-spi"; in rpcif_probe()
604 } else if (of_device_is_compatible(flash, "cfi-flash")) { in rpcif_probe()
605 name = "rpc-if-hyperflash"; in rpcif_probe()
608 dev_warn(&pdev->dev, "unknown flash type\n"); in rpcif_probe()
609 return -ENODEV; in rpcif_probe()
613 vdev = platform_device_alloc(name, pdev->id); in rpcif_probe()
614 if (!vdev) in rpcif_probe()
615 return -ENOMEM; in rpcif_probe()
616 vdev->dev.parent = &pdev->dev; in rpcif_probe()
631 { .compatible = "renesas,rcar-gen3-rpc-if", },
640 .name = "rpc-if",
646 MODULE_DESCRIPTION("Renesas RPC-IF core driver");