diff options
Diffstat (limited to 'target/linux/layerscape/patches-5.4/805-display-0056-LF-794-3-gpu-cdn-imx8qm-Add-firmware-loading-support.patch')
-rw-r--r-- | target/linux/layerscape/patches-5.4/805-display-0056-LF-794-3-gpu-cdn-imx8qm-Add-firmware-loading-support.patch | 268 |
1 files changed, 0 insertions, 268 deletions
diff --git a/target/linux/layerscape/patches-5.4/805-display-0056-LF-794-3-gpu-cdn-imx8qm-Add-firmware-loading-support.patch b/target/linux/layerscape/patches-5.4/805-display-0056-LF-794-3-gpu-cdn-imx8qm-Add-firmware-loading-support.patch deleted file mode 100644 index ca7f488b8b..0000000000 --- a/target/linux/layerscape/patches-5.4/805-display-0056-LF-794-3-gpu-cdn-imx8qm-Add-firmware-loading-support.patch +++ /dev/null @@ -1,268 +0,0 @@ -From 020578dd022e5d869db52e79c5aba95c1f1a84ec Mon Sep 17 00:00:00 2001 -From: Abel Vesa <abel.vesa@nxp.com> -Date: Wed, 11 Dec 2019 09:21:23 +0200 -Subject: [PATCH] LF-794-3 gpu: cdn: imx8qm: Add firmware loading support - -This allows the HDP i.MX8QM driver to load the firmware on init -and resume. In order to have backward compatibility, if there is -no firmware-name property defined in the hdmi node, the driver -probing sequence skips the firmware loading. - -Also, if u-boot has loaded already a firmware, we run with that -but when probing the driver, the request_firmware_nowait is used -to locate and keep safe the firmware for when suspend/resume happens. - -This leads to 4 possible scenarios: - -1. u-boot loads the firmware, the kernel driver finds the firmware -when rootfs is mounted. This is the most desirable scenario. Also -this is the only scenario that allows the hdmi to work after resume. - -2. u-boot loads the firmware, the kernel driver _doesn't_ find -the firmware in rootfs. If there is no suspend ever happening, -the kernel driver will keep using the firmware that was loaded by -u-boot. On the first suspend/resume, the firmware is lost -because the HDMI IP gets powered down. - -3. u-boot doesn't load the firmare, the kernel driver probing -tries to load the firmware, assuming this is available -(see CONFIG_EXTRA_FIRMWARE). - -4. u-boot doesn't load the firmware and the kernel driver is not -able to find it either. The probing fails and there is no HDMI -available in linux. - -Signed-off-by: Abel Vesa <abel.vesa@nxp.com> -Reviewed-by: Sandor Yu <sandor.yu@nxp.com> -Acked-by: Wen He <wen.he_1@nxp.com> -Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com> ---- - drivers/gpu/drm/imx/cdn-mhdp-imx8qm.c | 78 +++++++++++++++++++++++++++++++++-- - drivers/gpu/drm/imx/cdn-mhdp-imxdrv.c | 30 ++++++++++++++ - drivers/gpu/drm/imx/cdns-mhdp-imx.h | 4 ++ - include/drm/bridge/cdns-mhdp-common.h | 3 ++ - 4 files changed, 111 insertions(+), 4 deletions(-) - ---- a/drivers/gpu/drm/imx/cdn-mhdp-imx8qm.c -+++ b/drivers/gpu/drm/imx/cdn-mhdp-imx8qm.c -@@ -7,12 +7,17 @@ - */ - #include <dt-bindings/firmware/imx/rsrc.h> - #include <linux/firmware/imx/sci.h> -+#include <linux/firmware.h> - #include <linux/pm_domain.h> - #include <linux/clk.h> - #include <drm/drmP.h> - - #include "cdns-mhdp-imx.h" - -+#define FW_IRAM_OFFSET 0x2000 -+#define FW_IRAM_SIZE 0x10000 -+#define FW_DRAM_SIZE 0x8000 -+ - #define PLL_800MHZ (800000000) - - #define HDP_DUAL_MODE_MIN_PCLK_RATE 300000 /* KHz */ -@@ -517,24 +522,69 @@ void cdns_mhdp_pclk_rate_imx8qm(struct c - imx8qm_pixel_link_mux(imx_mhdp); - } - --int cdns_mhdp_firmware_init_imx8qm(struct cdns_mhdp_device *mhdp) -+static void cdns_mhdp_firmware_load_cont(const struct firmware *fw, void *context) - { -- struct imx_mhdp_device *imx_mhdp = -- container_of(mhdp, struct imx_mhdp_device, mhdp); -+ struct imx_mhdp_device *imx_mhdp = context; -+ -+ imx_mhdp->fw = fw; -+} -+ -+static int cdns_mhdp_load_firmware_imx8qm(struct imx_mhdp_device *imx_mhdp) -+{ -+ const u8 *iram; -+ const u8 *dram; - u32 rate; - int ret; - - /* configure HDMI/DP core clock */ - rate = clk_get_rate(imx_mhdp->clks.clk_core); -- if (mhdp->is_ls1028a) -+ if (imx_mhdp->mhdp.is_ls1028a) - rate = rate / 4; - - cdns_mhdp_set_fw_clk(&imx_mhdp->mhdp, rate); - -+ /* skip fw loading if none is specified */ -+ if (!imx_mhdp->firmware_name) -+ goto out; -+ -+ if (!imx_mhdp->fw) { -+ ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOHOTPLUG, -+ imx_mhdp->firmware_name, -+ imx_mhdp->mhdp.dev, GFP_KERNEL, -+ imx_mhdp, -+ cdns_mhdp_firmware_load_cont); -+ if (ret < 0) { -+ DRM_ERROR("failed to load firmware\n"); -+ return -ENOENT; -+ } -+ } else { -+ iram = imx_mhdp->fw->data + FW_IRAM_OFFSET; -+ dram = iram + FW_IRAM_SIZE; -+ -+ cdns_mhdp_load_firmware(&imx_mhdp->mhdp, -+ (const u32 *) iram, FW_IRAM_SIZE, -+ (const u32 *) dram, FW_DRAM_SIZE); -+ } -+ -+out: - /* un-reset ucpu */ - cdns_mhdp_bus_write(0, &imx_mhdp->mhdp, APB_CTRL); - DRM_INFO("Started firmware!\n"); - -+ return 0; -+} -+ -+int cdns_mhdp_firmware_init_imx8qm(struct cdns_mhdp_device *mhdp) -+{ -+ struct imx_mhdp_device *imx_mhdp = -+ container_of(mhdp, struct imx_mhdp_device, mhdp); -+ int ret; -+ -+ /* load firmware */ -+ ret = cdns_mhdp_load_firmware_imx8qm(imx_mhdp); -+ if (ret) -+ return ret; -+ - ret = cdns_mhdp_check_alive(&imx_mhdp->mhdp); - if (ret == false) { - DRM_ERROR("NO HDMI FW running\n"); -@@ -550,3 +600,23 @@ int cdns_mhdp_firmware_init_imx8qm(struc - - return 0; - } -+ -+int cdns_mhdp_suspend_imx8qm(struct cdns_mhdp_device *mhdp) -+{ -+ struct imx_mhdp_device *imx_mhdp = -+ container_of(mhdp, struct imx_mhdp_device, mhdp); -+ -+ imx8qm_pixel_clk_disable(imx_mhdp); -+ -+ return 0; -+} -+ -+int cdns_mhdp_resume_imx8qm(struct cdns_mhdp_device *mhdp) -+{ -+ struct imx_mhdp_device *imx_mhdp = -+ container_of(mhdp, struct imx_mhdp_device, mhdp); -+ -+ imx8qm_pixel_clk_enable(imx_mhdp); -+ -+ return cdns_mhdp_firmware_init_imx8qm(mhdp); -+} ---- a/drivers/gpu/drm/imx/cdn-mhdp-imxdrv.c -+++ b/drivers/gpu/drm/imx/cdn-mhdp-imxdrv.c -@@ -82,6 +82,8 @@ static struct cdns_plat_data imx8qm_hdmi - .phy_video_valid = cdns_hdmi_phy_video_valid_imx8qm, - .power_on = cdns_mhdp_power_on_imx8qm, - .firmware_init = cdns_mhdp_firmware_init_imx8qm, -+ .resume = cdns_mhdp_resume_imx8qm, -+ .suspend = cdns_mhdp_suspend_imx8qm, - .pclk_rate = cdns_mhdp_pclk_rate_imx8qm, - .plat_init = cdns_mhdp_plat_init_imx8qm, - .plat_deinit = cdns_mhdp_plat_deinit_imx8qm, -@@ -96,6 +98,8 @@ static struct cdns_plat_data imx8qm_dp_d - .phy_set = cdns_dp_phy_set_imx8qm, - .power_on = cdns_mhdp_power_on_imx8qm, - .firmware_init = cdns_mhdp_firmware_init_imx8qm, -+ .resume = cdns_mhdp_resume_imx8qm, -+ .suspend = cdns_mhdp_suspend_imx8qm, - .pclk_rate = cdns_mhdp_pclk_rate_imx8qm, - .plat_init = cdns_mhdp_plat_init_imx8qm, - .plat_deinit = cdns_mhdp_plat_deinit_imx8qm, -@@ -157,6 +161,9 @@ static int cdns_mhdp_imx_bind(struct dev - encoder = &imx_mhdp->encoder; - - encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node); -+ -+ ret = of_property_read_string(pdev->dev.of_node, "firmware-name", -+ &imx_mhdp->firmware_name); - /* - * If we failed to find the CRTC(s) which this encoder is - * supposed to be connected to, it's because the CRTC has -@@ -198,6 +205,24 @@ static const struct component_ops cdns_m - .unbind = cdns_mhdp_imx_unbind, - }; - -+static int cdns_mhdp_imx_suspend(struct device *dev) -+{ -+ struct imx_mhdp_device *imx_mhdp = dev_get_drvdata(dev); -+ -+ cdns_mhdp_plat_call(&imx_mhdp->mhdp, suspend); -+ -+ return 0; -+} -+ -+static int cdns_mhdp_imx_resume(struct device *dev) -+{ -+ struct imx_mhdp_device *imx_mhdp = dev_get_drvdata(dev); -+ -+ cdns_mhdp_plat_call(&imx_mhdp->mhdp, resume); -+ -+ return 0; -+} -+ - static int cdns_mhdp_imx_probe(struct platform_device *pdev) - { - return component_add(&pdev->dev, &cdns_mhdp_imx_ops); -@@ -210,12 +235,17 @@ static int cdns_mhdp_imx_remove(struct p - return 0; - } - -+static const struct dev_pm_ops cdns_mhdp_imx_pm_ops = { -+ SET_LATE_SYSTEM_SLEEP_PM_OPS(cdns_mhdp_imx_suspend, cdns_mhdp_imx_resume) -+}; -+ - static struct platform_driver cdns_mhdp_imx_platform_driver = { - .probe = cdns_mhdp_imx_probe, - .remove = cdns_mhdp_imx_remove, - .driver = { - .name = "cdns-mhdp-imx", - .of_match_table = cdns_mhdp_imx_dt_ids, -+ .pm = &cdns_mhdp_imx_pm_ops, - }, - }; - ---- a/drivers/gpu/drm/imx/cdns-mhdp-imx.h -+++ b/drivers/gpu/drm/imx/cdns-mhdp-imx.h -@@ -50,6 +50,8 @@ struct imx_mhdp_device { - bool active; - bool suspended; - struct imx_hdp_clks clks; -+ const struct firmware *fw; -+ const char *firmware_name; - - int bus_type; - -@@ -65,6 +67,8 @@ void cdns_mhdp_plat_init_imx8qm(struct c - void cdns_mhdp_plat_deinit_imx8qm(struct cdns_mhdp_device *mhdp); - 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_resume_imx8qm(struct cdns_mhdp_device *mhdp); -+int cdns_mhdp_suspend_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); ---- a/include/drm/bridge/cdns-mhdp-common.h -+++ b/include/drm/bridge/cdns-mhdp-common.h -@@ -645,6 +645,9 @@ struct cdns_plat_data { - int (*firmware_init)(struct cdns_mhdp_device *mhdp); - void (*pclk_rate)(struct cdns_mhdp_device *mhdp); - -+ int (*suspend)(struct cdns_mhdp_device *mhdp); -+ int (*resume)(struct cdns_mhdp_device *mhdp); -+ - int (*power_on)(struct cdns_mhdp_device *mhdp); - int (*power_off)(struct cdns_mhdp_device *mhdp); - |