[7/8] drm/loongson: Support to infer DC reversion from CPU's PRID value

Message ID 20231029194607.379459-8-suijingfeng@loongson.cn
State New
Headers
Series drm/loongson: Submit a mini VBIOS support and a display bridge driver |

Commit Message

Sui Jingfeng Oct. 29, 2023, 7:46 p.m. UTC
  Due to the fact that the same display IP core has been integrated into
different platform, there is a need to differentiate them on the runtime.
The DC in LS7A1000/LS2K1000 has the PCI vendor & device ID of 0x0014:0x7A06
The DC in LS7A2000/LS2K2000 has the PCI vendor & device ID of 0x0014:0x7A36

Because the output ports and host platform of the DC IP varies, without a
revision information we can't achieve fine-grained controls. The canonical
approach to do such a thing is to read reversion register from the PCIe
device. But LS2K1000 SoC was taped out at 2017, it is rather old. Our BIOS
engineer don't assign a different revision ID to it, probably because of
ignorance.

LS2K2000 SoC was newly taped on 2023, we strictly force the BIOS engineer
assign a different revision ID(0x10) to it. But the problem is that it is
too casual, there is no formal convention or public documented rule
established. For Loongson LS2K series SoC, the display controller IP is
taped togather with the CPU core. For Loongson LS7A series bridge chips,
the display controller IP is taped togather with the bridge chips itself.
Consider the fact the all Loongson CPU has a unique PRID, this patch choose
to infer DC reversion from CPU's PRID value.

 - LS3A4000/LS3A5000 has 0xC0 as its processor ID.
 - LS2K2000 has 0xB0 as its processor ID.
 - LS2K2000LA has 0xA0 as its processor ID.

The provided approach has no dependency on DT or ACPI, thus is preferfed.
Besides, this approach can be used to acquire more addtional HW features.
So the provided method has the potential to bring more benifits.

Signed-off-by: Sui Jingfeng <suijingfeng@loongson.cn>
---
 drivers/gpu/drm/loongson/lsdc_drv.h   |  2 ++
 drivers/gpu/drm/loongson/lsdc_probe.c | 35 +++++++++++++++++++++++++++
 drivers/gpu/drm/loongson/lsdc_probe.h |  2 ++
 3 files changed, 39 insertions(+)
  

Comments

