[PATCH 1/7] irqchip/gic-v3: Add a DMA Non-Coherent flag

Lucas Tanure lucas.tanure at collabora.com
Tue Mar 14 06:25:28 PDT 2023


On 10-03-2023 12:04, Robin Murphy wrote:
> On 2023-03-10 11:41, Peter Geis wrote:
>> On Fri, Mar 10, 2023 at 3:05 AM Lucas Tanure 
>> <lucas.tanure at collabora.com> wrote:
>>>
>>> The GIC600 integration in RK356x, used in rk3588, doesn't support
>>> any of the shareability or cacheability attributes, and requires
>>> both values to be set to 0b00 for all the ITS and Redistributor
>>> tables.
>>>
>>> This is loosely based on prior work from XiaoDong Huang and
>>> Peter Geis fixing this issue specifically for Rockchip 356x.
>>
>> Good Morning,
>>
>> Since the gic is using dma, would it be reasonable to have all memory
>> allocations be requested with the GFP_DMA flag? Otherwise this doesn't
>> fully solve the problem for rk356x, where only the lower 4GB range is
>> DMA capable, but this tends to get allocated in the upper 4GB on 8GB
>> boards.
> 
> Not really, because there's no fixed definition of what GFP_DMA actually 
> means, and it may mean nothing (same for GFP_DMA32, which may or may not 
> be meaningful depending on kernel config and platform topology). Drivers 
> should really use the DMA API allocation functions if they care about 
> what they get, which comes back round to the notion from years ago of 
> converting the ITS driver to a regular platform driver, so it can 
> benefit from regular DT concepts like "dma-ranges" automatically.
> 
> Thanks,
> Robin.
> 
I am looking how to do that conversion to platform driver.
But about the communication between irq-gic-v3-its and irq-gic-v3.
Should irq-gic-v3-its be a MFD child of irq-gic-v3?
Or use the component bind/unbind framework?

