aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Zyngier <marc.zyngier@arm.com>2017-07-28 16:20:37 -0400
committerMarc Zyngier <marc.zyngier@arm.com>2017-10-19 06:22:40 -0400
commit5c9a882e940dde2f3e80eb3c7635a3307be511b6 (patch)
treedef7f8046f327efd4147035bf34059543d6698ab
parent67047f90d7dd886d3f505185a6d75517bdbd907c (diff)
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>
-rw-r--r--Documentation/arm64/silicon-errata.txt1
-rw-r--r--arch/arm64/Kconfig11
-rw-r--r--drivers/irqchip/irq-gic-v3-its.c30
3 files changed, 40 insertions, 2 deletions
diff --git a/Documentation/arm64/silicon-errata.txt b/Documentation/arm64/silicon-errata.txt
index 66e8ce14d23d..304bf22bb83c 100644
--- a/Documentation/arm64/silicon-errata.txt
+++ b/Documentation/arm64/silicon-errata.txt
@@ -70,6 +70,7 @@ stable kernels.
70| | | | | 70| | | | |
71| Hisilicon | Hip0{5,6,7} | #161010101 | HISILICON_ERRATUM_161010101 | 71| Hisilicon | Hip0{5,6,7} | #161010101 | HISILICON_ERRATUM_161010101 |
72| Hisilicon | Hip0{6,7} | #161010701 | N/A | 72| Hisilicon | Hip0{6,7} | #161010701 | N/A |
73| Hisilicon | Hip07 | #161600802 | HISILICON_ERRATUM_161600802 |
73| | | | | 74| | | | |
74| Qualcomm Tech. | Falkor v1 | E1003 | QCOM_FALKOR_ERRATUM_1003 | 75| Qualcomm Tech. | Falkor v1 | E1003 | QCOM_FALKOR_ERRATUM_1003 |
75| Qualcomm Tech. | Falkor v1 | E1009 | QCOM_FALKOR_ERRATUM_1009 | 76| Qualcomm Tech. | Falkor v1 | E1009 | QCOM_FALKOR_ERRATUM_1009 |
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index c4361dff2b74..22455e4168c1 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -539,6 +539,7 @@ config QCOM_QDF2400_ERRATUM_0065
539 539
540 If unsure, say Y. 540 If unsure, say Y.
541 541
542
542config SOCIONEXT_SYNQUACER_PREITS 543config SOCIONEXT_SYNQUACER_PREITS
543 bool "Socionext Synquacer: Workaround for GICv3 pre-ITS" 544 bool "Socionext Synquacer: Workaround for GICv3 pre-ITS"
544 default y 545 default y
@@ -547,6 +548,16 @@ config SOCIONEXT_SYNQUACER_PREITS
547 MSI doorbell writes with non-zero values for the device ID. 548 MSI doorbell writes with non-zero values for the device ID.
548 549
549 If unsure, say Y. 550 If unsure, say Y.
551
552config 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.
559
560 If unsure, say Y.
550endmenu 561endmenu
551 562
552 563
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 4aedbdc62aa0..6cc57dc142df 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -109,6 +109,7 @@ struct its_node {
109 unsigned int msi_domain_flags; 109 unsigned int msi_domain_flags;
110 u32 pre_its_base; /* for Socionext Synquacer */ 110 u32 pre_its_base; /* for Socionext Synquacer */
111 bool is_v4; 111 bool is_v4;
112 int vlpi_redist_offset;
112}; 113};
113 114
114#define ITS_ITT_ALIGN SZ_256 115#define ITS_ITT_ALIGN SZ_256
@@ -558,13 +559,15 @@ static struct its_vpe *its_build_vmapp_cmd(struct its_node *its,
558 struct its_cmd_desc *desc) 559 struct its_cmd_desc *desc)
559{ 560{
560 unsigned long vpt_addr; 561 unsigned long vpt_addr;
562 u64 target;
561 563
562 vpt_addr = virt_to_phys(page_address(desc->its_vmapp_cmd.vpe->vpt_page)); 564 vpt_addr = virt_to_phys(page_address(desc->its_vmapp_cmd.vpe->vpt_page));
565 target = desc->its_vmapp_cmd.col->target_address + its->vlpi_redist_offset;
563 566
564 its_encode_cmd(cmd, GITS_CMD_VMAPP); 567 its_encode_cmd(cmd, GITS_CMD_VMAPP);
565 its_encode_vpeid(cmd, desc->its_vmapp_cmd.vpe->vpe_id); 568 its_encode_vpeid(cmd, desc->its_vmapp_cmd.vpe->vpe_id);
566 its_encode_valid(cmd, desc->its_vmapp_cmd.valid); 569 its_encode_valid(cmd, desc->its_vmapp_cmd.valid);
567 its_encode_target(cmd, desc->its_vmapp_cmd.col->target_address); 570 its_encode_target(cmd, target);
568 its_encode_vpt_addr(cmd, vpt_addr); 571 its_encode_vpt_addr(cmd, vpt_addr);
569 its_encode_vpt_size(cmd, LPI_NRBITS - 1); 572 its_encode_vpt_size(cmd, LPI_NRBITS - 1);
570 573
@@ -623,11 +626,14 @@ static struct its_vpe *its_build_vmovp_cmd(struct its_node *its,
623 struct its_cmd_block *cmd, 626 struct its_cmd_block *cmd,
624 struct its_cmd_desc *desc) 627 struct its_cmd_desc *desc)
625{ 628{
629 u64 target;
630
631 target = desc->its_vmovp_cmd.col->target_address + its->vlpi_redist_offset;
626 its_encode_cmd(cmd, GITS_CMD_VMOVP); 632 its_encode_cmd(cmd, GITS_CMD_VMOVP);
627 its_encode_seq_num(cmd, desc->its_vmovp_cmd.seq_num); 633 its_encode_seq_num(cmd, desc->its_vmovp_cmd.seq_num);
628 its_encode_its_list(cmd, desc->its_vmovp_cmd.its_list); 634 its_encode_its_list(cmd, desc->its_vmovp_cmd.its_list);
629 its_encode_vpeid(cmd, desc->its_vmovp_cmd.vpe->vpe_id); 635 its_encode_vpeid(cmd, desc->its_vmovp_cmd.vpe->vpe_id);
630 its_encode_target(cmd, desc->its_vmovp_cmd.col->target_address); 636 its_encode_target(cmd, target);
631 637
632 its_fixup_cmd(cmd); 638 its_fixup_cmd(cmd);
633 639
@@ -2834,6 +2840,18 @@ static bool __maybe_unused its_enable_quirk_socionext_synquacer(void *data)
2834 return false; 2840 return false;
2835} 2841}
2836 2842
2843static bool __maybe_unused its_enable_quirk_hip07_161600802(void *data)
2844{
2845 struct its_node *its = data;
2846
2847 /*
2848 * Hip07 insists on using the wrong address for the VLPI
2849 * page. Trick it into doing the right thing...
2850 */
2851 its->vlpi_redist_offset = SZ_128K;
2852 return true;
2853}
2854
2837static const struct gic_quirk its_quirks[] = { 2855static const struct gic_quirk its_quirks[] = {
2838#ifdef CONFIG_CAVIUM_ERRATUM_22375 2856#ifdef CONFIG_CAVIUM_ERRATUM_22375
2839 { 2857 {
@@ -2872,6 +2890,14 @@ static const struct gic_quirk its_quirks[] = {
2872 .init = its_enable_quirk_socionext_synquacer, 2890 .init = its_enable_quirk_socionext_synquacer,
2873 }, 2891 },
2874#endif 2892#endif
2893#ifdef CONFIG_HISILICON_ERRATUM_161600802
2894 {
2895 .desc = "ITS: Hip07 erratum 161600802",
2896 .iidr = 0x00000004,
2897 .mask = 0xffffffff,
2898 .init = its_enable_quirk_hip07_161600802,
2899 },
2900#endif
2875 { 2901 {
2876 } 2902 }
2877}; 2903};