Skip to content

Commit be90ae1

Browse files
jhnikulaalexandrebelloni
authored andcommitted
i3c: mipi-i3c-hci: Fix number of DAT/DCT entries for HCI versions < 1.1
I was wrong about the TABLE_SIZE field description in the commit 0676bfe ("i3c: mipi-i3c-hci: Fix DAT/DCT entry sizes"). For the MIPI I3C HCI versions 1.0 and earlier the TABLE_SIZE field in the registers DAT_SECTION_OFFSET and DCT_SECTION_OFFSET is indeed defined in DWORDs and not number of entries like it is defined in later versions. Where above fix allowed driver initialization to continue the wrongly interpreted TABLE_SIZE field leads variables DAT_entries being twice and DCT_entries four times as big as they really are. That in turn leads clearing the DAT table over the boundary in the dat_v1.c: hci_dat_v1_init(). So interprete the TABLE_SIZE field in DWORDs for HCI versions < 1.1 and fix number of DAT/DCT entries accordingly. Fixes: 0676bfe ("i3c: mipi-i3c-hci: Fix DAT/DCT entry sizes") Signed-off-by: Jarkko Nikula <[email protected]> Signed-off-by: Alexandre Belloni <[email protected]>
1 parent 9bc7501 commit be90ae1

File tree

1 file changed

+8
-0
lines changed
  • drivers/i3c/master/mipi-i3c-hci

1 file changed

+8
-0
lines changed

drivers/i3c/master/mipi-i3c-hci/core.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -631,6 +631,7 @@ static irqreturn_t i3c_hci_irq_handler(int irq, void *dev_id)
631631
static int i3c_hci_init(struct i3c_hci *hci)
632632
{
633633
u32 regval, offset;
634+
bool size_in_dwords;
634635
int ret;
635636

636637
/* Validate HCI hardware version */
@@ -654,11 +655,16 @@ static int i3c_hci_init(struct i3c_hci *hci)
654655
hci->caps = reg_read(HC_CAPABILITIES);
655656
DBG("caps = %#x", hci->caps);
656657

658+
size_in_dwords = hci->version_major < 1 ||
659+
(hci->version_major == 1 && hci->version_minor < 1);
660+
657661
regval = reg_read(DAT_SECTION);
658662
offset = FIELD_GET(DAT_TABLE_OFFSET, regval);
659663
hci->DAT_regs = offset ? hci->base_regs + offset : NULL;
660664
hci->DAT_entries = FIELD_GET(DAT_TABLE_SIZE, regval);
661665
hci->DAT_entry_size = FIELD_GET(DAT_ENTRY_SIZE, regval) ? 0 : 8;
666+
if (size_in_dwords)
667+
hci->DAT_entries = 4 * hci->DAT_entries / hci->DAT_entry_size;
662668
dev_info(&hci->master.dev, "DAT: %u %u-bytes entries at offset %#x\n",
663669
hci->DAT_entries, hci->DAT_entry_size, offset);
664670

@@ -667,6 +673,8 @@ static int i3c_hci_init(struct i3c_hci *hci)
667673
hci->DCT_regs = offset ? hci->base_regs + offset : NULL;
668674
hci->DCT_entries = FIELD_GET(DCT_TABLE_SIZE, regval);
669675
hci->DCT_entry_size = FIELD_GET(DCT_ENTRY_SIZE, regval) ? 0 : 16;
676+
if (size_in_dwords)
677+
hci->DCT_entries = 4 * hci->DCT_entries / hci->DCT_entry_size;
670678
dev_info(&hci->master.dev, "DCT: %u %u-bytes entries at offset %#x\n",
671679
hci->DCT_entries, hci->DCT_entry_size, offset);
672680

0 commit comments

Comments
 (0)