Lines Matching refs:gi2c
155 static int geni_i2c_clk_map_idx(struct geni_i2c_dev *gi2c)
161 if (itr->clk_freq_out == gi2c->clk_freq_out) {
162 gi2c->clk_fld = itr;
169 static void qcom_geni_i2c_conf(struct geni_i2c_dev *gi2c)
171 const struct geni_i2c_clk_fld *itr = gi2c->clk_fld;
174 writel_relaxed(0, gi2c->se.base + SE_GENI_CLK_SEL);
177 writel_relaxed(val, gi2c->se.base + GENI_SER_M_CLK_CFG);
182 writel_relaxed(val, gi2c->se.base + SE_I2C_SCL_COUNTERS);
185 static void geni_i2c_err_misc(struct geni_i2c_dev *gi2c)
187 u32 m_cmd = readl_relaxed(gi2c->se.base + SE_GENI_M_CMD0);
188 u32 m_stat = readl_relaxed(gi2c->se.base + SE_GENI_M_IRQ_STATUS);
189 u32 geni_s = readl_relaxed(gi2c->se.base + SE_GENI_STATUS);
190 u32 geni_ios = readl_relaxed(gi2c->se.base + SE_GENI_IOS);
191 u32 dma = readl_relaxed(gi2c->se.base + SE_GENI_DMA_MODE_EN);
195 rx_st = readl_relaxed(gi2c->se.base + SE_DMA_RX_IRQ_STAT);
196 tx_st = readl_relaxed(gi2c->se.base + SE_DMA_TX_IRQ_STAT);
198 rx_st = readl_relaxed(gi2c->se.base + SE_GENI_RX_FIFO_STATUS);
199 tx_st = readl_relaxed(gi2c->se.base + SE_GENI_TX_FIFO_STATUS);
201 dev_dbg(gi2c->se.dev, "DMA:%d tx_stat:0x%x, rx_stat:0x%x, irq-stat:0x%x\n",
203 dev_dbg(gi2c->se.dev, "m_cmd:0x%x, geni_status:0x%x, geni_ios:0x%x\n",
207 static void geni_i2c_err(struct geni_i2c_dev *gi2c, int err)
209 if (!gi2c->err)
210 gi2c->err = gi2c_log[err].err;
211 if (gi2c->cur)
212 dev_dbg(gi2c->se.dev, "len:%d, slv-addr:0x%x, RD/WR:%d\n",
213 gi2c->cur->len, gi2c->cur->addr, gi2c->cur->flags);
217 gi2c->abort_done = true;
221 dev_dbg(gi2c->se.dev, "%s\n", gi2c_log[err].msg);
224 dev_err(gi2c->se.dev, "%s\n", gi2c_log[err].msg);
225 geni_i2c_err_misc(gi2c);
232 struct geni_i2c_dev *gi2c = dev;
233 void __iomem *base = gi2c->se.base;
243 spin_lock(&gi2c->lock);
249 cur = gi2c->cur;
255 geni_i2c_err(gi2c, NACK);
257 geni_i2c_err(gi2c, BUS_PROTO);
259 geni_i2c_err(gi2c, ARB_LOST);
261 geni_i2c_err(gi2c, GENI_OVERRUN);
263 geni_i2c_err(gi2c, GENI_ILLEGAL_CMD);
265 geni_i2c_err(gi2c, GENI_ABORT_DONE);
267 geni_i2c_err(gi2c, GP_IRQ0);
273 dev_dbg(gi2c->se.dev, "i2c dma tx:0x%x, dma rx:0x%x\n",
282 while (gi2c->cur_rd < cur->len && p < sizeof(val)) {
283 cur->buf[gi2c->cur_rd++] = val & 0xff;
287 if (gi2c->cur_rd == cur->len)
292 for (j = 0; j < gi2c->tx_wm; j++) {
297 while (gi2c->cur_wr < cur->len && p < sizeof(val)) {
298 temp = cur->buf[gi2c->cur_wr++];
304 if (gi2c->cur_wr == cur->len) {
323 complete(&gi2c->done);
325 spin_unlock(&gi2c->lock);
330 static void geni_i2c_abort_xfer(struct geni_i2c_dev *gi2c)
335 spin_lock_irqsave(&gi2c->lock, flags);
336 geni_i2c_err(gi2c, GENI_TIMEOUT);
337 gi2c->cur = NULL;
338 gi2c->abort_done = false;
339 geni_se_abort_m_cmd(&gi2c->se);
340 spin_unlock_irqrestore(&gi2c->lock, flags);
343 time_left = wait_for_completion_timeout(&gi2c->done, time_left);
344 } while (!gi2c->abort_done && time_left);
347 dev_err(gi2c->se.dev, "Timeout abort_m_cmd\n");
350 static void geni_i2c_rx_fsm_rst(struct geni_i2c_dev *gi2c)
355 writel_relaxed(1, gi2c->se.base + SE_DMA_RX_FSM_RST);
357 time_left = wait_for_completion_timeout(&gi2c->done, time_left);
358 val = readl_relaxed(gi2c->se.base + SE_DMA_RX_IRQ_STAT);
362 dev_err(gi2c->se.dev, "Timeout resetting RX_FSM\n");
365 static void geni_i2c_tx_fsm_rst(struct geni_i2c_dev *gi2c)
370 writel_relaxed(1, gi2c->se.base + SE_DMA_TX_FSM_RST);
372 time_left = wait_for_completion_timeout(&gi2c->done, time_left);
373 val = readl_relaxed(gi2c->se.base + SE_DMA_TX_IRQ_STAT);
377 dev_err(gi2c->se.dev, "Timeout resetting TX_FSM\n");
380 static void geni_i2c_rx_msg_cleanup(struct geni_i2c_dev *gi2c,
383 gi2c->cur_rd = 0;
384 if (gi2c->dma_buf) {
385 if (gi2c->err)
386 geni_i2c_rx_fsm_rst(gi2c);
387 geni_se_rx_dma_unprep(&gi2c->se, gi2c->dma_addr, gi2c->xfer_len);
388 i2c_put_dma_safe_msg_buf(gi2c->dma_buf, cur, !gi2c->err);
392 static void geni_i2c_tx_msg_cleanup(struct geni_i2c_dev *gi2c,
395 gi2c->cur_wr = 0;
396 if (gi2c->dma_buf) {
397 if (gi2c->err)
398 geni_i2c_tx_fsm_rst(gi2c);
399 geni_se_tx_dma_unprep(&gi2c->se, gi2c->dma_addr, gi2c->xfer_len);
400 i2c_put_dma_safe_msg_buf(gi2c->dma_buf, cur, !gi2c->err);
404 static int geni_i2c_rx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg,
410 struct geni_se *se = &gi2c->se;
428 gi2c->xfer_len = len;
429 gi2c->dma_addr = rx_dma;
430 gi2c->dma_buf = dma_buf;
433 cur = gi2c->cur;
434 time_left = wait_for_completion_timeout(&gi2c->done, XFER_TIMEOUT);
436 geni_i2c_abort_xfer(gi2c);
438 geni_i2c_rx_msg_cleanup(gi2c, cur);
440 return gi2c->err;
443 static int geni_i2c_tx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg,
449 struct geni_se *se = &gi2c->se;
467 gi2c->xfer_len = len;
468 gi2c->dma_addr = tx_dma;
469 gi2c->dma_buf = dma_buf;
475 cur = gi2c->cur;
476 time_left = wait_for_completion_timeout(&gi2c->done, XFER_TIMEOUT);
478 geni_i2c_abort_xfer(gi2c);
480 geni_i2c_tx_msg_cleanup(gi2c, cur);
482 return gi2c->err;
487 struct geni_i2c_dev *gi2c = cb;
490 dev_err(gi2c->se.dev, "DMA txn failed:%d\n", result->result);
491 gi2c->err = -EIO;
493 dev_dbg(gi2c->se.dev, "DMA xfer has pending: %d\n", result->residue);
496 complete(&gi2c->done);
499 static void geni_i2c_gpi_unmap(struct geni_i2c_dev *gi2c, struct i2c_msg *msg,
504 dma_unmap_single(gi2c->se.dev->parent, tx_addr, msg->len, DMA_TO_DEVICE);
505 i2c_put_dma_safe_msg_buf(tx_buf, msg, !gi2c->err);
509 dma_unmap_single(gi2c->se.dev->parent, rx_addr, msg->len, DMA_FROM_DEVICE);
510 i2c_put_dma_safe_msg_buf(rx_buf, msg, !gi2c->err);
514 static int geni_i2c_gpi(struct geni_i2c_dev *gi2c, struct i2c_msg *msg,
538 addr = dma_map_single(gi2c->se.dev->parent, dma_buf, msg->len, map_dirn);
539 if (dma_mapping_error(gi2c->se.dev->parent, addr)) {
550 dev_err(gi2c->se.dev, "dma config error: %d for op:%d\n", ret, op);
565 dev_err(gi2c->se.dev, "prep_slave_sg failed\n");
571 desc->callback_param = gi2c;
580 dma_unmap_single(gi2c->se.dev->parent, addr, msg->len, map_dirn);
585 static int geni_i2c_gpi_xfer(struct geni_i2c_dev *gi2c, struct i2c_msg msgs[], int num)
592 const struct geni_i2c_clk_fld *itr = gi2c->clk_fld;
606 gi2c->cur = &msgs[i];
607 gi2c->err = 0;
608 dev_dbg(gi2c->se.dev, "msg[%d].len:%d\n", i, gi2c->cur->len);
616 ret = geni_i2c_gpi(gi2c, &msgs[i], &config,
617 &tx_addr, &tx_buf, I2C_WRITE, gi2c->tx_c);
622 ret = geni_i2c_gpi(gi2c, &msgs[i], &config,
623 &rx_addr, &rx_buf, I2C_READ, gi2c->rx_c);
627 dma_async_issue_pending(gi2c->rx_c);
630 dma_async_issue_pending(gi2c->tx_c);
632 timeout = wait_for_completion_timeout(&gi2c->done, XFER_TIMEOUT);
634 dev_err(gi2c->se.dev, "I2C timeout gpi flags:%d addr:0x%x\n",
635 gi2c->cur->flags, gi2c->cur->addr);
636 gi2c->err = -ETIMEDOUT;
639 if (gi2c->err) {
640 ret = gi2c->err;
644 geni_i2c_gpi_unmap(gi2c, &msgs[i], tx_buf, tx_addr, rx_buf, rx_addr);
650 dev_err(gi2c->se.dev, "GPI transfer failed: %d\n", ret);
651 dmaengine_terminate_sync(gi2c->rx_c);
652 dmaengine_terminate_sync(gi2c->tx_c);
653 geni_i2c_gpi_unmap(gi2c, &msgs[i], tx_buf, tx_addr, rx_buf, rx_addr);
657 static int geni_i2c_fifo_xfer(struct geni_i2c_dev *gi2c,
667 gi2c->cur = &msgs[i];
669 ret = geni_i2c_rx_one_msg(gi2c, &msgs[i], m_param);
671 ret = geni_i2c_tx_one_msg(gi2c, &msgs[i], m_param);
684 struct geni_i2c_dev *gi2c = i2c_get_adapdata(adap);
687 gi2c->err = 0;
688 reinit_completion(&gi2c->done);
689 ret = pm_runtime_get_sync(gi2c->se.dev);
691 dev_err(gi2c->se.dev, "error turning SE resources:%d\n", ret);
692 pm_runtime_put_noidle(gi2c->se.dev);
694 pm_runtime_set_suspended(gi2c->se.dev);
698 qcom_geni_i2c_conf(gi2c);
700 if (gi2c->gpi_mode)
701 ret = geni_i2c_gpi_xfer(gi2c, msgs, num);
703 ret = geni_i2c_fifo_xfer(gi2c, msgs, num);
705 pm_runtime_mark_last_busy(gi2c->se.dev);
706 pm_runtime_put_autosuspend(gi2c->se.dev);
707 gi2c->cur = NULL;
708 gi2c->err = 0;
730 static void release_gpi_dma(struct geni_i2c_dev *gi2c)
732 if (gi2c->rx_c)
733 dma_release_channel(gi2c->rx_c);
735 if (gi2c->tx_c)
736 dma_release_channel(gi2c->tx_c);
739 static int setup_gpi_dma(struct geni_i2c_dev *gi2c)
743 geni_se_select_mode(&gi2c->se, GENI_GPI_DMA);
744 gi2c->tx_c = dma_request_chan(gi2c->se.dev, "tx");
745 if (IS_ERR(gi2c->tx_c)) {
746 ret = dev_err_probe(gi2c->se.dev, PTR_ERR(gi2c->tx_c),
751 gi2c->rx_c = dma_request_chan(gi2c->se.dev, "rx");
752 if (IS_ERR(gi2c->rx_c)) {
753 ret = dev_err_probe(gi2c->se.dev, PTR_ERR(gi2c->rx_c),
758 dev_dbg(gi2c->se.dev, "Grabbed GPI dma channels\n");
762 dma_release_channel(gi2c->tx_c);
769 struct geni_i2c_dev *gi2c;
775 gi2c = devm_kzalloc(dev, sizeof(*gi2c), GFP_KERNEL);
776 if (!gi2c)
779 gi2c->se.dev = dev;
780 gi2c->se.wrapper = dev_get_drvdata(dev->parent);
781 gi2c->se.base = devm_platform_ioremap_resource(pdev, 0);
782 if (IS_ERR(gi2c->se.base))
783 return PTR_ERR(gi2c->se.base);
788 gi2c->core_clk = devm_clk_get(dev, "core");
789 if (IS_ERR(gi2c->core_clk))
790 return PTR_ERR(gi2c->core_clk);
793 gi2c->se.clk = devm_clk_get(dev, "se");
794 if (IS_ERR(gi2c->se.clk) && !has_acpi_companion(dev))
795 return PTR_ERR(gi2c->se.clk);
798 &gi2c->clk_freq_out);
801 gi2c->clk_freq_out = KHZ(100);
805 ACPI_COMPANION_SET(&gi2c->adap.dev, ACPI_COMPANION(dev));
807 gi2c->irq = platform_get_irq(pdev, 0);
808 if (gi2c->irq < 0)
809 return gi2c->irq;
811 ret = geni_i2c_clk_map_idx(gi2c);
814 gi2c->clk_freq_out, ret);
818 gi2c->adap.algo = &geni_i2c_algo;
819 init_completion(&gi2c->done);
820 spin_lock_init(&gi2c->lock);
821 platform_set_drvdata(pdev, gi2c);
822 ret = devm_request_irq(dev, gi2c->irq, geni_i2c_irq, 0,
823 dev_name(dev), gi2c);
826 gi2c->irq, ret);
830 disable_irq(gi2c->irq);
831 i2c_set_adapdata(&gi2c->adap, gi2c);
832 gi2c->adap.dev.parent = dev;
833 gi2c->adap.dev.of_node = dev->of_node;
834 strscpy(gi2c->adap.name, "Geni-I2C", sizeof(gi2c->adap.name));
836 ret = geni_icc_get(&gi2c->se, desc ? desc->icc_ddr : "qup-memory");
844 gi2c->se.icc_paths[GENI_TO_CORE].avg_bw = GENI_DEFAULT_BW;
845 gi2c->se.icc_paths[CPU_TO_GENI].avg_bw = GENI_DEFAULT_BW;
847 gi2c->se.icc_paths[GENI_TO_DDR].avg_bw = Bps_to_icc(gi2c->clk_freq_out);
849 ret = geni_icc_set_bw(&gi2c->se);
853 ret = clk_prepare_enable(gi2c->core_clk);
857 ret = geni_se_resources_on(&gi2c->se);
860 clk_disable_unprepare(gi2c->core_clk);
863 proto = geni_se_read_proto(&gi2c->se);
866 geni_se_resources_off(&gi2c->se);
867 clk_disable_unprepare(gi2c->core_clk);
874 fifo_disable = readl_relaxed(gi2c->se.base + GENI_IF_DISABLE_RO) & FIFO_IF_DISABLE;
878 gi2c->gpi_mode = true;
879 ret = setup_gpi_dma(gi2c);
881 geni_se_resources_off(&gi2c->se);
882 clk_disable_unprepare(gi2c->core_clk);
888 gi2c->gpi_mode = false;
889 tx_depth = geni_se_get_tx_fifo_depth(&gi2c->se);
897 geni_se_resources_off(&gi2c->se);
898 clk_disable_unprepare(gi2c->core_clk);
902 gi2c->tx_wm = tx_depth - 1;
903 geni_se_init(&gi2c->se, gi2c->tx_wm, tx_depth);
904 geni_se_config_packing(&gi2c->se, BITS_PER_BYTE,
910 clk_disable_unprepare(gi2c->core_clk);
911 ret = geni_se_resources_off(&gi2c->se);
917 ret = geni_icc_disable(&gi2c->se);
921 gi2c->suspended = 1;
922 pm_runtime_set_suspended(gi2c->se.dev);
923 pm_runtime_set_autosuspend_delay(gi2c->se.dev, I2C_AUTO_SUSPEND_DELAY);
924 pm_runtime_use_autosuspend(gi2c->se.dev);
925 pm_runtime_enable(gi2c->se.dev);
927 ret = i2c_add_adapter(&gi2c->adap);
930 pm_runtime_disable(gi2c->se.dev);
939 release_gpi_dma(gi2c);
945 struct geni_i2c_dev *gi2c = platform_get_drvdata(pdev);
947 i2c_del_adapter(&gi2c->adap);
948 release_gpi_dma(gi2c);
949 pm_runtime_disable(gi2c->se.dev);
954 struct geni_i2c_dev *gi2c = platform_get_drvdata(pdev);
957 i2c_mark_adapter_suspended(&gi2c->adap);
963 struct geni_i2c_dev *gi2c = dev_get_drvdata(dev);
965 disable_irq(gi2c->irq);
966 ret = geni_se_resources_off(&gi2c->se);
968 enable_irq(gi2c->irq);
972 gi2c->suspended = 1;
975 clk_disable_unprepare(gi2c->core_clk);
977 return geni_icc_disable(&gi2c->se);
983 struct geni_i2c_dev *gi2c = dev_get_drvdata(dev);
985 ret = geni_icc_enable(&gi2c->se);
989 ret = clk_prepare_enable(gi2c->core_clk);
993 ret = geni_se_resources_on(&gi2c->se);
997 enable_irq(gi2c->irq);
998 gi2c->suspended = 0;
1004 struct geni_i2c_dev *gi2c = dev_get_drvdata(dev);
1006 i2c_mark_adapter_suspended(&gi2c->adap);
1008 if (!gi2c->suspended) {
1019 struct geni_i2c_dev *gi2c = dev_get_drvdata(dev);
1021 i2c_mark_adapter_resumed(&gi2c->adap);