1097 lines
34 KiB
Diff
1097 lines
34 KiB
Diff
From fe1824851dd6f7d3ee6d5411edba4102dacea873 Mon Sep 17 00:00:00 2001
|
|
From: Sandor Yu <Sandor.yu@nxp.com>
|
|
Date: Wed, 11 Sep 2019 17:16:47 +0800
|
|
Subject: [PATCH] drm: bridge: cadence: move struct imx_mhdp_device to drm/imx
|
|
|
|
move struct imx_mhdp_device to drm/imx folder.
|
|
change the base address name from regs to regs_base.
|
|
add mhdp bus access function.
|
|
uniform variable name.
|
|
|
|
Signed-off-by: Sandor Yu <Sandor.yu@nxp.com>
|
|
---
|
|
drivers/gpu/drm/bridge/cadence/cdns-dp-core.c | 188 ++++++++++-----------
|
|
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c | 190 ++++++++++------------
|
|
drivers/gpu/drm/bridge/cadence/cdns-mhdp-audio.c | 1 -
|
|
drivers/gpu/drm/bridge/cadence/cdns-mhdp-cec.c | 2 +-
|
|
drivers/gpu/drm/bridge/cadence/cdns-mhdp-common.c | 43 ++---
|
|
drivers/gpu/drm/bridge/cadence/cdns-mhdp-hdmi.c | 1 -
|
|
include/drm/bridge/cdns-mhdp-common.h | 67 +++++++-
|
|
include/drm/bridge/cdns-mhdp-imx.h | 121 --------------
|
|
8 files changed, 258 insertions(+), 355 deletions(-)
|
|
delete mode 100644 include/drm/bridge/cdns-mhdp-imx.h
|
|
|
|
--- a/drivers/gpu/drm/bridge/cadence/cdns-dp-core.c
|
|
+++ b/drivers/gpu/drm/bridge/cadence/cdns-dp-core.c
|
|
@@ -9,8 +9,7 @@
|
|
* (at your option) any later version.
|
|
*
|
|
*/
|
|
-
|
|
-#include <drm/bridge/cdns-mhdp-imx.h>
|
|
+#include <drm/bridge/cdns-mhdp-common.h>
|
|
#include <drm/drm_atomic_helper.h>
|
|
#include <drm/drm_crtc_helper.h>
|
|
#include <drm/drm_edid.h>
|
|
@@ -25,8 +24,6 @@
|
|
#include <linux/mutex.h>
|
|
#include <linux/of_device.h>
|
|
|
|
-#define aux_to_hdp(x) container_of(x, struct imx_mhdp_device, aux)
|
|
-
|
|
/*
|
|
* This function only implements native DPDC reads and writes
|
|
*/
|
|
@@ -111,24 +108,24 @@ static void dp_pixel_clk_reset(struct cd
|
|
cdns_mhdp_reg_write(mhdp, SOURCE_HDTX_CAR, val);
|
|
}
|
|
|
|
-static void cdns_dp_mode_set(struct imx_mhdp_device *dp,
|
|
+static void cdns_dp_mode_set(struct cdns_mhdp_device *mhdp,
|
|
const struct drm_display_mode *mode)
|
|
{
|
|
struct drm_dp_link link;
|
|
- struct cdns_mhdp_device *mhdp = &dp->mhdp;
|
|
u32 lane_mapping = mhdp->lane_mapping;
|
|
int ret;
|
|
char linkid[6];
|
|
|
|
memcpy(&mhdp->mode, mode, sizeof(struct drm_display_mode));
|
|
|
|
- dp->dual_mode = video_is_dual_mode(mode);
|
|
+ //Sandor TODO
|
|
+// mhdp->dual_mode = video_is_dual_mode(mode);
|
|
|
|
dp_pixel_clk_reset(mhdp);
|
|
|
|
- hdp_plat_call(dp, pclock_change);
|
|
+ cdns_mhdp_plat_call(mhdp, pclk_rate);
|
|
|
|
- hdp_plat_call(dp, phy_init);
|
|
+ cdns_mhdp_plat_call(mhdp, phy_set);
|
|
|
|
ret = drm_dp_downstream_id(&mhdp->dp.aux, linkid);
|
|
if (ret < 0) {
|
|
@@ -168,7 +165,7 @@ static void cdns_dp_mode_set(struct imx_
|
|
/* initialize phy if lanes or link rate differnt */
|
|
if (mhdp->dp.link.num_lanes != mhdp->dp.num_lanes ||
|
|
mhdp->dp.link.rate != mhdp->dp.link_rate)
|
|
- hdp_plat_call(dp, phy_init);
|
|
+ cdns_mhdp_plat_call(mhdp, phy_set);
|
|
|
|
/* Video off */
|
|
ret = cdns_mhdp_set_video_status(mhdp, CONTROL_VIDEO_IDLE);
|
|
@@ -215,11 +212,11 @@ static void cdns_dp_mode_set(struct imx_
|
|
static enum drm_connector_status
|
|
cdns_dp_connector_detect(struct drm_connector *connector, bool force)
|
|
{
|
|
- struct imx_mhdp_device *dp = container_of(connector,
|
|
- struct imx_mhdp_device, mhdp.connector.base);
|
|
+ struct cdns_mhdp_device *mhdp = container_of(connector,
|
|
+ struct cdns_mhdp_device, connector.base);
|
|
u8 hpd = 0xf;
|
|
|
|
- hpd = cdns_mhdp_read_hpd(&dp->mhdp);
|
|
+ hpd = cdns_mhdp_read_hpd(mhdp);
|
|
if (hpd == 1)
|
|
/* Cable Connected */
|
|
return connector_status_connected;
|
|
@@ -235,15 +232,15 @@ cdns_dp_connector_detect(struct drm_conn
|
|
|
|
static int cdns_dp_connector_get_modes(struct drm_connector *connector)
|
|
{
|
|
- struct imx_mhdp_device *dp = container_of(connector,
|
|
- struct imx_mhdp_device, mhdp.connector.base);
|
|
+ struct cdns_mhdp_device *mhdp = container_of(connector,
|
|
+ struct cdns_mhdp_device, connector.base);
|
|
int num_modes = 0;
|
|
struct edid *edid;
|
|
|
|
- edid = drm_do_get_edid(&dp->mhdp.connector.base,
|
|
- cdns_mhdp_get_edid_block, &dp->mhdp);
|
|
+ edid = drm_do_get_edid(&mhdp->connector.base,
|
|
+ cdns_mhdp_get_edid_block, mhdp);
|
|
if (edid) {
|
|
- dev_info(dp->mhdp.dev, "%x,%x,%x,%x,%x,%x,%x,%x\n",
|
|
+ dev_info(mhdp->dev, "%x,%x,%x,%x,%x,%x,%x,%x\n",
|
|
edid->header[0], edid->header[1],
|
|
edid->header[2], edid->header[3],
|
|
edid->header[4], edid->header[5],
|
|
@@ -273,9 +270,9 @@ static const struct drm_connector_helper
|
|
|
|
static int cdns_dp_bridge_attach(struct drm_bridge *bridge)
|
|
{
|
|
- struct imx_mhdp_device *dp = bridge->driver_private;
|
|
+ struct cdns_mhdp_device *mhdp = bridge->driver_private;
|
|
struct drm_encoder *encoder = bridge->encoder;
|
|
- struct drm_connector *connector = &dp->mhdp.connector.base;
|
|
+ struct drm_connector *connector = &mhdp->connector.base;
|
|
|
|
connector->interlace_allowed = 1;
|
|
connector->polled = DRM_CONNECTOR_POLL_HPD;
|
|
@@ -319,9 +316,9 @@ static void cdns_dp_bridge_mode_set(stru
|
|
const struct drm_display_mode *orig_mode,
|
|
const struct drm_display_mode *mode)
|
|
{
|
|
- struct imx_mhdp_device *dp = bridge->driver_private;
|
|
- struct drm_display_info *display_info = &dp->mhdp.connector.base.display_info;
|
|
- struct video_info *video = &dp->mhdp.video_info;
|
|
+ struct cdns_mhdp_device *mhdp = bridge->driver_private;
|
|
+ struct drm_display_info *display_info = &mhdp->connector.base.display_info;
|
|
+ struct video_info *video = &mhdp->video_info;
|
|
|
|
switch (display_info->bpc) {
|
|
case 10:
|
|
@@ -341,11 +338,11 @@ static void cdns_dp_bridge_mode_set(stru
|
|
|
|
DRM_INFO("Mode: %dx%dp%d\n", mode->hdisplay, mode->vdisplay, mode->clock);
|
|
|
|
- mutex_lock(&dp->lock);
|
|
+ mutex_lock(&mhdp->lock);
|
|
|
|
- cdns_dp_mode_set(dp, mode);
|
|
+ cdns_dp_mode_set(mhdp, mode);
|
|
|
|
- mutex_unlock(&dp->lock);
|
|
+ mutex_unlock(&mhdp->lock);
|
|
}
|
|
|
|
static void cdn_hdp_bridge_enable(struct drm_bridge *bridge)
|
|
@@ -354,8 +351,7 @@ static void cdn_hdp_bridge_enable(struct
|
|
|
|
static void cdn_hdp_bridge_disable(struct drm_bridge *bridge)
|
|
{
|
|
- struct imx_mhdp_device *dp = bridge->driver_private;
|
|
- struct cdns_mhdp_device *mhdp = &dp->mhdp;
|
|
+ struct cdns_mhdp_device *mhdp = bridge->driver_private;
|
|
|
|
cdns_mhdp_set_video_status(mhdp, CONTROL_VIDEO_IDLE);
|
|
drm_dp_link_power_down(&mhdp->dp.aux, &mhdp->dp.link);
|
|
@@ -371,29 +367,29 @@ static const struct drm_bridge_funcs cdn
|
|
|
|
static void hotplug_work_func(struct work_struct *work)
|
|
{
|
|
- struct imx_mhdp_device *dp = container_of(work,
|
|
- struct imx_mhdp_device, hotplug_work.work);
|
|
- struct drm_connector *connector = &dp->mhdp.connector.base;
|
|
+ struct cdns_mhdp_device *mhdp = container_of(work,
|
|
+ struct cdns_mhdp_device, hotplug_work.work);
|
|
+ struct drm_connector *connector = &mhdp->connector.base;
|
|
|
|
drm_helper_hpd_irq_event(connector->dev);
|
|
|
|
if (connector->status == connector_status_connected) {
|
|
DRM_INFO("HDMI/DP Cable Plug In\n");
|
|
- enable_irq(dp->irq[IRQ_OUT]);
|
|
+ enable_irq(mhdp->irq[IRQ_OUT]);
|
|
} else if (connector->status == connector_status_disconnected) {
|
|
/* Cable Disconnedted */
|
|
DRM_INFO("HDMI/DP Cable Plug Out\n");
|
|
- enable_irq(dp->irq[IRQ_IN]);
|
|
+ enable_irq(mhdp->irq[IRQ_IN]);
|
|
}
|
|
}
|
|
|
|
static irqreturn_t cdns_dp_irq_thread(int irq, void *data)
|
|
{
|
|
- struct imx_mhdp_device *dp = data;
|
|
+ struct cdns_mhdp_device *mhdp = data;
|
|
|
|
disable_irq_nosync(irq);
|
|
|
|
- mod_delayed_work(system_wq, &dp->hotplug_work,
|
|
+ mod_delayed_work(system_wq, &mhdp->hotplug_work,
|
|
msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS));
|
|
|
|
return IRQ_HANDLED;
|
|
@@ -430,111 +426,92 @@ static void cdns_dp_parse_dt(struct cdns
|
|
mhdp->dp.link.rate= mhdp->dp.link_rate;
|
|
}
|
|
|
|
-static struct imx_mhdp_device *
|
|
-__cdns_dp_probe(struct platform_device *pdev,
|
|
- const struct cdn_plat_data *plat_data)
|
|
+static int __cdns_dp_probe(struct platform_device *pdev,
|
|
+ struct cdns_mhdp_device *mhdp)
|
|
{
|
|
struct device *dev = &pdev->dev;
|
|
- struct imx_mhdp_device *dp;
|
|
struct resource *iores = NULL;
|
|
int ret;
|
|
|
|
- dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL);
|
|
- if (!dp)
|
|
- return ERR_PTR(-ENOMEM);
|
|
-
|
|
- dp->plat_data = plat_data;
|
|
- dp->mhdp.dev = dev;
|
|
-
|
|
- mutex_init(&dp->lock);
|
|
- mutex_init(&dp->audio_mutex);
|
|
- spin_lock_init(&dp->audio_lock);
|
|
+ mutex_init(&mhdp->lock);
|
|
|
|
- INIT_DELAYED_WORK(&dp->hotplug_work, hotplug_work_func);
|
|
+ INIT_DELAYED_WORK(&mhdp->hotplug_work, hotplug_work_func);
|
|
|
|
iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
|
- dp->mhdp.regs = devm_ioremap(dev, iores->start, resource_size(iores));
|
|
- if (IS_ERR(dp->mhdp.regs)) {
|
|
- ret = PTR_ERR(dp->mhdp.regs);
|
|
- goto err_out;
|
|
- }
|
|
+ mhdp->regs_base = devm_ioremap(dev, iores->start, resource_size(iores));
|
|
+ if (IS_ERR(mhdp->regs_base))
|
|
+ return -ENOMEM;
|
|
|
|
-#if 0
|
|
iores = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
|
- dp->regs_ss = devm_ioremap(dev, iores->start, resource_size(iores));
|
|
- if (IS_ERR(dp->regs_ss)) {
|
|
- ret = PTR_ERR(dp->regs_ss);
|
|
- goto err_out;
|
|
- }
|
|
-#endif
|
|
+ mhdp->regs_sec = devm_ioremap(dev, iores->start, resource_size(iores));
|
|
+ if (IS_ERR(mhdp->regs_sec))
|
|
+ return -ENOMEM;
|
|
|
|
- dp->irq[IRQ_IN] = platform_get_irq_byname(pdev, "plug_in");
|
|
- if (dp->irq[IRQ_IN] < 0)
|
|
+ mhdp->irq[IRQ_IN] = platform_get_irq_byname(pdev, "plug_in");
|
|
+ if (mhdp->irq[IRQ_IN] < 0)
|
|
dev_info(dev, "No plug_in irq number\n");
|
|
|
|
- dp->irq[IRQ_OUT] = platform_get_irq_byname(pdev, "plug_out");
|
|
- if (dp->irq[IRQ_OUT] < 0)
|
|
+ mhdp->irq[IRQ_OUT] = platform_get_irq_byname(pdev, "plug_out");
|
|
+ if (mhdp->irq[IRQ_OUT] < 0)
|
|
dev_info(dev, "No plug_out irq number\n");
|
|
|
|
- cdns_dp_parse_dt(&dp->mhdp);
|
|
+ cdns_dp_parse_dt(mhdp);
|
|
|
|
- dp->dual_mode = false;
|
|
- hdp_plat_call(dp, fw_init);
|
|
+// mhdp->dual_mode = false;
|
|
+ cdns_mhdp_plat_call(mhdp, firmware_init);
|
|
|
|
/* DP FW alive check */
|
|
- ret = cdns_mhdp_check_alive(&dp->mhdp);
|
|
+ ret = cdns_mhdp_check_alive(mhdp);
|
|
if (ret == false) {
|
|
DRM_ERROR("NO dp FW running\n");
|
|
- return ERR_PTR(-ENXIO);
|
|
+ return -ENXIO;
|
|
}
|
|
|
|
/* DP PHY init before AUX init */
|
|
- hdp_plat_call(dp, phy_init);
|
|
+ cdns_mhdp_plat_call(mhdp, phy_set);
|
|
|
|
/* Enable Hotplug Detect IRQ thread */
|
|
- irq_set_status_flags(dp->irq[IRQ_IN], IRQ_NOAUTOEN);
|
|
- ret = devm_request_threaded_irq(dev, dp->irq[IRQ_IN],
|
|
+ irq_set_status_flags(mhdp->irq[IRQ_IN], IRQ_NOAUTOEN);
|
|
+ ret = devm_request_threaded_irq(dev, mhdp->irq[IRQ_IN],
|
|
NULL, cdns_dp_irq_thread,
|
|
IRQF_ONESHOT, dev_name(dev),
|
|
- dp);
|
|
+ mhdp);
|
|
if (ret) {
|
|
dev_err(dev, "can't claim irq %d\n",
|
|
- dp->irq[IRQ_IN]);
|
|
- goto err_out;
|
|
+ mhdp->irq[IRQ_IN]);
|
|
+ return -EINVAL;
|
|
}
|
|
|
|
- irq_set_status_flags(dp->irq[IRQ_OUT], IRQ_NOAUTOEN);
|
|
- ret = devm_request_threaded_irq(dev, dp->irq[IRQ_OUT],
|
|
+ irq_set_status_flags(mhdp->irq[IRQ_OUT], IRQ_NOAUTOEN);
|
|
+ ret = devm_request_threaded_irq(dev, mhdp->irq[IRQ_OUT],
|
|
NULL, cdns_dp_irq_thread,
|
|
IRQF_ONESHOT, dev_name(dev),
|
|
- dp);
|
|
+ mhdp);
|
|
if (ret) {
|
|
dev_err(dev, "can't claim irq %d\n",
|
|
- dp->irq[IRQ_OUT]);
|
|
- goto err_out;
|
|
+ mhdp->irq[IRQ_OUT]);
|
|
+ return -EINVAL;
|
|
}
|
|
- if (cdns_mhdp_read_hpd(&dp->mhdp))
|
|
- enable_irq(dp->irq[IRQ_OUT]);
|
|
+
|
|
+ if (cdns_mhdp_read_hpd(mhdp))
|
|
+ enable_irq(mhdp->irq[IRQ_OUT]);
|
|
else
|
|
- enable_irq(dp->irq[IRQ_IN]);
|
|
+ enable_irq(mhdp->irq[IRQ_IN]);
|
|
|
|
- dp->mhdp.bridge.base.driver_private = dp;
|
|
- dp->mhdp.bridge.base.funcs = &cdns_dp_bridge_funcs;
|
|
+ mhdp->bridge.base.driver_private = mhdp;
|
|
+ mhdp->bridge.base.funcs = &cdns_dp_bridge_funcs;
|
|
#ifdef CONFIG_OF
|
|
- dp->mhdp.bridge.base.of_node = dev->of_node;
|
|
+ mhdp->bridge.base.of_node = dev->of_node;
|
|
#endif
|
|
|
|
- dev_set_drvdata(dev, &dp->mhdp);
|
|
+ dev_set_drvdata(dev, mhdp);
|
|
|
|
/* register audio driver */
|
|
cdns_mhdp_register_audio_driver(dev);
|
|
|
|
- dp_aux_init(&dp->mhdp, dev);
|
|
-
|
|
- return dp;
|
|
+ dp_aux_init(mhdp, dev);
|
|
|
|
-err_out:
|
|
- return ERR_PTR(ret);
|
|
+ return 0;
|
|
}
|
|
|
|
static void __cdns_dp_remove(struct cdns_mhdp_device *mhdp)
|
|
@@ -547,15 +524,15 @@ static void __cdns_dp_remove(struct cdns
|
|
* Probe/remove API, used from platforms based on the DRM bridge API.
|
|
*/
|
|
int cdns_dp_probe(struct platform_device *pdev,
|
|
- const struct cdn_plat_data *plat_data)
|
|
+ struct cdns_mhdp_device *mhdp)
|
|
{
|
|
- struct imx_mhdp_device *dp;
|
|
+ int ret;
|
|
|
|
- dp = __cdns_dp_probe(pdev, plat_data);
|
|
- if (IS_ERR(dp))
|
|
- return PTR_ERR(dp);
|
|
+ ret = __cdns_dp_probe(pdev, mhdp);
|
|
+ if (ret)
|
|
+ return ret;
|
|
|
|
- drm_bridge_add(&dp->mhdp.bridge.base);
|
|
+ drm_bridge_add(&mhdp->bridge.base);
|
|
|
|
return 0;
|
|
}
|
|
@@ -575,16 +552,15 @@ EXPORT_SYMBOL_GPL(cdns_dp_remove);
|
|
* Bind/unbind API, used from platforms based on the component framework.
|
|
*/
|
|
int cdns_dp_bind(struct platform_device *pdev, struct drm_encoder *encoder,
|
|
- const struct cdn_plat_data *plat_data)
|
|
+ struct cdns_mhdp_device *mhdp)
|
|
{
|
|
- struct imx_mhdp_device *dp;
|
|
int ret;
|
|
|
|
- dp = __cdns_dp_probe(pdev, plat_data);
|
|
- if (IS_ERR(dp))
|
|
- return PTR_ERR(dp);
|
|
+ ret = __cdns_dp_probe(pdev, mhdp);
|
|
+ if (ret < 0)
|
|
+ return ret;
|
|
|
|
- ret = drm_bridge_attach(encoder, &dp->mhdp.bridge.base, NULL);
|
|
+ ret = drm_bridge_attach(encoder, &mhdp->bridge.base, NULL);
|
|
if (ret) {
|
|
cdns_dp_remove(pdev);
|
|
DRM_ERROR("Failed to initialize bridge with drm\n");
|
|
--- a/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c
|
|
+++ b/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c
|
|
@@ -9,7 +9,7 @@
|
|
* (at your option) any later version.
|
|
*
|
|
*/
|
|
-#include <drm/bridge/cdns-mhdp-imx.h>
|
|
+#include <drm/bridge/cdns-mhdp-common.h>
|
|
#include <drm/drm_atomic_helper.h>
|
|
#include <drm/drm_crtc_helper.h>
|
|
#include <drm/drm_edid.h>
|
|
@@ -60,8 +60,6 @@ static int hdmi_sink_config(struct cdns_
|
|
static void hdmi_lanes_config(struct cdns_mhdp_device *mhdp)
|
|
{
|
|
/* Line swaping */
|
|
- /* For imx8qm lane_mapping = 0x93
|
|
- * For imx8mq lane_mapping = 0xe4*/
|
|
cdns_mhdp_reg_write(mhdp, LANES_CONFIG, 0x00400000 | mhdp->lane_mapping);
|
|
}
|
|
|
|
@@ -216,12 +214,12 @@ void cdns_hdmi_mode_set(struct cdns_mhdp
|
|
static enum drm_connector_status
|
|
cdns_hdmi_connector_detect(struct drm_connector *connector, bool force)
|
|
{
|
|
- struct imx_mhdp_device *hdmi =
|
|
- container_of(connector, struct imx_mhdp_device, mhdp.connector.base);
|
|
+ struct cdns_mhdp_device *mhdp =
|
|
+ container_of(connector, struct cdns_mhdp_device, connector.base);
|
|
|
|
u8 hpd = 0xf;
|
|
|
|
- hpd = cdns_mhdp_read_hpd(&hdmi->mhdp);
|
|
+ hpd = cdns_mhdp_read_hpd(mhdp);
|
|
|
|
if (hpd == 1)
|
|
/* Cable Connected */
|
|
@@ -238,15 +236,15 @@ cdns_hdmi_connector_detect(struct drm_co
|
|
|
|
static int cdns_hdmi_connector_get_modes(struct drm_connector *connector)
|
|
{
|
|
- struct imx_mhdp_device *hdmi = container_of(connector, struct imx_mhdp_device,
|
|
- mhdp.connector.base);
|
|
+ struct cdns_mhdp_device *mhdp =
|
|
+ container_of(connector, struct cdns_mhdp_device, connector.base);
|
|
int num_modes = 0;
|
|
struct edid *edid;
|
|
|
|
- edid = drm_do_get_edid(&hdmi->mhdp.connector.base,
|
|
- cdns_hdmi_get_edid_block, &hdmi->mhdp);
|
|
+ edid = drm_do_get_edid(&mhdp->connector.base,
|
|
+ cdns_hdmi_get_edid_block, mhdp);
|
|
if (edid) {
|
|
- dev_info(hdmi->mhdp.dev, "%x,%x,%x,%x,%x,%x,%x,%x\n",
|
|
+ dev_info(mhdp->dev, "%x,%x,%x,%x,%x,%x,%x,%x\n",
|
|
edid->header[0], edid->header[1],
|
|
edid->header[2], edid->header[3],
|
|
edid->header[4], edid->header[5],
|
|
@@ -276,9 +274,9 @@ static const struct drm_connector_helper
|
|
|
|
static int cdns_hdmi_bridge_attach(struct drm_bridge *bridge)
|
|
{
|
|
- struct imx_mhdp_device *hdmi = bridge->driver_private;
|
|
+ struct cdns_mhdp_device *mhdp = bridge->driver_private;
|
|
struct drm_encoder *encoder = bridge->encoder;
|
|
- struct drm_connector *connector = &hdmi->mhdp.connector.base;
|
|
+ struct drm_connector *connector = &mhdp->connector.base;
|
|
|
|
connector->interlace_allowed = 1;
|
|
connector->polled = DRM_CONNECTOR_POLL_HPD;
|
|
@@ -319,9 +317,9 @@ static void cdns_hdmi_bridge_mode_set(st
|
|
const struct drm_display_mode *orig_mode,
|
|
const struct drm_display_mode *mode)
|
|
{
|
|
- struct imx_mhdp_device *hdmi = bridge->driver_private;
|
|
- struct drm_display_info *display_info = &hdmi->mhdp.connector.base.display_info;
|
|
- struct video_info *video = &hdmi->mhdp.video_info;
|
|
+ struct cdns_mhdp_device *mhdp = bridge->driver_private;
|
|
+ struct drm_display_info *display_info = &mhdp->connector.base.display_info;
|
|
+ struct video_info *video = &mhdp->video_info;
|
|
|
|
switch (display_info->bpc) {
|
|
case 10:
|
|
@@ -339,23 +337,24 @@ static void cdns_hdmi_bridge_mode_set(st
|
|
video->v_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NVSYNC);
|
|
video->h_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NHSYNC);
|
|
|
|
- mutex_lock(&hdmi->lock);
|
|
+ mutex_lock(&mhdp->lock);
|
|
|
|
DRM_INFO("Mode: %dx%dp%d\n", mode->hdisplay, mode->vdisplay, mode->clock);
|
|
|
|
- memcpy(&hdmi->mhdp.mode, mode, sizeof(struct drm_display_mode));
|
|
+ memcpy(&mhdp->mode, mode, sizeof(struct drm_display_mode));
|
|
|
|
- hdmi->dual_mode = video_is_dual_mode(mode);
|
|
+ //Sandor TODO
|
|
+// hdmi->dual_mode = video_is_dual_mode(mode);
|
|
|
|
- hdmi_lanes_config(&hdmi->mhdp);
|
|
+ hdmi_lanes_config(mhdp);
|
|
|
|
- hdp_plat_call(hdmi, pclock_change);
|
|
+ cdns_mhdp_plat_call(mhdp, pclk_rate);
|
|
|
|
- hdp_plat_call(hdmi, phy_init);
|
|
+ cdns_mhdp_plat_call(mhdp, phy_set);
|
|
|
|
- cdns_hdmi_mode_set(&hdmi->mhdp);
|
|
+ cdns_hdmi_mode_set(mhdp);
|
|
|
|
- mutex_unlock(&hdmi->lock);
|
|
+ mutex_unlock(&mhdp->lock);
|
|
}
|
|
|
|
static const struct drm_bridge_funcs cdns_hdmi_bridge_funcs = {
|
|
@@ -366,30 +365,30 @@ static const struct drm_bridge_funcs cdn
|
|
|
|
static void hotplug_work_func(struct work_struct *work)
|
|
{
|
|
- struct imx_mhdp_device *hdmi = container_of(work,
|
|
- struct imx_mhdp_device, hotplug_work.work);
|
|
- struct drm_connector *connector = &hdmi->mhdp.connector.base;
|
|
+ struct cdns_mhdp_device *mhdp = container_of(work,
|
|
+ struct cdns_mhdp_device, hotplug_work.work);
|
|
+ struct drm_connector *connector = &mhdp->connector.base;
|
|
|
|
drm_helper_hpd_irq_event(connector->dev);
|
|
|
|
if (connector->status == connector_status_connected) {
|
|
/* Cable Connected */
|
|
DRM_INFO("HDMI Cable Plug In\n");
|
|
- enable_irq(hdmi->irq[IRQ_OUT]);
|
|
+ enable_irq(mhdp->irq[IRQ_OUT]);
|
|
} else if (connector->status == connector_status_disconnected) {
|
|
/* Cable Disconnedted */
|
|
DRM_INFO("HDMI Cable Plug Out\n");
|
|
- enable_irq(hdmi->irq[IRQ_IN]);
|
|
+ enable_irq(mhdp->irq[IRQ_IN]);
|
|
}
|
|
}
|
|
|
|
static irqreturn_t cdns_hdmi_irq_thread(int irq, void *data)
|
|
{
|
|
- struct imx_mhdp_device *hdmi = data;
|
|
+ struct cdns_mhdp_device *mhdp = data;
|
|
|
|
disable_irq_nosync(irq);
|
|
|
|
- mod_delayed_work(system_wq, &hdmi->hotplug_work,
|
|
+ mod_delayed_work(system_wq, &mhdp->hotplug_work,
|
|
msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS));
|
|
|
|
return IRQ_HANDLED;
|
|
@@ -408,109 +407,99 @@ static void cdns_hdmi_parse_dt(struct cd
|
|
dev_info(mhdp->dev, "lane-mapping 0x%02x\n", mhdp->lane_mapping);
|
|
}
|
|
|
|
-static struct imx_mhdp_device *
|
|
-__cdns_hdmi_probe(struct platform_device *pdev,
|
|
- const struct cdn_plat_data *plat_data)
|
|
+static int __cdns_hdmi_probe(struct platform_device *pdev,
|
|
+ struct cdns_mhdp_device *mhdp)
|
|
{
|
|
struct device *dev = &pdev->dev;
|
|
- struct device_node *np = dev->of_node;
|
|
struct platform_device_info pdevinfo;
|
|
- struct imx_mhdp_device *hdmi;
|
|
struct resource *iores = NULL;
|
|
int ret;
|
|
|
|
- hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
|
|
- if (!hdmi)
|
|
- return ERR_PTR(-ENOMEM);
|
|
-
|
|
- hdmi->plat_data = plat_data;
|
|
- hdmi->mhdp.dev = dev;
|
|
-
|
|
- mutex_init(&hdmi->lock);
|
|
- mutex_init(&hdmi->audio_mutex);
|
|
- spin_lock_init(&hdmi->audio_lock);
|
|
+ mutex_init(&mhdp->lock);
|
|
|
|
- INIT_DELAYED_WORK(&hdmi->hotplug_work, hotplug_work_func);
|
|
+ INIT_DELAYED_WORK(&mhdp->hotplug_work, hotplug_work_func);
|
|
|
|
iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
|
- hdmi->mhdp.regs = devm_ioremap(dev, iores->start, resource_size(iores));
|
|
- if (IS_ERR(hdmi->mhdp.regs)) {
|
|
- ret = PTR_ERR(hdmi->mhdp.regs);
|
|
- goto err_out;
|
|
+ mhdp->regs_base = devm_ioremap(dev, iores->start, resource_size(iores));
|
|
+ if (IS_ERR(mhdp->regs_base)) {
|
|
+ dev_err(dev, "No regs_base memory\n");
|
|
+ return -ENOMEM;
|
|
+ }
|
|
+
|
|
+ /* sec register base */
|
|
+ iores = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
|
+ mhdp->regs_sec = devm_ioremap(dev, iores->start, resource_size(iores));
|
|
+ if (IS_ERR(mhdp->regs_sec)) {
|
|
+ dev_err(dev, "No regs_sec memory\n");
|
|
+ return -ENOMEM;
|
|
}
|
|
|
|
- /* csr register base */
|
|
- hdmi->regmap_csr = syscon_regmap_lookup_by_phandle(np, "csr");
|
|
- if (IS_ERR(hdmi->regmap_csr)) {
|
|
- dev_info(dev, "No csr regmap\n");
|
|
- }
|
|
-
|
|
- hdmi->irq[IRQ_IN] = platform_get_irq_byname(pdev, "plug_in");
|
|
- if (hdmi->irq[IRQ_IN] < 0) {
|
|
+ mhdp->irq[IRQ_IN] = platform_get_irq_byname(pdev, "plug_in");
|
|
+ if (mhdp->irq[IRQ_IN] < 0) {
|
|
dev_info(dev, "No plug_in irq number\n");
|
|
- return ERR_PTR(-EPROBE_DEFER);
|
|
+ return -EPROBE_DEFER;
|
|
}
|
|
|
|
- hdmi->irq[IRQ_OUT] = platform_get_irq_byname(pdev, "plug_out");
|
|
- if (hdmi->irq[IRQ_OUT] < 0) {
|
|
+ mhdp->irq[IRQ_OUT] = platform_get_irq_byname(pdev, "plug_out");
|
|
+ if (mhdp->irq[IRQ_OUT] < 0) {
|
|
dev_info(dev, "No plug_out irq number\n");
|
|
- return ERR_PTR(-EPROBE_DEFER);
|
|
+ return -EPROBE_DEFER;
|
|
}
|
|
|
|
/* Initialize dual_mode to false */
|
|
- hdmi->dual_mode = false;
|
|
+// hdmi->dual_mode = false;
|
|
|
|
/* Initialize FW */
|
|
- hdp_plat_call(hdmi, fw_init);
|
|
+ cdns_mhdp_plat_call(mhdp, firmware_init);
|
|
|
|
/* HDMI FW alive check */
|
|
- ret = cdns_mhdp_check_alive(&hdmi->mhdp);
|
|
+ ret = cdns_mhdp_check_alive(mhdp);
|
|
if (ret == false) {
|
|
- DRM_ERROR("NO HDMI FW running\n");
|
|
- return ERR_PTR(-ENXIO);
|
|
+ dev_err(dev, "NO HDMI FW running\n");
|
|
+ return -ENXIO;
|
|
}
|
|
|
|
/* Enable Hotplug Detect thread */
|
|
- irq_set_status_flags(hdmi->irq[IRQ_IN], IRQ_NOAUTOEN);
|
|
- ret = devm_request_threaded_irq(dev, hdmi->irq[IRQ_IN],
|
|
+ irq_set_status_flags(mhdp->irq[IRQ_IN], IRQ_NOAUTOEN);
|
|
+ ret = devm_request_threaded_irq(dev, mhdp->irq[IRQ_IN],
|
|
NULL, cdns_hdmi_irq_thread,
|
|
IRQF_ONESHOT, dev_name(dev),
|
|
- hdmi);
|
|
- if (ret) {
|
|
+ mhdp);
|
|
+ if (ret < 0) {
|
|
dev_err(dev, "can't claim irq %d\n",
|
|
- hdmi->irq[IRQ_IN]);
|
|
- goto err_out;
|
|
+ mhdp->irq[IRQ_IN]);
|
|
+ return -EINVAL;
|
|
}
|
|
|
|
- irq_set_status_flags(hdmi->irq[IRQ_OUT], IRQ_NOAUTOEN);
|
|
- ret = devm_request_threaded_irq(dev, hdmi->irq[IRQ_OUT],
|
|
+ irq_set_status_flags(mhdp->irq[IRQ_OUT], IRQ_NOAUTOEN);
|
|
+ ret = devm_request_threaded_irq(dev, mhdp->irq[IRQ_OUT],
|
|
NULL, cdns_hdmi_irq_thread,
|
|
IRQF_ONESHOT, dev_name(dev),
|
|
- hdmi);
|
|
- if (ret) {
|
|
+ mhdp);
|
|
+ if (ret < 0) {
|
|
dev_err(dev, "can't claim irq %d\n",
|
|
- hdmi->irq[IRQ_OUT]);
|
|
- goto err_out;
|
|
+ mhdp->irq[IRQ_OUT]);
|
|
+ return -EINVAL;
|
|
}
|
|
|
|
- cdns_hdmi_parse_dt(&hdmi->mhdp);
|
|
+ cdns_hdmi_parse_dt(mhdp);
|
|
|
|
- if (cdns_mhdp_read_hpd(&hdmi->mhdp))
|
|
- enable_irq(hdmi->irq[IRQ_OUT]);
|
|
+ if (cdns_mhdp_read_hpd(mhdp))
|
|
+ enable_irq(mhdp->irq[IRQ_OUT]);
|
|
else
|
|
- enable_irq(hdmi->irq[IRQ_IN]);
|
|
+ enable_irq(mhdp->irq[IRQ_IN]);
|
|
|
|
- hdmi->mhdp.bridge.base.driver_private = hdmi;
|
|
- hdmi->mhdp.bridge.base.funcs = &cdns_hdmi_bridge_funcs;
|
|
+ mhdp->bridge.base.driver_private = mhdp;
|
|
+ mhdp->bridge.base.funcs = &cdns_hdmi_bridge_funcs;
|
|
#ifdef CONFIG_OF
|
|
- hdmi->mhdp.bridge.base.of_node = dev->of_node;
|
|
+ mhdp->bridge.base.of_node = dev->of_node;
|
|
#endif
|
|
|
|
memset(&pdevinfo, 0, sizeof(pdevinfo));
|
|
pdevinfo.parent = dev;
|
|
pdevinfo.id = PLATFORM_DEVID_AUTO;
|
|
|
|
- dev_set_drvdata(dev, &hdmi->mhdp);
|
|
+ dev_set_drvdata(dev, mhdp);
|
|
|
|
/* register audio driver */
|
|
cdns_mhdp_register_audio_driver(dev);
|
|
@@ -520,11 +509,7 @@ __cdns_hdmi_probe(struct platform_device
|
|
cdns_mhdp_register_cec_driver(dev);
|
|
#endif
|
|
|
|
- return hdmi;
|
|
-
|
|
-err_out:
|
|
-
|
|
- return ERR_PTR(ret);
|
|
+ return 0;
|
|
}
|
|
|
|
static void __cdns_hdmi_remove(struct cdns_mhdp_device *mhdp)
|
|
@@ -540,15 +525,15 @@ static void __cdns_hdmi_remove(struct cd
|
|
* Probe/remove API, used from platforms based on the DRM bridge API.
|
|
*/
|
|
int cdns_hdmi_probe(struct platform_device *pdev,
|
|
- const struct cdn_plat_data *plat_data)
|
|
+ struct cdns_mhdp_device *mhdp)
|
|
{
|
|
- struct imx_mhdp_device *hdmi;
|
|
+ int ret;
|
|
|
|
- hdmi = __cdns_hdmi_probe(pdev, plat_data);
|
|
- if (IS_ERR(hdmi))
|
|
- return PTR_ERR(hdmi);
|
|
+ ret = __cdns_hdmi_probe(pdev, mhdp);
|
|
+ if (ret < 0)
|
|
+ return ret;
|
|
|
|
- drm_bridge_add(&hdmi->mhdp.bridge.base);
|
|
+ drm_bridge_add(&mhdp->bridge.base);
|
|
|
|
return 0;
|
|
}
|
|
@@ -568,16 +553,15 @@ EXPORT_SYMBOL_GPL(cdns_hdmi_remove);
|
|
* Bind/unbind API, used from platforms based on the component framework.
|
|
*/
|
|
int cdns_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder,
|
|
- const struct cdn_plat_data *plat_data)
|
|
+ struct cdns_mhdp_device *mhdp)
|
|
{
|
|
- struct imx_mhdp_device *hdmi;
|
|
int ret;
|
|
|
|
- hdmi = __cdns_hdmi_probe(pdev, plat_data);
|
|
- if (IS_ERR(hdmi))
|
|
- return PTR_ERR(hdmi);
|
|
+ ret = __cdns_hdmi_probe(pdev, mhdp);
|
|
+ if (ret)
|
|
+ return ret;
|
|
|
|
- ret = drm_bridge_attach(encoder, &hdmi->mhdp.bridge.base, NULL);
|
|
+ ret = drm_bridge_attach(encoder, &mhdp->bridge.base, NULL);
|
|
if (ret) {
|
|
cdns_hdmi_remove(pdev);
|
|
DRM_ERROR("Failed to initialize bridge with drm\n");
|
|
--- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp-audio.c
|
|
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp-audio.c
|
|
@@ -16,7 +16,6 @@
|
|
#include <linux/reset.h>
|
|
#include <drm/bridge/cdns-mhdp-common.h>
|
|
#include <sound/hdmi-codec.h>
|
|
-#include <drm/bridge/cdns-mhdp-imx.h>
|
|
#include <drm/drm_of.h>
|
|
#include <drm/drmP.h>
|
|
|
|
--- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp-cec.c
|
|
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp-cec.c
|
|
@@ -344,4 +344,4 @@ int cdns_mhdp_unregister_cec_driver(stru
|
|
|
|
MODULE_AUTHOR("Sandor.Yu@NXP.com");
|
|
MODULE_LICENSE("GPL");
|
|
-MODULE_DESCRIPTION("NXP CDNS MHDP CEC driver");
|
|
+MODULE_DESCRIPTION("NXP CDNS MHDP HDMI CEC driver");
|
|
--- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp-common.c
|
|
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp-common.c
|
|
@@ -23,7 +23,6 @@
|
|
#include <asm/unaligned.h>
|
|
|
|
#include <drm/bridge/cdns-mhdp-common.h>
|
|
-#include <drm/bridge/cdns-mhdp-imx.h>
|
|
#include <drm/drm_modes.h>
|
|
#include <drm/drm_print.h>
|
|
#include <linux/regmap.h>
|
|
@@ -74,18 +73,20 @@ static inline void put_unaligned_be24(u3
|
|
|
|
u32 cdns_mhdp_bus_read(struct cdns_mhdp_device *mhdp, u32 offset)
|
|
{
|
|
- struct imx_mhdp_device *hdmi = container_of(mhdp, struct imx_mhdp_device, mhdp);
|
|
u32 val;
|
|
|
|
- /* TODO */
|
|
- if (offset >= 0x1000 && hdmi->regmap_csr) {
|
|
+ if (mhdp->bus_type == BUS_TYPE_LOW4K_SAPB) {
|
|
+ /* Remap address to low 4K SAPB bus */
|
|
+ writel(offset >> 12, mhdp->regs_sec + 0xc);
|
|
+ val = readl((offset & 0xfff) + mhdp->regs_base);
|
|
+ } else if (mhdp->bus_type == BUS_TYPE_LOW4K_APB) {
|
|
/* Remap address to low 4K memory */
|
|
- regmap_write(hdmi->regmap_csr, hdmi->csr_ctrl0_reg, offset >> 12);
|
|
- val = readl((offset & 0xfff) + mhdp->regs);
|
|
- /* Restore address mapping */
|
|
- regmap_write(hdmi->regmap_csr, hdmi->csr_ctrl0_reg, 0);
|
|
- } else
|
|
- val = readl(mhdp->regs + offset);
|
|
+ writel(offset >> 12, mhdp->regs_sec + 8);
|
|
+ val = readl((offset & 0xfff) + mhdp->regs_base);
|
|
+ } else if (mhdp->bus_type == BUS_TYPE_NORMAL_SAPB)
|
|
+ val = readl(mhdp->regs_sec + offset);
|
|
+ else
|
|
+ val = readl(mhdp->regs_base + offset);
|
|
|
|
return val;
|
|
}
|
|
@@ -93,18 +94,18 @@ EXPORT_SYMBOL(cdns_mhdp_bus_read);
|
|
|
|
void cdns_mhdp_bus_write(u32 val, struct cdns_mhdp_device *mhdp, u32 offset)
|
|
{
|
|
- struct imx_mhdp_device *hdmi = container_of(mhdp, struct imx_mhdp_device, mhdp);
|
|
-
|
|
- /* TODO */
|
|
- if (offset >= 0x1000 && hdmi->regmap_csr) {
|
|
+ if (mhdp->bus_type == BUS_TYPE_LOW4K_SAPB) {
|
|
+ /* Remap address to low 4K SAPB bus */
|
|
+ writel(offset >> 12, mhdp->regs_sec + 0xc);
|
|
+ writel(val, (offset & 0xfff) + mhdp->regs_base);
|
|
+ } else if (mhdp->bus_type == BUS_TYPE_LOW4K_APB) {
|
|
/* Remap address to low 4K memory */
|
|
- regmap_write(hdmi->regmap_csr, hdmi->csr_ctrl0_reg, offset >> 12);
|
|
- writel(val, (offset & 0xfff) + mhdp->regs);
|
|
- /* Restore address mapping */
|
|
- regmap_write(hdmi->regmap_csr, hdmi->csr_ctrl0_reg, 0);
|
|
-
|
|
- } else
|
|
- writel(val, mhdp->regs + offset);
|
|
+ writel(offset >> 12, mhdp->regs_sec + 8);
|
|
+ writel(val, (offset & 0xfff) + mhdp->regs_base);
|
|
+ } else if (mhdp->bus_type == BUS_TYPE_NORMAL_SAPB)
|
|
+ writel(val, mhdp->regs_sec + offset);
|
|
+ else
|
|
+ writel(val, mhdp->regs_base + offset);
|
|
}
|
|
EXPORT_SYMBOL(cdns_mhdp_bus_write);
|
|
|
|
--- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp-hdmi.c
|
|
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp-hdmi.c
|
|
@@ -10,7 +10,6 @@
|
|
#include <drm/drmP.h>
|
|
#include <linux/io.h>
|
|
#include <drm/bridge/cdns-mhdp-common.h>
|
|
-#include <drm/bridge/cdns-mhdp-imx.h>
|
|
#include <linux/regmap.h>
|
|
|
|
void cdns_mhdp_infoframe_set(struct cdns_mhdp_device *mhdp,
|
|
--- a/include/drm/bridge/cdns-mhdp-common.h
|
|
+++ b/include/drm/bridge/cdns-mhdp-common.h
|
|
@@ -495,6 +495,22 @@
|
|
|
|
#define HOTPLUG_DEBOUNCE_MS 200
|
|
|
|
+#define IRQ_IN 0
|
|
+#define IRQ_OUT 1
|
|
+#define IRQ_NUM 2
|
|
+
|
|
+#define cdns_mhdp_plat_call(mhdp, operation) \
|
|
+ (!(mhdp) ? -ENODEV : (((mhdp)->plat_data && (mhdp)->plat_data->operation) ? \
|
|
+ (mhdp)->plat_data->operation(mhdp) : ENOIOCTLCMD))
|
|
+
|
|
+/* bus access type */
|
|
+enum {
|
|
+ BUS_TYPE_NORMAL_APB = 0,
|
|
+ BUS_TYPE_NORMAL_SAPB = 1,
|
|
+ BUS_TYPE_LOW4K_APB = 2,
|
|
+ BUS_TYPE_LOW4K_SAPB = 3,
|
|
+};
|
|
+
|
|
enum voltage_swing_level {
|
|
VOLTAGE_LEVEL_0,
|
|
VOLTAGE_LEVEL_1,
|
|
@@ -616,8 +632,33 @@ struct cdns_mhdp_cec {
|
|
};
|
|
#endif
|
|
|
|
+struct cdns_plat_data {
|
|
+ /* Vendor PHY support */
|
|
+ int (*bind)(struct platform_device *pdev,
|
|
+ struct drm_encoder *encoder,
|
|
+ struct cdns_mhdp_device *mhdp);
|
|
+ void (*unbind)(struct device *dev);
|
|
+
|
|
+ void (*plat_init)(struct cdns_mhdp_device *mhdp);
|
|
+ void (*plat_deinit)(struct cdns_mhdp_device *mhdp);
|
|
+
|
|
+ int (*phy_set)(struct cdns_mhdp_device *mhdp);
|
|
+ int (*firmware_init)(struct cdns_mhdp_device *mhdp);
|
|
+ void (*pclk_rate)(struct cdns_mhdp_device *mhdp);
|
|
+
|
|
+ int (*power_on)(struct cdns_mhdp_device *mhdp);
|
|
+ int (*power_off)(struct cdns_mhdp_device *mhdp);
|
|
+
|
|
+ int bus_type;
|
|
+ int video_format;
|
|
+ char is_dp;
|
|
+};
|
|
+
|
|
struct cdns_mhdp_device {
|
|
- void __iomem *regs;
|
|
+ void __iomem *regs_base;
|
|
+ void __iomem *regs_sec;
|
|
+
|
|
+ int bus_type;
|
|
|
|
struct device *dev;
|
|
|
|
@@ -642,6 +683,9 @@ struct cdns_mhdp_device {
|
|
bool link_up;
|
|
bool power_up;
|
|
bool plugged;
|
|
+ struct mutex lock;
|
|
+
|
|
+ int irq[IRQ_NUM];
|
|
|
|
union {
|
|
struct _dp_data {
|
|
@@ -663,6 +707,8 @@ struct cdns_mhdp_device {
|
|
u32 hdmi_type;
|
|
} hdmi;
|
|
};
|
|
+ const struct cdns_plat_data *plat_data;
|
|
+
|
|
};
|
|
|
|
u32 cdns_mhdp_bus_read(struct cdns_mhdp_device *mhdp, u32 offset);
|
|
@@ -727,6 +773,25 @@ int cdns_hdmi_disable_gcp(struct cdns_mh
|
|
int cdns_hdmi_enable_gcp(struct cdns_mhdp_device *mhdp);
|
|
|
|
bool cdns_mhdp_check_alive(struct cdns_mhdp_device *mhdp);
|
|
+
|
|
+/* HDMI */
|
|
+int cdns_hdmi_probe(struct platform_device *pdev,
|
|
+ struct cdns_mhdp_device *mhdp);
|
|
+void cdns_hdmi_remove(struct platform_device *pdev);
|
|
+void cdns_hdmi_unbind(struct device *dev);
|
|
+int cdns_hdmi_bind(struct platform_device *pdev,
|
|
+ struct drm_encoder *encoder, struct cdns_mhdp_device *mhdp);
|
|
+void cdns_hdmi_set_sample_rate(struct cdns_mhdp_device *mhdp, unsigned int rate);
|
|
+void cdns_hdmi_audio_enable(struct cdns_mhdp_device *mhdp);
|
|
+void cdns_hdmi_audio_disable(struct cdns_mhdp_device *mhdp);
|
|
+/* DP */
|
|
+int cdns_dp_probe(struct platform_device *pdev,
|
|
+ struct cdns_mhdp_device *mhdp);
|
|
+void cdns_dp_remove(struct platform_device *pdev);
|
|
+void cdns_dp_unbind(struct device *dev);
|
|
+int cdns_dp_bind(struct platform_device *pdev,
|
|
+ struct drm_encoder *encoder, struct cdns_mhdp_device *mhdp);
|
|
+
|
|
/* CEC */
|
|
#ifdef CONFIG_DRM_CDNS_HDMI_CEC
|
|
int cdns_mhdp_register_cec_driver(struct device *dev);
|
|
--- a/include/drm/bridge/cdns-mhdp-imx.h
|
|
+++ /dev/null
|
|
@@ -1,121 +0,0 @@
|
|
-/*
|
|
- * Cadence High-Definition Multimedia Interface (HDMI) driver
|
|
- *
|
|
- * Copyright (C) 2019 NXP Semiconductor, Inc.
|
|
- *
|
|
- * This program is free software; you can redistribute it and/or modify
|
|
- * it under the terms of the GNU General Public License as published by
|
|
- * the Free Software Foundation; either version 2 of the License, or
|
|
- * (at your option) any later version.
|
|
- *
|
|
- */
|
|
-#ifndef CDNS_MHDP_IMX_H_
|
|
-#define CDNS_MHDP_IMX_H_
|
|
-
|
|
-#include <drm/bridge/cdns-mhdp-common.h>
|
|
-
|
|
-#define IRQ_IN 0
|
|
-#define IRQ_OUT 1
|
|
-#define IRQ_NUM 2
|
|
-
|
|
-#define hdp_plat_call(hdp, operation) \
|
|
- (!(hdp) ? -ENODEV : (((hdp)->plat_data && (hdp)->plat_data->operation) ? \
|
|
- (hdp)->plat_data->operation(hdp) : ENOIOCTLCMD))
|
|
-
|
|
-#define HDP_DUAL_MODE_MIN_PCLK_RATE 300000 /* KHz */
|
|
-#define HDP_SINGLE_MODE_MAX_WIDTH 1920
|
|
-
|
|
-static inline bool video_is_dual_mode(const struct drm_display_mode *mode)
|
|
-{
|
|
- return (mode->clock > HDP_DUAL_MODE_MIN_PCLK_RATE ||
|
|
- mode->hdisplay > HDP_SINGLE_MODE_MAX_WIDTH) ? true : false;
|
|
-}
|
|
-
|
|
-struct imx_mhdp_device;
|
|
-
|
|
-struct imx_hdp_clks {
|
|
- struct clk *av_pll;
|
|
- struct clk *dig_pll;
|
|
- struct clk *clk_ipg;
|
|
- struct clk *clk_core;
|
|
- struct clk *clk_pxl;
|
|
- struct clk *clk_pxl_mux;
|
|
- struct clk *clk_pxl_link;
|
|
-
|
|
- struct clk *lpcg_hdp;
|
|
- struct clk *lpcg_msi;
|
|
- struct clk *lpcg_pxl;
|
|
- struct clk *lpcg_vif;
|
|
- struct clk *lpcg_lis;
|
|
- struct clk *lpcg_apb;
|
|
- struct clk *lpcg_apb_csr;
|
|
- struct clk *lpcg_apb_ctrl;
|
|
-
|
|
- struct clk *lpcg_i2s;
|
|
- struct clk *clk_i2s_bypass;
|
|
-};
|
|
-
|
|
-struct cdn_plat_data {
|
|
- /* Vendor PHY support */
|
|
- int (*phy_init)(struct imx_mhdp_device *hdmi);
|
|
- int (*bind)(struct platform_device *pdev,
|
|
- struct drm_encoder *encoder,
|
|
- const struct cdn_plat_data *plat_data);
|
|
- void (*unbind)(struct device *dev);
|
|
- int (*fw_init)(struct imx_mhdp_device *hdp);
|
|
- void (*pclock_change)(struct imx_mhdp_device *hdp);
|
|
- char is_dp;
|
|
-};
|
|
-
|
|
-struct imx_mhdp_device {
|
|
- struct cdns_mhdp_device mhdp;
|
|
-
|
|
- struct mutex lock;
|
|
- struct mutex audio_mutex;
|
|
- spinlock_t audio_lock;
|
|
- bool connected;
|
|
- bool active;
|
|
- bool suspended;
|
|
- struct imx_hdp_clks clks;
|
|
-
|
|
- const struct cdn_plat_data *plat_data;
|
|
-
|
|
- int irq[IRQ_NUM];
|
|
- struct delayed_work hotplug_work;
|
|
- //void __iomem *regmap_csr;
|
|
- struct regmap *regmap_csr;
|
|
- u32 csr_pxl_mux_reg;
|
|
- u32 csr_ctrl0_reg;
|
|
- u32 csr_ctrl0_sec;
|
|
-
|
|
- struct audio_info audio_info;
|
|
- bool sink_has_audio;
|
|
- u32 dual_mode;
|
|
-
|
|
- struct device *pd_mhdp_dev;
|
|
- struct device *pd_pll0_dev;
|
|
- struct device *pd_pll1_dev;
|
|
- struct device_link *pd_mhdp_link;
|
|
- struct device_link *pd_pll0_link;
|
|
- struct device_link *pd_pll1_link;
|
|
-
|
|
- u32 phy_init;
|
|
-};
|
|
-
|
|
-int cdns_hdmi_probe(struct platform_device *pdev,
|
|
- const struct cdn_plat_data *plat_data);
|
|
-void cdns_hdmi_remove(struct platform_device *pdev);
|
|
-void cdns_hdmi_unbind(struct device *dev);
|
|
-int cdns_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder,
|
|
- const struct cdn_plat_data *plat_data);
|
|
-void cdns_hdmi_set_sample_rate(struct imx_mhdp_device *hdmi, unsigned int rate);
|
|
-void cdns_hdmi_audio_enable(struct imx_mhdp_device *hdmi);
|
|
-void cdns_hdmi_audio_disable(struct imx_mhdp_device *hdmi);
|
|
-int cdns_dp_probe(struct platform_device *pdev,
|
|
- const struct cdn_plat_data *plat_data);
|
|
-void cdns_dp_remove(struct platform_device *pdev);
|
|
-void cdns_dp_unbind(struct device *dev);
|
|
-int cdns_dp_bind(struct platform_device *pdev, struct drm_encoder *encoder,
|
|
- const struct cdn_plat_data *plat_data);
|
|
-
|
|
-#endif /* CDNS_MHDP_IMX_H_ */
|