Lines Matching +full:i3c +full:- +full:master

1 // SPDX-License-Identifier: GPL-2.0
13 #include <linux/i3c/master.h>
26 #include "dw-i3c-master.h"
94 #define QUEUE_THLD_CTRL_IBI_STAT(x) (((x) - 1) << 24)
98 #define QUEUE_THLD_CTRL_RESP_BUF(x) (((x) - 1) << 8)
257 if (cmd->ndests > 1) in dw_i3c_master_supports_ccc_cmd()
260 switch (cmd->id) { in dw_i3c_master_supports_ccc_cmd()
292 to_dw_i3c_master(struct i3c_master_controller *master) in to_dw_i3c_master() argument
294 return container_of(master, struct dw_i3c_master, base); in to_dw_i3c_master()
297 static void dw_i3c_master_disable(struct dw_i3c_master *master) in dw_i3c_master_disable() argument
299 writel(readl(master->regs + DEVICE_CTRL) & ~DEV_CTRL_ENABLE, in dw_i3c_master_disable()
300 master->regs + DEVICE_CTRL); in dw_i3c_master_disable()
303 static void dw_i3c_master_enable(struct dw_i3c_master *master) in dw_i3c_master_enable() argument
307 dev_ctrl = readl(master->regs + DEVICE_CTRL); in dw_i3c_master_enable()
308 /* For now don't support Hot-Join */ in dw_i3c_master_enable()
310 if (master->i2c_slv_prsnt) in dw_i3c_master_enable()
313 master->regs + DEVICE_CTRL); in dw_i3c_master_enable()
316 static int dw_i3c_master_get_addr_pos(struct dw_i3c_master *master, u8 addr) in dw_i3c_master_get_addr_pos() argument
320 for (pos = 0; pos < master->maxdevs; pos++) { in dw_i3c_master_get_addr_pos()
321 if (addr == master->devs[pos].addr) in dw_i3c_master_get_addr_pos()
325 return -EINVAL; in dw_i3c_master_get_addr_pos()
328 static int dw_i3c_master_get_free_pos(struct dw_i3c_master *master) in dw_i3c_master_get_free_pos() argument
330 if (!(master->free_pos & GENMASK(master->maxdevs - 1, 0))) in dw_i3c_master_get_free_pos()
331 return -ENOSPC; in dw_i3c_master_get_free_pos()
333 return ffs(master->free_pos) - 1; in dw_i3c_master_get_free_pos()
336 static void dw_i3c_master_wr_tx_fifo(struct dw_i3c_master *master, in dw_i3c_master_wr_tx_fifo() argument
339 writesl(master->regs + RX_TX_DATA_PORT, bytes, nbytes / 4); in dw_i3c_master_wr_tx_fifo()
344 writesl(master->regs + RX_TX_DATA_PORT, &tmp, 1); in dw_i3c_master_wr_tx_fifo()
348 static void dw_i3c_master_read_fifo(struct dw_i3c_master *master, in dw_i3c_master_read_fifo() argument
351 readsl(master->regs + reg, bytes, nbytes / 4); in dw_i3c_master_read_fifo()
355 readsl(master->regs + reg, &tmp, 1); in dw_i3c_master_read_fifo()
360 static void dw_i3c_master_read_rx_fifo(struct dw_i3c_master *master, in dw_i3c_master_read_rx_fifo() argument
363 return dw_i3c_master_read_fifo(master, RX_TX_DATA_PORT, bytes, nbytes); in dw_i3c_master_read_rx_fifo()
366 static void dw_i3c_master_read_ibi_fifo(struct dw_i3c_master *master, in dw_i3c_master_read_ibi_fifo() argument
369 return dw_i3c_master_read_fifo(master, IBI_QUEUE_STATUS, bytes, nbytes); in dw_i3c_master_read_ibi_fifo()
373 dw_i3c_master_alloc_xfer(struct dw_i3c_master *master, unsigned int ncmds) in dw_i3c_master_alloc_xfer() argument
381 INIT_LIST_HEAD(&xfer->node); in dw_i3c_master_alloc_xfer()
382 xfer->ncmds = ncmds; in dw_i3c_master_alloc_xfer()
383 xfer->ret = -ETIMEDOUT; in dw_i3c_master_alloc_xfer()
393 static void dw_i3c_master_start_xfer_locked(struct dw_i3c_master *master) in dw_i3c_master_start_xfer_locked() argument
395 struct dw_i3c_xfer *xfer = master->xferqueue.cur; in dw_i3c_master_start_xfer_locked()
402 for (i = 0; i < xfer->ncmds; i++) { in dw_i3c_master_start_xfer_locked()
403 struct dw_i3c_cmd *cmd = &xfer->cmds[i]; in dw_i3c_master_start_xfer_locked()
405 dw_i3c_master_wr_tx_fifo(master, cmd->tx_buf, cmd->tx_len); in dw_i3c_master_start_xfer_locked()
408 thld_ctrl = readl(master->regs + QUEUE_THLD_CTRL); in dw_i3c_master_start_xfer_locked()
410 thld_ctrl |= QUEUE_THLD_CTRL_RESP_BUF(xfer->ncmds); in dw_i3c_master_start_xfer_locked()
411 writel(thld_ctrl, master->regs + QUEUE_THLD_CTRL); in dw_i3c_master_start_xfer_locked()
413 for (i = 0; i < xfer->ncmds; i++) { in dw_i3c_master_start_xfer_locked()
414 struct dw_i3c_cmd *cmd = &xfer->cmds[i]; in dw_i3c_master_start_xfer_locked()
416 writel(cmd->cmd_hi, master->regs + COMMAND_QUEUE_PORT); in dw_i3c_master_start_xfer_locked()
417 writel(cmd->cmd_lo, master->regs + COMMAND_QUEUE_PORT); in dw_i3c_master_start_xfer_locked()
421 static void dw_i3c_master_enqueue_xfer(struct dw_i3c_master *master, in dw_i3c_master_enqueue_xfer() argument
426 init_completion(&xfer->comp); in dw_i3c_master_enqueue_xfer()
427 spin_lock_irqsave(&master->xferqueue.lock, flags); in dw_i3c_master_enqueue_xfer()
428 if (master->xferqueue.cur) { in dw_i3c_master_enqueue_xfer()
429 list_add_tail(&xfer->node, &master->xferqueue.list); in dw_i3c_master_enqueue_xfer()
431 master->xferqueue.cur = xfer; in dw_i3c_master_enqueue_xfer()
432 dw_i3c_master_start_xfer_locked(master); in dw_i3c_master_enqueue_xfer()
434 spin_unlock_irqrestore(&master->xferqueue.lock, flags); in dw_i3c_master_enqueue_xfer()
437 static void dw_i3c_master_dequeue_xfer_locked(struct dw_i3c_master *master, in dw_i3c_master_dequeue_xfer_locked() argument
440 if (master->xferqueue.cur == xfer) { in dw_i3c_master_dequeue_xfer_locked()
443 master->xferqueue.cur = NULL; in dw_i3c_master_dequeue_xfer_locked()
447 master->regs + RESET_CTRL); in dw_i3c_master_dequeue_xfer_locked()
449 readl_poll_timeout_atomic(master->regs + RESET_CTRL, status, in dw_i3c_master_dequeue_xfer_locked()
452 list_del_init(&xfer->node); in dw_i3c_master_dequeue_xfer_locked()
456 static void dw_i3c_master_dequeue_xfer(struct dw_i3c_master *master, in dw_i3c_master_dequeue_xfer() argument
461 spin_lock_irqsave(&master->xferqueue.lock, flags); in dw_i3c_master_dequeue_xfer()
462 dw_i3c_master_dequeue_xfer_locked(master, xfer); in dw_i3c_master_dequeue_xfer()
463 spin_unlock_irqrestore(&master->xferqueue.lock, flags); in dw_i3c_master_dequeue_xfer()
466 static void dw_i3c_master_end_xfer_locked(struct dw_i3c_master *master, u32 isr) in dw_i3c_master_end_xfer_locked() argument
468 struct dw_i3c_xfer *xfer = master->xferqueue.cur; in dw_i3c_master_end_xfer_locked()
475 nresp = readl(master->regs + QUEUE_STATUS_LEVEL); in dw_i3c_master_end_xfer_locked()
482 resp = readl(master->regs + RESPONSE_QUEUE_PORT); in dw_i3c_master_end_xfer_locked()
484 cmd = &xfer->cmds[RESPONSE_PORT_TID(resp)]; in dw_i3c_master_end_xfer_locked()
485 cmd->rx_len = RESPONSE_PORT_DATA_LEN(resp); in dw_i3c_master_end_xfer_locked()
486 cmd->error = RESPONSE_PORT_ERR_STATUS(resp); in dw_i3c_master_end_xfer_locked()
487 if (cmd->rx_len && !cmd->error) in dw_i3c_master_end_xfer_locked()
488 dw_i3c_master_read_rx_fifo(master, cmd->rx_buf, in dw_i3c_master_end_xfer_locked()
489 cmd->rx_len); in dw_i3c_master_end_xfer_locked()
493 switch (xfer->cmds[i].error) { in dw_i3c_master_end_xfer_locked()
501 ret = -EIO; in dw_i3c_master_end_xfer_locked()
504 ret = -ENOSPC; in dw_i3c_master_end_xfer_locked()
509 ret = -EINVAL; in dw_i3c_master_end_xfer_locked()
514 xfer->ret = ret; in dw_i3c_master_end_xfer_locked()
515 complete(&xfer->comp); in dw_i3c_master_end_xfer_locked()
518 dw_i3c_master_dequeue_xfer_locked(master, xfer); in dw_i3c_master_end_xfer_locked()
519 writel(readl(master->regs + DEVICE_CTRL) | DEV_CTRL_RESUME, in dw_i3c_master_end_xfer_locked()
520 master->regs + DEVICE_CTRL); in dw_i3c_master_end_xfer_locked()
523 xfer = list_first_entry_or_null(&master->xferqueue.list, in dw_i3c_master_end_xfer_locked()
527 list_del_init(&xfer->node); in dw_i3c_master_end_xfer_locked()
529 master->xferqueue.cur = xfer; in dw_i3c_master_end_xfer_locked()
530 dw_i3c_master_start_xfer_locked(master); in dw_i3c_master_end_xfer_locked()
533 static void dw_i3c_master_set_intr_regs(struct dw_i3c_master *master) in dw_i3c_master_set_intr_regs() argument
537 thld_ctrl = readl(master->regs + QUEUE_THLD_CTRL); in dw_i3c_master_set_intr_regs()
543 writel(thld_ctrl, master->regs + QUEUE_THLD_CTRL); in dw_i3c_master_set_intr_regs()
545 thld_ctrl = readl(master->regs + DATA_BUFFER_THLD_CTRL); in dw_i3c_master_set_intr_regs()
547 writel(thld_ctrl, master->regs + DATA_BUFFER_THLD_CTRL); in dw_i3c_master_set_intr_regs()
549 writel(INTR_ALL, master->regs + INTR_STATUS); in dw_i3c_master_set_intr_regs()
550 writel(INTR_MASTER_MASK, master->regs + INTR_STATUS_EN); in dw_i3c_master_set_intr_regs()
551 writel(INTR_MASTER_MASK, master->regs + INTR_SIGNAL_EN); in dw_i3c_master_set_intr_regs()
553 master->sir_rej_mask = IBI_REQ_REJECT_ALL; in dw_i3c_master_set_intr_regs()
554 writel(master->sir_rej_mask, master->regs + IBI_SIR_REQ_REJECT); in dw_i3c_master_set_intr_regs()
556 writel(IBI_REQ_REJECT_ALL, master->regs + IBI_MR_REQ_REJECT); in dw_i3c_master_set_intr_regs()
559 static int dw_i3c_clk_cfg(struct dw_i3c_master *master) in dw_i3c_clk_cfg() argument
565 core_rate = clk_get_rate(master->core_clk); in dw_i3c_clk_cfg()
567 return -EINVAL; in dw_i3c_clk_cfg()
571 hcnt = DIV_ROUND_UP(I3C_BUS_THIGH_MAX_NS, core_period) - 1; in dw_i3c_clk_cfg()
575 lcnt = DIV_ROUND_UP(core_rate, master->base.bus.scl_rate.i3c) - hcnt; in dw_i3c_clk_cfg()
580 writel(scl_timing, master->regs + SCL_I3C_PP_TIMING); in dw_i3c_clk_cfg()
581 master->i3c_pp_timing = scl_timing; in dw_i3c_clk_cfg()
584 * In pure i3c mode, MST_FREE represents tCAS. In shared mode, this in dw_i3c_clk_cfg()
587 if (master->base.bus.mode == I3C_BUS_MODE_PURE) { in dw_i3c_clk_cfg()
588 writel(BUS_I3C_MST_FREE(lcnt), master->regs + BUS_FREE_TIMING); in dw_i3c_clk_cfg()
589 master->bus_free_timing = BUS_I3C_MST_FREE(lcnt); in dw_i3c_clk_cfg()
595 writel(scl_timing, master->regs + SCL_I3C_OD_TIMING); in dw_i3c_clk_cfg()
596 master->i3c_od_timing = scl_timing; in dw_i3c_clk_cfg()
598 lcnt = DIV_ROUND_UP(core_rate, I3C_BUS_SDR1_SCL_RATE) - hcnt; in dw_i3c_clk_cfg()
600 lcnt = DIV_ROUND_UP(core_rate, I3C_BUS_SDR2_SCL_RATE) - hcnt; in dw_i3c_clk_cfg()
602 lcnt = DIV_ROUND_UP(core_rate, I3C_BUS_SDR3_SCL_RATE) - hcnt; in dw_i3c_clk_cfg()
604 lcnt = DIV_ROUND_UP(core_rate, I3C_BUS_SDR4_SCL_RATE) - hcnt; in dw_i3c_clk_cfg()
606 writel(scl_timing, master->regs + SCL_EXT_LCNT_TIMING); in dw_i3c_clk_cfg()
607 master->ext_lcnt_timing = scl_timing; in dw_i3c_clk_cfg()
612 static int dw_i2c_clk_cfg(struct dw_i3c_master *master) in dw_i2c_clk_cfg() argument
618 core_rate = clk_get_rate(master->core_clk); in dw_i2c_clk_cfg()
620 return -EINVAL; in dw_i2c_clk_cfg()
625 hcnt = DIV_ROUND_UP(core_rate, I3C_BUS_I2C_FM_PLUS_SCL_RATE) - lcnt; in dw_i2c_clk_cfg()
628 writel(scl_timing, master->regs + SCL_I2C_FMP_TIMING); in dw_i2c_clk_cfg()
629 master->i2c_fmp_timing = scl_timing; in dw_i2c_clk_cfg()
632 hcnt = DIV_ROUND_UP(core_rate, I3C_BUS_I2C_FM_SCL_RATE) - lcnt; in dw_i2c_clk_cfg()
635 writel(scl_timing, master->regs + SCL_I2C_FM_TIMING); in dw_i2c_clk_cfg()
636 master->i2c_fm_timing = scl_timing; in dw_i2c_clk_cfg()
638 writel(BUS_I3C_MST_FREE(lcnt), master->regs + BUS_FREE_TIMING); in dw_i2c_clk_cfg()
639 master->bus_free_timing = BUS_I3C_MST_FREE(lcnt); in dw_i2c_clk_cfg()
641 writel(readl(master->regs + DEVICE_CTRL) | DEV_CTRL_I2C_SLAVE_PRESENT, in dw_i2c_clk_cfg()
642 master->regs + DEVICE_CTRL); in dw_i2c_clk_cfg()
643 master->i2c_slv_prsnt = true; in dw_i2c_clk_cfg()
650 struct dw_i3c_master *master = to_dw_i3c_master(m); in dw_i3c_master_bus_init() local
655 ret = pm_runtime_resume_and_get(master->dev); in dw_i3c_master_bus_init()
657 dev_err(master->dev, in dw_i3c_master_bus_init()
658 "<%s> cannot resume i3c bus master, err: %d\n", in dw_i3c_master_bus_init()
663 ret = master->platform_ops->init(master); in dw_i3c_master_bus_init()
667 switch (bus->mode) { in dw_i3c_master_bus_init()
670 ret = dw_i2c_clk_cfg(master); in dw_i3c_master_bus_init()
675 ret = dw_i3c_clk_cfg(master); in dw_i3c_master_bus_init()
680 ret = -EINVAL; in dw_i3c_master_bus_init()
689 master->regs + DEVICE_ADDR); in dw_i3c_master_bus_init()
690 master->dev_addr = ret; in dw_i3c_master_bus_init()
694 ret = i3c_master_set_info(&master->base, &info); in dw_i3c_master_bus_init()
698 dw_i3c_master_set_intr_regs(master); in dw_i3c_master_bus_init()
699 dw_i3c_master_enable(master); in dw_i3c_master_bus_init()
702 pm_runtime_mark_last_busy(master->dev); in dw_i3c_master_bus_init()
703 pm_runtime_put_autosuspend(master->dev); in dw_i3c_master_bus_init()
709 struct dw_i3c_master *master = to_dw_i3c_master(m); in dw_i3c_master_bus_cleanup() local
711 dw_i3c_master_disable(master); in dw_i3c_master_bus_cleanup()
714 static int dw_i3c_ccc_set(struct dw_i3c_master *master, in dw_i3c_ccc_set() argument
721 if (ccc->id & I3C_CCC_DIRECT) { in dw_i3c_ccc_set()
722 pos = dw_i3c_master_get_addr_pos(master, ccc->dests[0].addr); in dw_i3c_ccc_set()
727 xfer = dw_i3c_master_alloc_xfer(master, 1); in dw_i3c_ccc_set()
729 return -ENOMEM; in dw_i3c_ccc_set()
731 cmd = xfer->cmds; in dw_i3c_ccc_set()
732 cmd->tx_buf = ccc->dests[0].payload.data; in dw_i3c_ccc_set()
733 cmd->tx_len = ccc->dests[0].payload.len; in dw_i3c_ccc_set()
735 cmd->cmd_hi = COMMAND_PORT_ARG_DATA_LEN(ccc->dests[0].payload.len) | in dw_i3c_ccc_set()
738 cmd->cmd_lo = COMMAND_PORT_CP | in dw_i3c_ccc_set()
740 COMMAND_PORT_CMD(ccc->id) | in dw_i3c_ccc_set()
744 dw_i3c_master_enqueue_xfer(master, xfer); in dw_i3c_ccc_set()
745 if (!wait_for_completion_timeout(&xfer->comp, XFER_TIMEOUT)) in dw_i3c_ccc_set()
746 dw_i3c_master_dequeue_xfer(master, xfer); in dw_i3c_ccc_set()
748 ret = xfer->ret; in dw_i3c_ccc_set()
749 if (xfer->cmds[0].error == RESPONSE_ERROR_IBA_NACK) in dw_i3c_ccc_set()
750 ccc->err = I3C_ERROR_M2; in dw_i3c_ccc_set()
757 static int dw_i3c_ccc_get(struct dw_i3c_master *master, struct i3c_ccc_cmd *ccc) in dw_i3c_ccc_get() argument
763 pos = dw_i3c_master_get_addr_pos(master, ccc->dests[0].addr); in dw_i3c_ccc_get()
767 xfer = dw_i3c_master_alloc_xfer(master, 1); in dw_i3c_ccc_get()
769 return -ENOMEM; in dw_i3c_ccc_get()
771 cmd = xfer->cmds; in dw_i3c_ccc_get()
772 cmd->rx_buf = ccc->dests[0].payload.data; in dw_i3c_ccc_get()
773 cmd->rx_len = ccc->dests[0].payload.len; in dw_i3c_ccc_get()
775 cmd->cmd_hi = COMMAND_PORT_ARG_DATA_LEN(ccc->dests[0].payload.len) | in dw_i3c_ccc_get()
778 cmd->cmd_lo = COMMAND_PORT_READ_TRANSFER | in dw_i3c_ccc_get()
781 COMMAND_PORT_CMD(ccc->id) | in dw_i3c_ccc_get()
785 dw_i3c_master_enqueue_xfer(master, xfer); in dw_i3c_ccc_get()
786 if (!wait_for_completion_timeout(&xfer->comp, XFER_TIMEOUT)) in dw_i3c_ccc_get()
787 dw_i3c_master_dequeue_xfer(master, xfer); in dw_i3c_ccc_get()
789 ret = xfer->ret; in dw_i3c_ccc_get()
790 if (xfer->cmds[0].error == RESPONSE_ERROR_IBA_NACK) in dw_i3c_ccc_get()
791 ccc->err = I3C_ERROR_M2; in dw_i3c_ccc_get()
797 static void amd_configure_od_pp_quirk(struct dw_i3c_master *master) in amd_configure_od_pp_quirk() argument
799 master->i3c_od_timing = AMD_I3C_OD_TIMING; in amd_configure_od_pp_quirk()
800 master->i3c_pp_timing = AMD_I3C_PP_TIMING; in amd_configure_od_pp_quirk()
806 struct dw_i3c_master *master = to_dw_i3c_master(m); in dw_i3c_master_send_ccc_cmd() local
809 if (ccc->id == I3C_CCC_ENTDAA) in dw_i3c_master_send_ccc_cmd()
810 return -EINVAL; in dw_i3c_master_send_ccc_cmd()
813 if (master->quirks & AMD_I3C_OD_PP_TIMING) { in dw_i3c_master_send_ccc_cmd()
814 amd_configure_od_pp_quirk(master); in dw_i3c_master_send_ccc_cmd()
815 writel(master->i3c_pp_timing, master->regs + SCL_I3C_PP_TIMING); in dw_i3c_master_send_ccc_cmd()
816 writel(master->i3c_od_timing, master->regs + SCL_I3C_OD_TIMING); in dw_i3c_master_send_ccc_cmd()
819 ret = pm_runtime_resume_and_get(master->dev); in dw_i3c_master_send_ccc_cmd()
821 dev_err(master->dev, in dw_i3c_master_send_ccc_cmd()
822 "<%s> cannot resume i3c bus master, err: %d\n", in dw_i3c_master_send_ccc_cmd()
827 if (ccc->rnw) in dw_i3c_master_send_ccc_cmd()
828 ret = dw_i3c_ccc_get(master, ccc); in dw_i3c_master_send_ccc_cmd()
830 ret = dw_i3c_ccc_set(master, ccc); in dw_i3c_master_send_ccc_cmd()
832 pm_runtime_mark_last_busy(master->dev); in dw_i3c_master_send_ccc_cmd()
833 pm_runtime_put_autosuspend(master->dev); in dw_i3c_master_send_ccc_cmd()
839 struct dw_i3c_master *master = to_dw_i3c_master(m); in dw_i3c_master_daa() local
846 ret = pm_runtime_resume_and_get(master->dev); in dw_i3c_master_daa()
848 dev_err(master->dev, in dw_i3c_master_daa()
849 "<%s> cannot resume i3c bus master, err: %d\n", in dw_i3c_master_daa()
854 olddevs = ~(master->free_pos); in dw_i3c_master_daa()
857 for (pos = 0; pos < master->maxdevs; pos++) { in dw_i3c_master_daa()
863 ret = -ENOSPC; in dw_i3c_master_daa()
867 master->devs[pos].addr = ret; in dw_i3c_master_daa()
873 master->regs + in dw_i3c_master_daa()
874 DEV_ADDR_TABLE_LOC(master->datstartaddr, pos)); in dw_i3c_master_daa()
879 xfer = dw_i3c_master_alloc_xfer(master, 1); in dw_i3c_master_daa()
881 ret = -ENOMEM; in dw_i3c_master_daa()
885 pos = dw_i3c_master_get_free_pos(master); in dw_i3c_master_daa()
891 cmd = &xfer->cmds[0]; in dw_i3c_master_daa()
892 cmd->cmd_hi = 0x1; in dw_i3c_master_daa()
893 cmd->cmd_lo = COMMAND_PORT_DEV_COUNT(master->maxdevs - pos) | in dw_i3c_master_daa()
900 dw_i3c_master_enqueue_xfer(master, xfer); in dw_i3c_master_daa()
901 if (!wait_for_completion_timeout(&xfer->comp, XFER_TIMEOUT)) in dw_i3c_master_daa()
902 dw_i3c_master_dequeue_xfer(master, xfer); in dw_i3c_master_daa()
904 newdevs = GENMASK(master->maxdevs - cmd->rx_len - 1, 0); in dw_i3c_master_daa()
907 for (pos = 0; pos < master->maxdevs; pos++) { in dw_i3c_master_daa()
909 i3c_master_add_i3c_dev_locked(m, master->devs[pos].addr); in dw_i3c_master_daa()
915 pm_runtime_mark_last_busy(master->dev); in dw_i3c_master_daa()
916 pm_runtime_put_autosuspend(master->dev); in dw_i3c_master_daa()
926 struct dw_i3c_master *master = to_dw_i3c_master(m); in dw_i3c_master_priv_xfers() local
934 if (i3c_nxfers > master->caps.cmdfifodepth) in dw_i3c_master_priv_xfers()
935 return -ENOTSUPP; in dw_i3c_master_priv_xfers()
944 if (ntxwords > master->caps.datafifodepth || in dw_i3c_master_priv_xfers()
945 nrxwords > master->caps.datafifodepth) in dw_i3c_master_priv_xfers()
946 return -ENOTSUPP; in dw_i3c_master_priv_xfers()
948 xfer = dw_i3c_master_alloc_xfer(master, i3c_nxfers); in dw_i3c_master_priv_xfers()
950 return -ENOMEM; in dw_i3c_master_priv_xfers()
952 ret = pm_runtime_resume_and_get(master->dev); in dw_i3c_master_priv_xfers()
954 dev_err(master->dev, in dw_i3c_master_priv_xfers()
955 "<%s> cannot resume i3c bus master, err: %d\n", in dw_i3c_master_priv_xfers()
961 struct dw_i3c_cmd *cmd = &xfer->cmds[i]; in dw_i3c_master_priv_xfers()
963 cmd->cmd_hi = COMMAND_PORT_ARG_DATA_LEN(i3c_xfers[i].len) | in dw_i3c_master_priv_xfers()
967 cmd->rx_buf = i3c_xfers[i].data.in; in dw_i3c_master_priv_xfers()
968 cmd->rx_len = i3c_xfers[i].len; in dw_i3c_master_priv_xfers()
969 cmd->cmd_lo = COMMAND_PORT_READ_TRANSFER | in dw_i3c_master_priv_xfers()
970 COMMAND_PORT_SPEED(dev->info.max_read_ds); in dw_i3c_master_priv_xfers()
973 cmd->tx_buf = i3c_xfers[i].data.out; in dw_i3c_master_priv_xfers()
974 cmd->tx_len = i3c_xfers[i].len; in dw_i3c_master_priv_xfers()
975 cmd->cmd_lo = in dw_i3c_master_priv_xfers()
976 COMMAND_PORT_SPEED(dev->info.max_write_ds); in dw_i3c_master_priv_xfers()
979 cmd->cmd_lo |= COMMAND_PORT_TID(i) | in dw_i3c_master_priv_xfers()
980 COMMAND_PORT_DEV_INDEX(data->index) | in dw_i3c_master_priv_xfers()
983 if (i == (i3c_nxfers - 1)) in dw_i3c_master_priv_xfers()
984 cmd->cmd_lo |= COMMAND_PORT_TOC; in dw_i3c_master_priv_xfers()
987 dw_i3c_master_enqueue_xfer(master, xfer); in dw_i3c_master_priv_xfers()
988 if (!wait_for_completion_timeout(&xfer->comp, XFER_TIMEOUT)) in dw_i3c_master_priv_xfers()
989 dw_i3c_master_dequeue_xfer(master, xfer); in dw_i3c_master_priv_xfers()
992 struct dw_i3c_cmd *cmd = &xfer->cmds[i]; in dw_i3c_master_priv_xfers()
995 i3c_xfers[i].len = cmd->rx_len; in dw_i3c_master_priv_xfers()
998 ret = xfer->ret; in dw_i3c_master_priv_xfers()
1001 pm_runtime_mark_last_busy(master->dev); in dw_i3c_master_priv_xfers()
1002 pm_runtime_put_autosuspend(master->dev); in dw_i3c_master_priv_xfers()
1011 struct dw_i3c_master *master = to_dw_i3c_master(m); in dw_i3c_master_reattach_i3c_dev() local
1014 pos = dw_i3c_master_get_free_pos(master); in dw_i3c_master_reattach_i3c_dev()
1016 if (data->index > pos && pos > 0) { in dw_i3c_master_reattach_i3c_dev()
1018 master->regs + in dw_i3c_master_reattach_i3c_dev()
1019 DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index)); in dw_i3c_master_reattach_i3c_dev()
1021 master->devs[data->index].addr = 0; in dw_i3c_master_reattach_i3c_dev()
1022 master->free_pos |= BIT(data->index); in dw_i3c_master_reattach_i3c_dev()
1024 data->index = pos; in dw_i3c_master_reattach_i3c_dev()
1025 master->devs[pos].addr = dev->info.dyn_addr; in dw_i3c_master_reattach_i3c_dev()
1026 master->free_pos &= ~BIT(pos); in dw_i3c_master_reattach_i3c_dev()
1029 writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(dev->info.dyn_addr), in dw_i3c_master_reattach_i3c_dev()
1030 master->regs + in dw_i3c_master_reattach_i3c_dev()
1031 DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index)); in dw_i3c_master_reattach_i3c_dev()
1033 master->devs[data->index].addr = dev->info.dyn_addr; in dw_i3c_master_reattach_i3c_dev()
1041 struct dw_i3c_master *master = to_dw_i3c_master(m); in dw_i3c_master_attach_i3c_dev() local
1045 pos = dw_i3c_master_get_free_pos(master); in dw_i3c_master_attach_i3c_dev()
1051 return -ENOMEM; in dw_i3c_master_attach_i3c_dev()
1053 data->index = pos; in dw_i3c_master_attach_i3c_dev()
1054 master->devs[pos].addr = dev->info.dyn_addr ? : dev->info.static_addr; in dw_i3c_master_attach_i3c_dev()
1055 master->free_pos &= ~BIT(pos); in dw_i3c_master_attach_i3c_dev()
1058 writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(master->devs[pos].addr), in dw_i3c_master_attach_i3c_dev()
1059 master->regs + in dw_i3c_master_attach_i3c_dev()
1060 DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index)); in dw_i3c_master_attach_i3c_dev()
1069 struct dw_i3c_master *master = to_dw_i3c_master(m); in dw_i3c_master_detach_i3c_dev() local
1072 master->regs + in dw_i3c_master_detach_i3c_dev()
1073 DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index)); in dw_i3c_master_detach_i3c_dev()
1076 master->devs[data->index].addr = 0; in dw_i3c_master_detach_i3c_dev()
1077 master->free_pos |= BIT(data->index); in dw_i3c_master_detach_i3c_dev()
1087 struct dw_i3c_master *master = to_dw_i3c_master(m); in dw_i3c_master_i2c_xfers() local
1095 if (i2c_nxfers > master->caps.cmdfifodepth) in dw_i3c_master_i2c_xfers()
1096 return -ENOTSUPP; in dw_i3c_master_i2c_xfers()
1105 if (ntxwords > master->caps.datafifodepth || in dw_i3c_master_i2c_xfers()
1106 nrxwords > master->caps.datafifodepth) in dw_i3c_master_i2c_xfers()
1107 return -ENOTSUPP; in dw_i3c_master_i2c_xfers()
1109 xfer = dw_i3c_master_alloc_xfer(master, i2c_nxfers); in dw_i3c_master_i2c_xfers()
1111 return -ENOMEM; in dw_i3c_master_i2c_xfers()
1113 ret = pm_runtime_resume_and_get(master->dev); in dw_i3c_master_i2c_xfers()
1115 dev_err(master->dev, in dw_i3c_master_i2c_xfers()
1116 "<%s> cannot resume i3c bus master, err: %d\n", in dw_i3c_master_i2c_xfers()
1122 struct dw_i3c_cmd *cmd = &xfer->cmds[i]; in dw_i3c_master_i2c_xfers()
1124 cmd->cmd_hi = COMMAND_PORT_ARG_DATA_LEN(i2c_xfers[i].len) | in dw_i3c_master_i2c_xfers()
1127 cmd->cmd_lo = COMMAND_PORT_TID(i) | in dw_i3c_master_i2c_xfers()
1128 COMMAND_PORT_DEV_INDEX(data->index) | in dw_i3c_master_i2c_xfers()
1132 cmd->cmd_lo |= COMMAND_PORT_READ_TRANSFER; in dw_i3c_master_i2c_xfers()
1133 cmd->rx_buf = i2c_xfers[i].buf; in dw_i3c_master_i2c_xfers()
1134 cmd->rx_len = i2c_xfers[i].len; in dw_i3c_master_i2c_xfers()
1136 cmd->tx_buf = i2c_xfers[i].buf; in dw_i3c_master_i2c_xfers()
1137 cmd->tx_len = i2c_xfers[i].len; in dw_i3c_master_i2c_xfers()
1140 if (i == (i2c_nxfers - 1)) in dw_i3c_master_i2c_xfers()
1141 cmd->cmd_lo |= COMMAND_PORT_TOC; in dw_i3c_master_i2c_xfers()
1144 dw_i3c_master_enqueue_xfer(master, xfer); in dw_i3c_master_i2c_xfers()
1145 if (!wait_for_completion_timeout(&xfer->comp, XFER_TIMEOUT)) in dw_i3c_master_i2c_xfers()
1146 dw_i3c_master_dequeue_xfer(master, xfer); in dw_i3c_master_i2c_xfers()
1148 ret = xfer->ret; in dw_i3c_master_i2c_xfers()
1151 pm_runtime_mark_last_busy(master->dev); in dw_i3c_master_i2c_xfers()
1152 pm_runtime_put_autosuspend(master->dev); in dw_i3c_master_i2c_xfers()
1159 struct dw_i3c_master *master = to_dw_i3c_master(m); in dw_i3c_master_attach_i2c_dev() local
1163 pos = dw_i3c_master_get_free_pos(master); in dw_i3c_master_attach_i2c_dev()
1169 return -ENOMEM; in dw_i3c_master_attach_i2c_dev()
1171 data->index = pos; in dw_i3c_master_attach_i2c_dev()
1172 master->devs[pos].addr = dev->addr; in dw_i3c_master_attach_i2c_dev()
1173 master->devs[pos].is_i2c_addr = true; in dw_i3c_master_attach_i2c_dev()
1174 master->free_pos &= ~BIT(pos); in dw_i3c_master_attach_i2c_dev()
1178 DEV_ADDR_TABLE_STATIC_ADDR(dev->addr), in dw_i3c_master_attach_i2c_dev()
1179 master->regs + in dw_i3c_master_attach_i2c_dev()
1180 DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index)); in dw_i3c_master_attach_i2c_dev()
1189 struct dw_i3c_master *master = to_dw_i3c_master(m); in dw_i3c_master_detach_i2c_dev() local
1192 master->regs + in dw_i3c_master_detach_i2c_dev()
1193 DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index)); in dw_i3c_master_detach_i2c_dev()
1196 master->devs[data->index].addr = 0; in dw_i3c_master_detach_i2c_dev()
1197 master->free_pos |= BIT(data->index); in dw_i3c_master_detach_i2c_dev()
1206 struct dw_i3c_master *master = to_dw_i3c_master(m); in dw_i3c_master_request_ibi() local
1209 data->ibi_pool = i3c_generic_ibi_alloc_pool(dev, req); in dw_i3c_master_request_ibi()
1210 if (IS_ERR(data->ibi_pool)) in dw_i3c_master_request_ibi()
1211 return PTR_ERR(data->ibi_pool); in dw_i3c_master_request_ibi()
1213 spin_lock_irqsave(&master->devs_lock, flags); in dw_i3c_master_request_ibi()
1214 master->devs[data->index].ibi_dev = dev; in dw_i3c_master_request_ibi()
1215 spin_unlock_irqrestore(&master->devs_lock, flags); in dw_i3c_master_request_ibi()
1224 struct dw_i3c_master *master = to_dw_i3c_master(m); in dw_i3c_master_free_ibi() local
1227 spin_lock_irqsave(&master->devs_lock, flags); in dw_i3c_master_free_ibi()
1228 master->devs[data->index].ibi_dev = NULL; in dw_i3c_master_free_ibi()
1229 spin_unlock_irqrestore(&master->devs_lock, flags); in dw_i3c_master_free_ibi()
1231 i3c_generic_ibi_free_pool(data->ibi_pool); in dw_i3c_master_free_ibi()
1232 data->ibi_pool = NULL; in dw_i3c_master_free_ibi()
1235 static void dw_i3c_master_enable_sir_signal(struct dw_i3c_master *master, bool enable) in dw_i3c_master_enable_sir_signal() argument
1239 reg = readl(master->regs + INTR_STATUS_EN); in dw_i3c_master_enable_sir_signal()
1243 writel(reg, master->regs + INTR_STATUS_EN); in dw_i3c_master_enable_sir_signal()
1245 reg = readl(master->regs + INTR_SIGNAL_EN); in dw_i3c_master_enable_sir_signal()
1249 writel(reg, master->regs + INTR_SIGNAL_EN); in dw_i3c_master_enable_sir_signal()
1252 static void dw_i3c_master_set_sir_enabled(struct dw_i3c_master *master, in dw_i3c_master_set_sir_enabled() argument
1260 dat_entry = DEV_ADDR_TABLE_LOC(master->datstartaddr, idx); in dw_i3c_master_set_sir_enabled()
1262 spin_lock_irqsave(&master->devs_lock, flags); in dw_i3c_master_set_sir_enabled()
1263 reg = readl(master->regs + dat_entry); in dw_i3c_master_set_sir_enabled()
1266 if (dev->info.bcr & I3C_BCR_IBI_PAYLOAD) in dw_i3c_master_set_sir_enabled()
1271 master->platform_ops->set_dat_ibi(master, dev, enable, &reg); in dw_i3c_master_set_sir_enabled()
1272 writel(reg, master->regs + dat_entry); in dw_i3c_master_set_sir_enabled()
1275 global = (master->sir_rej_mask == IBI_REQ_REJECT_ALL); in dw_i3c_master_set_sir_enabled()
1276 master->sir_rej_mask &= ~BIT(idx); in dw_i3c_master_set_sir_enabled()
1278 bool hj_rejected = !!(readl(master->regs + DEVICE_CTRL) & DEV_CTRL_HOT_JOIN_NACK); in dw_i3c_master_set_sir_enabled()
1280 master->sir_rej_mask |= BIT(idx); in dw_i3c_master_set_sir_enabled()
1281 global = (master->sir_rej_mask == IBI_REQ_REJECT_ALL) && hj_rejected; in dw_i3c_master_set_sir_enabled()
1283 writel(master->sir_rej_mask, master->regs + IBI_SIR_REQ_REJECT); in dw_i3c_master_set_sir_enabled()
1286 dw_i3c_master_enable_sir_signal(master, enable); in dw_i3c_master_set_sir_enabled()
1289 spin_unlock_irqrestore(&master->devs_lock, flags); in dw_i3c_master_set_sir_enabled()
1294 struct dw_i3c_master *master = to_dw_i3c_master(m); in dw_i3c_master_enable_hotjoin() local
1297 ret = pm_runtime_resume_and_get(master->dev); in dw_i3c_master_enable_hotjoin()
1299 dev_err(master->dev, in dw_i3c_master_enable_hotjoin()
1300 "<%s> cannot resume i3c bus master, err: %d\n", in dw_i3c_master_enable_hotjoin()
1305 dw_i3c_master_enable_sir_signal(master, true); in dw_i3c_master_enable_hotjoin()
1306 writel(readl(master->regs + DEVICE_CTRL) & ~DEV_CTRL_HOT_JOIN_NACK, in dw_i3c_master_enable_hotjoin()
1307 master->regs + DEVICE_CTRL); in dw_i3c_master_enable_hotjoin()
1314 struct dw_i3c_master *master = to_dw_i3c_master(m); in dw_i3c_master_disable_hotjoin() local
1316 writel(readl(master->regs + DEVICE_CTRL) | DEV_CTRL_HOT_JOIN_NACK, in dw_i3c_master_disable_hotjoin()
1317 master->regs + DEVICE_CTRL); in dw_i3c_master_disable_hotjoin()
1319 pm_runtime_mark_last_busy(master->dev); in dw_i3c_master_disable_hotjoin()
1320 pm_runtime_put_autosuspend(master->dev); in dw_i3c_master_disable_hotjoin()
1328 struct dw_i3c_master *master = to_dw_i3c_master(m); in dw_i3c_master_enable_ibi() local
1331 rc = pm_runtime_resume_and_get(master->dev); in dw_i3c_master_enable_ibi()
1333 dev_err(master->dev, in dw_i3c_master_enable_ibi()
1334 "<%s> cannot resume i3c bus master, err: %d\n", in dw_i3c_master_enable_ibi()
1339 dw_i3c_master_set_sir_enabled(master, dev, data->index, true); in dw_i3c_master_enable_ibi()
1341 rc = i3c_master_enec_locked(m, dev->info.dyn_addr, I3C_CCC_EVENT_SIR); in dw_i3c_master_enable_ibi()
1344 dw_i3c_master_set_sir_enabled(master, dev, data->index, false); in dw_i3c_master_enable_ibi()
1345 pm_runtime_mark_last_busy(master->dev); in dw_i3c_master_enable_ibi()
1346 pm_runtime_put_autosuspend(master->dev); in dw_i3c_master_enable_ibi()
1356 struct dw_i3c_master *master = to_dw_i3c_master(m); in dw_i3c_master_disable_ibi() local
1359 rc = i3c_master_disec_locked(m, dev->info.dyn_addr, I3C_CCC_EVENT_SIR); in dw_i3c_master_disable_ibi()
1363 dw_i3c_master_set_sir_enabled(master, dev, data->index, false); in dw_i3c_master_disable_ibi()
1365 pm_runtime_mark_last_busy(master->dev); in dw_i3c_master_disable_ibi()
1366 pm_runtime_put_autosuspend(master->dev); in dw_i3c_master_disable_ibi()
1375 i3c_generic_ibi_recycle_slot(data->ibi_pool, slot); in dw_i3c_master_recycle_ibi_slot()
1378 static void dw_i3c_master_drain_ibi_queue(struct dw_i3c_master *master, in dw_i3c_master_drain_ibi_queue() argument
1384 readl(master->regs + IBI_QUEUE_STATUS); in dw_i3c_master_drain_ibi_queue()
1387 static void dw_i3c_master_handle_ibi_sir(struct dw_i3c_master *master, in dw_i3c_master_handle_ibi_sir() argument
1411 spin_lock_irqsave(&master->devs_lock, flags); in dw_i3c_master_handle_ibi_sir()
1412 idx = dw_i3c_master_get_addr_pos(master, addr); in dw_i3c_master_handle_ibi_sir()
1414 dev_dbg_ratelimited(&master->base.dev, in dw_i3c_master_handle_ibi_sir()
1419 dev = master->devs[idx].ibi_dev; in dw_i3c_master_handle_ibi_sir()
1420 if (!dev || !dev->ibi) { in dw_i3c_master_handle_ibi_sir()
1421 dev_dbg_ratelimited(&master->base.dev, in dw_i3c_master_handle_ibi_sir()
1422 "IBI from non-requested dev idx %d\n", idx); in dw_i3c_master_handle_ibi_sir()
1427 slot = i3c_generic_ibi_get_free_slot(data->ibi_pool); in dw_i3c_master_handle_ibi_sir()
1429 dev_dbg_ratelimited(&master->base.dev, in dw_i3c_master_handle_ibi_sir()
1434 if (dev->ibi->max_payload_len < len) { in dw_i3c_master_handle_ibi_sir()
1435 dev_dbg_ratelimited(&master->base.dev, in dw_i3c_master_handle_ibi_sir()
1437 len, dev->ibi->max_payload_len); in dw_i3c_master_handle_ibi_sir()
1442 dw_i3c_master_read_ibi_fifo(master, slot->data, len); in dw_i3c_master_handle_ibi_sir()
1443 slot->len = len; in dw_i3c_master_handle_ibi_sir()
1447 spin_unlock_irqrestore(&master->devs_lock, flags); in dw_i3c_master_handle_ibi_sir()
1452 dw_i3c_master_drain_ibi_queue(master, len); in dw_i3c_master_handle_ibi_sir()
1454 spin_unlock_irqrestore(&master->devs_lock, flags); in dw_i3c_master_handle_ibi_sir()
1457 /* "ibis": referring to In-Band Interrupts, and not
1461 static void dw_i3c_master_irq_handle_ibis(struct dw_i3c_master *master) in dw_i3c_master_irq_handle_ibis() argument
1466 reg = readl(master->regs + QUEUE_STATUS_LEVEL); in dw_i3c_master_irq_handle_ibis()
1472 reg = readl(master->regs + IBI_QUEUE_STATUS); in dw_i3c_master_irq_handle_ibis()
1475 dw_i3c_master_handle_ibi_sir(master, reg); in dw_i3c_master_irq_handle_ibis()
1477 queue_work(master->base.wq, &master->hj_work); in dw_i3c_master_irq_handle_ibis()
1480 dev_info(&master->base.dev, in dw_i3c_master_irq_handle_ibis()
1483 dw_i3c_master_drain_ibi_queue(master, len); in dw_i3c_master_irq_handle_ibis()
1490 struct dw_i3c_master *master = dev_id; in dw_i3c_master_irq_handler() local
1493 status = readl(master->regs + INTR_STATUS); in dw_i3c_master_irq_handler()
1495 if (!(status & readl(master->regs + INTR_STATUS_EN))) { in dw_i3c_master_irq_handler()
1496 writel(INTR_ALL, master->regs + INTR_STATUS); in dw_i3c_master_irq_handler()
1500 spin_lock(&master->xferqueue.lock); in dw_i3c_master_irq_handler()
1501 dw_i3c_master_end_xfer_locked(master, status); in dw_i3c_master_irq_handler()
1503 writel(INTR_TRANSFER_ERR_STAT, master->regs + INTR_STATUS); in dw_i3c_master_irq_handler()
1504 spin_unlock(&master->xferqueue.lock); in dw_i3c_master_irq_handler()
1507 dw_i3c_master_irq_handle_ibis(master); in dw_i3c_master_irq_handler()
1535 static int dw_i3c_platform_init_nop(struct dw_i3c_master *i3c) in dw_i3c_platform_init_nop() argument
1540 static void dw_i3c_platform_set_dat_ibi_nop(struct dw_i3c_master *i3c, in dw_i3c_platform_set_dat_ibi_nop() argument
1553 struct dw_i3c_master *master = in dw_i3c_hj_work() local
1554 container_of(work, typeof(*master), hj_work); in dw_i3c_hj_work()
1556 i3c_master_do_daa(&master->base); in dw_i3c_hj_work()
1559 int dw_i3c_common_probe(struct dw_i3c_master *master, in dw_i3c_common_probe() argument
1564 if (!master->platform_ops) in dw_i3c_common_probe()
1565 master->platform_ops = &dw_i3c_platform_ops_default; in dw_i3c_common_probe()
1567 master->dev = &pdev->dev; in dw_i3c_common_probe()
1569 master->regs = devm_platform_ioremap_resource(pdev, 0); in dw_i3c_common_probe()
1570 if (IS_ERR(master->regs)) in dw_i3c_common_probe()
1571 return PTR_ERR(master->regs); in dw_i3c_common_probe()
1573 master->core_clk = devm_clk_get_enabled(&pdev->dev, NULL); in dw_i3c_common_probe()
1574 if (IS_ERR(master->core_clk)) in dw_i3c_common_probe()
1575 return PTR_ERR(master->core_clk); in dw_i3c_common_probe()
1577 master->pclk = devm_clk_get_optional_enabled(&pdev->dev, "pclk"); in dw_i3c_common_probe()
1578 if (IS_ERR(master->pclk)) in dw_i3c_common_probe()
1579 return PTR_ERR(master->pclk); in dw_i3c_common_probe()
1581 master->core_rst = devm_reset_control_get_optional_exclusive(&pdev->dev, in dw_i3c_common_probe()
1583 if (IS_ERR(master->core_rst)) in dw_i3c_common_probe()
1584 return PTR_ERR(master->core_rst); in dw_i3c_common_probe()
1586 reset_control_deassert(master->core_rst); in dw_i3c_common_probe()
1588 spin_lock_init(&master->xferqueue.lock); in dw_i3c_common_probe()
1589 INIT_LIST_HEAD(&master->xferqueue.list); in dw_i3c_common_probe()
1591 writel(INTR_ALL, master->regs + INTR_STATUS); in dw_i3c_common_probe()
1593 ret = devm_request_irq(&pdev->dev, irq, in dw_i3c_common_probe()
1595 dev_name(&pdev->dev), master); in dw_i3c_common_probe()
1599 platform_set_drvdata(pdev, master); in dw_i3c_common_probe()
1601 pm_runtime_set_autosuspend_delay(&pdev->dev, RPM_AUTOSUSPEND_TIMEOUT); in dw_i3c_common_probe()
1602 pm_runtime_use_autosuspend(&pdev->dev); in dw_i3c_common_probe()
1603 pm_runtime_set_active(&pdev->dev); in dw_i3c_common_probe()
1604 pm_runtime_enable(&pdev->dev); in dw_i3c_common_probe()
1607 ret = readl(master->regs + QUEUE_STATUS_LEVEL); in dw_i3c_common_probe()
1608 master->caps.cmdfifodepth = QUEUE_STATUS_LEVEL_CMD(ret); in dw_i3c_common_probe()
1610 ret = readl(master->regs + DATA_BUFFER_STATUS_LEVEL); in dw_i3c_common_probe()
1611 master->caps.datafifodepth = DATA_BUFFER_STATUS_LEVEL_TX(ret); in dw_i3c_common_probe()
1613 ret = readl(master->regs + DEVICE_ADDR_TABLE_POINTER); in dw_i3c_common_probe()
1614 master->datstartaddr = ret; in dw_i3c_common_probe()
1615 master->maxdevs = ret >> 16; in dw_i3c_common_probe()
1616 master->free_pos = GENMASK(master->maxdevs - 1, 0); in dw_i3c_common_probe()
1618 master->quirks = (unsigned long)device_get_match_data(&pdev->dev); in dw_i3c_common_probe()
1620 INIT_WORK(&master->hj_work, dw_i3c_hj_work); in dw_i3c_common_probe()
1621 ret = i3c_master_register(&master->base, &pdev->dev, in dw_i3c_common_probe()
1629 pm_runtime_disable(&pdev->dev); in dw_i3c_common_probe()
1630 pm_runtime_set_suspended(&pdev->dev); in dw_i3c_common_probe()
1631 pm_runtime_dont_use_autosuspend(&pdev->dev); in dw_i3c_common_probe()
1634 reset_control_assert(master->core_rst); in dw_i3c_common_probe()
1640 void dw_i3c_common_remove(struct dw_i3c_master *master) in dw_i3c_common_remove() argument
1642 cancel_work_sync(&master->hj_work); in dw_i3c_common_remove()
1643 i3c_master_unregister(&master->base); in dw_i3c_common_remove()
1645 pm_runtime_disable(master->dev); in dw_i3c_common_remove()
1646 pm_runtime_set_suspended(master->dev); in dw_i3c_common_remove()
1647 pm_runtime_dont_use_autosuspend(master->dev); in dw_i3c_common_remove()
1655 struct dw_i3c_master *master; in dw_i3c_probe() local
1657 master = devm_kzalloc(&pdev->dev, sizeof(*master), GFP_KERNEL); in dw_i3c_probe()
1658 if (!master) in dw_i3c_probe()
1659 return -ENOMEM; in dw_i3c_probe()
1661 return dw_i3c_common_probe(master, pdev); in dw_i3c_probe()
1666 struct dw_i3c_master *master = platform_get_drvdata(pdev); in dw_i3c_remove() local
1668 dw_i3c_common_remove(master); in dw_i3c_remove()
1671 static void dw_i3c_master_restore_addrs(struct dw_i3c_master *master) in dw_i3c_master_restore_addrs() argument
1675 writel(DEV_ADDR_DYNAMIC_ADDR_VALID | DEV_ADDR_DYNAMIC(master->dev_addr), in dw_i3c_master_restore_addrs()
1676 master->regs + DEVICE_ADDR); in dw_i3c_master_restore_addrs()
1678 for (pos = 0; pos < master->maxdevs; pos++) { in dw_i3c_master_restore_addrs()
1679 if (master->free_pos & BIT(pos)) in dw_i3c_master_restore_addrs()
1682 if (master->devs[pos].is_i2c_addr) in dw_i3c_master_restore_addrs()
1684 DEV_ADDR_TABLE_STATIC_ADDR(master->devs[pos].addr); in dw_i3c_master_restore_addrs()
1686 reg_val = DEV_ADDR_TABLE_DYNAMIC_ADDR(master->devs[pos].addr); in dw_i3c_master_restore_addrs()
1688 writel(reg_val, master->regs + DEV_ADDR_TABLE_LOC(master->datstartaddr, pos)); in dw_i3c_master_restore_addrs()
1692 static void dw_i3c_master_restore_timing_regs(struct dw_i3c_master *master) in dw_i3c_master_restore_timing_regs() argument
1695 if (master->quirks & AMD_I3C_OD_PP_TIMING) in dw_i3c_master_restore_timing_regs()
1696 amd_configure_od_pp_quirk(master); in dw_i3c_master_restore_timing_regs()
1698 writel(master->i3c_pp_timing, master->regs + SCL_I3C_PP_TIMING); in dw_i3c_master_restore_timing_regs()
1699 writel(master->bus_free_timing, master->regs + BUS_FREE_TIMING); in dw_i3c_master_restore_timing_regs()
1700 writel(master->i3c_od_timing, master->regs + SCL_I3C_OD_TIMING); in dw_i3c_master_restore_timing_regs()
1701 writel(master->ext_lcnt_timing, master->regs + SCL_EXT_LCNT_TIMING); in dw_i3c_master_restore_timing_regs()
1703 if (master->i2c_slv_prsnt) { in dw_i3c_master_restore_timing_regs()
1704 writel(master->i2c_fmp_timing, master->regs + SCL_I2C_FMP_TIMING); in dw_i3c_master_restore_timing_regs()
1705 writel(master->i2c_fm_timing, master->regs + SCL_I2C_FM_TIMING); in dw_i3c_master_restore_timing_regs()
1709 static int dw_i3c_master_enable_clks(struct dw_i3c_master *master) in dw_i3c_master_enable_clks() argument
1713 ret = clk_prepare_enable(master->core_clk); in dw_i3c_master_enable_clks()
1717 ret = clk_prepare_enable(master->pclk); in dw_i3c_master_enable_clks()
1719 clk_disable_unprepare(master->core_clk); in dw_i3c_master_enable_clks()
1726 static inline void dw_i3c_master_disable_clks(struct dw_i3c_master *master) in dw_i3c_master_disable_clks() argument
1728 clk_disable_unprepare(master->pclk); in dw_i3c_master_disable_clks()
1729 clk_disable_unprepare(master->core_clk); in dw_i3c_master_disable_clks()
1734 struct dw_i3c_master *master = dev_get_drvdata(dev); in dw_i3c_master_runtime_suspend() local
1736 dw_i3c_master_disable(master); in dw_i3c_master_runtime_suspend()
1738 reset_control_assert(master->core_rst); in dw_i3c_master_runtime_suspend()
1739 dw_i3c_master_disable_clks(master); in dw_i3c_master_runtime_suspend()
1746 struct dw_i3c_master *master = dev_get_drvdata(dev); in dw_i3c_master_runtime_resume() local
1749 dw_i3c_master_enable_clks(master); in dw_i3c_master_runtime_resume()
1750 reset_control_deassert(master->core_rst); in dw_i3c_master_runtime_resume()
1752 dw_i3c_master_set_intr_regs(master); in dw_i3c_master_runtime_resume()
1753 dw_i3c_master_restore_timing_regs(master); in dw_i3c_master_runtime_resume()
1754 dw_i3c_master_restore_addrs(master); in dw_i3c_master_runtime_resume()
1756 dw_i3c_master_enable(master); in dw_i3c_master_runtime_resume()
1766 { .compatible = "snps,dw-i3c-master-1.00a", },
1781 .name = "dw-i3c-master",
1790 MODULE_DESCRIPTION("DesignWare MIPI I3C driver");