Dmitry Baryshkov Oct. 29, 2023, 11:19 p.m. UTC | #1
On Sun, 29 Oct 2023 at 21:46, Sui Jingfeng <suijingfeng@loongson.cn> wrote:
>
> Due to the fact that the same display IP core has been integrated into
> different platform, there is a need to differentiate them on the runtime.
> The DC in LS7A1000/LS2K1000 has the PCI vendor & device ID of 0x0014:0x7A06
> The DC in LS7A2000/LS2K2000 has the PCI vendor & device ID of 0x0014:0x7A36
>
> Because the output ports and host platform of the DC IP varies, without a
> revision information we can't achieve fine-grained controls. The canonical
> approach to do such a thing is to read reversion register from the PCIe
> device. But LS2K1000 SoC was taped out at 2017, it is rather old. Our BIOS
> engineer don't assign a different revision ID to it, probably because of
> ignorance.
>
> LS2K2000 SoC was newly taped on 2023, we strictly force the BIOS engineer
> assign a different revision ID(0x10) to it. But the problem is that it is
> too casual, there is no formal convention or public documented rule
> established. For Loongson LS2K series SoC, the display controller IP is
> taped togather with the CPU core. For Loongson LS7A series bridge chips,
> the display controller IP is taped togather with the bridge chips itself.
> Consider the fact the all Loongson CPU has a unique PRID, this patch choose
> to infer DC reversion from CPU's PRID value.
>
>  - LS3A4000/LS3A5000 has 0xC0 as its processor ID.
>  - LS2K2000 has 0xB0 as its processor ID.
>  - LS2K2000LA has 0xA0 as its processor ID.
>
> The provided approach has no dependency on DT or ACPI, thus is preferfed.
> Besides, this approach can be used to acquire more addtional HW features.
> So the provided method has the potential to bring more benifits.
>
> Signed-off-by: Sui Jingfeng <suijingfeng@loongson.cn>
> ---
>  drivers/gpu/drm/loongson/lsdc_drv.h   |  2 ++
>  drivers/gpu/drm/loongson/lsdc_probe.c | 35 +++++++++++++++++++++++++++
>  drivers/gpu/drm/loongson/lsdc_probe.h |  2 ++
>  3 files changed, 39 insertions(+)
>
> diff --git a/drivers/gpu/drm/loongson/lsdc_drv.h b/drivers/gpu/drm/loongson/lsdc_drv.h
> index 46ba9b88a30d..e1f4a2db2a0a 100644
> --- a/drivers/gpu/drm/loongson/lsdc_drv.h
> +++ b/drivers/gpu/drm/loongson/lsdc_drv.h
> @@ -42,6 +42,8 @@
>  enum loongson_chip_id {
>         CHIP_LS7A1000 = 0,
>         CHIP_LS7A2000 = 1,
> +       CHIP_LS2K1000 = 2,
> +       CHIP_LS2K2000 = 3,
>         CHIP_LS_LAST,
>  };
>
> diff --git a/drivers/gpu/drm/loongson/lsdc_probe.c b/drivers/gpu/drm/loongson/lsdc_probe.c
> index 48ba69bb8a98..f49b642d8f65 100644
> --- a/drivers/gpu/drm/loongson/lsdc_probe.c
> +++ b/drivers/gpu/drm/loongson/lsdc_probe.c
> @@ -54,3 +54,38 @@ unsigned int loongson_cpu_get_prid(u8 *imp, u8 *rev)
>
>         return prid;
>  }
> +
> +enum loongson_chip_id loongson_chip_id_fixup(enum loongson_chip_id chip_id)
> +{
> +       u8 impl;
> +
> +       if (loongson_cpu_get_prid(&impl, NULL)) {
> +               /*
> +                * LS2K2000 only has the LoongArch edition.
> +                */
> +               if (chip_id == CHIP_LS7A2000) {
> +                       if (impl == LOONGARCH_CPU_IMP_LS2K2000)
> +                               return CHIP_LS2K2000;
> +               }
> +
> +               /*
> +                * LS2K1000 has the LoongArch edition(with two LA264 CPU core)
> +                * and the Mips edition(with two mips64r2 CPU core), Only the
> +                * instruction set of the CPU are changed, the peripheral
> +                * devices are basically same.
> +                */
> +               if (chip_id == CHIP_LS7A1000) {
> +#if defined(__loongarch__)
> +                       if (impl == LOONGARCH_CPU_IMP_LS2K1000)
> +                               return CHIP_LS2K1000;
> +#endif
> +
> +#if defined(__mips__)
> +                       if (impl == LOONGSON_CPU_MIPS_IMP_LS2K)
> +                               return CHIP_LS2K1000;
> +#endif

Can you drop the ifdefs here? The code blocks do not seem to conflict
with each other.

> +               }
> +       }
> +
> +       return chip_id;
> +}
> diff --git a/drivers/gpu/drm/loongson/lsdc_probe.h b/drivers/gpu/drm/loongson/lsdc_probe.h
> index 8bb6de2e3c64..8c630c5c90ce 100644
> --- a/drivers/gpu/drm/loongson/lsdc_probe.h
> +++ b/drivers/gpu/drm/loongson/lsdc_probe.h
> @@ -9,4 +9,6 @@
>  /* Helpers for chip detection */
>  unsigned int loongson_cpu_get_prid(u8 *impl, u8 *rev);
>
> +enum loongson_chip_id loongson_chip_id_fixup(enum loongson_chip_id chip_id);
> +
>  #endif
> --
> 2.34.1
>
  
Sui Jingfeng Oct. 30, 2023, 8:50 a.m. UTC | #2
Hi,

