2 * Copyright 2015 Freescale Semiconductor, Inc.
4 * Freescale DCU drm device driver
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
12 #include <linux/backlight.h>
15 #include <drm/drm_atomic_helper.h>
16 #include <drm/drm_crtc_helper.h>
17 #include <drm/drm_panel.h>
19 #include "fsl_dcu_drm_drv.h"
22 fsl_dcu_drm_encoder_atomic_check(struct drm_encoder
*encoder
,
23 struct drm_crtc_state
*crtc_state
,
24 struct drm_connector_state
*conn_state
)
29 static void fsl_dcu_drm_encoder_disable(struct drm_encoder
*encoder
)
33 static void fsl_dcu_drm_encoder_enable(struct drm_encoder
*encoder
)
37 static const struct drm_encoder_helper_funcs encoder_helper_funcs
= {
38 .atomic_check
= fsl_dcu_drm_encoder_atomic_check
,
39 .disable
= fsl_dcu_drm_encoder_disable
,
40 .enable
= fsl_dcu_drm_encoder_enable
,
43 static void fsl_dcu_drm_encoder_destroy(struct drm_encoder
*encoder
)
45 drm_encoder_cleanup(encoder
);
48 static const struct drm_encoder_funcs encoder_funcs
= {
49 .destroy
= fsl_dcu_drm_encoder_destroy
,
52 int fsl_dcu_drm_encoder_create(struct fsl_dcu_drm_device
*fsl_dev
,
53 struct drm_crtc
*crtc
)
55 struct drm_encoder
*encoder
= &fsl_dev
->encoder
;
58 encoder
->possible_crtcs
= 1;
59 ret
= drm_encoder_init(fsl_dev
->drm
, encoder
, &encoder_funcs
,
60 DRM_MODE_ENCODER_LVDS
);
64 drm_encoder_helper_add(encoder
, &encoder_helper_funcs
);
69 static void fsl_dcu_drm_connector_destroy(struct drm_connector
*connector
)
71 drm_connector_unregister(connector
);
72 drm_connector_cleanup(connector
);
75 static enum drm_connector_status
76 fsl_dcu_drm_connector_detect(struct drm_connector
*connector
, bool force
)
78 return connector_status_connected
;
81 static const struct drm_connector_funcs fsl_dcu_drm_connector_funcs
= {
82 .atomic_duplicate_state
= drm_atomic_helper_connector_duplicate_state
,
83 .atomic_destroy_state
= drm_atomic_helper_connector_destroy_state
,
84 .destroy
= fsl_dcu_drm_connector_destroy
,
85 .detect
= fsl_dcu_drm_connector_detect
,
86 .dpms
= drm_atomic_helper_connector_dpms
,
87 .fill_modes
= drm_helper_probe_single_connector_modes
,
88 .reset
= drm_atomic_helper_connector_reset
,
91 static struct drm_encoder
*
92 fsl_dcu_drm_connector_best_encoder(struct drm_connector
*connector
)
94 struct fsl_dcu_drm_connector
*fsl_con
= to_fsl_dcu_connector(connector
);
96 return fsl_con
->encoder
;
99 static int fsl_dcu_drm_connector_get_modes(struct drm_connector
*connector
)
101 struct fsl_dcu_drm_connector
*fsl_connector
;
102 int (*get_modes
)(struct drm_panel
*panel
);
105 fsl_connector
= to_fsl_dcu_connector(connector
);
106 if (fsl_connector
->panel
&& fsl_connector
->panel
->funcs
&&
107 fsl_connector
->panel
->funcs
->get_modes
) {
108 get_modes
= fsl_connector
->panel
->funcs
->get_modes
;
109 num_modes
= get_modes(fsl_connector
->panel
);
115 static int fsl_dcu_drm_connector_mode_valid(struct drm_connector
*connector
,
116 struct drm_display_mode
*mode
)
118 if (mode
->hdisplay
& 0xf)
124 static const struct drm_connector_helper_funcs connector_helper_funcs
= {
125 .best_encoder
= fsl_dcu_drm_connector_best_encoder
,
126 .get_modes
= fsl_dcu_drm_connector_get_modes
,
127 .mode_valid
= fsl_dcu_drm_connector_mode_valid
,
130 int fsl_dcu_drm_connector_create(struct fsl_dcu_drm_device
*fsl_dev
,
131 struct drm_encoder
*encoder
)
133 struct drm_connector
*connector
= &fsl_dev
->connector
.base
;
134 struct drm_mode_config mode_config
= fsl_dev
->drm
->mode_config
;
135 struct device_node
*panel_node
;
138 fsl_dev
->connector
.encoder
= encoder
;
140 ret
= drm_connector_init(fsl_dev
->drm
, connector
,
141 &fsl_dcu_drm_connector_funcs
,
142 DRM_MODE_CONNECTOR_LVDS
);
146 drm_connector_helper_add(connector
, &connector_helper_funcs
);
147 ret
= drm_connector_register(connector
);
151 ret
= drm_mode_connector_attach_encoder(connector
, encoder
);
155 drm_object_property_set_value(&connector
->base
,
156 mode_config
.dpms_property
,
159 panel_node
= of_parse_phandle(fsl_dev
->np
, "fsl,panel", 0);
161 fsl_dev
->connector
.panel
= of_drm_find_panel(panel_node
);
162 if (!fsl_dev
->connector
.panel
) {
166 of_node_put(panel_node
);
169 ret
= drm_panel_attach(fsl_dev
->connector
.panel
, connector
);
171 dev_err(fsl_dev
->dev
, "failed to attach panel\n");
178 drm_connector_unregister(connector
);
180 drm_connector_cleanup(connector
);