| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
|---|
| 1 | 2 | /* Copyright (C) 2011-2013 Freescale Semiconductor, Inc. |
|---|
| 2 | 3 | * |
|---|
| 3 | 4 | * derived from imx-hdmi.c(renamed to bridge/dw_hdmi.c now) |
|---|
| 4 | | - * |
|---|
| 5 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 6 | | - * it under the terms of the GNU General Public License version 2 as |
|---|
| 7 | | - * published by the Free Software Foundation. |
|---|
| 8 | 5 | */ |
|---|
| 9 | | -#include <linux/module.h> |
|---|
| 10 | | -#include <linux/platform_device.h> |
|---|
| 6 | + |
|---|
| 11 | 7 | #include <linux/component.h> |
|---|
| 12 | 8 | #include <linux/mfd/syscon.h> |
|---|
| 13 | 9 | #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h> |
|---|
| 14 | | -#include <drm/bridge/dw_hdmi.h> |
|---|
| 15 | | -#include <video/imx-ipu-v3.h> |
|---|
| 10 | +#include <linux/module.h> |
|---|
| 11 | +#include <linux/platform_device.h> |
|---|
| 16 | 12 | #include <linux/regmap.h> |
|---|
| 17 | | -#include <drm/drm_of.h> |
|---|
| 18 | | -#include <drm/drmP.h> |
|---|
| 19 | | -#include <drm/drm_crtc_helper.h> |
|---|
| 13 | + |
|---|
| 14 | +#include <video/imx-ipu-v3.h> |
|---|
| 15 | + |
|---|
| 16 | +#include <drm/bridge/dw_hdmi.h> |
|---|
| 17 | +#include <drm/drm_atomic_helper.h> |
|---|
| 20 | 18 | #include <drm/drm_edid.h> |
|---|
| 21 | | -#include <drm/drm_encoder_slave.h> |
|---|
| 19 | +#include <drm/drm_encoder.h> |
|---|
| 20 | +#include <drm/drm_of.h> |
|---|
| 21 | +#include <drm/drm_simple_kms_helper.h> |
|---|
| 22 | 22 | |
|---|
| 23 | 23 | #include "imx-drm.h" |
|---|
| 24 | 24 | |
|---|
| .. | .. |
|---|
| 111 | 111 | return 0; |
|---|
| 112 | 112 | } |
|---|
| 113 | 113 | |
|---|
| 114 | | -static void dw_hdmi_imx_encoder_disable(struct drm_encoder *encoder) |
|---|
| 115 | | -{ |
|---|
| 116 | | -} |
|---|
| 117 | | - |
|---|
| 118 | 114 | static void dw_hdmi_imx_encoder_enable(struct drm_encoder *encoder) |
|---|
| 119 | 115 | { |
|---|
| 120 | 116 | struct imx_hdmi *hdmi = enc_to_imx_hdmi(encoder); |
|---|
| .. | .. |
|---|
| 140 | 136 | |
|---|
| 141 | 137 | static const struct drm_encoder_helper_funcs dw_hdmi_imx_encoder_helper_funcs = { |
|---|
| 142 | 138 | .enable = dw_hdmi_imx_encoder_enable, |
|---|
| 143 | | - .disable = dw_hdmi_imx_encoder_disable, |
|---|
| 144 | 139 | .atomic_check = dw_hdmi_imx_atomic_check, |
|---|
| 145 | 140 | }; |
|---|
| 146 | 141 | |
|---|
| 147 | | -static const struct drm_encoder_funcs dw_hdmi_imx_encoder_funcs = { |
|---|
| 148 | | - .destroy = drm_encoder_cleanup, |
|---|
| 149 | | -}; |
|---|
| 150 | | - |
|---|
| 151 | 142 | static enum drm_mode_status |
|---|
| 152 | | -imx6q_hdmi_mode_valid(struct drm_connector *con, |
|---|
| 143 | +imx6q_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data, |
|---|
| 144 | + const struct drm_display_info *info, |
|---|
| 153 | 145 | const struct drm_display_mode *mode) |
|---|
| 154 | 146 | { |
|---|
| 155 | 147 | if (mode->clock < 13500) |
|---|
| .. | .. |
|---|
| 162 | 154 | } |
|---|
| 163 | 155 | |
|---|
| 164 | 156 | static enum drm_mode_status |
|---|
| 165 | | -imx6dl_hdmi_mode_valid(struct drm_connector *con, |
|---|
| 157 | +imx6dl_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data, |
|---|
| 158 | + const struct drm_display_info *info, |
|---|
| 166 | 159 | const struct drm_display_mode *mode) |
|---|
| 167 | 160 | { |
|---|
| 168 | 161 | if (mode->clock < 13500) |
|---|
| .. | .. |
|---|
| 213 | 206 | if (!pdev->dev.of_node) |
|---|
| 214 | 207 | return -ENODEV; |
|---|
| 215 | 208 | |
|---|
| 216 | | - hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL); |
|---|
| 217 | | - if (!hdmi) |
|---|
| 218 | | - return -ENOMEM; |
|---|
| 209 | + hdmi = dev_get_drvdata(dev); |
|---|
| 210 | + memset(hdmi, 0, sizeof(*hdmi)); |
|---|
| 219 | 211 | |
|---|
| 220 | 212 | match = of_match_node(dw_hdmi_imx_dt_ids, pdev->dev.of_node); |
|---|
| 221 | 213 | plat_data = match->data; |
|---|
| 222 | 214 | hdmi->dev = &pdev->dev; |
|---|
| 223 | 215 | encoder = &hdmi->encoder; |
|---|
| 224 | 216 | |
|---|
| 225 | | - encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node); |
|---|
| 226 | | - /* |
|---|
| 227 | | - * If we failed to find the CRTC(s) which this encoder is |
|---|
| 228 | | - * supposed to be connected to, it's because the CRTC has |
|---|
| 229 | | - * not been registered yet. Defer probing, and hope that |
|---|
| 230 | | - * the required CRTC is added later. |
|---|
| 231 | | - */ |
|---|
| 232 | | - if (encoder->possible_crtcs == 0) |
|---|
| 233 | | - return -EPROBE_DEFER; |
|---|
| 217 | + ret = imx_drm_encoder_parse_of(drm, encoder, dev->of_node); |
|---|
| 218 | + if (ret) |
|---|
| 219 | + return ret; |
|---|
| 234 | 220 | |
|---|
| 235 | 221 | ret = dw_hdmi_imx_parse_dt(hdmi); |
|---|
| 236 | 222 | if (ret < 0) |
|---|
| 237 | 223 | return ret; |
|---|
| 238 | 224 | |
|---|
| 239 | 225 | drm_encoder_helper_add(encoder, &dw_hdmi_imx_encoder_helper_funcs); |
|---|
| 240 | | - drm_encoder_init(drm, encoder, &dw_hdmi_imx_encoder_funcs, |
|---|
| 241 | | - DRM_MODE_ENCODER_TMDS, NULL); |
|---|
| 242 | | - |
|---|
| 243 | | - platform_set_drvdata(pdev, hdmi); |
|---|
| 226 | + drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS); |
|---|
| 244 | 227 | |
|---|
| 245 | 228 | hdmi->hdmi = dw_hdmi_bind(pdev, encoder, plat_data); |
|---|
| 246 | 229 | |
|---|
| .. | .. |
|---|
| 271 | 254 | |
|---|
| 272 | 255 | static int dw_hdmi_imx_probe(struct platform_device *pdev) |
|---|
| 273 | 256 | { |
|---|
| 257 | + struct imx_hdmi *hdmi; |
|---|
| 258 | + |
|---|
| 259 | + hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL); |
|---|
| 260 | + if (!hdmi) |
|---|
| 261 | + return -ENOMEM; |
|---|
| 262 | + |
|---|
| 263 | + platform_set_drvdata(pdev, hdmi); |
|---|
| 264 | + |
|---|
| 274 | 265 | return component_add(&pdev->dev, &dw_hdmi_imx_ops); |
|---|
| 275 | 266 | } |
|---|
| 276 | 267 | |
|---|