If unsure, say Y.
 
+
 config SOCIONEXT_SYNQUACER_PREITS
        bool "Socionext Synquacer: Workaround for GICv3 pre-ITS"
        default y
          Socionext Synquacer SoCs implement a separate h/w block to generate
          MSI doorbell writes with non-zero values for the device ID.
 
+         If unsure, say Y.
+
+config HISILICON_ERRATUM_161600802
+       bool "Hip07 161600802: Erroneous redistributor VLPI base"
+       default y
+       help
+         The HiSilicon Hip07 SoC usees the wrong redistributor base
+         when issued ITS commands such as VMOVP and VMAPP, and requires
+         a 128kB offset to be applied to the target address in this commands.
+
          If unsure, say Y.
 endmenu
 
 
        unsigned int            msi_domain_flags;
        u32                     pre_its_base; /* for Socionext Synquacer */
        bool                    is_v4;
+       int                     vlpi_redist_offset;
 };
 
 #define ITS_ITT_ALIGN          SZ_256
                                           struct its_cmd_desc *desc)
 {
        unsigned long vpt_addr;
+       u64 target;
 
        vpt_addr = virt_to_phys(page_address(desc->its_vmapp_cmd.vpe->vpt_page));
+       target = desc->its_vmapp_cmd.col->target_address + its->vlpi_redist_offset;
 
        its_encode_cmd(cmd, GITS_CMD_VMAPP);
        its_encode_vpeid(cmd, desc->its_vmapp_cmd.vpe->vpe_id);
        its_encode_valid(cmd, desc->its_vmapp_cmd.valid);
-       its_encode_target(cmd, desc->its_vmapp_cmd.col->target_address);
+       its_encode_target(cmd, target);
        its_encode_vpt_addr(cmd, vpt_addr);
        its_encode_vpt_size(cmd, LPI_NRBITS - 1);
 
                                           struct its_cmd_block *cmd,
                                           struct its_cmd_desc *desc)
 {
+       u64 target;
+
+       target = desc->its_vmovp_cmd.col->target_address + its->vlpi_redist_offset;
        its_encode_cmd(cmd, GITS_CMD_VMOVP);
        its_encode_seq_num(cmd, desc->its_vmovp_cmd.seq_num);
        its_encode_its_list(cmd, desc->its_vmovp_cmd.its_list);
        its_encode_vpeid(cmd, desc->its_vmovp_cmd.vpe->vpe_id);
-       its_encode_target(cmd, desc->its_vmovp_cmd.col->target_address);
+       its_encode_target(cmd, target);
 
        its_fixup_cmd(cmd);
 
        return false;
 }
 
+static bool __maybe_unused its_enable_quirk_hip07_161600802(void *data)
+{
+       struct its_node *its = data;
+
+       /*
+        * Hip07 insists on using the wrong address for the VLPI
+        * page. Trick it into doing the right thing...
+        */
+       its->vlpi_redist_offset = SZ_128K;
+       return true;
+}
+
 static const struct gic_quirk its_quirks[] = {
 #ifdef CONFIG_CAVIUM_ERRATUM_22375
        {
                .mask   = 0xffffffff,
                .init   = its_enable_quirk_socionext_synquacer,
        },
+#endif
+#ifdef CONFIG_HISILICON_ERRATUM_161600802
+       {
+               .desc   = "ITS: Hip07 erratum 161600802",
+               .iidr   = 0x00000004,
+               .mask   = 0xffffffff,
+               .init   = its_enable_quirk_hip07_161600802,
+       },
 #endif
        {
        }