diff options
Diffstat (limited to 'meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-arm64-ack-5.15/tc/0001-drm-Add-component-aware-simple-encoder.patch')
-rw-r--r-- | meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-arm64-ack-5.15/tc/0001-drm-Add-component-aware-simple-encoder.patch | 367 |
1 files changed, 0 insertions, 367 deletions
diff --git a/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-arm64-ack-5.15/tc/0001-drm-Add-component-aware-simple-encoder.patch b/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-arm64-ack-5.15/tc/0001-drm-Add-component-aware-simple-encoder.patch deleted file mode 100644 index d361efd59a..0000000000 --- a/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-arm64-ack-5.15/tc/0001-drm-Add-component-aware-simple-encoder.patch +++ /dev/null @@ -1,367 +0,0 @@ -From 5c07d2e7bf1634743249178bf2ca2a06779e6e7a Mon Sep 17 00:00:00 2001 -From: Tushar Khandelwal <tushar.khandelwal@arm.com> -Date: Tue, 16 Jun 2020 12:39:06 +0000 -Subject: [PATCH 01/40] drm: Add component-aware simple encoder - -This is a simple DRM encoder that gets its connector timings information -from a OF subnode in the device tree and exposes that as a "discovered" -panel. It can be used together with component-based DRM drivers in an -emulated environment where no real encoder or connector hardware exists -and the display output is configured outside the kernel. - -Signed-off-by: Tushar Khandelwal <tushar.khandelwal@arm.com> - -Upstream-Status: Backport [https://git.linaro.org/landing-teams/working/arm/kernel-release.git/commit/?h=latest-armlt&id=15283f7be4b1e586702551e85b4caf06531ac2fc] -Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com> -Change-Id: Ic68cbba7da7d36ee23359ff53bf30eb44cb78661 -Signed-off-by: Rupinderjit Singh <rupinderjit.singh@arm.com> ---- - drivers/gpu/drm/Kconfig | 11 + - drivers/gpu/drm/Makefile | 2 + - drivers/gpu/drm/drm_virtual_encoder.c | 299 ++++++++++++++++++++++++++ - 3 files changed, 312 insertions(+) - create mode 100644 drivers/gpu/drm/drm_virtual_encoder.c - -diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig -index cea777ae7fb9..2468ec7155ef 100644 ---- a/drivers/gpu/drm/Kconfig -+++ b/drivers/gpu/drm/Kconfig -@@ -291,6 +291,17 @@ config DRM_VKMS - - If M is selected the module will be called vkms. - -+config DRM_VIRT_ENCODER -+ tristate "Virtual OF-based encoder" -+ depends on DRM && OF -+ select VIDEOMODE_HELPERS -+ help -+ Choose this option to get a virtual encoder and its associated -+ connector that will use the device tree to read the display -+ timings information. If M is selected the module will be called -+ drm_vencoder. -+ -+ - source "drivers/gpu/drm/exynos/Kconfig" - - source "drivers/gpu/drm/rockchip/Kconfig" -diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile -index ad1112154898..361999b7d063 100644 ---- a/drivers/gpu/drm/Makefile -+++ b/drivers/gpu/drm/Makefile -@@ -59,6 +59,8 @@ drm_kms_helper-$(CONFIG_DRM_DP_CEC) += drm_dp_cec.o - - obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o - obj-$(CONFIG_DRM_DEBUG_SELFTEST) += selftests/ -+drm_vencoder-y := drm_virtual_encoder.o -+obj-$(CONFIG_DRM_VIRT_ENCODER) += drm_vencoder.o - - obj-$(CONFIG_DRM) += drm.o - obj-$(CONFIG_DRM_MIPI_DBI) += drm_mipi_dbi.o -diff --git a/drivers/gpu/drm/drm_virtual_encoder.c b/drivers/gpu/drm/drm_virtual_encoder.c -new file mode 100644 -index 000000000000..39a902ecfe32 ---- /dev/null -+++ b/drivers/gpu/drm/drm_virtual_encoder.c -@@ -0,0 +1,299 @@ -+/* -+ * Copyright (C) 2016 ARM Limited -+ * Author: Liviu Dudau <Liviu.Dudau@arm.com> -+ * -+ * Dummy encoder and connector that use the OF to "discover" the attached -+ * display timings. Can be used in situations where the encoder and connector's -+ * functionality are emulated and no setup steps are needed, or to describe -+ * attached panels for which no driver exists but can be used without -+ * additional hardware setup. -+ * -+ * The encoder also uses the component framework so that it can be a quick -+ * replacement for existing drivers when testing in an emulated environment. -+ * -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file COPYING in the main directory of this archive -+ * for more details. -+ * -+ */ -+ -+#include <drm/drm_crtc.h> -+#include <drm/drm_atomic_helper.h> -+#include <drm/drm_crtc_helper.h> -+#include <drm/drm_probe_helper.h> -+#include <drm/drm_print.h> -+#include <linux/platform_device.h> -+#include <drm/drm_of.h> -+#include <linux/component.h> -+#include <video/display_timing.h> -+#include <video/of_display_timing.h> -+#include <video/videomode.h> -+ -+struct drm_virt_priv { -+ struct drm_connector connector; -+ struct drm_encoder encoder; -+ struct display_timings *timings; -+}; -+ -+#define connector_to_drm_virt_priv(x) \ -+ container_of(x, struct drm_virt_priv, connector) -+ -+#define encoder_to_drm_virt_priv(x) \ -+ container_of(x, struct drm_virt_priv, encoder) -+ -+static void drm_virtcon_destroy(struct drm_connector *connector) -+{ -+ struct drm_virt_priv *conn = connector_to_drm_virt_priv(connector); -+ -+ drm_connector_cleanup(connector); -+ display_timings_release(conn->timings); -+} -+ -+static enum drm_connector_status -+drm_virtcon_detect(struct drm_connector *connector, bool force) -+{ -+ return connector_status_connected; -+} -+ -+static const struct drm_connector_funcs drm_virtcon_funcs = { -+ .reset = drm_atomic_helper_connector_reset, -+ .detect = drm_virtcon_detect, -+ .fill_modes = drm_helper_probe_single_connector_modes, -+ .destroy = drm_virtcon_destroy, -+ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, -+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, -+}; -+ -+static int drm_virtcon_get_modes(struct drm_connector *connector) -+{ -+ struct drm_virt_priv *conn = connector_to_drm_virt_priv(connector); -+ struct display_timings *timings = conn->timings; -+ int i; -+ -+ for (i = 0; i < timings->num_timings; i++) { -+ struct drm_display_mode *mode = drm_mode_create(connector->dev); -+ struct videomode vm; -+ -+ if (videomode_from_timings(timings, &vm, i)) -+ break; -+ -+ drm_display_mode_from_videomode(&vm, mode); -+ mode->type = DRM_MODE_TYPE_DRIVER; -+ if (timings->native_mode == i) -+ mode->type = DRM_MODE_TYPE_PREFERRED; -+ -+ drm_mode_set_name(mode); -+ drm_mode_probed_add(connector, mode); -+ } -+ -+ return i; -+} -+ -+static int drm_virtcon_mode_valid(struct drm_connector *connector, -+ struct drm_display_mode *mode) -+{ -+ return MODE_OK; -+} -+ -+struct drm_encoder *drm_virtcon_best_encoder(struct drm_connector *connector) -+{ -+ struct drm_virt_priv *priv = connector_to_drm_virt_priv(connector); -+ -+ return &priv->encoder; -+} -+ -+struct drm_encoder * -+drm_virtcon_atomic_best_encoder(struct drm_connector *connector, -+ struct drm_atomic_state *state) -+{ -+ struct drm_virt_priv *priv = connector_to_drm_virt_priv(connector); -+ -+ return &priv->encoder; -+} -+ -+static const struct drm_connector_helper_funcs drm_virtcon_helper_funcs = { -+ .get_modes = drm_virtcon_get_modes, -+ .mode_valid = drm_virtcon_mode_valid, -+ .best_encoder = drm_virtcon_best_encoder, -+ .atomic_best_encoder = drm_virtcon_atomic_best_encoder, -+}; -+ -+static void drm_vencoder_destroy(struct drm_encoder *encoder) -+{ -+ drm_encoder_cleanup(encoder); -+} -+ -+static const struct drm_encoder_funcs drm_vencoder_funcs = { -+ .destroy = drm_vencoder_destroy, -+}; -+ -+static void drm_vencoder_dpms(struct drm_encoder *encoder, int mode) -+{ -+ /* nothing needed */ -+} -+ -+static bool drm_vencoder_mode_fixup(struct drm_encoder *encoder, -+ const struct drm_display_mode *mode, -+ struct drm_display_mode *adjusted_mode) -+{ -+ /* nothing needed */ -+ return true; -+} -+ -+static void drm_vencoder_prepare(struct drm_encoder *encoder) -+{ -+ drm_vencoder_dpms(encoder, DRM_MODE_DPMS_OFF); -+} -+ -+static void drm_vencoder_commit(struct drm_encoder *encoder) -+{ -+ drm_vencoder_dpms(encoder, DRM_MODE_DPMS_ON); -+} -+ -+static void drm_vencoder_mode_set(struct drm_encoder *encoder, -+ struct drm_display_mode *mode, -+ struct drm_display_mode *adjusted_mode) -+{ -+ /* nothing needed */ -+} -+ -+static const struct drm_encoder_helper_funcs drm_vencoder_helper_funcs = { -+ .dpms = drm_vencoder_dpms, -+ .mode_fixup = drm_vencoder_mode_fixup, -+ .prepare = drm_vencoder_prepare, -+ .commit = drm_vencoder_commit, -+ .mode_set = drm_vencoder_mode_set, -+}; -+ -+static int drm_vencoder_bind(struct device *dev, struct device *master, -+ void *data) -+{ -+ struct drm_encoder *encoder; -+ struct drm_virt_priv *con; -+ struct drm_connector *connector; -+ struct drm_device *drm = data; -+ u32 crtcs = 0; -+ int ret; -+ -+ con = devm_kzalloc(dev, sizeof(*con), GFP_KERNEL); -+ if (!con) -+ return -ENOMEM; -+ -+ dev_set_drvdata(dev, con); -+ connector = &con->connector; -+ encoder = &con->encoder; -+ -+ if (dev->of_node) { -+ struct drm_bridge *bridge; -+ crtcs = drm_of_find_possible_crtcs(drm, dev->of_node); -+ bridge = of_drm_find_bridge(dev->of_node); -+ if (bridge) { -+ ret = drm_bridge_attach(encoder, bridge, NULL, 0); -+ if (ret) { -+ DRM_ERROR("Failed to initialize bridge\n"); -+ return ret; -+ } -+ } -+ con->timings = of_get_display_timings(dev->of_node); -+ if (!con->timings) { -+ dev_err(dev, "failed to get display panel timings\n"); -+ return ENXIO; -+ } -+ } -+ -+ /* If no CRTCs were found, fall back to the old encoder's behaviour */ -+ if (crtcs == 0) { -+ dev_warn(dev, "Falling back to first CRTC\n"); -+ crtcs = 1 << 0; -+ } -+ -+ encoder->possible_crtcs = crtcs ? crtcs : 1; -+ encoder->possible_clones = 0; -+ -+ ret = drm_encoder_init(drm, encoder, &drm_vencoder_funcs, -+ DRM_MODE_ENCODER_VIRTUAL, NULL); -+ if (ret) -+ goto encoder_init_err; -+ -+ drm_encoder_helper_add(encoder, &drm_vencoder_helper_funcs); -+ -+ /* bogus values, pretend we're a 24" screen for DPI calculations */ -+ connector->display_info.width_mm = 519; -+ connector->display_info.height_mm = 324; -+ connector->interlace_allowed = false; -+ connector->doublescan_allowed = false; -+ connector->polled = 0; -+ -+ ret = drm_connector_init(drm, connector, &drm_virtcon_funcs, -+ DRM_MODE_CONNECTOR_VIRTUAL); -+ if (ret) -+ goto connector_init_err; -+ -+ drm_connector_helper_add(connector, &drm_virtcon_helper_funcs); -+ -+ drm_connector_register(connector); -+ -+ ret = drm_connector_attach_encoder(connector, encoder); -+ if (ret) -+ goto attach_err; -+ -+ return ret; -+ -+attach_err: -+ drm_connector_unregister(connector); -+ drm_connector_cleanup(connector); -+connector_init_err: -+ drm_encoder_cleanup(encoder); -+encoder_init_err: -+ display_timings_release(con->timings); -+ -+ return ret; -+}; -+ -+static void drm_vencoder_unbind(struct device *dev, struct device *master, -+ void *data) -+{ -+ struct drm_virt_priv *con = dev_get_drvdata(dev); -+ -+ drm_connector_unregister(&con->connector); -+ drm_connector_cleanup(&con->connector); -+ drm_encoder_cleanup(&con->encoder); -+ display_timings_release(con->timings); -+} -+ -+static const struct component_ops drm_vencoder_ops = { -+ .bind = drm_vencoder_bind, -+ .unbind = drm_vencoder_unbind, -+}; -+ -+static int drm_vencoder_probe(struct platform_device *pdev) -+{ -+ return component_add(&pdev->dev, &drm_vencoder_ops); -+} -+ -+static int drm_vencoder_remove(struct platform_device *pdev) -+{ -+ component_del(&pdev->dev, &drm_vencoder_ops); -+ return 0; -+} -+ -+static const struct of_device_id drm_vencoder_of_match[] = { -+ { .compatible = "drm,virtual-encoder", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, drm_vencoder_of_match); -+ -+static struct platform_driver drm_vencoder_driver = { -+ .probe = drm_vencoder_probe, -+ .remove = drm_vencoder_remove, -+ .driver = { -+ .name = "drm_vencoder", -+ .of_match_table = drm_vencoder_of_match, -+ }, -+}; -+ -+module_platform_driver(drm_vencoder_driver); -+ -+MODULE_AUTHOR("Liviu Dudau"); -+MODULE_DESCRIPTION("Virtual DRM Encoder"); -+MODULE_LICENSE("GPL v2"); --- -2.34.1 - |