From fe1824851dd6f7d3ee6d5411edba4102dacea873 Mon Sep 17 00:00:00 2001 From: Sandor Yu 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 --- 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 +#include #include #include #include @@ -25,8 +24,6 @@ #include #include -#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 +#include #include #include #include @@ -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 #include #include -#include #include #include --- 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 #include -#include #include #include #include @@ -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 #include #include -#include #include 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 - -#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_ */