On 2023/10/30 07:19, Dmitry Baryshkov wrote:
> On Sun, 29 Oct 2023 at 21:46, Sui Jingfeng <suijingfeng@loongson.cn> wrote:
>> Due to the fact that the same display IP core has been integrated into
>> different platform, there is a need to differentiate them on the runtime.
>> The DC in LS7A1000/LS2K1000 has the PCI vendor & device ID of 0x0014:0x7A06
>> The DC in LS7A2000/LS2K2000 has the PCI vendor & device ID of 0x0014:0x7A36
>>
>> Because the output ports and host platform of the DC IP varies, without a
>> revision information we can't achieve fine-grained controls. The canonical
>> approach to do such a thing is to read reversion register from the PCIe
>> device. But LS2K1000 SoC was taped out at 2017, it is rather old. Our BIOS
>> engineer don't assign a different revision ID to it, probably because of
>> ignorance.
>>
>> LS2K2000 SoC was newly taped on 2023, we strictly force the BIOS engineer
>> assign a different revision ID(0x10) to it. But the problem is that it is
>> too casual, there is no formal convention or public documented rule
>> established. For Loongson LS2K series SoC, the display controller IP is
>> taped togather with the CPU core. For Loongson LS7A series bridge chips,
>> the display controller IP is taped togather with the bridge chips itself.
>> Consider the fact the all Loongson CPU has a unique PRID, this patch choose
>> to infer DC reversion from CPU's PRID value.
>>
>>   - LS3A4000/LS3A5000 has 0xC0 as its processor ID.
>>   - LS2K2000 has 0xB0 as its processor ID.
>>   - LS2K2000LA has 0xA0 as its processor ID.
>>
>> The provided approach has no dependency on DT or ACPI, thus is preferfed.
>> Besides, this approach can be used to acquire more addtional HW features.
>> So the provided method has the potential to bring more benifits.
>>
>> Signed-off-by: Sui Jingfeng <suijingfeng@loongson.cn>
>> ---
>>   drivers/gpu/drm/loongson/lsdc_drv.h   |  2 ++
>>   drivers/gpu/drm/loongson/lsdc_probe.c | 35 +++++++++++++++++++++++++++
>>   drivers/gpu/drm/loongson/lsdc_probe.h |  2 ++
>>   3 files changed, 39 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/loongson/lsdc_drv.h b/drivers/gpu/drm/loongson/lsdc_drv.h
>> index 46ba9b88a30d..e1f4a2db2a0a 100644
>> --- a/drivers/gpu/drm/loongson/lsdc_drv.h
>> +++ b/drivers/gpu/drm/loongson/lsdc_drv.h
>> @@ -42,6 +42,8 @@
>>   enum loongson_chip_id {
>>          CHIP_LS7A1000 = 0,
>>          CHIP_LS7A2000 = 1,
>> +       CHIP_LS2K1000 = 2,
>> +       CHIP_LS2K2000 = 3,
>>          CHIP_LS_LAST,
>>   };
>>
>> diff --git a/drivers/gpu/drm/loongson/lsdc_probe.c b/drivers/gpu/drm/loongson/lsdc_probe.c
>> index 48ba69bb8a98..f49b642d8f65 100644
>> --- a/drivers/gpu/drm/loongson/lsdc_probe.c
>> +++ b/drivers/gpu/drm/loongson/lsdc_probe.c
>> @@ -54,3 +54,38 @@ unsigned int loongson_cpu_get_prid(u8 *imp, u8 *rev)
>>
>>          return prid;
>>   }
>> +
>> +enum loongson_chip_id loongson_chip_id_fixup(enum loongson_chip_id chip_id)
>> +{
>> +       u8 impl;
>> +
>> +       if (loongson_cpu_get_prid(&impl, NULL)) {
>> +               /*
>> +                * LS2K2000 only has the LoongArch edition.
>> +                */
>> +               if (chip_id == CHIP_LS7A2000) {
>> +                       if (impl == LOONGARCH_CPU_IMP_LS2K2000)
>> +                               return CHIP_LS2K2000;
>> +               }
>> +
>> +               /*
>> +                * LS2K1000 has the LoongArch edition(with two LA264 CPU core)
>> +                * and the Mips edition(with two mips64r2 CPU core), Only the
>> +                * instruction set of the CPU are changed, the peripheral
>> +                * devices are basically same.
>> +                */
>> +               if (chip_id == CHIP_LS7A1000) {
>> +#if defined(__loongarch__)
>> +                       if (impl == LOONGARCH_CPU_IMP_LS2K1000)
>> +                               return CHIP_LS2K1000;
>> +#endif
>> +
>> +#if defined(__mips__)
>> +                       if (impl == LOONGSON_CPU_MIPS_IMP_LS2K)
>> +                               return CHIP_LS2K1000;
>> +#endif
> Can you drop the ifdefs here? The code blocks do not seem to conflict
> with each other.

OK, no problem. Will be fixed at the next version.

>> +               }
>> +       }
>> +
>> +       return chip_id;
>> +}
>> diff --git a/drivers/gpu/drm/loongson/lsdc_probe.h b/drivers/gpu/drm/loongson/lsdc_probe.h
>> index 8bb6de2e3c64..8c630c5c90ce 100644
>> --- a/drivers/gpu/drm/loongson/lsdc_probe.h
>> +++ b/drivers/gpu/drm/loongson/lsdc_probe.h
>> @@ -9,4 +9,6 @@
>>   /* Helpers for chip detection */
>>   unsigned int loongson_cpu_get_prid(u8 *impl, u8 *rev);
>>
>> +enum loongson_chip_id loongson_chip_id_fixup(enum loongson_chip_id chip_id);
>> +
>>   #endif
>> --
>> 2.34.1
>>
>
  