>>
>> Very Respectfully,
>> Peter Geis
>>
>>>
>>> Suggested-by: Robin Murphy <robin.murphy at arm.com>
>>> Signed-off-by: Lucas Tanure <lucas.tanure at collabora.com>
>>> ---
>>>   drivers/irqchip/irq-gic-v3-its.c | 22 ++++++++++++++++++++++
>>>   1 file changed, 22 insertions(+)
>>>
>>> diff --git a/drivers/irqchip/irq-gic-v3-its.c 
>>> b/drivers/irqchip/irq-gic-v3-its.c
>>> index 973ede0197e3..1c334dfeb647 100644
>>> --- a/drivers/irqchip/irq-gic-v3-its.c
>>> +++ b/drivers/irqchip/irq-gic-v3-its.c
>>> @@ -42,6 +42,7 @@
>>>   #define ITS_FLAGS_CMDQ_NEEDS_FLUSHING          (1ULL << 0)
>>>   #define ITS_FLAGS_WORKAROUND_CAVIUM_22375      (1ULL << 1)
>>>   #define ITS_FLAGS_WORKAROUND_CAVIUM_23144      (1ULL << 2)
>>> +#define ITS_FLAGS_DMA_NON_COHERENT             (1ULL << 3)
>>>
>>>   #define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING    (1 << 0)
>>>   #define RDIST_FLAGS_RD_TABLES_PREALLOCATED     (1 << 1)
>>> @@ -2359,6 +2360,13 @@ static int its_setup_baser(struct its_node 
>>> *its, struct its_baser *baser,
>>>          its_write_baser(its, baser, val);
>>>          tmp = baser->val;
>>>
>>> +       if (its->flags & ITS_FLAGS_DMA_NON_COHERENT) {
>>> +               if (tmp & GITS_BASER_SHAREABILITY_MASK)
>>> +                       tmp &= ~GITS_BASER_SHAREABILITY_MASK;
>>> +               else
>>> +                       gic_flush_dcache_to_poc(base, 
>>> PAGE_ORDER_TO_SIZE(order));
>>> +       }
>>> +
>>>          if ((val ^ tmp) & GITS_BASER_SHAREABILITY_MASK) {
>>>                  /*
>>>                   * Shareability didn't stick. Just use
>>> @@ -3055,6 +3063,7 @@ static u64 its_clear_vpend_valid(void __iomem 
>>> *vlpi_base, u64 clr, u64 set)
>>>
>>>   static void its_cpu_init_lpis(void)
>>>   {
>>> +       struct its_node *its = list_first_entry(&its_nodes, struct 
>>> its_node, entry);
>>>          void __iomem *rbase = gic_data_rdist_rd_base();
>>>          struct page *pend_page;
>>>          phys_addr_t paddr;
>>> @@ -3096,6 +3105,9 @@ static void its_cpu_init_lpis(void)
>>>          gicr_write_propbaser(val, rbase + GICR_PROPBASER);
>>>          tmp = gicr_read_propbaser(rbase + GICR_PROPBASER);
>>>
>>> +       if (its->flags & ITS_FLAGS_DMA_NON_COHERENT)
>>> +               tmp &= ~GICR_PROPBASER_SHAREABILITY_MASK;
>>> +
>>>          if ((tmp ^ val) & GICR_PROPBASER_SHAREABILITY_MASK) {
>>>                  if (!(tmp & GICR_PROPBASER_SHAREABILITY_MASK)) {
>>>                          /*
>>> @@ -3120,6 +3132,9 @@ static void its_cpu_init_lpis(void)
>>>          gicr_write_pendbaser(val, rbase + GICR_PENDBASER);
>>>          tmp = gicr_read_pendbaser(rbase + GICR_PENDBASER);
>>>
>>> +       if (its->flags & ITS_FLAGS_DMA_NON_COHERENT)
>>> +               tmp &= ~GICR_PENDBASER_SHAREABILITY_MASK;
>>> +
>>>          if (!(tmp & GICR_PENDBASER_SHAREABILITY_MASK)) {
>>>                  /*
>>>                   * The HW reports non-shareable, we must remove the
>>> @@ -5005,6 +5020,7 @@ static int __init 
>>> its_compute_its_list_map(struct resource *res,
>>>   static int __init its_probe_one(struct resource *res,
>>>                                  struct fwnode_handle *handle, int 
>>> numa_node)
>>>   {
>>> +       struct device_node *np = to_of_node(handle);
>>>          struct its_node *its;
>>>          void __iomem *its_base;
>>>          u64 baser, tmp, typer;
>>> @@ -5076,6 +5092,9 @@ static int __init its_probe_one(struct resource 
>>> *res,
>>>          its->get_msi_base = its_irq_get_msi_base;
>>>          its->msi_domain_flags = IRQ_DOMAIN_FLAG_MSI_REMAP;
>>>
>>> +       if (np && !of_dma_is_coherent(np))
>>> +               its->flags |= ITS_FLAGS_DMA_NON_COHERENT;
>>> +
>>>          its_enable_quirks(its);
>>>
>>>          err = its_alloc_tables(its);
>>> @@ -5095,6 +5114,9 @@ static int __init its_probe_one(struct resource 
>>> *res,
>>>          gits_write_cbaser(baser, its->base + GITS_CBASER);
>>>          tmp = gits_read_cbaser(its->base + GITS_CBASER);
>>>
>>> +       if (its->flags & ITS_FLAGS_DMA_NON_COHERENT)
>>> +               tmp &= ~GITS_CBASER_SHAREABILITY_MASK;
>>> +
>>>          if ((tmp ^ baser) & GITS_CBASER_SHAREABILITY_MASK) {
>>>                  if (!(tmp & GITS_CBASER_SHAREABILITY_MASK)) {
>>>                          /*
>>> -- 
>>> 2.39.2
>>>




More information about the Linux-rockchip mailing list