i3c: mipi-i3c-hci: Switch to lower_32_bits()/upper_32_bits() helpers
PATCH 1/4 i3c: mipi-i3c-hci: Switch to lower_32_bits()/upper_32_bits() helpers
Rather than having own lo32()/hi32() helpers for dealing with 32-bit and 64-bit build targets switch to generic lower_32_bits()/upper_32_bits() helpers.
--- drivers/i3c/master/mipi-i3c-hci/dma.c | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-)
drivers/i3c/master/mipi-i3c-hci/dma.c +6 -21
@@ -147,21 +147,6 @@ struct hci_dma_dev_ibi_data {unsigned int max_len; }; -static inline u32 lo32 (dma_addr_t physaddr) -{ -return physaddr; -} - -static inline u32 hi32 (dma_addr_t physaddr) -{ -/* trickery to avoid compiler warnings on 32-bit build targets */ -if (sizeof (dma_addr_t) >4 ) { -u64 hi = physaddr; -return hi >>32 ; - } -return 0 ; -} -static void hci_dma_cleanup (struct i3c_hci *hci) {struct hci_rings_data *rings = hci->io_data;
@@ -265,10 +250,10 @@ static int hci_dma_init(struct i3c_hci *hci)if (!rh->xfer || !rh->resp || !rh->src_xfers) goto err_out; -rh_reg_write (CMD_RING_BASE_LO ,lo32 (rh->xfer_dma)); -rh_reg_write (CMD_RING_BASE_HI ,hi32 (rh->xfer_dma)); -rh_reg_write (RESP_RING_BASE_LO ,lo32 (rh->resp_dma)); -rh_reg_write (RESP_RING_BASE_HI ,hi32 (rh->resp_dma)); +rh_reg_write (CMD_RING_BASE_LO ,lower_32_bits (rh->xfer_dma)); +rh_reg_write (CMD_RING_BASE_HI ,upper_32_bits (rh->xfer_dma)); +rh_reg_write (RESP_RING_BASE_LO ,lower_32_bits (rh->resp_dma)); +rh_reg_write (RESP_RING_BASE_HI ,upper_32_bits (rh->resp_dma)); regval =FIELD_PREP (CR_RING_SIZE , rh->xfer_entries);rh_reg_write (CR_SETUP , regval);
@@ -404,8 +389,8 @@ static int hci_dma_queue_xfer(struct i3c_hci *hci,hci_dma_unmap_xfer (hci, xfer_list, i);return -ENOMEM ; } - *ring_data++ =lo32 (xfer->data_dma); - *ring_data++ =hi32 (xfer->data_dma); + *ring_data++ =lower_32_bits (xfer->data_dma); + *ring_data++ =upper_32_bits (xfer->data_dma); }else { *ring_data++ =0 ; *ring_data++ =0 ;
Signature · 7 lines
2.43.0 -- linux-i3c mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-i3c
PATCH 2/4 i3c: mipi-i3c-hci: Set IBI Status and Data Ring base addresses
IBI Status and Data Ring base address registers are not set so HW obviously cannot update those rings after In-Band Interrupt.
Set them to already allocated and mapped ring addresses.
--- drivers/i3c/master/mipi-i3c-hci/dma.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/i3c/master/mipi-i3c-hci/dma.c +5 -0
@@ -300,6 +300,11 @@ static int hci_dma_init(struct i3c_hci *hci) goto err_out; } +rh_reg_write (IBI_STATUS_RING_BASE_LO ,lower_32_bits (rh->ibi_status_dma)); +rh_reg_write (IBI_STATUS_RING_BASE_HI ,upper_32_bits (rh->ibi_status_dma)); +rh_reg_write (IBI_DATA_RING_BASE_LO ,lower_32_bits (rh->ibi_data_dma)); +rh_reg_write (IBI_DATA_RING_BASE_HI ,upper_32_bits (rh->ibi_data_dma)); + regval =FIELD_PREP (IBI_STATUS_RING_SIZE , rh->ibi_status_entries) | FIELD_PREP(IBI_DATA_CHUNK_SIZE,
Signature · 7 lines
2.43.0 -- linux-i3c mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-i3c
PATCH 3/4 i3c: mipi-i3c-hci: Error out instead on BUG_ON() in IBI DMA setup
In reply to Jarkko NikulaDefinitely condition dma_get_cache_alignment * defined value > 256 during driver initialization is not reason to BUG_ON(). Turn that to graceful error out with -EINVAL.
--- drivers/i3c/master/mipi-i3c-hci/dma.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/i3c/master/mipi-i3c-hci/dma.c +4 -1
@@ -279,7 +279,10 @@ static int hci_dma_init(struct i3c_hci *hci) rh->ibi_chunk_sz =dma_get_cache_alignment (); rh->ibi_chunk_sz *=IBI_CHUNK_CACHELINES ; -BUG_ON (rh->ibi_chunk_sz >256 ); +if (rh->ibi_chunk_sz >256 ) { + ret = -EINVAL ; + goto err_out; + } ibi_status_ring_sz = rh->ibi_status_sz * rh->ibi_status_entries; ibi_data_ring_sz = rh->ibi_chunk_sz * rh->ibi_chunks_total;
Signature · 7 lines
2.43.0 -- linux-i3c mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-i3c
PATCH 4/4 i3c: mipi-i3c-hci: Round IBI data chunk size to HW supported value
In reply to Jarkko NikulaThe dma.c: hci_dma_init() sets the CHUNK_SIZE field in the IBI_SETUP register incorrectly if the calculated ibi_chunk_sz is not exactly 2^(n+2) bytes, where n is 0..6.
Fix this by rounding the chunk size up to nearest 2^(n+2) bytes.
--- drivers/i3c/master/mipi-i3c-hci/dma.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/i3c/master/mipi-i3c-hci/dma.c +7 -0
@@ -279,6 +279,13 @@ static int hci_dma_init(struct i3c_hci *hci) rh->ibi_chunk_sz =dma_get_cache_alignment (); rh->ibi_chunk_sz *=IBI_CHUNK_CACHELINES ; +/* +* Round IBI data chunk size to number of bytes supported by +* the HW. Chunk size can be 2^n number of DWORDs which is the +* same as 2^(n+2) bytes, where n is 0..6. +*/ + rh->ibi_chunk_sz =umax (4 , rh->ibi_chunk_sz); + rh->ibi_chunk_sz =roundup_pow_of_two (rh->ibi_chunk_sz);if (rh->ibi_chunk_sz >256 ) { ret = -EINVAL ; goto err_out;
Signature · 7 lines
2.43.0 -- linux-i3c mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-i3c
Quoted 5 lines · Jarkko Nikula
Rather than having own lo32()/hi32() helpers for dealing with 32-bit and 64-bit build targets switch to generic lower_32_bits()/upper_32_bits() helpers.
Applied, thanks!
[1/4] i3c: mipi-i3c-hci: Switch to lower_32_bits()/upper_32_bits() helpers
https://git.kernel.org/abelloni/c/8b4813a33a4b [2/4] i3c: mipi-i3c-hci: Set IBI Status and Data Ring base addresses https://git.kernel.org/abelloni/c/a95d8fa46962 [3/4] i3c: mipi-i3c-hci: Error out instead on BUG_ON() in IBI DMA setup https://git.kernel.org/abelloni/c/3b85c83cce0b [4/4] i3c: mipi-i3c-hci: Round IBI data chunk size to HW supported value https://git.kernel.org/abelloni/c/67678602c4fc
Best regards,
Signature · 8 lines
Alexandre Belloni, co-owner and COO, Bootlin Embedded Linux and Kernel engineering https://bootlin.com -- linux-i3c mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-i3c