diff options
Diffstat (limited to 'drivers/gpu/drm/exynos/exynos_drm_mic.c')
| -rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_mic.c | 108 |
1 files changed, 53 insertions, 55 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_mic.c b/drivers/gpu/drm/exynos/exynos_drm_mic.c index 2fd299a58297..29a8366513fa 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_mic.c +++ b/drivers/gpu/drm/exynos/exynos_drm_mic.c @@ -1,31 +1,32 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) 2015 Samsung Electronics Co.Ltd * Authors: * Hyungwon Hwang <human.hwang@samsung.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundationr */ -#include <linux/platform_device.h> -#include <video/of_videomode.h> -#include <linux/of_address.h> -#include <video/videomode.h> -#include <linux/module.h> +#include <linux/clk.h> +#include <linux/component.h> #include <linux/delay.h> +#include <linux/mfd/syscon.h> +#include <linux/module.h> #include <linux/mutex.h> #include <linux/of.h> +#include <linux/of_address.h> #include <linux/of_graph.h> -#include <linux/clk.h> -#include <linux/component.h> +#include <linux/platform_device.h> #include <linux/pm_runtime.h> -#include <drm/drmP.h> -#include <drm/drm_encoder.h> -#include <linux/mfd/syscon.h> #include <linux/regmap.h> +#include <video/of_videomode.h> +#include <video/videomode.h> + +#include <drm/drm_bridge.h> +#include <drm/drm_encoder.h> +#include <drm/drm_print.h> + #include "exynos_drm_drv.h" +#include "exynos_drm_crtc.h" /* Sysreg registers for MIC */ #define DSD_CFG_MUX 0x1004 @@ -88,7 +89,7 @@ #define MIC_BS_SIZE_2D(x) ((x) & 0x3fff) -static char *clk_names[] = { "pclk_mic0", "sclk_rgb_vclk_to_mic0" }; +static const char *const clk_names[] = { "pclk_mic0", "sclk_rgb_vclk_to_mic0" }; #define NUM_CLKS ARRAY_SIZE(clk_names) static DEFINE_MUTEX(mic_mutex); @@ -100,7 +101,6 @@ struct exynos_mic { bool i80_mode; struct videomode vm; - struct drm_encoder *encoder; struct drm_bridge bridge; bool enabled; @@ -113,7 +113,8 @@ static void mic_set_path(struct exynos_mic *mic, bool enable) ret = regmap_read(mic->sysreg, DSD_CFG_MUX, &val); if (ret) { - DRM_ERROR("mic: Failed to read system register\n"); + DRM_DEV_ERROR(mic->dev, + "mic: Failed to read system register\n"); return; } @@ -129,7 +130,8 @@ static void mic_set_path(struct exynos_mic *mic, bool enable) ret = regmap_write(mic->sysreg, DSD_CFG_MUX, val); if (ret) - DRM_ERROR("mic: Failed to read system register\n"); + DRM_DEV_ERROR(mic->dev, + "mic: Failed to read system register\n"); } static int mic_sw_reset(struct exynos_mic *mic) @@ -190,7 +192,7 @@ static void mic_set_output_timing(struct exynos_mic *mic) struct videomode vm = mic->vm; u32 reg, bs_size_2d; - DRM_DEBUG("w: %u, h: %u\n", vm.hactive, vm.vactive); + DRM_DEV_DEBUG(mic->dev, "w: %u, h: %u\n", vm.hactive, vm.vactive); bs_size_2d = ((vm.hactive >> 2) << 1) + (vm.vactive % 4); reg = MIC_BS_SIZE_2D(bs_size_2d); writel(reg, mic->reg + MIC_2D_OUTPUT_TIMING_2); @@ -226,8 +228,6 @@ static void mic_set_reg_on(struct exynos_mic *mic, bool enable) writel(reg, mic->reg + MIC_OP); } -static void mic_disable(struct drm_bridge *bridge) { } - static void mic_post_disable(struct drm_bridge *bridge) { struct exynos_mic *mic = bridge->driver_private; @@ -246,8 +246,8 @@ already_disabled: } static void mic_mode_set(struct drm_bridge *bridge, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) + const struct drm_display_mode *mode, + const struct drm_display_mode *adjusted_mode) { struct exynos_mic *mic = bridge->driver_private; @@ -266,7 +266,7 @@ static void mic_pre_enable(struct drm_bridge *bridge) if (mic->enabled) goto unlock; - ret = pm_runtime_get_sync(mic->dev); + ret = pm_runtime_resume_and_get(mic->dev); if (ret < 0) goto unlock; @@ -274,7 +274,7 @@ static void mic_pre_enable(struct drm_bridge *bridge) ret = mic_sw_reset(mic); if (ret) { - DRM_ERROR("Failed to reset\n"); + DRM_DEV_ERROR(mic->dev, "Failed to reset\n"); goto turn_off; } @@ -294,24 +294,30 @@ unlock: mutex_unlock(&mic_mutex); } -static void mic_enable(struct drm_bridge *bridge) { } - static const struct drm_bridge_funcs mic_bridge_funcs = { - .disable = mic_disable, .post_disable = mic_post_disable, .mode_set = mic_mode_set, .pre_enable = mic_pre_enable, - .enable = mic_enable, }; static int exynos_mic_bind(struct device *dev, struct device *master, void *data) { struct exynos_mic *mic = dev_get_drvdata(dev); + struct drm_device *drm_dev = data; + struct exynos_drm_crtc *crtc = exynos_drm_crtc_get_by_type(drm_dev, + EXYNOS_DISPLAY_TYPE_LCD); + struct drm_encoder *e, *encoder = NULL; + + drm_for_each_encoder(e, drm_dev) + if (e->possible_crtcs == drm_crtc_mask(&crtc->base)) + encoder = e; + if (!encoder) + return -ENODEV; mic->bridge.driver_private = mic; - return 0; + return drm_bridge_attach(encoder, &mic->bridge, NULL, 0); } static void exynos_mic_unbind(struct device *dev, struct device *master, @@ -334,7 +340,6 @@ static const struct component_ops exynos_mic_component_ops = { .unbind = exynos_mic_unbind, }; -#ifdef CONFIG_PM static int exynos_mic_suspend(struct device *dev) { struct exynos_mic *mic = dev_get_drvdata(dev); @@ -354,8 +359,8 @@ static int exynos_mic_resume(struct device *dev) for (i = 0; i < NUM_CLKS; i++) { ret = clk_prepare_enable(mic->clks[i]); if (ret < 0) { - DRM_ERROR("Failed to enable clock (%s)\n", - clk_names[i]); + DRM_DEV_ERROR(dev, "Failed to enable clock (%s)\n", + clk_names[i]); while (--i > -1) clk_disable_unprepare(mic->clks[i]); return ret; @@ -363,13 +368,9 @@ static int exynos_mic_resume(struct device *dev) } return 0; } -#endif -static const struct dev_pm_ops exynos_mic_pm_ops = { - SET_RUNTIME_PM_OPS(exynos_mic_suspend, exynos_mic_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, - pm_runtime_force_resume) -}; +static DEFINE_RUNTIME_DEV_PM_OPS(exynos_mic_pm_ops, exynos_mic_suspend, + exynos_mic_resume, NULL); static int exynos_mic_probe(struct platform_device *pdev) { @@ -378,10 +379,11 @@ static int exynos_mic_probe(struct platform_device *pdev) struct resource res; int ret, i; - mic = devm_kzalloc(dev, sizeof(*mic), GFP_KERNEL); - if (!mic) { - DRM_ERROR("mic: Failed to allocate memory for MIC object\n"); - ret = -ENOMEM; + mic = devm_drm_bridge_alloc(dev, struct exynos_mic, bridge, &mic_bridge_funcs); + if (IS_ERR(mic)) { + DRM_DEV_ERROR(dev, + "mic: Failed to allocate memory for MIC object\n"); + ret = PTR_ERR(mic); goto err; } @@ -389,12 +391,12 @@ static int exynos_mic_probe(struct platform_device *pdev) ret = of_address_to_resource(dev->of_node, 0, &res); if (ret) { - DRM_ERROR("mic: Failed to get mem region for MIC\n"); + DRM_DEV_ERROR(dev, "mic: Failed to get mem region for MIC\n"); goto err; } mic->reg = devm_ioremap(dev, res.start, resource_size(&res)); if (!mic->reg) { - DRM_ERROR("mic: Failed to remap for MIC\n"); + DRM_DEV_ERROR(dev, "mic: Failed to remap for MIC\n"); ret = -ENOMEM; goto err; } @@ -402,7 +404,7 @@ static int exynos_mic_probe(struct platform_device *pdev) mic->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node, "samsung,disp-syscon"); if (IS_ERR(mic->sysreg)) { - DRM_ERROR("mic: Failed to get system register.\n"); + DRM_DEV_ERROR(dev, "mic: Failed to get system register.\n"); ret = PTR_ERR(mic->sysreg); goto err; } @@ -410,8 +412,8 @@ static int exynos_mic_probe(struct platform_device *pdev) for (i = 0; i < NUM_CLKS; i++) { mic->clks[i] = devm_clk_get(dev, clk_names[i]); if (IS_ERR(mic->clks[i])) { - DRM_ERROR("mic: Failed to get clock (%s)\n", - clk_names[i]); + DRM_DEV_ERROR(dev, "mic: Failed to get clock (%s)\n", + clk_names[i]); ret = PTR_ERR(mic->clks[i]); goto err; } @@ -419,7 +421,6 @@ static int exynos_mic_probe(struct platform_device *pdev) platform_set_drvdata(pdev, mic); - mic->bridge.funcs = &mic_bridge_funcs; mic->bridge.of_node = dev->of_node; drm_bridge_add(&mic->bridge); @@ -430,7 +431,7 @@ static int exynos_mic_probe(struct platform_device *pdev) if (ret) goto err_pm; - DRM_DEBUG_KMS("MIC has been probed\n"); + DRM_DEV_DEBUG_KMS(dev, "MIC has been probed\n"); return 0; @@ -440,7 +441,7 @@ err: return ret; } -static int exynos_mic_remove(struct platform_device *pdev) +static void exynos_mic_remove(struct platform_device *pdev) { struct exynos_mic *mic = platform_get_drvdata(pdev); @@ -448,8 +449,6 @@ static int exynos_mic_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); drm_bridge_remove(&mic->bridge); - - return 0; } static const struct of_device_id exynos_mic_of_match[] = { @@ -463,8 +462,7 @@ struct platform_driver mic_driver = { .remove = exynos_mic_remove, .driver = { .name = "exynos-mic", - .pm = &exynos_mic_pm_ops, - .owner = THIS_MODULE, + .pm = pm_ptr(&exynos_mic_pm_ops), .of_match_table = exynos_mic_of_match, }, }; |
