Lines Matching refs:master

293 to_dw_i3c_master(struct i3c_master_controller *master)  in to_dw_i3c_master()  argument
295 return container_of(master, struct dw_i3c_master, base); in to_dw_i3c_master()
298 static void dw_i3c_master_disable(struct dw_i3c_master *master) in dw_i3c_master_disable() argument
300 writel(readl(master->regs + DEVICE_CTRL) & ~DEV_CTRL_ENABLE, in dw_i3c_master_disable()
301 master->regs + DEVICE_CTRL); in dw_i3c_master_disable()
304 static void dw_i3c_master_enable(struct dw_i3c_master *master) in dw_i3c_master_enable() argument
308 dev_ctrl = readl(master->regs + DEVICE_CTRL); in dw_i3c_master_enable()
311 if (master->i2c_slv_prsnt) in dw_i3c_master_enable()
314 master->regs + DEVICE_CTRL); in dw_i3c_master_enable()
317 static int dw_i3c_master_get_addr_pos(struct dw_i3c_master *master, u8 addr) in dw_i3c_master_get_addr_pos() argument
321 for (pos = 0; pos < master->maxdevs; pos++) { in dw_i3c_master_get_addr_pos()
322 if (addr == master->devs[pos].addr) in dw_i3c_master_get_addr_pos()
329 static int dw_i3c_master_get_free_pos(struct dw_i3c_master *master) in dw_i3c_master_get_free_pos() argument
331 if (!(master->free_pos & GENMASK(master->maxdevs - 1, 0))) in dw_i3c_master_get_free_pos()
334 return ffs(master->free_pos) - 1; in dw_i3c_master_get_free_pos()
337 static void dw_i3c_master_wr_tx_fifo(struct dw_i3c_master *master, in dw_i3c_master_wr_tx_fifo() argument
340 i3c_writel_fifo(master->regs + RX_TX_DATA_PORT, bytes, nbytes); in dw_i3c_master_wr_tx_fifo()
343 static void dw_i3c_master_read_rx_fifo(struct dw_i3c_master *master, in dw_i3c_master_read_rx_fifo() argument
346 i3c_readl_fifo(master->regs + RX_TX_DATA_PORT, bytes, nbytes); in dw_i3c_master_read_rx_fifo()
349 static void dw_i3c_master_read_ibi_fifo(struct dw_i3c_master *master, in dw_i3c_master_read_ibi_fifo() argument
352 i3c_readl_fifo(master->regs + IBI_QUEUE_STATUS, bytes, nbytes); in dw_i3c_master_read_ibi_fifo()
356 dw_i3c_master_alloc_xfer(struct dw_i3c_master *master, unsigned int ncmds) in dw_i3c_master_alloc_xfer() argument
376 static void dw_i3c_master_start_xfer_locked(struct dw_i3c_master *master) in dw_i3c_master_start_xfer_locked() argument
378 struct dw_i3c_xfer *xfer = master->xferqueue.cur; in dw_i3c_master_start_xfer_locked()
388 dw_i3c_master_wr_tx_fifo(master, cmd->tx_buf, cmd->tx_len); in dw_i3c_master_start_xfer_locked()
391 thld_ctrl = readl(master->regs + QUEUE_THLD_CTRL); in dw_i3c_master_start_xfer_locked()
394 writel(thld_ctrl, master->regs + QUEUE_THLD_CTRL); in dw_i3c_master_start_xfer_locked()
399 writel(cmd->cmd_hi, master->regs + COMMAND_QUEUE_PORT); in dw_i3c_master_start_xfer_locked()
400 writel(cmd->cmd_lo, master->regs + COMMAND_QUEUE_PORT); in dw_i3c_master_start_xfer_locked()
404 static void dw_i3c_master_enqueue_xfer(struct dw_i3c_master *master, in dw_i3c_master_enqueue_xfer() argument
410 spin_lock_irqsave(&master->xferqueue.lock, flags); in dw_i3c_master_enqueue_xfer()
411 if (master->xferqueue.cur) { in dw_i3c_master_enqueue_xfer()
412 list_add_tail(&xfer->node, &master->xferqueue.list); in dw_i3c_master_enqueue_xfer()
414 master->xferqueue.cur = xfer; in dw_i3c_master_enqueue_xfer()
415 dw_i3c_master_start_xfer_locked(master); in dw_i3c_master_enqueue_xfer()
417 spin_unlock_irqrestore(&master->xferqueue.lock, flags); in dw_i3c_master_enqueue_xfer()
420 static void dw_i3c_master_dequeue_xfer_locked(struct dw_i3c_master *master, in dw_i3c_master_dequeue_xfer_locked() argument
423 if (master->xferqueue.cur == xfer) { in dw_i3c_master_dequeue_xfer_locked()
426 master->xferqueue.cur = NULL; in dw_i3c_master_dequeue_xfer_locked()
430 master->regs + RESET_CTRL); in dw_i3c_master_dequeue_xfer_locked()
432 readl_poll_timeout_atomic(master->regs + RESET_CTRL, status, in dw_i3c_master_dequeue_xfer_locked()
439 static void dw_i3c_master_dequeue_xfer(struct dw_i3c_master *master, in dw_i3c_master_dequeue_xfer() argument
444 spin_lock_irqsave(&master->xferqueue.lock, flags); in dw_i3c_master_dequeue_xfer()
445 dw_i3c_master_dequeue_xfer_locked(master, xfer); in dw_i3c_master_dequeue_xfer()
446 spin_unlock_irqrestore(&master->xferqueue.lock, flags); in dw_i3c_master_dequeue_xfer()
449 static void dw_i3c_master_end_xfer_locked(struct dw_i3c_master *master, u32 isr) in dw_i3c_master_end_xfer_locked() argument
451 struct dw_i3c_xfer *xfer = master->xferqueue.cur; in dw_i3c_master_end_xfer_locked()
458 nresp = readl(master->regs + QUEUE_STATUS_LEVEL); in dw_i3c_master_end_xfer_locked()
465 resp = readl(master->regs + RESPONSE_QUEUE_PORT); in dw_i3c_master_end_xfer_locked()
471 dw_i3c_master_read_rx_fifo(master, cmd->rx_buf, in dw_i3c_master_end_xfer_locked()
501 dw_i3c_master_dequeue_xfer_locked(master, xfer); in dw_i3c_master_end_xfer_locked()
502 writel(readl(master->regs + DEVICE_CTRL) | DEV_CTRL_RESUME, in dw_i3c_master_end_xfer_locked()
503 master->regs + DEVICE_CTRL); in dw_i3c_master_end_xfer_locked()
506 xfer = list_first_entry_or_null(&master->xferqueue.list, in dw_i3c_master_end_xfer_locked()
512 master->xferqueue.cur = xfer; in dw_i3c_master_end_xfer_locked()
513 dw_i3c_master_start_xfer_locked(master); in dw_i3c_master_end_xfer_locked()
516 static void dw_i3c_master_set_intr_regs(struct dw_i3c_master *master) in dw_i3c_master_set_intr_regs() argument
520 thld_ctrl = readl(master->regs + QUEUE_THLD_CTRL); in dw_i3c_master_set_intr_regs()
526 writel(thld_ctrl, master->regs + QUEUE_THLD_CTRL); in dw_i3c_master_set_intr_regs()
528 thld_ctrl = readl(master->regs + DATA_BUFFER_THLD_CTRL); in dw_i3c_master_set_intr_regs()
530 writel(thld_ctrl, master->regs + DATA_BUFFER_THLD_CTRL); in dw_i3c_master_set_intr_regs()
532 writel(INTR_ALL, master->regs + INTR_STATUS); in dw_i3c_master_set_intr_regs()
533 writel(INTR_MASTER_MASK, master->regs + INTR_STATUS_EN); in dw_i3c_master_set_intr_regs()
534 writel(INTR_MASTER_MASK, master->regs + INTR_SIGNAL_EN); in dw_i3c_master_set_intr_regs()
536 master->sir_rej_mask = IBI_REQ_REJECT_ALL; in dw_i3c_master_set_intr_regs()
537 writel(master->sir_rej_mask, master->regs + IBI_SIR_REQ_REJECT); in dw_i3c_master_set_intr_regs()
539 writel(IBI_REQ_REJECT_ALL, master->regs + IBI_MR_REQ_REJECT); in dw_i3c_master_set_intr_regs()
542 static int dw_i3c_clk_cfg(struct dw_i3c_master *master) in dw_i3c_clk_cfg() argument
548 core_rate = clk_get_rate(master->core_clk); in dw_i3c_clk_cfg()
558 lcnt = DIV_ROUND_UP(core_rate, master->base.bus.scl_rate.i3c) - hcnt; in dw_i3c_clk_cfg()
563 writel(scl_timing, master->regs + SCL_I3C_PP_TIMING); in dw_i3c_clk_cfg()
564 master->i3c_pp_timing = scl_timing; in dw_i3c_clk_cfg()
570 if (master->base.bus.mode == I3C_BUS_MODE_PURE) { in dw_i3c_clk_cfg()
571 writel(BUS_I3C_MST_FREE(lcnt), master->regs + BUS_FREE_TIMING); in dw_i3c_clk_cfg()
572 master->bus_free_timing = BUS_I3C_MST_FREE(lcnt); in dw_i3c_clk_cfg()
578 writel(scl_timing, master->regs + SCL_I3C_OD_TIMING); in dw_i3c_clk_cfg()
579 master->i3c_od_timing = scl_timing; in dw_i3c_clk_cfg()
589 writel(scl_timing, master->regs + SCL_EXT_LCNT_TIMING); in dw_i3c_clk_cfg()
590 master->ext_lcnt_timing = scl_timing; in dw_i3c_clk_cfg()
595 static int dw_i2c_clk_cfg(struct dw_i3c_master *master) in dw_i2c_clk_cfg() argument
601 core_rate = clk_get_rate(master->core_clk); in dw_i2c_clk_cfg()
611 writel(scl_timing, master->regs + SCL_I2C_FMP_TIMING); in dw_i2c_clk_cfg()
612 master->i2c_fmp_timing = scl_timing; in dw_i2c_clk_cfg()
618 writel(scl_timing, master->regs + SCL_I2C_FM_TIMING); in dw_i2c_clk_cfg()
619 master->i2c_fm_timing = scl_timing; in dw_i2c_clk_cfg()
621 writel(BUS_I3C_MST_FREE(lcnt), master->regs + BUS_FREE_TIMING); in dw_i2c_clk_cfg()
622 master->bus_free_timing = BUS_I3C_MST_FREE(lcnt); in dw_i2c_clk_cfg()
624 writel(readl(master->regs + DEVICE_CTRL) | DEV_CTRL_I2C_SLAVE_PRESENT, in dw_i2c_clk_cfg()
625 master->regs + DEVICE_CTRL); in dw_i2c_clk_cfg()
626 master->i2c_slv_prsnt = true; in dw_i2c_clk_cfg()
633 struct dw_i3c_master *master = to_dw_i3c_master(m); in dw_i3c_master_bus_init() local
638 ret = pm_runtime_resume_and_get(master->dev); in dw_i3c_master_bus_init()
640 dev_err(master->dev, in dw_i3c_master_bus_init()
646 ret = master->platform_ops->init(master); in dw_i3c_master_bus_init()
653 ret = dw_i2c_clk_cfg(master); in dw_i3c_master_bus_init()
658 ret = dw_i3c_clk_cfg(master); in dw_i3c_master_bus_init()
672 master->regs + DEVICE_ADDR); in dw_i3c_master_bus_init()
673 master->dev_addr = ret; in dw_i3c_master_bus_init()
677 ret = i3c_master_set_info(&master->base, &info); in dw_i3c_master_bus_init()
681 dw_i3c_master_set_intr_regs(master); in dw_i3c_master_bus_init()
682 dw_i3c_master_enable(master); in dw_i3c_master_bus_init()
685 pm_runtime_put_autosuspend(master->dev); in dw_i3c_master_bus_init()
691 struct dw_i3c_master *master = to_dw_i3c_master(m); in dw_i3c_master_bus_cleanup() local
693 dw_i3c_master_disable(master); in dw_i3c_master_bus_cleanup()
696 static int dw_i3c_ccc_set(struct dw_i3c_master *master, in dw_i3c_ccc_set() argument
704 pos = dw_i3c_master_get_addr_pos(master, ccc->dests[0].addr); in dw_i3c_ccc_set()
709 xfer = dw_i3c_master_alloc_xfer(master, 1); in dw_i3c_ccc_set()
726 dw_i3c_master_enqueue_xfer(master, xfer); in dw_i3c_ccc_set()
728 dw_i3c_master_dequeue_xfer(master, xfer); in dw_i3c_ccc_set()
739 static int dw_i3c_ccc_get(struct dw_i3c_master *master, struct i3c_ccc_cmd *ccc) in dw_i3c_ccc_get() argument
745 pos = dw_i3c_master_get_addr_pos(master, ccc->dests[0].addr); in dw_i3c_ccc_get()
749 xfer = dw_i3c_master_alloc_xfer(master, 1); in dw_i3c_ccc_get()
767 dw_i3c_master_enqueue_xfer(master, xfer); in dw_i3c_ccc_get()
769 dw_i3c_master_dequeue_xfer(master, xfer); in dw_i3c_ccc_get()
779 static void amd_configure_od_pp_quirk(struct dw_i3c_master *master) in amd_configure_od_pp_quirk() argument
781 master->i3c_od_timing = AMD_I3C_OD_TIMING; in amd_configure_od_pp_quirk()
782 master->i3c_pp_timing = AMD_I3C_PP_TIMING; in amd_configure_od_pp_quirk()
788 struct dw_i3c_master *master = to_dw_i3c_master(m); in dw_i3c_master_send_ccc_cmd() local
795 if (master->quirks & AMD_I3C_OD_PP_TIMING) { in dw_i3c_master_send_ccc_cmd()
796 amd_configure_od_pp_quirk(master); in dw_i3c_master_send_ccc_cmd()
797 writel(master->i3c_pp_timing, master->regs + SCL_I3C_PP_TIMING); in dw_i3c_master_send_ccc_cmd()
798 writel(master->i3c_od_timing, master->regs + SCL_I3C_OD_TIMING); in dw_i3c_master_send_ccc_cmd()
801 ret = pm_runtime_resume_and_get(master->dev); in dw_i3c_master_send_ccc_cmd()
803 dev_err(master->dev, in dw_i3c_master_send_ccc_cmd()
810 ret = dw_i3c_ccc_get(master, ccc); in dw_i3c_master_send_ccc_cmd()
812 ret = dw_i3c_ccc_set(master, ccc); in dw_i3c_master_send_ccc_cmd()
814 pm_runtime_put_autosuspend(master->dev); in dw_i3c_master_send_ccc_cmd()
820 struct dw_i3c_master *master = to_dw_i3c_master(m); in dw_i3c_master_daa() local
827 ret = pm_runtime_resume_and_get(master->dev); in dw_i3c_master_daa()
829 dev_err(master->dev, in dw_i3c_master_daa()
835 olddevs = ~(master->free_pos); in dw_i3c_master_daa()
838 for (pos = 0; pos < master->maxdevs; pos++) { in dw_i3c_master_daa()
848 master->devs[pos].addr = ret; in dw_i3c_master_daa()
854 master->regs + in dw_i3c_master_daa()
855 DEV_ADDR_TABLE_LOC(master->datstartaddr, pos)); in dw_i3c_master_daa()
860 xfer = dw_i3c_master_alloc_xfer(master, 1); in dw_i3c_master_daa()
866 pos = dw_i3c_master_get_free_pos(master); in dw_i3c_master_daa()
874 cmd->cmd_lo = COMMAND_PORT_DEV_COUNT(master->maxdevs - pos) | in dw_i3c_master_daa()
881 dw_i3c_master_enqueue_xfer(master, xfer); in dw_i3c_master_daa()
883 dw_i3c_master_dequeue_xfer(master, xfer); in dw_i3c_master_daa()
885 newdevs = GENMASK(master->maxdevs - cmd->rx_len - 1, 0); in dw_i3c_master_daa()
888 for (pos = 0; pos < master->maxdevs; pos++) { in dw_i3c_master_daa()
890 i3c_master_add_i3c_dev_locked(m, master->devs[pos].addr); in dw_i3c_master_daa()
896 pm_runtime_put_autosuspend(master->dev); in dw_i3c_master_daa()
906 struct dw_i3c_master *master = to_dw_i3c_master(m); in dw_i3c_master_priv_xfers() local
914 if (i3c_nxfers > master->caps.cmdfifodepth) in dw_i3c_master_priv_xfers()
924 if (ntxwords > master->caps.datafifodepth || in dw_i3c_master_priv_xfers()
925 nrxwords > master->caps.datafifodepth) in dw_i3c_master_priv_xfers()
928 xfer = dw_i3c_master_alloc_xfer(master, i3c_nxfers); in dw_i3c_master_priv_xfers()
932 ret = pm_runtime_resume_and_get(master->dev); in dw_i3c_master_priv_xfers()
934 dev_err(master->dev, in dw_i3c_master_priv_xfers()
967 dw_i3c_master_enqueue_xfer(master, xfer); in dw_i3c_master_priv_xfers()
969 dw_i3c_master_dequeue_xfer(master, xfer); in dw_i3c_master_priv_xfers()
981 pm_runtime_put_autosuspend(master->dev); in dw_i3c_master_priv_xfers()
990 struct dw_i3c_master *master = to_dw_i3c_master(m); in dw_i3c_master_reattach_i3c_dev() local
993 pos = dw_i3c_master_get_free_pos(master); in dw_i3c_master_reattach_i3c_dev()
997 master->regs + in dw_i3c_master_reattach_i3c_dev()
998 DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index)); in dw_i3c_master_reattach_i3c_dev()
1000 master->devs[data->index].addr = 0; in dw_i3c_master_reattach_i3c_dev()
1001 master->free_pos |= BIT(data->index); in dw_i3c_master_reattach_i3c_dev()
1004 master->devs[pos].addr = dev->info.dyn_addr; in dw_i3c_master_reattach_i3c_dev()
1005 master->free_pos &= ~BIT(pos); in dw_i3c_master_reattach_i3c_dev()
1009 master->regs + in dw_i3c_master_reattach_i3c_dev()
1010 DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index)); in dw_i3c_master_reattach_i3c_dev()
1012 master->devs[data->index].addr = dev->info.dyn_addr; in dw_i3c_master_reattach_i3c_dev()
1020 struct dw_i3c_master *master = to_dw_i3c_master(m); in dw_i3c_master_attach_i3c_dev() local
1024 pos = dw_i3c_master_get_free_pos(master); in dw_i3c_master_attach_i3c_dev()
1033 master->devs[pos].addr = dev->info.dyn_addr ? : dev->info.static_addr; in dw_i3c_master_attach_i3c_dev()
1034 master->free_pos &= ~BIT(pos); in dw_i3c_master_attach_i3c_dev()
1037 writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(master->devs[pos].addr), in dw_i3c_master_attach_i3c_dev()
1038 master->regs + in dw_i3c_master_attach_i3c_dev()
1039 DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index)); in dw_i3c_master_attach_i3c_dev()
1048 struct dw_i3c_master *master = to_dw_i3c_master(m); in dw_i3c_master_detach_i3c_dev() local
1051 master->regs + in dw_i3c_master_detach_i3c_dev()
1052 DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index)); in dw_i3c_master_detach_i3c_dev()
1055 master->devs[data->index].addr = 0; in dw_i3c_master_detach_i3c_dev()
1056 master->free_pos |= BIT(data->index); in dw_i3c_master_detach_i3c_dev()
1066 struct dw_i3c_master *master = to_dw_i3c_master(m); in dw_i3c_master_i2c_xfers() local
1074 if (i2c_nxfers > master->caps.cmdfifodepth) in dw_i3c_master_i2c_xfers()
1084 if (ntxwords > master->caps.datafifodepth || in dw_i3c_master_i2c_xfers()
1085 nrxwords > master->caps.datafifodepth) in dw_i3c_master_i2c_xfers()
1088 xfer = dw_i3c_master_alloc_xfer(master, i2c_nxfers); in dw_i3c_master_i2c_xfers()
1092 ret = pm_runtime_resume_and_get(master->dev); in dw_i3c_master_i2c_xfers()
1094 dev_err(master->dev, in dw_i3c_master_i2c_xfers()
1123 dw_i3c_master_enqueue_xfer(master, xfer); in dw_i3c_master_i2c_xfers()
1125 dw_i3c_master_dequeue_xfer(master, xfer); in dw_i3c_master_i2c_xfers()
1130 pm_runtime_put_autosuspend(master->dev); in dw_i3c_master_i2c_xfers()
1137 struct dw_i3c_master *master = to_dw_i3c_master(m); in dw_i3c_master_attach_i2c_dev() local
1141 pos = dw_i3c_master_get_free_pos(master); in dw_i3c_master_attach_i2c_dev()
1150 master->devs[pos].addr = dev->addr; in dw_i3c_master_attach_i2c_dev()
1151 master->devs[pos].is_i2c_addr = true; in dw_i3c_master_attach_i2c_dev()
1152 master->free_pos &= ~BIT(pos); in dw_i3c_master_attach_i2c_dev()
1157 master->regs + in dw_i3c_master_attach_i2c_dev()
1158 DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index)); in dw_i3c_master_attach_i2c_dev()
1167 struct dw_i3c_master *master = to_dw_i3c_master(m); in dw_i3c_master_detach_i2c_dev() local
1170 master->regs + in dw_i3c_master_detach_i2c_dev()
1171 DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index)); in dw_i3c_master_detach_i2c_dev()
1174 master->devs[data->index].addr = 0; in dw_i3c_master_detach_i2c_dev()
1175 master->free_pos |= BIT(data->index); in dw_i3c_master_detach_i2c_dev()
1184 struct dw_i3c_master *master = to_dw_i3c_master(m); in dw_i3c_master_request_ibi() local
1191 spin_lock_irqsave(&master->devs_lock, flags); in dw_i3c_master_request_ibi()
1192 master->devs[data->index].ibi_dev = dev; in dw_i3c_master_request_ibi()
1193 spin_unlock_irqrestore(&master->devs_lock, flags); in dw_i3c_master_request_ibi()
1202 struct dw_i3c_master *master = to_dw_i3c_master(m); in dw_i3c_master_free_ibi() local
1205 spin_lock_irqsave(&master->devs_lock, flags); in dw_i3c_master_free_ibi()
1206 master->devs[data->index].ibi_dev = NULL; in dw_i3c_master_free_ibi()
1207 spin_unlock_irqrestore(&master->devs_lock, flags); in dw_i3c_master_free_ibi()
1213 static void dw_i3c_master_enable_sir_signal(struct dw_i3c_master *master, bool enable) in dw_i3c_master_enable_sir_signal() argument
1217 reg = readl(master->regs + INTR_STATUS_EN); in dw_i3c_master_enable_sir_signal()
1221 writel(reg, master->regs + INTR_STATUS_EN); in dw_i3c_master_enable_sir_signal()
1223 reg = readl(master->regs + INTR_SIGNAL_EN); in dw_i3c_master_enable_sir_signal()
1227 writel(reg, master->regs + INTR_SIGNAL_EN); in dw_i3c_master_enable_sir_signal()
1230 static void dw_i3c_master_set_sir_enabled(struct dw_i3c_master *master, in dw_i3c_master_set_sir_enabled() argument
1238 dat_entry = DEV_ADDR_TABLE_LOC(master->datstartaddr, idx); in dw_i3c_master_set_sir_enabled()
1240 spin_lock_irqsave(&master->devs_lock, flags); in dw_i3c_master_set_sir_enabled()
1241 reg = readl(master->regs + dat_entry); in dw_i3c_master_set_sir_enabled()
1249 master->platform_ops->set_dat_ibi(master, dev, enable, &reg); in dw_i3c_master_set_sir_enabled()
1250 writel(reg, master->regs + dat_entry); in dw_i3c_master_set_sir_enabled()
1253 global = (master->sir_rej_mask == IBI_REQ_REJECT_ALL); in dw_i3c_master_set_sir_enabled()
1254 master->sir_rej_mask &= ~BIT(idx); in dw_i3c_master_set_sir_enabled()
1256 bool hj_rejected = !!(readl(master->regs + DEVICE_CTRL) & DEV_CTRL_HOT_JOIN_NACK); in dw_i3c_master_set_sir_enabled()
1258 master->sir_rej_mask |= BIT(idx); in dw_i3c_master_set_sir_enabled()
1259 global = (master->sir_rej_mask == IBI_REQ_REJECT_ALL) && hj_rejected; in dw_i3c_master_set_sir_enabled()
1261 writel(master->sir_rej_mask, master->regs + IBI_SIR_REQ_REJECT); in dw_i3c_master_set_sir_enabled()
1264 dw_i3c_master_enable_sir_signal(master, enable); in dw_i3c_master_set_sir_enabled()
1267 spin_unlock_irqrestore(&master->devs_lock, flags); in dw_i3c_master_set_sir_enabled()
1272 struct dw_i3c_master *master = to_dw_i3c_master(m); in dw_i3c_master_enable_hotjoin() local
1275 ret = pm_runtime_resume_and_get(master->dev); in dw_i3c_master_enable_hotjoin()
1277 dev_err(master->dev, in dw_i3c_master_enable_hotjoin()
1283 dw_i3c_master_enable_sir_signal(master, true); in dw_i3c_master_enable_hotjoin()
1284 writel(readl(master->regs + DEVICE_CTRL) & ~DEV_CTRL_HOT_JOIN_NACK, in dw_i3c_master_enable_hotjoin()
1285 master->regs + DEVICE_CTRL); in dw_i3c_master_enable_hotjoin()
1292 struct dw_i3c_master *master = to_dw_i3c_master(m); in dw_i3c_master_disable_hotjoin() local
1294 writel(readl(master->regs + DEVICE_CTRL) | DEV_CTRL_HOT_JOIN_NACK, in dw_i3c_master_disable_hotjoin()
1295 master->regs + DEVICE_CTRL); in dw_i3c_master_disable_hotjoin()
1297 pm_runtime_put_autosuspend(master->dev); in dw_i3c_master_disable_hotjoin()
1305 struct dw_i3c_master *master = to_dw_i3c_master(m); in dw_i3c_master_enable_ibi() local
1308 rc = pm_runtime_resume_and_get(master->dev); in dw_i3c_master_enable_ibi()
1310 dev_err(master->dev, in dw_i3c_master_enable_ibi()
1316 dw_i3c_master_set_sir_enabled(master, dev, data->index, true); in dw_i3c_master_enable_ibi()
1321 dw_i3c_master_set_sir_enabled(master, dev, data->index, false); in dw_i3c_master_enable_ibi()
1322 pm_runtime_put_autosuspend(master->dev); in dw_i3c_master_enable_ibi()
1332 struct dw_i3c_master *master = to_dw_i3c_master(m); in dw_i3c_master_disable_ibi() local
1339 dw_i3c_master_set_sir_enabled(master, dev, data->index, false); in dw_i3c_master_disable_ibi()
1341 pm_runtime_put_autosuspend(master->dev); in dw_i3c_master_disable_ibi()
1353 static void dw_i3c_master_drain_ibi_queue(struct dw_i3c_master *master, in dw_i3c_master_drain_ibi_queue() argument
1359 readl(master->regs + IBI_QUEUE_STATUS); in dw_i3c_master_drain_ibi_queue()
1362 static void dw_i3c_master_handle_ibi_sir(struct dw_i3c_master *master, in dw_i3c_master_handle_ibi_sir() argument
1386 spin_lock_irqsave(&master->devs_lock, flags); in dw_i3c_master_handle_ibi_sir()
1387 idx = dw_i3c_master_get_addr_pos(master, addr); in dw_i3c_master_handle_ibi_sir()
1389 dev_dbg_ratelimited(&master->base.dev, in dw_i3c_master_handle_ibi_sir()
1394 dev = master->devs[idx].ibi_dev; in dw_i3c_master_handle_ibi_sir()
1396 dev_dbg_ratelimited(&master->base.dev, in dw_i3c_master_handle_ibi_sir()
1404 dev_dbg_ratelimited(&master->base.dev, in dw_i3c_master_handle_ibi_sir()
1410 dev_dbg_ratelimited(&master->base.dev, in dw_i3c_master_handle_ibi_sir()
1417 dw_i3c_master_read_ibi_fifo(master, slot->data, len); in dw_i3c_master_handle_ibi_sir()
1422 spin_unlock_irqrestore(&master->devs_lock, flags); in dw_i3c_master_handle_ibi_sir()
1427 dw_i3c_master_drain_ibi_queue(master, len); in dw_i3c_master_handle_ibi_sir()
1429 spin_unlock_irqrestore(&master->devs_lock, flags); in dw_i3c_master_handle_ibi_sir()
1436 static void dw_i3c_master_irq_handle_ibis(struct dw_i3c_master *master) in dw_i3c_master_irq_handle_ibis() argument
1441 reg = readl(master->regs + QUEUE_STATUS_LEVEL); in dw_i3c_master_irq_handle_ibis()
1447 reg = readl(master->regs + IBI_QUEUE_STATUS); in dw_i3c_master_irq_handle_ibis()
1450 dw_i3c_master_handle_ibi_sir(master, reg); in dw_i3c_master_irq_handle_ibis()
1452 queue_work(master->base.wq, &master->hj_work); in dw_i3c_master_irq_handle_ibis()
1455 dev_info(&master->base.dev, in dw_i3c_master_irq_handle_ibis()
1458 dw_i3c_master_drain_ibi_queue(master, len); in dw_i3c_master_irq_handle_ibis()
1465 struct dw_i3c_master *master = dev_id; in dw_i3c_master_irq_handler() local
1468 status = readl(master->regs + INTR_STATUS); in dw_i3c_master_irq_handler()
1470 if (!(status & readl(master->regs + INTR_STATUS_EN))) { in dw_i3c_master_irq_handler()
1471 writel(INTR_ALL, master->regs + INTR_STATUS); in dw_i3c_master_irq_handler()
1475 spin_lock(&master->xferqueue.lock); in dw_i3c_master_irq_handler()
1476 dw_i3c_master_end_xfer_locked(master, status); in dw_i3c_master_irq_handler()
1478 writel(INTR_TRANSFER_ERR_STAT, master->regs + INTR_STATUS); in dw_i3c_master_irq_handler()
1479 spin_unlock(&master->xferqueue.lock); in dw_i3c_master_irq_handler()
1482 dw_i3c_master_irq_handle_ibis(master); in dw_i3c_master_irq_handler()
1528 struct dw_i3c_master *master = in dw_i3c_hj_work() local
1529 container_of(work, typeof(*master), hj_work); in dw_i3c_hj_work()
1531 i3c_master_do_daa(&master->base); in dw_i3c_hj_work()
1534 int dw_i3c_common_probe(struct dw_i3c_master *master, in dw_i3c_common_probe() argument
1539 if (!master->platform_ops) in dw_i3c_common_probe()
1540 master->platform_ops = &dw_i3c_platform_ops_default; in dw_i3c_common_probe()
1542 master->dev = &pdev->dev; in dw_i3c_common_probe()
1544 master->regs = devm_platform_ioremap_resource(pdev, 0); in dw_i3c_common_probe()
1545 if (IS_ERR(master->regs)) in dw_i3c_common_probe()
1546 return PTR_ERR(master->regs); in dw_i3c_common_probe()
1548 master->core_clk = devm_clk_get_enabled(&pdev->dev, NULL); in dw_i3c_common_probe()
1549 if (IS_ERR(master->core_clk)) in dw_i3c_common_probe()
1550 return PTR_ERR(master->core_clk); in dw_i3c_common_probe()
1552 master->pclk = devm_clk_get_optional_enabled(&pdev->dev, "pclk"); in dw_i3c_common_probe()
1553 if (IS_ERR(master->pclk)) in dw_i3c_common_probe()
1554 return PTR_ERR(master->pclk); in dw_i3c_common_probe()
1556 master->core_rst = devm_reset_control_get_optional_exclusive(&pdev->dev, in dw_i3c_common_probe()
1558 if (IS_ERR(master->core_rst)) in dw_i3c_common_probe()
1559 return PTR_ERR(master->core_rst); in dw_i3c_common_probe()
1561 reset_control_deassert(master->core_rst); in dw_i3c_common_probe()
1563 spin_lock_init(&master->xferqueue.lock); in dw_i3c_common_probe()
1564 INIT_LIST_HEAD(&master->xferqueue.list); in dw_i3c_common_probe()
1566 writel(INTR_ALL, master->regs + INTR_STATUS); in dw_i3c_common_probe()
1570 dev_name(&pdev->dev), master); in dw_i3c_common_probe()
1574 platform_set_drvdata(pdev, master); in dw_i3c_common_probe()
1582 ret = readl(master->regs + QUEUE_STATUS_LEVEL); in dw_i3c_common_probe()
1583 master->caps.cmdfifodepth = QUEUE_STATUS_LEVEL_CMD(ret); in dw_i3c_common_probe()
1585 ret = readl(master->regs + DATA_BUFFER_STATUS_LEVEL); in dw_i3c_common_probe()
1586 master->caps.datafifodepth = DATA_BUFFER_STATUS_LEVEL_TX(ret); in dw_i3c_common_probe()
1588 ret = readl(master->regs + DEVICE_ADDR_TABLE_POINTER); in dw_i3c_common_probe()
1589 master->datstartaddr = ret; in dw_i3c_common_probe()
1590 master->maxdevs = ret >> 16; in dw_i3c_common_probe()
1591 master->free_pos = GENMASK(master->maxdevs - 1, 0); in dw_i3c_common_probe()
1593 master->quirks = (unsigned long)device_get_match_data(&pdev->dev); in dw_i3c_common_probe()
1595 INIT_WORK(&master->hj_work, dw_i3c_hj_work); in dw_i3c_common_probe()
1596 ret = i3c_master_register(&master->base, &pdev->dev, in dw_i3c_common_probe()
1609 reset_control_assert(master->core_rst); in dw_i3c_common_probe()
1615 void dw_i3c_common_remove(struct dw_i3c_master *master) in dw_i3c_common_remove() argument
1617 cancel_work_sync(&master->hj_work); in dw_i3c_common_remove()
1618 i3c_master_unregister(&master->base); in dw_i3c_common_remove()
1620 pm_runtime_disable(master->dev); in dw_i3c_common_remove()
1621 pm_runtime_set_suspended(master->dev); in dw_i3c_common_remove()
1622 pm_runtime_dont_use_autosuspend(master->dev); in dw_i3c_common_remove()
1630 struct dw_i3c_master *master; in dw_i3c_probe() local
1632 master = devm_kzalloc(&pdev->dev, sizeof(*master), GFP_KERNEL); in dw_i3c_probe()
1633 if (!master) in dw_i3c_probe()
1636 return dw_i3c_common_probe(master, pdev); in dw_i3c_probe()
1641 struct dw_i3c_master *master = platform_get_drvdata(pdev); in dw_i3c_remove() local
1643 dw_i3c_common_remove(master); in dw_i3c_remove()
1646 static void dw_i3c_master_restore_addrs(struct dw_i3c_master *master) in dw_i3c_master_restore_addrs() argument
1650 writel(DEV_ADDR_DYNAMIC_ADDR_VALID | DEV_ADDR_DYNAMIC(master->dev_addr), in dw_i3c_master_restore_addrs()
1651 master->regs + DEVICE_ADDR); in dw_i3c_master_restore_addrs()
1653 for (pos = 0; pos < master->maxdevs; pos++) { in dw_i3c_master_restore_addrs()
1654 if (master->free_pos & BIT(pos)) in dw_i3c_master_restore_addrs()
1657 if (master->devs[pos].is_i2c_addr) in dw_i3c_master_restore_addrs()
1659 DEV_ADDR_TABLE_STATIC_ADDR(master->devs[pos].addr); in dw_i3c_master_restore_addrs()
1661 reg_val = DEV_ADDR_TABLE_DYNAMIC_ADDR(master->devs[pos].addr); in dw_i3c_master_restore_addrs()
1663 writel(reg_val, master->regs + DEV_ADDR_TABLE_LOC(master->datstartaddr, pos)); in dw_i3c_master_restore_addrs()
1667 static void dw_i3c_master_restore_timing_regs(struct dw_i3c_master *master) in dw_i3c_master_restore_timing_regs() argument
1670 if (master->quirks & AMD_I3C_OD_PP_TIMING) in dw_i3c_master_restore_timing_regs()
1671 amd_configure_od_pp_quirk(master); in dw_i3c_master_restore_timing_regs()
1673 writel(master->i3c_pp_timing, master->regs + SCL_I3C_PP_TIMING); in dw_i3c_master_restore_timing_regs()
1674 writel(master->bus_free_timing, master->regs + BUS_FREE_TIMING); in dw_i3c_master_restore_timing_regs()
1675 writel(master->i3c_od_timing, master->regs + SCL_I3C_OD_TIMING); in dw_i3c_master_restore_timing_regs()
1676 writel(master->ext_lcnt_timing, master->regs + SCL_EXT_LCNT_TIMING); in dw_i3c_master_restore_timing_regs()
1678 if (master->i2c_slv_prsnt) { in dw_i3c_master_restore_timing_regs()
1679 writel(master->i2c_fmp_timing, master->regs + SCL_I2C_FMP_TIMING); in dw_i3c_master_restore_timing_regs()
1680 writel(master->i2c_fm_timing, master->regs + SCL_I2C_FM_TIMING); in dw_i3c_master_restore_timing_regs()
1684 static int dw_i3c_master_enable_clks(struct dw_i3c_master *master) in dw_i3c_master_enable_clks() argument
1688 ret = clk_prepare_enable(master->core_clk); in dw_i3c_master_enable_clks()
1692 ret = clk_prepare_enable(master->pclk); in dw_i3c_master_enable_clks()
1694 clk_disable_unprepare(master->core_clk); in dw_i3c_master_enable_clks()
1701 static inline void dw_i3c_master_disable_clks(struct dw_i3c_master *master) in dw_i3c_master_disable_clks() argument
1703 clk_disable_unprepare(master->pclk); in dw_i3c_master_disable_clks()
1704 clk_disable_unprepare(master->core_clk); in dw_i3c_master_disable_clks()
1709 struct dw_i3c_master *master = dev_get_drvdata(dev); in dw_i3c_master_runtime_suspend() local
1711 dw_i3c_master_disable(master); in dw_i3c_master_runtime_suspend()
1713 reset_control_assert(master->core_rst); in dw_i3c_master_runtime_suspend()
1714 dw_i3c_master_disable_clks(master); in dw_i3c_master_runtime_suspend()
1721 struct dw_i3c_master *master = dev_get_drvdata(dev); in dw_i3c_master_runtime_resume() local
1724 dw_i3c_master_enable_clks(master); in dw_i3c_master_runtime_resume()
1725 reset_control_deassert(master->core_rst); in dw_i3c_master_runtime_resume()
1727 dw_i3c_master_set_intr_regs(master); in dw_i3c_master_runtime_resume()
1728 dw_i3c_master_restore_timing_regs(master); in dw_i3c_master_runtime_resume()
1729 dw_i3c_master_restore_addrs(master); in dw_i3c_master_runtime_resume()
1731 dw_i3c_master_enable(master); in dw_i3c_master_runtime_resume()
1742 struct dw_i3c_master *master = platform_get_drvdata(pdev); in dw_i3c_shutdown() local
1745 ret = pm_runtime_resume_and_get(master->dev); in dw_i3c_shutdown()
1747 dev_err(master->dev, in dw_i3c_shutdown()
1753 cancel_work_sync(&master->hj_work); in dw_i3c_shutdown()
1756 writel((u32)~INTR_ALL, master->regs + INTR_STATUS_EN); in dw_i3c_shutdown()
1757 writel((u32)~INTR_ALL, master->regs + INTR_SIGNAL_EN); in dw_i3c_shutdown()
1759 pm_runtime_put_autosuspend(master->dev); in dw_i3c_shutdown()