Lines Matching full:hci
19 #include "hci.h"
29 #define HCI_VERSION 0x00 /* HCI Version (in BCD) */
120 struct i3c_hci *hci = to_i3c_hci(m); in i3c_hci_bus_init() local
126 if (hci->cmd == &mipi_i3c_hci_cmd_v1) { in i3c_hci_bus_init()
127 ret = mipi_i3c_hci_dat_v1.init(hci); in i3c_hci_bus_init()
143 ret = hci->io->init(hci); in i3c_hci_bus_init()
148 if (hci->quirks & HCI_QUIRK_RESP_BUF_THLD) in i3c_hci_bus_init()
149 amd_set_resp_buf_thld(hci); in i3c_hci_bus_init()
159 struct i3c_hci *hci = to_i3c_hci(m); in i3c_hci_bus_cleanup() local
166 hci->io->cleanup(hci); in i3c_hci_bus_cleanup()
167 if (hci->cmd == &mipi_i3c_hci_cmd_v1) in i3c_hci_bus_cleanup()
168 mipi_i3c_hci_dat_v1.cleanup(hci); in i3c_hci_bus_cleanup()
171 void mipi_i3c_hci_resume(struct i3c_hci *hci) in mipi_i3c_hci_resume() argument
177 void mipi_i3c_hci_pio_reset(struct i3c_hci *hci) in mipi_i3c_hci_pio_reset() argument
183 void mipi_i3c_hci_dct_index_reset(struct i3c_hci *hci) in mipi_i3c_hci_dct_index_reset() argument
191 struct i3c_hci *hci = to_i3c_hci(m); in i3c_hci_send_ccc_cmd() local
193 bool raw = !!(hci->quirks & HCI_QUIRK_RAW_CCC); in i3c_hci_send_ccc_cmd()
210 hci->cmd->prep_ccc(hci, xfer, I3C_BROADCAST_ADDR, in i3c_hci_send_ccc_cmd()
219 ret = hci->cmd->prep_ccc(hci, &xfer[i], ccc->dests[i].addr, in i3c_hci_send_ccc_cmd()
232 ret = hci->io->queue_xfer(hci, xfer, nxfers); in i3c_hci_send_ccc_cmd()
236 hci->io->dequeue_xfer(hci, xfer, nxfers)) { in i3c_hci_send_ccc_cmd()
268 struct i3c_hci *hci = to_i3c_hci(m); in i3c_hci_daa() local
272 return hci->cmd->perform_daa(hci); in i3c_hci_daa()
275 static int i3c_hci_alloc_safe_xfer_buf(struct i3c_hci *hci, in i3c_hci_alloc_safe_xfer_buf() argument
278 if (hci->io != &mipi_i3c_hci_dma || in i3c_hci_alloc_safe_xfer_buf()
291 static void i3c_hci_free_safe_xfer_buf(struct i3c_hci *hci, in i3c_hci_free_safe_xfer_buf() argument
294 if (hci->io != &mipi_i3c_hci_dma || xfer->bounce_buf == NULL) in i3c_hci_free_safe_xfer_buf()
308 struct i3c_hci *hci = to_i3c_hci(m); in i3c_hci_priv_xfers() local
320 size_limit = 1U << (16 + FIELD_GET(HC_CAP_MAX_DATA_LENGTH, hci->caps)); in i3c_hci_priv_xfers()
334 hci->cmd->prep_i3c_xfer(hci, dev, &xfer[i]); in i3c_hci_priv_xfers()
336 ret = i3c_hci_alloc_safe_xfer_buf(hci, &xfer[i]); in i3c_hci_priv_xfers()
344 ret = hci->io->queue_xfer(hci, xfer, nxfers); in i3c_hci_priv_xfers()
348 hci->io->dequeue_xfer(hci, xfer, nxfers)) { in i3c_hci_priv_xfers()
363 i3c_hci_free_safe_xfer_buf(hci, &xfer[i]); in i3c_hci_priv_xfers()
373 struct i3c_hci *hci = to_i3c_hci(m); in i3c_hci_i2c_xfers() local
388 hci->cmd->prep_i2c_xfer(hci, dev, &xfer[i]); in i3c_hci_i2c_xfers()
390 ret = i3c_hci_alloc_safe_xfer_buf(hci, &xfer[i]); in i3c_hci_i2c_xfers()
398 ret = hci->io->queue_xfer(hci, xfer, nxfers); in i3c_hci_i2c_xfers()
402 hci->io->dequeue_xfer(hci, xfer, nxfers)) { in i3c_hci_i2c_xfers()
415 i3c_hci_free_safe_xfer_buf(hci, &xfer[i]); in i3c_hci_i2c_xfers()
424 struct i3c_hci *hci = to_i3c_hci(m); in i3c_hci_attach_i3c_dev() local
433 if (hci->cmd == &mipi_i3c_hci_cmd_v1) { in i3c_hci_attach_i3c_dev()
434 ret = mipi_i3c_hci_dat_v1.alloc_entry(hci); in i3c_hci_attach_i3c_dev()
439 mipi_i3c_hci_dat_v1.set_dynamic_addr(hci, ret, in i3c_hci_attach_i3c_dev()
450 struct i3c_hci *hci = to_i3c_hci(m); in i3c_hci_reattach_i3c_dev() local
455 if (hci->cmd == &mipi_i3c_hci_cmd_v1) in i3c_hci_reattach_i3c_dev()
456 mipi_i3c_hci_dat_v1.set_dynamic_addr(hci, dev_data->dat_idx, in i3c_hci_reattach_i3c_dev()
464 struct i3c_hci *hci = to_i3c_hci(m); in i3c_hci_detach_i3c_dev() local
470 if (hci->cmd == &mipi_i3c_hci_cmd_v1) in i3c_hci_detach_i3c_dev()
471 mipi_i3c_hci_dat_v1.free_entry(hci, dev_data->dat_idx); in i3c_hci_detach_i3c_dev()
478 struct i3c_hci *hci = to_i3c_hci(m); in i3c_hci_attach_i2c_dev() local
484 if (hci->cmd != &mipi_i3c_hci_cmd_v1) in i3c_hci_attach_i2c_dev()
489 ret = mipi_i3c_hci_dat_v1.alloc_entry(hci); in i3c_hci_attach_i2c_dev()
494 mipi_i3c_hci_dat_v1.set_static_addr(hci, ret, dev->addr); in i3c_hci_attach_i2c_dev()
495 mipi_i3c_hci_dat_v1.set_flags(hci, ret, DAT_0_I2C_DEVICE, 0); in i3c_hci_attach_i2c_dev()
504 struct i3c_hci *hci = to_i3c_hci(m); in i3c_hci_detach_i2c_dev() local
511 if (hci->cmd == &mipi_i3c_hci_cmd_v1) in i3c_hci_detach_i2c_dev()
512 mipi_i3c_hci_dat_v1.free_entry(hci, dev_data->dat_idx); in i3c_hci_detach_i2c_dev()
521 struct i3c_hci *hci = to_i3c_hci(m); in i3c_hci_request_ibi() local
526 mipi_i3c_hci_dat_v1.set_flags(hci, dat_idx, DAT_0_IBI_PAYLOAD, 0); in i3c_hci_request_ibi()
528 mipi_i3c_hci_dat_v1.clear_flags(hci, dat_idx, DAT_0_IBI_PAYLOAD, 0); in i3c_hci_request_ibi()
529 return hci->io->request_ibi(hci, dev, req); in i3c_hci_request_ibi()
535 struct i3c_hci *hci = to_i3c_hci(m); in i3c_hci_free_ibi() local
537 hci->io->free_ibi(hci, dev); in i3c_hci_free_ibi()
543 struct i3c_hci *hci = to_i3c_hci(m); in i3c_hci_enable_ibi() local
546 mipi_i3c_hci_dat_v1.clear_flags(hci, dev_data->dat_idx, DAT_0_SIR_REJECT, 0); in i3c_hci_enable_ibi()
553 struct i3c_hci *hci = to_i3c_hci(m); in i3c_hci_disable_ibi() local
556 mipi_i3c_hci_dat_v1.set_flags(hci, dev_data->dat_idx, DAT_0_SIR_REJECT, 0); in i3c_hci_disable_ibi()
564 struct i3c_hci *hci = to_i3c_hci(m); in i3c_hci_recycle_ibi_slot() local
566 hci->io->recycle_ibi_slot(hci, dev, slot); in i3c_hci_recycle_ibi_slot()
590 struct i3c_hci *hci = dev_id; in i3c_hci_irq_handler() local
606 dev_err(&hci->master.dev, "Host Controller Internal Error\n"); in i3c_hci_irq_handler()
610 hci->io->irq_handler(hci); in i3c_hci_irq_handler()
613 dev_err(&hci->master.dev, "unexpected INTR_STATUS %#x\n", val); in i3c_hci_irq_handler()
620 static int i3c_hci_init(struct i3c_hci *hci) in i3c_hci_init() argument
626 /* Validate HCI hardware version */ in i3c_hci_init()
628 hci->version_major = (regval >> 8) & 0xf; in i3c_hci_init()
629 hci->version_minor = (regval >> 4) & 0xf; in i3c_hci_init()
630 hci->revision = regval & 0xf; in i3c_hci_init()
631 dev_notice(&hci->master.dev, "MIPI I3C HCI v%u.%u r%02u\n", in i3c_hci_init()
632 hci->version_major, hci->version_minor, hci->revision); in i3c_hci_init()
640 dev_err(&hci->master.dev, "unsupported HCI version\n"); in i3c_hci_init()
644 hci->caps = reg_read(HC_CAPABILITIES); in i3c_hci_init()
645 DBG("caps = %#x", hci->caps); in i3c_hci_init()
647 size_in_dwords = hci->version_major < 1 || in i3c_hci_init()
648 (hci->version_major == 1 && hci->version_minor < 1); in i3c_hci_init()
652 hci->DAT_regs = offset ? hci->base_regs + offset : NULL; in i3c_hci_init()
653 hci->DAT_entries = FIELD_GET(DAT_TABLE_SIZE, regval); in i3c_hci_init()
654 hci->DAT_entry_size = FIELD_GET(DAT_ENTRY_SIZE, regval) ? 0 : 8; in i3c_hci_init()
656 hci->DAT_entries = 4 * hci->DAT_entries / hci->DAT_entry_size; in i3c_hci_init()
657 dev_info(&hci->master.dev, "DAT: %u %u-bytes entries at offset %#x\n", in i3c_hci_init()
658 hci->DAT_entries, hci->DAT_entry_size, offset); in i3c_hci_init()
662 hci->DCT_regs = offset ? hci->base_regs + offset : NULL; in i3c_hci_init()
663 hci->DCT_entries = FIELD_GET(DCT_TABLE_SIZE, regval); in i3c_hci_init()
664 hci->DCT_entry_size = FIELD_GET(DCT_ENTRY_SIZE, regval) ? 0 : 16; in i3c_hci_init()
666 hci->DCT_entries = 4 * hci->DCT_entries / hci->DCT_entry_size; in i3c_hci_init()
667 dev_info(&hci->master.dev, "DCT: %u %u-bytes entries at offset %#x\n", in i3c_hci_init()
668 hci->DCT_entries, hci->DCT_entry_size, offset); in i3c_hci_init()
672 hci->RHS_regs = offset ? hci->base_regs + offset : NULL; in i3c_hci_init()
673 dev_info(&hci->master.dev, "Ring Headers at offset %#x\n", offset); in i3c_hci_init()
677 hci->PIO_regs = offset ? hci->base_regs + offset : NULL; in i3c_hci_init()
678 dev_info(&hci->master.dev, "PIO section at offset %#x\n", offset); in i3c_hci_init()
682 hci->EXTCAPS_regs = offset ? hci->base_regs + offset : NULL; in i3c_hci_init()
683 dev_info(&hci->master.dev, "Extended Caps at offset %#x\n", offset); in i3c_hci_init()
685 ret = i3c_hci_parse_ext_caps(hci); in i3c_hci_init()
716 dev_err(&hci->master.dev, "cannot set BE mode\n"); in i3c_hci_init()
726 dev_err(&hci->master.dev, "cannot clear BE mode\n"); in i3c_hci_init()
733 switch (FIELD_GET(HC_CAP_CMD_SIZE, hci->caps)) { in i3c_hci_init()
735 hci->cmd = &mipi_i3c_hci_cmd_v1; in i3c_hci_init()
738 hci->cmd = &mipi_i3c_hci_cmd_v2; in i3c_hci_init()
741 dev_err(&hci->master.dev, "wrong CMD_SIZE capability value\n"); in i3c_hci_init()
745 mode_selector = hci->version_major > 1 || in i3c_hci_init()
746 (hci->version_major == 1 && hci->version_minor > 0); in i3c_hci_init()
749 if (hci->quirks & HCI_QUIRK_PIO_MODE) in i3c_hci_init()
750 hci->RHS_regs = NULL; in i3c_hci_init()
753 if (hci->RHS_regs) { in i3c_hci_init()
756 dev_err(&hci->master.dev, "PIO mode is stuck\n"); in i3c_hci_init()
759 hci->io = &mipi_i3c_hci_dma; in i3c_hci_init()
760 dev_info(&hci->master.dev, "Using DMA\n"); in i3c_hci_init()
765 if (!hci->io && hci->PIO_regs) { in i3c_hci_init()
768 dev_err(&hci->master.dev, "DMA mode is stuck\n"); in i3c_hci_init()
771 hci->io = &mipi_i3c_hci_pio; in i3c_hci_init()
772 dev_info(&hci->master.dev, "Using PIO\n"); in i3c_hci_init()
776 if (!hci->io) { in i3c_hci_init()
777 dev_err(&hci->master.dev, "neither DMA nor PIO can be used\n"); in i3c_hci_init()
784 if (hci->quirks & HCI_QUIRK_OD_PP_TIMING) in i3c_hci_init()
785 amd_set_od_pp_timing(hci); in i3c_hci_init()
792 struct i3c_hci *hci; in i3c_hci_probe() local
795 hci = devm_kzalloc(&pdev->dev, sizeof(*hci), GFP_KERNEL); in i3c_hci_probe()
796 if (!hci) in i3c_hci_probe()
798 hci->base_regs = devm_platform_ioremap_resource(pdev, 0); in i3c_hci_probe()
799 if (IS_ERR(hci->base_regs)) in i3c_hci_probe()
800 return PTR_ERR(hci->base_regs); in i3c_hci_probe()
802 platform_set_drvdata(pdev, hci); in i3c_hci_probe()
804 hci->master.dev.init_name = dev_name(&pdev->dev); in i3c_hci_probe()
806 hci->quirks = (unsigned long)device_get_match_data(&pdev->dev); in i3c_hci_probe()
808 ret = i3c_hci_init(hci); in i3c_hci_probe()
814 0, NULL, hci); in i3c_hci_probe()
818 ret = i3c_master_register(&hci->master, &pdev->dev, in i3c_hci_probe()
828 struct i3c_hci *hci = platform_get_drvdata(pdev); in i3c_hci_remove() local
830 i3c_master_unregister(&hci->master); in i3c_hci_remove()
834 { .compatible = "mipi-i3c-hci", },
849 .name = "mipi-i3c-hci",
855 MODULE_ALIAS("platform:mipi-i3c-hci");
858 MODULE_DESCRIPTION("MIPI I3C HCI driver");