0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/clk.h>
0010 #include <linux/component.h>
0011 #include <linux/err.h>
0012 #include <linux/module.h>
0013 #include <linux/of.h>
0014 #include <linux/of_graph.h>
0015 #include <linux/platform_device.h>
0016 #include <linux/pm_runtime.h>
0017 #include <video/of_display_timing.h>
0018 #include <video/of_videomode.h>
0019 #include <video/videomode.h>
0020
0021 #include <drm/bridge/analogix_dp.h>
0022 #include <drm/drm_atomic_helper.h>
0023 #include <drm/drm_bridge.h>
0024 #include <drm/drm_crtc.h>
0025 #include <drm/drm_of.h>
0026 #include <drm/drm_panel.h>
0027 #include <drm/drm_print.h>
0028 #include <drm/drm_probe_helper.h>
0029 #include <drm/drm_simple_kms_helper.h>
0030 #include <drm/exynos_drm.h>
0031
0032 #include "exynos_drm_crtc.h"
0033
0034 #define to_dp(nm) container_of(nm, struct exynos_dp_device, nm)
0035
0036 struct exynos_dp_device {
0037 struct drm_encoder encoder;
0038 struct drm_connector *connector;
0039 struct drm_bridge *ptn_bridge;
0040 struct drm_device *drm_dev;
0041 struct device *dev;
0042
0043 struct videomode vm;
0044 struct analogix_dp_device *adp;
0045 struct analogix_dp_plat_data plat_data;
0046 };
0047
0048 static int exynos_dp_crtc_clock_enable(struct analogix_dp_plat_data *plat_data,
0049 bool enable)
0050 {
0051 struct exynos_dp_device *dp = to_dp(plat_data);
0052 struct drm_encoder *encoder = &dp->encoder;
0053
0054 if (!encoder->crtc)
0055 return -EPERM;
0056
0057 exynos_drm_pipe_clk_enable(to_exynos_crtc(encoder->crtc), enable);
0058
0059 return 0;
0060 }
0061
0062 static int exynos_dp_poweron(struct analogix_dp_plat_data *plat_data)
0063 {
0064 return exynos_dp_crtc_clock_enable(plat_data, true);
0065 }
0066
0067 static int exynos_dp_poweroff(struct analogix_dp_plat_data *plat_data)
0068 {
0069 return exynos_dp_crtc_clock_enable(plat_data, false);
0070 }
0071
0072 static int exynos_dp_get_modes(struct analogix_dp_plat_data *plat_data,
0073 struct drm_connector *connector)
0074 {
0075 struct exynos_dp_device *dp = to_dp(plat_data);
0076 struct drm_display_mode *mode;
0077 int num_modes = 0;
0078
0079 if (dp->plat_data.panel)
0080 return num_modes;
0081
0082 mode = drm_mode_create(connector->dev);
0083 if (!mode) {
0084 DRM_DEV_ERROR(dp->dev,
0085 "failed to create a new display mode.\n");
0086 return num_modes;
0087 }
0088
0089 drm_display_mode_from_videomode(&dp->vm, mode);
0090 connector->display_info.width_mm = mode->width_mm;
0091 connector->display_info.height_mm = mode->height_mm;
0092
0093 mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
0094 drm_mode_set_name(mode);
0095 drm_mode_probed_add(connector, mode);
0096
0097 return num_modes + 1;
0098 }
0099
0100 static int exynos_dp_bridge_attach(struct analogix_dp_plat_data *plat_data,
0101 struct drm_bridge *bridge,
0102 struct drm_connector *connector)
0103 {
0104 struct exynos_dp_device *dp = to_dp(plat_data);
0105 int ret;
0106
0107 dp->connector = connector;
0108
0109
0110 if (dp->ptn_bridge) {
0111 ret = drm_bridge_attach(&dp->encoder, dp->ptn_bridge, bridge,
0112 0);
0113 if (ret)
0114 return ret;
0115 }
0116
0117 return 0;
0118 }
0119
0120 static void exynos_dp_mode_set(struct drm_encoder *encoder,
0121 struct drm_display_mode *mode,
0122 struct drm_display_mode *adjusted_mode)
0123 {
0124 }
0125
0126 static void exynos_dp_nop(struct drm_encoder *encoder)
0127 {
0128
0129 }
0130
0131 static const struct drm_encoder_helper_funcs exynos_dp_encoder_helper_funcs = {
0132 .mode_set = exynos_dp_mode_set,
0133 .enable = exynos_dp_nop,
0134 .disable = exynos_dp_nop,
0135 };
0136
0137 static int exynos_dp_dt_parse_panel(struct exynos_dp_device *dp)
0138 {
0139 int ret;
0140
0141 ret = of_get_videomode(dp->dev->of_node, &dp->vm, OF_USE_NATIVE_MODE);
0142 if (ret) {
0143 DRM_DEV_ERROR(dp->dev,
0144 "failed: of_get_videomode() : %d\n", ret);
0145 return ret;
0146 }
0147 return 0;
0148 }
0149
0150 static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
0151 {
0152 struct exynos_dp_device *dp = dev_get_drvdata(dev);
0153 struct drm_encoder *encoder = &dp->encoder;
0154 struct drm_device *drm_dev = data;
0155 int ret;
0156
0157 dp->drm_dev = drm_dev;
0158
0159 if (!dp->plat_data.panel && !dp->ptn_bridge) {
0160 ret = exynos_dp_dt_parse_panel(dp);
0161 if (ret)
0162 return ret;
0163 }
0164
0165 drm_simple_encoder_init(drm_dev, encoder, DRM_MODE_ENCODER_TMDS);
0166
0167 drm_encoder_helper_add(encoder, &exynos_dp_encoder_helper_funcs);
0168
0169 ret = exynos_drm_set_possible_crtcs(encoder, EXYNOS_DISPLAY_TYPE_LCD);
0170 if (ret < 0)
0171 return ret;
0172
0173 dp->plat_data.encoder = encoder;
0174
0175 ret = analogix_dp_bind(dp->adp, dp->drm_dev);
0176 if (ret)
0177 dp->encoder.funcs->destroy(&dp->encoder);
0178
0179 return ret;
0180 }
0181
0182 static void exynos_dp_unbind(struct device *dev, struct device *master,
0183 void *data)
0184 {
0185 struct exynos_dp_device *dp = dev_get_drvdata(dev);
0186
0187 analogix_dp_unbind(dp->adp);
0188 dp->encoder.funcs->destroy(&dp->encoder);
0189 }
0190
0191 static const struct component_ops exynos_dp_ops = {
0192 .bind = exynos_dp_bind,
0193 .unbind = exynos_dp_unbind,
0194 };
0195
0196 static int exynos_dp_probe(struct platform_device *pdev)
0197 {
0198 struct device *dev = &pdev->dev;
0199 struct device_node *np;
0200 struct exynos_dp_device *dp;
0201 struct drm_panel *panel;
0202 struct drm_bridge *bridge;
0203 int ret;
0204
0205 dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device),
0206 GFP_KERNEL);
0207 if (!dp)
0208 return -ENOMEM;
0209
0210 dp->dev = dev;
0211
0212
0213
0214
0215
0216 platform_set_drvdata(pdev, dp);
0217
0218
0219 np = of_parse_phandle(dev->of_node, "panel", 0);
0220 if (np) {
0221 dp->plat_data.panel = of_drm_find_panel(np);
0222
0223 of_node_put(np);
0224 if (IS_ERR(dp->plat_data.panel))
0225 return PTR_ERR(dp->plat_data.panel);
0226
0227 goto out;
0228 }
0229
0230 ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0, &panel, &bridge);
0231 if (ret)
0232 return ret;
0233
0234
0235 dp->plat_data.panel = panel;
0236 dp->plat_data.dev_type = EXYNOS_DP;
0237 dp->plat_data.power_on_start = exynos_dp_poweron;
0238 dp->plat_data.power_off = exynos_dp_poweroff;
0239 dp->plat_data.attach = exynos_dp_bridge_attach;
0240 dp->plat_data.get_modes = exynos_dp_get_modes;
0241 dp->plat_data.skip_connector = !!bridge;
0242
0243 dp->ptn_bridge = bridge;
0244
0245 out:
0246 dp->adp = analogix_dp_probe(dev, &dp->plat_data);
0247 if (IS_ERR(dp->adp))
0248 return PTR_ERR(dp->adp);
0249
0250 return component_add(&pdev->dev, &exynos_dp_ops);
0251 }
0252
0253 static int exynos_dp_remove(struct platform_device *pdev)
0254 {
0255 struct exynos_dp_device *dp = platform_get_drvdata(pdev);
0256
0257 component_del(&pdev->dev, &exynos_dp_ops);
0258 analogix_dp_remove(dp->adp);
0259
0260 return 0;
0261 }
0262
0263 #ifdef CONFIG_PM
0264 static int exynos_dp_suspend(struct device *dev)
0265 {
0266 struct exynos_dp_device *dp = dev_get_drvdata(dev);
0267
0268 return analogix_dp_suspend(dp->adp);
0269 }
0270
0271 static int exynos_dp_resume(struct device *dev)
0272 {
0273 struct exynos_dp_device *dp = dev_get_drvdata(dev);
0274
0275 return analogix_dp_resume(dp->adp);
0276 }
0277 #endif
0278
0279 static const struct dev_pm_ops exynos_dp_pm_ops = {
0280 SET_RUNTIME_PM_OPS(exynos_dp_suspend, exynos_dp_resume, NULL)
0281 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
0282 pm_runtime_force_resume)
0283 };
0284
0285 static const struct of_device_id exynos_dp_match[] = {
0286 { .compatible = "samsung,exynos5-dp" },
0287 {},
0288 };
0289 MODULE_DEVICE_TABLE(of, exynos_dp_match);
0290
0291 struct platform_driver dp_driver = {
0292 .probe = exynos_dp_probe,
0293 .remove = exynos_dp_remove,
0294 .driver = {
0295 .name = "exynos-dp",
0296 .owner = THIS_MODULE,
0297 .pm = &exynos_dp_pm_ops,
0298 .of_match_table = exynos_dp_match,
0299 },
0300 };
0301
0302 MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>");
0303 MODULE_DESCRIPTION("Samsung Specific Analogix-DP Driver Extension");
0304 MODULE_LICENSE("GPL v2");