Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/exynos: Remove dpms link between encoder/connector

This patch removes the call from encoder dpms into connector dpms (which
will then call back into encoder dpms through the helper function). The
callback is likely to keep connector->dpms in the right state when
initiating dpms from crtc or encoder, but this isn't the right way to do
it. This patch is the first step towards rationalizing power management
in the exynos drm driver.

Signed-off-by: Sean Paul <seanpaul@chromium.org>
Reviewed-by: Tomasz Figa <t.figa@samsung.com>
Signed-off-by: Inki Dae <inki.dae@samsung.com>

authored by

Sean Paul and committed by
Inki Dae
e5b89916 87244fa6

+8 -88
+3 -39
drivers/gpu/drm/exynos/exynos_drm_connector.c
··· 26 26 struct drm_connector drm_connector; 27 27 uint32_t encoder_id; 28 28 struct exynos_drm_manager *manager; 29 - uint32_t dpms; 30 29 }; 31 30 32 31 static int exynos_drm_connector_get_modes(struct drm_connector *connector) ··· 118 119 return ret; 119 120 } 120 121 121 - struct drm_encoder *exynos_drm_best_encoder(struct drm_connector *connector) 122 + static struct drm_encoder *exynos_drm_best_encoder( 123 + struct drm_connector *connector) 122 124 { 123 125 struct drm_device *dev = connector->dev; 124 126 struct exynos_drm_connector *exynos_connector = ··· 145 145 .mode_valid = exynos_drm_connector_mode_valid, 146 146 .best_encoder = exynos_drm_best_encoder, 147 147 }; 148 - 149 - void exynos_drm_display_power(struct drm_connector *connector, int mode) 150 - { 151 - struct drm_encoder *encoder = exynos_drm_best_encoder(connector); 152 - struct exynos_drm_connector *exynos_connector; 153 - struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder); 154 - struct exynos_drm_display_ops *display_ops = manager->display_ops; 155 - 156 - exynos_connector = to_exynos_connector(connector); 157 - 158 - if (exynos_connector->dpms == mode) { 159 - DRM_DEBUG_KMS("desired dpms mode is same as previous one.\n"); 160 - return; 161 - } 162 - 163 - if (display_ops && display_ops->power_on) 164 - display_ops->power_on(manager->dev, mode); 165 - 166 - exynos_connector->dpms = mode; 167 - } 168 - 169 - static void exynos_drm_connector_dpms(struct drm_connector *connector, 170 - int mode) 171 - { 172 - /* 173 - * in case that drm_crtc_helper_set_mode() is called, 174 - * encoder/crtc->funcs->dpms() will be just returned 175 - * because they already were DRM_MODE_DPMS_ON so only 176 - * exynos_drm_display_power() will be called. 177 - */ 178 - drm_helper_connector_dpms(connector, mode); 179 - 180 - exynos_drm_display_power(connector, mode); 181 - 182 - } 183 148 184 149 static int exynos_drm_connector_fill_modes(struct drm_connector *connector, 185 150 unsigned int max_width, unsigned int max_height) ··· 201 236 } 202 237 203 238 static struct drm_connector_funcs exynos_connector_funcs = { 204 - .dpms = exynos_drm_connector_dpms, 239 + .dpms = drm_helper_connector_dpms, 205 240 .fill_modes = exynos_drm_connector_fill_modes, 206 241 .detect = exynos_drm_connector_detect, 207 242 .destroy = exynos_drm_connector_destroy, ··· 246 281 247 282 exynos_connector->encoder_id = encoder->base.id; 248 283 exynos_connector->manager = manager; 249 - exynos_connector->dpms = DRM_MODE_DPMS_OFF; 250 284 connector->dpms = DRM_MODE_DPMS_OFF; 251 285 connector->encoder = encoder; 252 286
-4
drivers/gpu/drm/exynos/exynos_drm_connector.h
··· 17 17 struct drm_connector *exynos_drm_connector_create(struct drm_device *dev, 18 18 struct drm_encoder *encoder); 19 19 20 - struct drm_encoder *exynos_drm_best_encoder(struct drm_connector *connector); 21 - 22 - void exynos_drm_display_power(struct drm_connector *connector, int mode); 23 - 24 20 #endif
+5 -45
drivers/gpu/drm/exynos/exynos_drm_encoder.c
··· 29 29 * @manager: specific encoder has its own manager to control a hardware 30 30 * appropriately and we can access a hardware drawing on this manager. 31 31 * @dpms: store the encoder dpms value. 32 - * @updated: indicate whether overlay data updating is needed or not. 33 32 */ 34 33 struct exynos_drm_encoder { 35 34 struct drm_crtc *old_crtc; 36 35 struct drm_encoder drm_encoder; 37 36 struct exynos_drm_manager *manager; 38 37 int dpms; 39 - bool updated; 40 38 }; 41 - 42 - static void exynos_drm_connector_power(struct drm_encoder *encoder, int mode) 43 - { 44 - struct drm_device *dev = encoder->dev; 45 - struct drm_connector *connector; 46 - 47 - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 48 - if (exynos_drm_best_encoder(connector) == encoder) { 49 - DRM_DEBUG_KMS("connector[%d] dpms[%d]\n", 50 - connector->base.id, mode); 51 - 52 - exynos_drm_display_power(connector, mode); 53 - } 54 - } 55 - } 56 39 57 40 static void exynos_drm_encoder_dpms(struct drm_encoder *encoder, int mode) 58 41 { 59 - struct drm_device *dev = encoder->dev; 42 + struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder); 60 43 struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder); 44 + struct exynos_drm_display_ops *display_ops = manager->display_ops; 61 45 62 46 DRM_DEBUG_KMS("encoder dpms: %d\n", mode); 63 47 ··· 50 66 return; 51 67 } 52 68 53 - mutex_lock(&dev->struct_mutex); 69 + if (display_ops && display_ops->power_on) 70 + display_ops->power_on(manager->ctx, mode); 54 71 55 - switch (mode) { 56 - case DRM_MODE_DPMS_ON: 57 - exynos_drm_connector_power(encoder, mode); 58 - exynos_encoder->dpms = mode; 59 - break; 60 - case DRM_MODE_DPMS_STANDBY: 61 - case DRM_MODE_DPMS_SUSPEND: 62 - case DRM_MODE_DPMS_OFF: 63 - exynos_drm_connector_power(encoder, mode); 64 - exynos_encoder->dpms = mode; 65 - exynos_encoder->updated = false; 66 - break; 67 - default: 68 - DRM_ERROR("unspecified mode %d\n", mode); 69 - break; 70 - } 71 - 72 - mutex_unlock(&dev->struct_mutex); 72 + exynos_encoder->dpms = mode; 73 73 } 74 74 75 75 static bool ··· 157 189 158 190 if (manager_ops && manager_ops->commit) 159 191 manager_ops->commit(manager); 160 - 161 - /* 162 - * this will avoid one issue that overlay data is updated to 163 - * real hardware two times. 164 - * And this variable will be used to check if the data was 165 - * already updated or not by exynos_drm_encoder_dpms function. 166 - */ 167 - exynos_encoder->updated = true; 168 192 169 193 /* 170 194 * In case of setcrtc, there is no way to update encoder's dpms