diff options
Diffstat (limited to 'drivers/gpu/drm/drm_crtc_helper.c')
-rw-r--r-- | drivers/gpu/drm/drm_crtc_helper.c | 77 |
1 files changed, 70 insertions, 7 deletions
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 3969f7553fe7..84a4a809793f 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -34,6 +34,7 @@ #include "drmP.h" #include "drm_crtc.h" +#include "drm_fourcc.h" #include "drm_crtc_helper.h" #include "drm_fb_helper.h" @@ -456,6 +457,30 @@ done: EXPORT_SYMBOL(drm_crtc_helper_set_mode); +static int +drm_crtc_helper_disable(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_connector *connector; + struct drm_encoder *encoder; + + /* Decouple all encoders and their attached connectors from this crtc */ + list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { + if (encoder->crtc != crtc) + continue; + + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + if (connector->encoder != encoder) + continue; + + connector->encoder = NULL; + } + } + + drm_helper_disable_unused_functions(dev); + return 0; +} + /** * drm_crtc_helper_set_config - set a new config from userspace * @crtc: CRTC to setup @@ -510,8 +535,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) (int)set->num_connectors, set->x, set->y); } else { DRM_DEBUG_KMS("[CRTC:%d] [NOFB]\n", set->crtc->base.id); - set->mode = NULL; - set->num_connectors = 0; + return drm_crtc_helper_disable(set->crtc); } dev = set->crtc->dev; @@ -687,7 +711,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) for (i = 0; i < set->num_connectors; i++) { DRM_DEBUG_KMS("\t[CONNECTOR:%d:%s] set DPMS on\n", set->connectors[i]->base.id, drm_get_connector_name(set->connectors[i])); - set->connectors[i]->dpms = DRM_MODE_DPMS_ON; + set->connectors[i]->funcs->dpms(set->connectors[i], DRM_MODE_DPMS_ON); } } drm_helper_disable_unused_functions(dev); @@ -824,13 +848,19 @@ void drm_helper_connector_dpms(struct drm_connector *connector, int mode) EXPORT_SYMBOL(drm_helper_connector_dpms); int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb, - struct drm_mode_fb_cmd *mode_cmd) + struct drm_mode_fb_cmd2 *mode_cmd) { + int i; + fb->width = mode_cmd->width; fb->height = mode_cmd->height; - fb->pitch = mode_cmd->pitch; - fb->bits_per_pixel = mode_cmd->bpp; - fb->depth = mode_cmd->depth; + for (i = 0; i < 4; i++) { + fb->pitches[i] = mode_cmd->pitches[i]; + fb->offsets[i] = mode_cmd->offsets[i]; + } + drm_fb_get_bpp_depth(mode_cmd->pixel_format, &fb->depth, + &fb->bits_per_pixel); + fb->pixel_format = mode_cmd->pixel_format; return 0; } @@ -985,3 +1015,36 @@ void drm_helper_hpd_irq_event(struct drm_device *dev) queue_delayed_work(system_nrt_wq, &dev->mode_config.output_poll_work, 0); } EXPORT_SYMBOL(drm_helper_hpd_irq_event); + + +/** + * drm_format_num_planes - get the number of planes for format + * @format: pixel format (DRM_FORMAT_*) + * + * RETURNS: + * The number of planes used by the specified pixel format. + */ +int drm_format_num_planes(uint32_t format) +{ + switch (format) { + case DRM_FORMAT_YUV410: + case DRM_FORMAT_YVU410: + case DRM_FORMAT_YUV411: + case DRM_FORMAT_YVU411: + case DRM_FORMAT_YUV420: + case DRM_FORMAT_YVU420: + case DRM_FORMAT_YUV422: + case DRM_FORMAT_YVU422: + case DRM_FORMAT_YUV444: + case DRM_FORMAT_YVU444: + return 3; + case DRM_FORMAT_NV12: + case DRM_FORMAT_NV21: + case DRM_FORMAT_NV16: + case DRM_FORMAT_NV61: + return 2; + default: + return 1; + } +} +EXPORT_SYMBOL(drm_format_num_planes); |