[PATCH v7 4/4] drm/loongson: Use acpi to get video bios.
From: Chenyang Li
Date: Sat Jun 25 2022 - 05:08:02 EST
Add get video bios from the ACPI table.
Define new acpi table "VIAT" for loongson video bios.
Signed-off-by: Chenyang Li <lichenyang@xxxxxxxxxxx>
---
drivers/gpu/drm/loongson/Makefile | 3 +-
drivers/gpu/drm/loongson/loongson_drv.c | 21 +++++++-
drivers/gpu/drm/loongson/loongson_drv.h | 1 +
drivers/gpu/drm/loongson/loongson_vbios.c | 62 +++++++++++++++++++++++
drivers/gpu/drm/loongson/loongson_vbios.h | 29 +++++++++++
5 files changed, 113 insertions(+), 3 deletions(-)
create mode 100644 drivers/gpu/drm/loongson/loongson_vbios.c
create mode 100644 drivers/gpu/drm/loongson/loongson_vbios.h
diff --git a/drivers/gpu/drm/loongson/Makefile b/drivers/gpu/drm/loongson/Makefile
index b083854d789b..b774a91003d9 100644
--- a/drivers/gpu/drm/loongson/Makefile
+++ b/drivers/gpu/drm/loongson/Makefile
@@ -11,5 +11,6 @@ loongson-y := loongson_connector.o \
loongson_encoder.o \
loongson_i2c.o \
loongson_irq.o \
- loongson_plane.o
+ loongson_plane.o \
+ loongson_vbios.o
obj-$(CONFIG_DRM_LOONGSON) += loongson.o
diff --git a/drivers/gpu/drm/loongson/loongson_drv.c b/drivers/gpu/drm/loongson/loongson_drv.c
index 1d6f35e78813..1c212200f088 100644
--- a/drivers/gpu/drm/loongson/loongson_drv.c
+++ b/drivers/gpu/drm/loongson/loongson_drv.c
@@ -19,14 +19,28 @@
#include <drm/drm_probe_helper.h>
#include "loongson_drv.h"
+#include "loongson_vbios.h"
+
+/*
+ * Completed
+ * 1.Displays controller device initialization and display funcitons
+ * 2.I2c bus driver and DDC functions
+ * 3.Vblank and vsync interrupt support
+ * 4.Use acpi to get video bios
+ * Todo
+ * 1.Video bios parse functions
+ * 2.Hardware cursor driver
+ * 3.New device support as well as Loongson GPU
+ */
/* Interface history:
* 0.1 - original.
* 0.2 - add i2c and connector detect.
* 0.3 - Vblank and vsync interrupt support.
+ * 0.4 - Use acpi to get vbios.
*/
#define DRIVER_MAJOR 0
-#define DRIVER_MINOR 3
+#define DRIVER_MINOR 4
static const struct drm_mode_config_funcs loongson_mode_funcs = {
.fb_create = drm_gem_fb_create,
@@ -88,7 +102,10 @@ static int loongson_device_init(struct drm_device *dev)
if (!ldev->io)
return -ENOMEM;
- ldev->num_crtc = 2;
+ if (!loongson_vbios_init(ldev)) {
+ DRM_WARN("Get vbios failed, enable two crtc\n");
+ ldev->num_crtc = 2;
+ }
ret = loongson_dc_gpio_init(ldev);
if (ret)
diff --git a/drivers/gpu/drm/loongson/loongson_drv.h b/drivers/gpu/drm/loongson/loongson_drv.h
index af47e68487fd..4e5cb5977c9a 100644
--- a/drivers/gpu/drm/loongson/loongson_drv.h
+++ b/drivers/gpu/drm/loongson/loongson_drv.h
@@ -109,6 +109,7 @@ struct loongson_device {
u32 num_crtc;
struct loongson_mode_info mode_info[2];
struct pci_dev *gpu_pdev; /* LS7A gpu device info */
+ void *vbios;
struct loongson_i2c i2c_bus[DC_MAX_I2C_BUS];
};
diff --git a/drivers/gpu/drm/loongson/loongson_vbios.c b/drivers/gpu/drm/loongson/loongson_vbios.c
new file mode 100644
index 000000000000..2b3a2757102a
--- /dev/null
+++ b/drivers/gpu/drm/loongson/loongson_vbios.c
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
+ */
+
+#include "loongson_drv.h"
+#include "loongson_vbios.h"
+
+#ifdef CONFIG_ACPI
+static bool read_bios_from_acpi(struct loongson_device *ldev)
+{
+ void *vaddr;
+ struct acpi_table_header *hdr;
+ struct acpi_viat_table *viat;
+ acpi_size tbl_size;
+
+ if (!ACPI_SUCCESS(acpi_get_table("VIAT", 1, &hdr)))
+ return false;
+
+ tbl_size = hdr->length;
+ if (tbl_size != sizeof(struct acpi_viat_table)) {
+ DRM_WARN("ACPI viat table present but broken(too short #1)\n");
+ return false;
+ }
+
+ viat = (struct acpi_viat_table *)hdr;
+ ldev->vbios = kmalloc(VBIOS_SIZE, GFP_KERNEL);
+ if (!ldev->vbios) {
+ kfree(ldev->vbios);
+ return false;
+ }
+
+ vaddr = phys_to_virt(viat->vbios_addr);
+ memcpy(ldev->vbios, vaddr, VBIOS_SIZE);
+ DRM_INFO("Get vbios from ACPI success!\n");
+
+ return true;
+}
+#else
+static bool read_bios_from_acpi(struct loongson_device *ldev)
+{
+ return false;
+}
+#endif
+
+bool loongson_vbios_init(struct loongson_device *ldev)
+{
+ int ret;
+ struct loongson_vbios *header;
+
+ ret = read_bios_from_acpi(ldev);
+ if (!ret)
+ return ret;
+
+ header = ldev->vbios;
+ ldev->num_crtc = header->crtc_num;
+
+ DRM_INFO("Loongson vbios version %d.%d crtc num %d.\n",
+ header->version_major, header->version_minor, ldev->num_crtc);
+
+ return ret;
+}
diff --git a/drivers/gpu/drm/loongson/loongson_vbios.h b/drivers/gpu/drm/loongson/loongson_vbios.h
new file mode 100644
index 000000000000..b7d8ce15c6c5
--- /dev/null
+++ b/drivers/gpu/drm/loongson/loongson_vbios.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
+ */
+
+#ifndef __LOONGSON_VBIOS_H__
+#define __LOONGSON_VBIOS_H__
+
+#include <linux/acpi.h>
+
+#define VBIOS_SIZE 0x40000
+
+struct loongson_vbios {
+ uint32_t version_major;
+ uint32_t version_minor;
+ uint32_t crtc_num;
+} __packed;
+
+#ifdef CONFIG_ACPI
+/* VBOIS INFO ADDRESS TABLE */
+struct acpi_viat_table {
+ struct acpi_table_header header;
+ u64 vbios_addr;
+} __packed;
+#endif
+
+bool loongson_vbios_init(struct loongson_device *ldev);
+
+#endif /* __LOONGSON_VBIOS_H__ */
--
2.25.1