Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

irqchip/gic-v3-its: Workaround HiSilicon Hip07 redistributor addressing

The ITSes on the Hip07 (as present in the Huawei D05) are broken when
it comes to addressing the redistributors, and need to be explicitely
told to address the VLPI page instead of the redistributor base address.

So let's add yet another quirk, fixing up the target address
in the command stream.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>

+40 -2
+1
Documentation/arm64/silicon-errata.txt
··· 70 70 | | | | | 71 71 | Hisilicon | Hip0{5,6,7} | #161010101 | HISILICON_ERRATUM_161010101 | 72 72 | Hisilicon | Hip0{6,7} | #161010701 | N/A | 73 + | Hisilicon | Hip07 | #161600802 | HISILICON_ERRATUM_161600802 | 73 74 | | | | | 74 75 | Qualcomm Tech. | Falkor v1 | E1003 | QCOM_FALKOR_ERRATUM_1003 | 75 76 | Qualcomm Tech. | Falkor v1 | E1009 | QCOM_FALKOR_ERRATUM_1009 |
+11
arch/arm64/Kconfig
··· 539 539 540 540 If unsure, say Y. 541 541 542 + 542 543 config SOCIONEXT_SYNQUACER_PREITS 543 544 bool "Socionext Synquacer: Workaround for GICv3 pre-ITS" 544 545 default y 545 546 help 546 547 Socionext Synquacer SoCs implement a separate h/w block to generate 547 548 MSI doorbell writes with non-zero values for the device ID. 549 + 550 + If unsure, say Y. 551 + 552 + config HISILICON_ERRATUM_161600802 553 + bool "Hip07 161600802: Erroneous redistributor VLPI base" 554 + default y 555 + help 556 + The HiSilicon Hip07 SoC usees the wrong redistributor base 557 + when issued ITS commands such as VMOVP and VMAPP, and requires 558 + a 128kB offset to be applied to the target address in this commands. 548 559 549 560 If unsure, say Y. 550 561 endmenu
+28 -2
drivers/irqchip/irq-gic-v3-its.c
··· 109 109 unsigned int msi_domain_flags; 110 110 u32 pre_its_base; /* for Socionext Synquacer */ 111 111 bool is_v4; 112 + int vlpi_redist_offset; 112 113 }; 113 114 114 115 #define ITS_ITT_ALIGN SZ_256 ··· 559 558 struct its_cmd_desc *desc) 560 559 { 561 560 unsigned long vpt_addr; 561 + u64 target; 562 562 563 563 vpt_addr = virt_to_phys(page_address(desc->its_vmapp_cmd.vpe->vpt_page)); 564 + target = desc->its_vmapp_cmd.col->target_address + its->vlpi_redist_offset; 564 565 565 566 its_encode_cmd(cmd, GITS_CMD_VMAPP); 566 567 its_encode_vpeid(cmd, desc->its_vmapp_cmd.vpe->vpe_id); 567 568 its_encode_valid(cmd, desc->its_vmapp_cmd.valid); 568 - its_encode_target(cmd, desc->its_vmapp_cmd.col->target_address); 569 + its_encode_target(cmd, target); 569 570 its_encode_vpt_addr(cmd, vpt_addr); 570 571 its_encode_vpt_size(cmd, LPI_NRBITS - 1); 571 572 ··· 626 623 struct its_cmd_block *cmd, 627 624 struct its_cmd_desc *desc) 628 625 { 626 + u64 target; 627 + 628 + target = desc->its_vmovp_cmd.col->target_address + its->vlpi_redist_offset; 629 629 its_encode_cmd(cmd, GITS_CMD_VMOVP); 630 630 its_encode_seq_num(cmd, desc->its_vmovp_cmd.seq_num); 631 631 its_encode_its_list(cmd, desc->its_vmovp_cmd.its_list); 632 632 its_encode_vpeid(cmd, desc->its_vmovp_cmd.vpe->vpe_id); 633 - its_encode_target(cmd, desc->its_vmovp_cmd.col->target_address); 633 + its_encode_target(cmd, target); 634 634 635 635 its_fixup_cmd(cmd); 636 636 ··· 2840 2834 return false; 2841 2835 } 2842 2836 2837 + static bool __maybe_unused its_enable_quirk_hip07_161600802(void *data) 2838 + { 2839 + struct its_node *its = data; 2840 + 2841 + /* 2842 + * Hip07 insists on using the wrong address for the VLPI 2843 + * page. Trick it into doing the right thing... 2844 + */ 2845 + its->vlpi_redist_offset = SZ_128K; 2846 + return true; 2847 + } 2848 + 2843 2849 static const struct gic_quirk its_quirks[] = { 2844 2850 #ifdef CONFIG_CAVIUM_ERRATUM_22375 2845 2851 { ··· 2888 2870 .iidr = 0x0001143b, 2889 2871 .mask = 0xffffffff, 2890 2872 .init = its_enable_quirk_socionext_synquacer, 2873 + }, 2874 + #endif 2875 + #ifdef CONFIG_HISILICON_ERRATUM_161600802 2876 + { 2877 + .desc = "ITS: Hip07 erratum 161600802", 2878 + .iidr = 0x00000004, 2879 + .mask = 0xffffffff, 2880 + .init = its_enable_quirk_hip07_161600802, 2891 2881 }, 2892 2882 #endif 2893 2883 {