Patch

diff --git a/drivers/gpu/drm/loongson/lsdc_drv.h b/drivers/gpu/drm/loongson/lsdc_drv.h
index 46ba9b88a30d..e1f4a2db2a0a 100644
--- a/drivers/gpu/drm/loongson/lsdc_drv.h
+++ b/drivers/gpu/drm/loongson/lsdc_drv.h
@@ -42,6 +42,8 @@ 
 enum loongson_chip_id {
 	CHIP_LS7A1000 = 0,
 	CHIP_LS7A2000 = 1,
+	CHIP_LS2K1000 = 2,
+	CHIP_LS2K2000 = 3,
 	CHIP_LS_LAST,
 };
 
diff --git a/drivers/gpu/drm/loongson/lsdc_probe.c b/drivers/gpu/drm/loongson/lsdc_probe.c
index 48ba69bb8a98..f49b642d8f65 100644
--- a/drivers/gpu/drm/loongson/lsdc_probe.c
+++ b/drivers/gpu/drm/loongson/lsdc_probe.c
@@ -54,3 +54,38 @@  unsigned int loongson_cpu_get_prid(u8 *imp, u8 *rev)
 
 	return prid;
 }
+
+enum loongson_chip_id loongson_chip_id_fixup(enum loongson_chip_id chip_id)
+{
+	u8 impl;
+
+	if (loongson_cpu_get_prid(&impl, NULL)) {
+		/*
+		 * LS2K2000 only has the LoongArch edition.
+		 */
+		if (chip_id == CHIP_LS7A2000) {
+			if (impl == LOONGARCH_CPU_IMP_LS2K2000)
+				return CHIP_LS2K2000;
+		}
+
+		/*
+		 * LS2K1000 has the LoongArch edition(with two LA264 CPU core)
+		 * and the Mips edition(with two mips64r2 CPU core), Only the
+		 * instruction set of the CPU are changed, the peripheral
+		 * devices are basically same.
+		 */
+		if (chip_id == CHIP_LS7A1000) {
+#if defined(__loongarch__)
+			if (impl == LOONGARCH_CPU_IMP_LS2K1000)
+				return CHIP_LS2K1000;
+#endif
+
+#if defined(__mips__)
+			if (impl == LOONGSON_CPU_MIPS_IMP_LS2K)
+				return CHIP_LS2K1000;
+#endif
+		}
+	}
+
+	return chip_id;
+}
diff --git a/drivers/gpu/drm/loongson/lsdc_probe.h b/drivers/gpu/drm/loongson/lsdc_probe.h
index 8bb6de2e3c64..8c630c5c90ce 100644
--- a/drivers/gpu/drm/loongson/lsdc_probe.h
+++ b/drivers/gpu/drm/loongson/lsdc_probe.h
@@ -9,4 +9,6 @@ 
 /* Helpers for chip detection */
 unsigned int loongson_cpu_get_prid(u8 *impl, u8 *rev);
 
+enum loongson_chip_id loongson_chip_id_fixup(enum loongson_chip_id chip_id);
+
 #endif