mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-25 16:31:13 +00:00
187 lines
5.5 KiB
Diff
187 lines
5.5 KiB
Diff
|
From 06e912bd821b21d9360a75cde2d78b03f17a5872 Mon Sep 17 00:00:00 2001
|
||
|
From: Wen He <wen.he_1@nxp.com>
|
||
|
Date: Tue, 17 Sep 2019 15:35:52 +0800
|
||
|
Subject: [PATCH] drm: ls1028a: Add DP driver support for LS1028A
|
||
|
|
||
|
Add Display Port driver support for NXP Layerscape LS1028A platform.
|
||
|
|
||
|
Signed-off-by: Wen He <wen.he_1@nxp.com>
|
||
|
---
|
||
|
drivers/gpu/drm/bridge/cadence/cdns-dp-core.c | 1 +
|
||
|
drivers/gpu/drm/imx/Makefile | 2 +-
|
||
|
drivers/gpu/drm/imx/cdn-mhdp-imxdrv.c | 13 +++
|
||
|
drivers/gpu/drm/imx/cdn-mhdp-ls1028a.c | 110 ++++++++++++++++++++++++++
|
||
|
drivers/gpu/drm/imx/cdns-mhdp-imx.h | 2 +
|
||
|
5 files changed, 127 insertions(+), 1 deletion(-)
|
||
|
create mode 100644 drivers/gpu/drm/imx/cdn-mhdp-ls1028a.c
|
||
|
|
||
|
--- a/drivers/gpu/drm/bridge/cadence/cdns-dp-core.c
|
||
|
+++ b/drivers/gpu/drm/bridge/cadence/cdns-dp-core.c
|
||
|
@@ -275,6 +275,7 @@ static int cdns_dp_bridge_attach(struct
|
||
|
struct drm_connector *connector = &mhdp->connector.base;
|
||
|
|
||
|
connector->interlace_allowed = 1;
|
||
|
+
|
||
|
connector->polled = DRM_CONNECTOR_POLL_HPD;
|
||
|
|
||
|
drm_connector_helper_add(connector, &cdns_dp_connector_helper_funcs);
|
||
|
--- a/drivers/gpu/drm/imx/Makefile
|
||
|
+++ b/drivers/gpu/drm/imx/Makefile
|
||
|
@@ -9,4 +9,4 @@ obj-$(CONFIG_DRM_IMX_TVE) += imx-tve.o
|
||
|
obj-$(CONFIG_DRM_IMX_LDB) += imx-ldb.o
|
||
|
|
||
|
obj-$(CONFIG_DRM_IMX_HDMI) += dw_hdmi-imx.o
|
||
|
-obj-$(CONFIG_DRM_IMX_CDNS_MHDP) += cdn-mhdp-imxdrv.o cdn-mhdp-dp-phy.o cdn-mhdp-hdmi-phy.o cdn-mhdp-imx8qm.o
|
||
|
+obj-$(CONFIG_DRM_IMX_CDNS_MHDP) += cdn-mhdp-imxdrv.o cdn-mhdp-dp-phy.o cdn-mhdp-hdmi-phy.o cdn-mhdp-imx8qm.o cdn-mhdp-ls1028a.o
|
||
|
--- a/drivers/gpu/drm/imx/cdn-mhdp-imxdrv.c
|
||
|
+++ b/drivers/gpu/drm/imx/cdn-mhdp-imxdrv.c
|
||
|
@@ -94,6 +94,16 @@ static struct cdns_plat_data imx8qm_dp_d
|
||
|
.is_dp = true,
|
||
|
};
|
||
|
|
||
|
+static struct cdns_plat_data ls1028a_dp_drv_data = {
|
||
|
+ .bind = cdns_dp_bind,
|
||
|
+ .unbind = cdns_dp_unbind,
|
||
|
+ .phy_set = cdns_dp_phy_set_imx8mq,
|
||
|
+ .power_on = cdns_mhdp_power_on_ls1028a,
|
||
|
+ .firmware_init = cdns_mhdp_firmware_init_imx8qm,
|
||
|
+ .pclk_rate = cdns_mhdp_pclk_rate_ls1028a,
|
||
|
+ .bus_type = BUS_TYPE_NORMAL_APB,
|
||
|
+};
|
||
|
+
|
||
|
static const struct of_device_id cdns_mhdp_imx_dt_ids[] = {
|
||
|
{ .compatible = "cdn,imx8mq-hdmi",
|
||
|
.data = &imx8mq_hdmi_drv_data
|
||
|
@@ -107,6 +117,9 @@ static const struct of_device_id cdns_mh
|
||
|
{ .compatible = "cdn,imx8qm-dp",
|
||
|
.data = &imx8qm_dp_drv_data
|
||
|
},
|
||
|
+ { .compatible = "cdn,ls1028a-dp",
|
||
|
+ .data = &ls1028a_dp_drv_data
|
||
|
+ },
|
||
|
{},
|
||
|
};
|
||
|
MODULE_DEVICE_TABLE(of, cdns_mhdp_imx_dt_ids);
|
||
|
--- /dev/null
|
||
|
+++ b/drivers/gpu/drm/imx/cdn-mhdp-ls1028a.c
|
||
|
@@ -0,0 +1,110 @@
|
||
|
+// SPDX-License-Identifier: GPL-2.0
|
||
|
+/*
|
||
|
+ * Copyright 2019 NXP
|
||
|
+ *
|
||
|
+ */
|
||
|
+#include <linux/clk.h>
|
||
|
+#include <drm/drmP.h>
|
||
|
+#include <linux/of.h>
|
||
|
+#include <linux/of_address.h>
|
||
|
+#include <linux/of_device.h>
|
||
|
+
|
||
|
+#include "cdns-mhdp-imx.h"
|
||
|
+
|
||
|
+static const struct of_device_id scfg_device_ids[] = {
|
||
|
+ { .compatible = "fsl,ls1028a-scfg", },
|
||
|
+ {}
|
||
|
+};
|
||
|
+
|
||
|
+static void ls1028a_phy_reset(u8 reset)
|
||
|
+{
|
||
|
+ struct device_node *scfg_node;
|
||
|
+ void __iomem *scfg_base = NULL;
|
||
|
+
|
||
|
+ scfg_node = of_find_matching_node(NULL, scfg_device_ids);
|
||
|
+ if (scfg_node)
|
||
|
+ scfg_base = of_iomap(scfg_node, 0);
|
||
|
+
|
||
|
+ iowrite32(reset, scfg_base + 0x230);
|
||
|
+}
|
||
|
+
|
||
|
+int ls1028a_clocks_init(struct imx_mhdp_device *imx_mhdp)
|
||
|
+{
|
||
|
+ struct device *dev = imx_mhdp->mhdp.dev;
|
||
|
+ struct imx_hdp_clks *clks = &imx_mhdp->clks;
|
||
|
+
|
||
|
+ clks->clk_core = devm_clk_get(dev, "clk_core");
|
||
|
+ if (IS_ERR(clks->clk_core)) {
|
||
|
+ dev_warn(dev, "failed to get hdp core clk\n");
|
||
|
+ return PTR_ERR(clks->clk_core);
|
||
|
+ }
|
||
|
+
|
||
|
+ clks->clk_pxl = devm_clk_get(dev, "clk_pxl");
|
||
|
+ if (IS_ERR(clks->clk_pxl)) {
|
||
|
+ dev_warn(dev, "failed to get pxl clk\n");
|
||
|
+ return PTR_ERR(clks->clk_pxl);
|
||
|
+ }
|
||
|
+
|
||
|
+ return true;
|
||
|
+}
|
||
|
+
|
||
|
+static int ls1028a_pixel_clk_enable(struct imx_mhdp_device *imx_mhdp)
|
||
|
+{
|
||
|
+ struct imx_hdp_clks *clks = &imx_mhdp->clks;
|
||
|
+ struct device *dev = imx_mhdp->mhdp.dev;
|
||
|
+ int ret;
|
||
|
+
|
||
|
+ ret = clk_prepare_enable(clks->clk_pxl);
|
||
|
+ if (ret < 0) {
|
||
|
+ dev_err(dev, "%s, pre clk pxl error\n", __func__);
|
||
|
+ return ret;
|
||
|
+ }
|
||
|
+
|
||
|
+ return ret;
|
||
|
+}
|
||
|
+
|
||
|
+static void ls1028a_pixel_clk_disable(struct imx_mhdp_device *imx_mhdp)
|
||
|
+{
|
||
|
+ struct imx_hdp_clks *clks = &imx_mhdp->clks;
|
||
|
+
|
||
|
+ clk_disable_unprepare(clks->clk_pxl);
|
||
|
+}
|
||
|
+
|
||
|
+static void ls1028a_pixel_clk_set_rate(struct imx_mhdp_device *imx_mhdp,
|
||
|
+ u32 pclock)
|
||
|
+{
|
||
|
+ struct imx_hdp_clks *clks = &imx_mhdp->clks;
|
||
|
+
|
||
|
+ clk_set_rate(clks->clk_pxl, pclock);
|
||
|
+}
|
||
|
+
|
||
|
+int cdns_mhdp_power_on_ls1028a(struct cdns_mhdp_device *mhdp)
|
||
|
+{
|
||
|
+ struct imx_mhdp_device *imx_mhdp = container_of
|
||
|
+ (mhdp, struct imx_mhdp_device, mhdp);
|
||
|
+
|
||
|
+ /* clock init and rate set */
|
||
|
+ ls1028a_clocks_init(imx_mhdp);
|
||
|
+
|
||
|
+ ls1028a_pixel_clk_enable(imx_mhdp);
|
||
|
+
|
||
|
+ /* Init pixel clock with 148.5MHz before FW init */
|
||
|
+ ls1028a_pixel_clk_set_rate(imx_mhdp, 148500000);
|
||
|
+
|
||
|
+ ls1028a_phy_reset(1);
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+void cdns_mhdp_pclk_rate_ls1028a(struct cdns_mhdp_device *mhdp)
|
||
|
+{
|
||
|
+ struct imx_mhdp_device *imx_mhdp = container_of
|
||
|
+ (mhdp, struct imx_mhdp_device, mhdp);
|
||
|
+
|
||
|
+ /* set pixel clock before video mode setup */
|
||
|
+ ls1028a_pixel_clk_disable(imx_mhdp);
|
||
|
+
|
||
|
+ ls1028a_pixel_clk_set_rate(imx_mhdp, imx_mhdp->mhdp.mode.clock * 1000);
|
||
|
+
|
||
|
+ ls1028a_pixel_clk_enable(imx_mhdp);
|
||
|
+}
|
||
|
--- a/drivers/gpu/drm/imx/cdns-mhdp-imx.h
|
||
|
+++ b/drivers/gpu/drm/imx/cdns-mhdp-imx.h
|
||
|
@@ -78,4 +78,6 @@ void cdns_mhdp_plat_deinit_imx8qm(struct
|
||
|
void cdns_mhdp_pclk_rate_imx8qm(struct cdns_mhdp_device *mhdp);
|
||
|
int cdns_mhdp_firmware_init_imx8qm(struct cdns_mhdp_device *mhdp);
|
||
|
int cdns_mhdp_power_on_imx8qm(struct cdns_mhdp_device *mhdp);
|
||
|
+int cdns_mhdp_power_on_ls1028a(struct cdns_mhdp_device *mhdp);
|
||
|
+void cdns_mhdp_pclk_rate_ls1028a(struct cdns_mhdp_device *mhdp);
|
||
|
#endif /* CDNS_MHDP_IMX_H_ */
|