Lines Matching +full:sdm845 +full:- +full:cci

1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
3 // Copyright (c) 2017-2022 Linaro Limited.
98 u16 tsu_sto; /* set-up time for STOP condition */
99 u16 tsu_sta; /* set-up time for a repeated START condition */
108 struct cci;
116 struct cci *cci; member
127 struct cci { struct
139 struct cci *cci = dev; in cci_isr() argument
143 val = readl(cci->base + CCI_IRQ_STATUS_0); in cci_isr()
144 writel(val, cci->base + CCI_IRQ_CLEAR_0); in cci_isr()
145 writel(0x1, cci->base + CCI_IRQ_GLOBAL_CLEAR_CMD); in cci_isr()
148 complete(&cci->master[0].irq_complete); in cci_isr()
149 if (cci->master[1].master) in cci_isr()
150 complete(&cci->master[1].irq_complete); in cci_isr()
157 cci->master[0].status = 0; in cci_isr()
158 complete(&cci->master[0].irq_complete); in cci_isr()
165 cci->master[1].status = 0; in cci_isr()
166 complete(&cci->master[1].irq_complete); in cci_isr()
181 writel(reset, cci->base + CCI_RESET_CMD); in cci_isr()
186 cci->master[0].status = -ENXIO; in cci_isr()
188 cci->master[0].status = -EIO; in cci_isr()
190 writel(CCI_HALT_REQ_I2C_M0_Q0Q1, cci->base + CCI_HALT_REQ); in cci_isr()
197 cci->master[1].status = -ENXIO; in cci_isr()
199 cci->master[1].status = -EIO; in cci_isr()
201 writel(CCI_HALT_REQ_I2C_M1_Q0Q1, cci->base + CCI_HALT_REQ); in cci_isr()
208 static int cci_halt(struct cci *cci, u8 master_num) in cci_halt() argument
213 if (master_num >= cci->data->num_masters) { in cci_halt()
214 dev_err(cci->dev, "Unsupported master idx (%u)\n", master_num); in cci_halt()
215 return -EINVAL; in cci_halt()
219 master = &cci->master[master_num]; in cci_halt()
221 reinit_completion(&master->irq_complete); in cci_halt()
222 writel(val, cci->base + CCI_HALT_REQ); in cci_halt()
224 if (!wait_for_completion_timeout(&master->irq_complete, CCI_TIMEOUT)) { in cci_halt()
225 dev_err(cci->dev, "CCI halt timeout\n"); in cci_halt()
226 return -ETIMEDOUT; in cci_halt()
232 static int cci_reset(struct cci *cci) in cci_reset() argument
238 reinit_completion(&cci->master[0].irq_complete); in cci_reset()
239 writel(CCI_RESET_CMD_MASK, cci->base + CCI_RESET_CMD); in cci_reset()
241 if (!wait_for_completion_timeout(&cci->master[0].irq_complete, in cci_reset()
243 dev_err(cci->dev, "CCI reset timeout\n"); in cci_reset()
244 return -ETIMEDOUT; in cci_reset()
250 static int cci_init(struct cci *cci) in cci_init() argument
265 writel(val, cci->base + CCI_IRQ_MASK_0); in cci_init()
267 for (i = 0; i < cci->data->num_masters; i++) { in cci_init()
268 int mode = cci->master[i].mode; in cci_init()
271 if (!cci->master[i].cci) in cci_init()
274 hw = &cci->data->params[mode]; in cci_init()
276 val = hw->thigh << 16 | hw->tlow; in cci_init()
277 writel(val, cci->base + CCI_I2C_Mm_SCL_CTL(i)); in cci_init()
279 val = hw->tsu_sto << 16 | hw->tsu_sta; in cci_init()
280 writel(val, cci->base + CCI_I2C_Mm_SDA_CTL_0(i)); in cci_init()
282 val = hw->thd_dat << 16 | hw->thd_sta; in cci_init()
283 writel(val, cci->base + CCI_I2C_Mm_SDA_CTL_1(i)); in cci_init()
285 val = hw->tbuf; in cci_init()
286 writel(val, cci->base + CCI_I2C_Mm_SDA_CTL_2(i)); in cci_init()
288 val = hw->scl_stretch_en << 8 | hw->trdhld << 4 | hw->tsp; in cci_init()
289 writel(val, cci->base + CCI_I2C_Mm_MISC_CTL(i)); in cci_init()
295 static int cci_run_queue(struct cci *cci, u8 master, u8 queue) in cci_run_queue() argument
299 val = readl(cci->base + CCI_I2C_Mm_Qn_CUR_WORD_CNT(master, queue)); in cci_run_queue()
300 writel(val, cci->base + CCI_I2C_Mm_Qn_EXEC_WORD_CNT(master, queue)); in cci_run_queue()
302 reinit_completion(&cci->master[master].irq_complete); in cci_run_queue()
304 writel(val, cci->base + CCI_QUEUE_START); in cci_run_queue()
306 if (!wait_for_completion_timeout(&cci->master[master].irq_complete, in cci_run_queue()
308 dev_err(cci->dev, "master %d queue %d timeout\n", in cci_run_queue()
310 cci_reset(cci); in cci_run_queue()
311 cci_init(cci); in cci_run_queue()
312 return -ETIMEDOUT; in cci_run_queue()
315 return cci->master[master].status; in cci_run_queue()
318 static int cci_validate_queue(struct cci *cci, u8 master, u8 queue) in cci_validate_queue() argument
322 val = readl(cci->base + CCI_I2C_Mm_Qn_CUR_WORD_CNT(master, queue)); in cci_validate_queue()
323 if (val == cci->data->queue_size[queue]) in cci_validate_queue()
324 return -EINVAL; in cci_validate_queue()
330 writel(val, cci->base + CCI_I2C_Mm_Qn_LOAD_DATA(master, queue)); in cci_validate_queue()
332 return cci_run_queue(cci, master, queue); in cci_validate_queue()
335 static int cci_i2c_read(struct cci *cci, u16 master, in cci_i2c_read() argument
347 ret = cci_validate_queue(cci, master, queue); in cci_i2c_read()
352 writel(val, cci->base + CCI_I2C_Mm_Qn_LOAD_DATA(master, queue)); in cci_i2c_read()
355 writel(val, cci->base + CCI_I2C_Mm_Qn_LOAD_DATA(master, queue)); in cci_i2c_read()
357 ret = cci_run_queue(cci, master, queue); in cci_i2c_read()
361 words_read = readl(cci->base + CCI_I2C_Mm_READ_BUF_LEVEL(master)); in cci_i2c_read()
364 dev_err(cci->dev, "words read = %d, words expected = %d\n", in cci_i2c_read()
366 return -EIO; in cci_i2c_read()
370 val = readl(cci->base + CCI_I2C_Mm_READ_DATA(master)); in cci_i2c_read()
383 } while (--words_read); in cci_i2c_read()
388 static int cci_i2c_write(struct cci *cci, u16 master, in cci_i2c_write() argument
400 ret = cci_validate_queue(cci, master, queue); in cci_i2c_write()
405 writel(val, cci->base + CCI_I2C_Mm_Qn_LOAD_DATA(master, queue)); in cci_i2c_write()
417 writel(val, cci->base + CCI_I2C_Mm_Qn_LOAD_DATA(master, queue)); in cci_i2c_write()
421 writel(val, cci->base + CCI_I2C_Mm_Qn_LOAD_DATA(master, queue)); in cci_i2c_write()
423 return cci_run_queue(cci, master, queue); in cci_i2c_write()
429 struct cci *cci = cci_master->cci; in cci_xfer() local
432 ret = pm_runtime_get_sync(cci->dev); in cci_xfer()
438 ret = cci_i2c_read(cci, cci_master->master, in cci_xfer()
442 ret = cci_i2c_write(cci, cci_master->master, in cci_xfer()
454 pm_runtime_mark_last_busy(cci->dev); in cci_xfer()
455 pm_runtime_put_autosuspend(cci->dev); in cci_xfer()
470 static int cci_enable_clocks(struct cci *cci) in cci_enable_clocks() argument
472 return clk_bulk_prepare_enable(cci->nclocks, cci->clocks); in cci_enable_clocks()
475 static void cci_disable_clocks(struct cci *cci) in cci_disable_clocks() argument
477 clk_bulk_disable_unprepare(cci->nclocks, cci->clocks); in cci_disable_clocks()
482 struct cci *cci = dev_get_drvdata(dev); in cci_suspend_runtime() local
484 cci_disable_clocks(cci); in cci_suspend_runtime()
490 struct cci *cci = dev_get_drvdata(dev); in cci_resume_runtime() local
493 ret = cci_enable_clocks(cci); in cci_resume_runtime()
497 cci_init(cci); in cci_resume_runtime()
525 struct device *dev = &pdev->dev; in cci_probe()
529 struct cci *cci; in cci_probe() local
533 cci = devm_kzalloc(dev, sizeof(*cci), GFP_KERNEL); in cci_probe()
534 if (!cci) in cci_probe()
535 return -ENOMEM; in cci_probe()
537 cci->dev = dev; in cci_probe()
538 platform_set_drvdata(pdev, cci); in cci_probe()
539 cci->data = device_get_match_data(dev); in cci_probe()
540 if (!cci->data) in cci_probe()
541 return -ENOENT; in cci_probe()
543 for_each_available_child_of_node(dev->of_node, child) { in cci_probe()
553 if (idx >= cci->data->num_masters) { in cci_probe()
555 child, idx, cci->data->num_masters - 1); in cci_probe()
559 master = &cci->master[idx]; in cci_probe()
560 master->adap.quirks = &cci->data->quirks; in cci_probe()
561 master->adap.algo = &cci_algo; in cci_probe()
562 master->adap.dev.parent = dev; in cci_probe()
563 master->adap.dev.of_node = of_node_get(child); in cci_probe()
564 master->master = idx; in cci_probe()
565 master->cci = cci; in cci_probe()
567 i2c_set_adapdata(&master->adap, master); in cci_probe()
568 snprintf(master->adap.name, sizeof(master->adap.name), "Qualcomm-CCI"); in cci_probe()
570 master->mode = I2C_MODE_STANDARD; in cci_probe()
571 ret = of_property_read_u32(child, "clock-frequency", &val); in cci_probe()
574 master->mode = I2C_MODE_FAST; in cci_probe()
576 master->mode = I2C_MODE_FAST_PLUS; in cci_probe()
579 init_completion(&master->irq_complete); in cci_probe()
584 cci->base = devm_platform_get_and_ioremap_resource(pdev, 0, &r); in cci_probe()
585 if (IS_ERR(cci->base)) in cci_probe()
586 return PTR_ERR(cci->base); in cci_probe()
590 ret = devm_clk_bulk_get_all(dev, &cci->clocks); in cci_probe()
594 return dev_err_probe(dev, -EINVAL, "not enough clocks in DT\n"); in cci_probe()
595 cci->nclocks = ret; in cci_probe()
597 /* Retrieve CCI clock rate */ in cci_probe()
598 for (i = 0; i < cci->nclocks; i++) { in cci_probe()
599 if (!strcmp(cci->clocks[i].id, "cci")) { in cci_probe()
600 cci_clk_rate = clk_get_rate(cci->clocks[i].clk); in cci_probe()
605 if (cci_clk_rate != cci->data->cci_clk_rate) { in cci_probe()
606 /* cci clock set by the bootloader or via assigned clock rate in cci_probe()
609 dev_warn(dev, "Found %lu cci clk rate while %lu was expected\n", in cci_probe()
610 cci_clk_rate, cci->data->cci_clk_rate); in cci_probe()
613 ret = cci_enable_clocks(cci); in cci_probe()
622 cci->irq = ret; in cci_probe()
624 ret = devm_request_irq(dev, cci->irq, cci_isr, 0, dev_name(dev), cci); in cci_probe()
630 val = readl(cci->base + CCI_HW_VERSION); in cci_probe()
631 dev_dbg(dev, "CCI HW version = 0x%08x", val); in cci_probe()
633 ret = cci_reset(cci); in cci_probe()
637 ret = cci_init(cci); in cci_probe()
646 for (i = 0; i < cci->data->num_masters; i++) { in cci_probe()
647 if (!cci->master[i].cci) in cci_probe()
650 ret = i2c_add_adapter(&cci->master[i].adap); in cci_probe()
652 of_node_put(cci->master[i].adap.dev.of_node); in cci_probe()
663 for (--i ; i >= 0; i--) { in cci_probe()
664 if (cci->master[i].cci) { in cci_probe()
665 i2c_del_adapter(&cci->master[i].adap); in cci_probe()
666 of_node_put(cci->master[i].adap.dev.of_node); in cci_probe()
670 disable_irq(cci->irq); in cci_probe()
672 cci_disable_clocks(cci); in cci_probe()
679 struct cci *cci = platform_get_drvdata(pdev); in cci_remove() local
682 for (i = 0; i < cci->data->num_masters; i++) { in cci_remove()
683 if (cci->master[i].cci) { in cci_remove()
684 i2c_del_adapter(&cci->master[i].adap); in cci_remove()
685 of_node_put(cci->master[i].adap.dev.of_node); in cci_remove()
687 cci_halt(cci, i); in cci_remove()
690 disable_irq(cci->irq); in cci_remove()
691 pm_runtime_disable(&pdev->dev); in cci_remove()
692 pm_runtime_set_suspended(&pdev->dev); in cci_remove()
810 { .compatible = "qcom,msm8226-cci", .data = &cci_v1_data},
811 { .compatible = "qcom,msm8974-cci", .data = &cci_v1_5_data},
812 { .compatible = "qcom,msm8996-cci", .data = &cci_v2_data},
819 { .compatible = "qcom,msm8916-cci", .data = &cci_v1_data},
820 { .compatible = "qcom,sdm845-cci", .data = &cci_v2_data},
821 { .compatible = "qcom,sm8250-cci", .data = &cci_v2_data},
822 { .compatible = "qcom,sm8450-cci", .data = &cci_v2_data},
831 .name = "i2c-qcom-cci",