1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
|
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_ */
|