From 1c055e55a242a33e574e48be530e06770a210dcd Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Mon, 19 Feb 2024 03:26:26 +0000
Subject: [PATCH] add r8169 read mac form eeprom
---
kernel/drivers/gpu/drm/omapdrm/omap_encoder.c | 184 ++++++++++++++++++++++++---------------------
1 files changed, 97 insertions(+), 87 deletions(-)
diff --git a/kernel/drivers/gpu/drm/omapdrm/omap_encoder.c b/kernel/drivers/gpu/drm/omapdrm/omap_encoder.c
index fcdf4b0..ae4b867 100644
--- a/kernel/drivers/gpu/drm/omapdrm/omap_encoder.c
+++ b/kernel/drivers/gpu/drm/omapdrm/omap_encoder.c
@@ -1,24 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
* Author: Rob Clark <rob@ti.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/list.h>
+#include <drm/drm_bridge.h>
#include <drm/drm_crtc.h>
-#include <drm/drm_crtc_helper.h>
+#include <drm/drm_modeset_helper_vtables.h>
#include <drm/drm_edid.h>
#include "omap_drv.h"
@@ -36,15 +26,8 @@
*/
struct omap_encoder {
struct drm_encoder base;
- struct omap_dss_device *dssdev;
+ struct omap_dss_device *output;
};
-
-struct omap_dss_device *omap_encoder_get_dssdev(struct drm_encoder *encoder)
-{
- struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
-
- return omap_encoder->dssdev;
-}
static void omap_encoder_destroy(struct drm_encoder *encoder)
{
@@ -58,102 +41,129 @@
.destroy = omap_encoder_destroy,
};
-static void omap_encoder_mode_set(struct drm_encoder *encoder,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
+static void omap_encoder_update_videomode_flags(struct videomode *vm,
+ u32 bus_flags)
{
- struct drm_device *dev = encoder->dev;
+ if (!(vm->flags & (DISPLAY_FLAGS_DE_LOW |
+ DISPLAY_FLAGS_DE_HIGH))) {
+ if (bus_flags & DRM_BUS_FLAG_DE_LOW)
+ vm->flags |= DISPLAY_FLAGS_DE_LOW;
+ else if (bus_flags & DRM_BUS_FLAG_DE_HIGH)
+ vm->flags |= DISPLAY_FLAGS_DE_HIGH;
+ }
+
+ if (!(vm->flags & (DISPLAY_FLAGS_PIXDATA_POSEDGE |
+ DISPLAY_FLAGS_PIXDATA_NEGEDGE))) {
+ if (bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE)
+ vm->flags |= DISPLAY_FLAGS_PIXDATA_POSEDGE;
+ else if (bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE)
+ vm->flags |= DISPLAY_FLAGS_PIXDATA_NEGEDGE;
+ }
+
+ if (!(vm->flags & (DISPLAY_FLAGS_SYNC_POSEDGE |
+ DISPLAY_FLAGS_SYNC_NEGEDGE))) {
+ if (bus_flags & DRM_BUS_FLAG_SYNC_DRIVE_POSEDGE)
+ vm->flags |= DISPLAY_FLAGS_SYNC_POSEDGE;
+ else if (bus_flags & DRM_BUS_FLAG_SYNC_DRIVE_NEGEDGE)
+ vm->flags |= DISPLAY_FLAGS_SYNC_NEGEDGE;
+ }
+}
+
+static void omap_encoder_mode_set(struct drm_encoder *encoder,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
- struct omap_dss_device *dssdev = omap_encoder->dssdev;
+ struct omap_dss_device *output = omap_encoder->output;
+ struct omap_dss_device *dssdev;
+ struct drm_device *dev = encoder->dev;
struct drm_connector *connector;
- bool hdmi_mode;
- int r;
+ struct drm_bridge *bridge;
+ struct videomode vm = { 0 };
+ u32 bus_flags;
- hdmi_mode = false;
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
- if (connector->encoder == encoder) {
- hdmi_mode = omap_connector_get_hdmi_mode(connector);
+ if (connector->encoder == encoder)
break;
- }
}
- if (dssdev->driver->set_hdmi_mode)
- dssdev->driver->set_hdmi_mode(dssdev, hdmi_mode);
+ drm_display_mode_to_videomode(adjusted_mode, &vm);
- if (hdmi_mode && dssdev->driver->set_hdmi_infoframe) {
- struct hdmi_avi_infoframe avi;
+ /*
+ * HACK: This fixes the vm flags.
+ * struct drm_display_mode does not contain the VSYNC/HSYNC/DE flags and
+ * they get lost when converting back and forth between struct
+ * drm_display_mode and struct videomode. The hack below goes and
+ * fetches the missing flags.
+ *
+ * A better solution is to use DRM's bus-flags through the whole driver.
+ */
+ for (dssdev = output; dssdev; dssdev = dssdev->next)
+ omap_encoder_update_videomode_flags(&vm, dssdev->bus_flags);
- r = drm_hdmi_avi_infoframe_from_display_mode(&avi, adjusted_mode,
- false);
- if (r == 0)
- dssdev->driver->set_hdmi_infoframe(dssdev, &avi);
+ for (bridge = output->bridge; bridge;
+ bridge = drm_bridge_get_next_bridge(bridge)) {
+ if (!bridge->timings)
+ continue;
+
+ bus_flags = bridge->timings->input_bus_flags;
+ omap_encoder_update_videomode_flags(&vm, bus_flags);
}
+
+ bus_flags = connector->display_info.bus_flags;
+ omap_encoder_update_videomode_flags(&vm, bus_flags);
+
+ /* Set timings for the dss manager. */
+ dss_mgr_set_timings(output, &vm);
}
static void omap_encoder_disable(struct drm_encoder *encoder)
{
struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
- struct omap_dss_device *dssdev = omap_encoder->dssdev;
- struct omap_dss_driver *dssdrv = dssdev->driver;
-
- dssdrv->disable(dssdev);
-}
-
-static int omap_encoder_update(struct drm_encoder *encoder,
- enum omap_channel channel,
- struct videomode *vm)
-{
+ struct omap_dss_device *dssdev = omap_encoder->output;
struct drm_device *dev = encoder->dev;
- struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
- struct omap_dss_device *dssdev = omap_encoder->dssdev;
- struct omap_dss_driver *dssdrv = dssdev->driver;
- int ret;
- if (dssdrv->check_timings) {
- ret = dssdrv->check_timings(dssdev, vm);
- } else {
- struct videomode t = {0};
+ dev_dbg(dev->dev, "disable(%s)\n", dssdev->name);
- dssdrv->get_timings(dssdev, &t);
-
- if (memcmp(vm, &t, sizeof(*vm)))
- ret = -EINVAL;
- else
- ret = 0;
- }
-
- if (ret) {
- dev_err(dev->dev, "could not set timings: %d\n", ret);
- return ret;
- }
-
- if (dssdrv->set_timings)
- dssdrv->set_timings(dssdev, vm);
-
- return 0;
+ /*
+ * Disable the chain of external devices, starting at the one at the
+ * internal encoder's output. This is used for DSI outputs only, as
+ * dssdev->next is NULL for all other outputs.
+ */
+ omapdss_device_disable(dssdev->next);
}
static void omap_encoder_enable(struct drm_encoder *encoder)
{
struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
- struct omap_dss_device *dssdev = omap_encoder->dssdev;
- struct omap_dss_driver *dssdrv = dssdev->driver;
- int r;
+ struct omap_dss_device *dssdev = omap_encoder->output;
+ struct drm_device *dev = encoder->dev;
- omap_encoder_update(encoder, omap_crtc_channel(encoder->crtc),
- omap_crtc_timings(encoder->crtc));
+ dev_dbg(dev->dev, "enable(%s)\n", dssdev->name);
- r = dssdrv->enable(dssdev);
- if (r)
- dev_err(encoder->dev->dev,
- "Failed to enable display '%s': %d\n",
- dssdev->name, r);
+ /*
+ * Enable the chain of external devices, starting at the one at the
+ * internal encoder's output. This is used for DSI outputs only, as
+ * dssdev->next is NULL for all other outputs.
+ */
+ omapdss_device_enable(dssdev->next);
}
static int omap_encoder_atomic_check(struct drm_encoder *encoder,
struct drm_crtc_state *crtc_state,
struct drm_connector_state *conn_state)
{
+ struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
+ enum drm_mode_status status;
+
+ status = omap_connector_mode_fixup(omap_encoder->output,
+ &crtc_state->mode,
+ &crtc_state->adjusted_mode);
+ if (status != MODE_OK) {
+ dev_err(encoder->dev->dev, "invalid timings: %d\n", status);
+ return -EINVAL;
+ }
+
return 0;
}
@@ -166,7 +176,7 @@
/* initialize encoder */
struct drm_encoder *omap_encoder_init(struct drm_device *dev,
- struct omap_dss_device *dssdev)
+ struct omap_dss_device *output)
{
struct drm_encoder *encoder = NULL;
struct omap_encoder *omap_encoder;
@@ -175,7 +185,7 @@
if (!omap_encoder)
goto fail;
- omap_encoder->dssdev = dssdev;
+ omap_encoder->output = output;
encoder = &omap_encoder->base;
--
Gitblit v1.6.2