Loading drivers/gpu/drm/omapdrm/omap_connector.c +25 −2 Original line number Diff line number Diff line Loading @@ -110,6 +110,11 @@ static enum drm_connector_status omap_connector_detect( ret = connector_status_connected; else ret = connector_status_disconnected; } else if (dssdev->type == OMAP_DISPLAY_TYPE_DPI || dssdev->type == OMAP_DISPLAY_TYPE_DBI || dssdev->type == OMAP_DISPLAY_TYPE_SDI || dssdev->type == OMAP_DISPLAY_TYPE_DSI) { ret = connector_status_connected; } else { ret = connector_status_unknown; } Loading Loading @@ -189,12 +194,30 @@ static int omap_connector_mode_valid(struct drm_connector *connector, struct omap_video_timings timings = {0}; struct drm_device *dev = connector->dev; struct drm_display_mode *new_mode; int ret = MODE_BAD; int r, ret = MODE_BAD; copy_timings_drm_to_omap(&timings, mode); mode->vrefresh = drm_mode_vrefresh(mode); if (!dssdrv->check_timings(dssdev, &timings)) { /* * if the panel driver doesn't have a check_timings, it's most likely * a fixed resolution panel, check if the timings match with the * panel's timings */ if (dssdrv->check_timings) { r = dssdrv->check_timings(dssdev, &timings); } else { struct omap_video_timings t = {0}; dssdrv->get_timings(dssdev, &t); if (memcmp(&timings, &t, sizeof(struct omap_video_timings))) r = -EINVAL; else r = 0; } if (!r) { /* check if vrefresh is still valid */ new_mode = drm_mode_duplicate(dev, mode); new_mode->clock = timings.pixel_clock; Loading drivers/gpu/drm/omapdrm/omap_crtc.c +14 −7 Original line number Diff line number Diff line Loading @@ -74,6 +74,13 @@ struct omap_crtc { struct work_struct page_flip_work; }; uint32_t pipe2vbl(struct drm_crtc *crtc) { struct omap_crtc *omap_crtc = to_omap_crtc(crtc); return dispc_mgr_get_vsync_irq(omap_crtc->channel); } /* * Manager-ops, callbacks from output when they need to configure * the upstream part of the video pipe. Loading Loading @@ -613,7 +620,13 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev, omap_crtc->apply.pre_apply = omap_crtc_pre_apply; omap_crtc->apply.post_apply = omap_crtc_post_apply; omap_crtc->apply_irq.irqmask = pipe2vbl(id); omap_crtc->channel = channel; omap_crtc->plane = plane; omap_crtc->plane->crtc = crtc; omap_crtc->name = channel_names[channel]; omap_crtc->pipe = id; omap_crtc->apply_irq.irqmask = pipe2vbl(crtc); omap_crtc->apply_irq.irq = omap_crtc_apply_irq; omap_crtc->error_irq.irqmask = Loading @@ -621,12 +634,6 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev, omap_crtc->error_irq.irq = omap_crtc_error_irq; omap_irq_register(dev, &omap_crtc->error_irq); omap_crtc->channel = channel; omap_crtc->plane = plane; omap_crtc->plane->crtc = crtc; omap_crtc->name = channel_names[channel]; omap_crtc->pipe = id; /* temporary: */ omap_crtc->mgr.id = channel; Loading drivers/gpu/drm/omapdrm/omap_drv.c +133 −32 Original line number Diff line number Diff line Loading @@ -74,54 +74,53 @@ static int get_connector_type(struct omap_dss_device *dssdev) } } static bool channel_used(struct drm_device *dev, enum omap_channel channel) { struct omap_drm_private *priv = dev->dev_private; int i; for (i = 0; i < priv->num_crtcs; i++) { struct drm_crtc *crtc = priv->crtcs[i]; if (omap_crtc_channel(crtc) == channel) return true; } return false; } static int omap_modeset_init(struct drm_device *dev) { struct omap_drm_private *priv = dev->dev_private; struct omap_dss_device *dssdev = NULL; int num_ovls = dss_feat_get_num_ovls(); int id; int num_mgrs = dss_feat_get_num_mgrs(); int num_crtcs; int i, id = 0; drm_mode_config_init(dev); omap_drm_irq_install(dev); /* * Create private planes and CRTCs for the last NUM_CRTCs overlay * plus manager: * We usually don't want to create a CRTC for each manager, at least * not until we have a way to expose private planes to userspace. * Otherwise there would not be enough video pipes left for drm planes. * We use the num_crtc argument to limit the number of crtcs we create. */ for (id = 0; id < min(num_crtc, num_ovls); id++) { struct drm_plane *plane; struct drm_crtc *crtc; num_crtcs = min3(num_crtc, num_mgrs, num_ovls); plane = omap_plane_init(dev, id, true); crtc = omap_crtc_init(dev, plane, pipe2chan(id), id); BUG_ON(priv->num_crtcs >= ARRAY_SIZE(priv->crtcs)); priv->crtcs[id] = crtc; priv->num_crtcs++; priv->planes[id] = plane; priv->num_planes++; } /* * Create normal planes for the remaining overlays: */ for (; id < num_ovls; id++) { struct drm_plane *plane = omap_plane_init(dev, id, false); BUG_ON(priv->num_planes >= ARRAY_SIZE(priv->planes)); priv->planes[priv->num_planes++] = plane; } dssdev = NULL; for_each_dss_dev(dssdev) { struct drm_connector *connector; struct drm_encoder *encoder; enum omap_channel channel; if (!dssdev->driver) { dev_warn(dev->dev, "%s has no driver.. skipping it\n", dssdev->name); return 0; continue; } if (!(dssdev->driver->get_timings || Loading @@ -129,7 +128,7 @@ static int omap_modeset_init(struct drm_device *dev) dev_warn(dev->dev, "%s driver does not support " "get_timings or read_edid.. skipping it!\n", dssdev->name); return 0; continue; } encoder = omap_encoder_init(dev, dssdev); Loading Loading @@ -157,16 +156,118 @@ static int omap_modeset_init(struct drm_device *dev) drm_mode_connector_attach_encoder(connector, encoder); /* * if we have reached the limit of the crtcs we are allowed to * create, let's not try to look for a crtc for this * panel/encoder and onwards, we will, of course, populate the * the possible_crtcs field for all the encoders with the final * set of crtcs we create */ if (id == num_crtcs) continue; /* * get the recommended DISPC channel for this encoder. For now, * we only try to get create a crtc out of the recommended, the * other possible channels to which the encoder can connect are * not considered. */ channel = dssdev->output->dispc_channel; /* * if this channel hasn't already been taken by a previously * allocated crtc, we create a new crtc for it */ if (!channel_used(dev, channel)) { struct drm_plane *plane; struct drm_crtc *crtc; plane = omap_plane_init(dev, id, true); crtc = omap_crtc_init(dev, plane, channel, id); BUG_ON(priv->num_crtcs >= ARRAY_SIZE(priv->crtcs)); priv->crtcs[id] = crtc; priv->num_crtcs++; priv->planes[id] = plane; priv->num_planes++; id++; } } /* * we have allocated crtcs according to the need of the panels/encoders, * adding more crtcs here if needed */ for (; id < num_crtcs; id++) { /* find a free manager for this crtc */ for (i = 0; i < num_mgrs; i++) { if (!channel_used(dev, i)) { struct drm_plane *plane; struct drm_crtc *crtc; plane = omap_plane_init(dev, id, true); crtc = omap_crtc_init(dev, plane, i, id); BUG_ON(priv->num_crtcs >= ARRAY_SIZE(priv->crtcs)); priv->crtcs[id] = crtc; priv->num_crtcs++; priv->planes[id] = plane; priv->num_planes++; break; } else { continue; } } if (i == num_mgrs) { /* this shouldn't really happen */ dev_err(dev->dev, "no managers left for crtc\n"); return -ENOMEM; } } /* * Create normal planes for the remaining overlays: */ for (; id < num_ovls; id++) { struct drm_plane *plane = omap_plane_init(dev, id, false); BUG_ON(priv->num_planes >= ARRAY_SIZE(priv->planes)); priv->planes[priv->num_planes++] = plane; } for (i = 0; i < priv->num_encoders; i++) { struct drm_encoder *encoder = priv->encoders[i]; struct omap_dss_device *dssdev = omap_encoder_get_dssdev(encoder); /* figure out which crtc's we can connect the encoder to: */ encoder->possible_crtcs = 0; for (id = 0; id < priv->num_crtcs; id++) { enum omap_dss_output_id supported_outputs = dss_feat_get_supported_outputs(pipe2chan(id)); struct drm_crtc *crtc = priv->crtcs[id]; enum omap_channel crtc_channel; enum omap_dss_output_id supported_outputs; crtc_channel = omap_crtc_channel(crtc); supported_outputs = dss_feat_get_supported_outputs(crtc_channel); if (supported_outputs & dssdev->output->id) encoder->possible_crtcs |= (1 << id); } } DBG("registered %d planes, %d crtcs, %d encoders and %d connectors\n", priv->num_planes, priv->num_crtcs, priv->num_encoders, priv->num_connectors); dev->mode_config.min_width = 32; dev->mode_config.min_height = 32; Loading Loading @@ -303,7 +404,7 @@ static int ioctl_gem_info(struct drm_device *dev, void *data, return ret; } struct drm_ioctl_desc ioctls[DRM_COMMAND_END - DRM_COMMAND_BASE] = { static struct drm_ioctl_desc ioctls[DRM_COMMAND_END - DRM_COMMAND_BASE] = { DRM_IOCTL_DEF_DRV(OMAP_GET_PARAM, ioctl_get_param, DRM_UNLOCKED|DRM_AUTH), DRM_IOCTL_DEF_DRV(OMAP_SET_PARAM, ioctl_set_param, DRM_UNLOCKED|DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF_DRV(OMAP_GEM_NEW, ioctl_gem_new, DRM_UNLOCKED|DRM_AUTH), Loading Loading @@ -567,7 +668,7 @@ static const struct dev_pm_ops omapdrm_pm_ops = { }; #endif struct platform_driver pdev = { static struct platform_driver pdev = { .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, Loading drivers/gpu/drm/omapdrm/omap_drv.h +4 −34 Original line number Diff line number Diff line Loading @@ -139,8 +139,8 @@ void omap_gem_describe_objects(struct list_head *list, struct seq_file *m); int omap_gem_resume(struct device *dev); #endif int omap_irq_enable_vblank(struct drm_device *dev, int crtc); void omap_irq_disable_vblank(struct drm_device *dev, int crtc); int omap_irq_enable_vblank(struct drm_device *dev, int crtc_id); void omap_irq_disable_vblank(struct drm_device *dev, int crtc_id); irqreturn_t omap_irq_handler(DRM_IRQ_ARGS); void omap_irq_preinstall(struct drm_device *dev); int omap_irq_postinstall(struct drm_device *dev); Loading Loading @@ -271,39 +271,9 @@ static inline int align_pitch(int pitch, int width, int bpp) return ALIGN(pitch, 8 * bytespp); } static inline enum omap_channel pipe2chan(int pipe) { int num_mgrs = dss_feat_get_num_mgrs(); /* * We usually don't want to create a CRTC for each manager, * at least not until we have a way to expose private planes * to userspace. Otherwise there would not be enough video * pipes left for drm planes. The higher #'d managers tend * to have more features so start in reverse order. */ return num_mgrs - pipe - 1; } /* map crtc to vblank mask */ static inline uint32_t pipe2vbl(int crtc) { enum omap_channel channel = pipe2chan(crtc); return dispc_mgr_get_vsync_irq(channel); } static inline int crtc2pipe(struct drm_device *dev, struct drm_crtc *crtc) { struct omap_drm_private *priv = dev->dev_private; int i; for (i = 0; i < ARRAY_SIZE(priv->crtcs); i++) if (priv->crtcs[i] == crtc) return i; BUG(); /* bogus CRTC ptr */ return -1; } uint32_t pipe2vbl(struct drm_crtc *crtc); struct omap_dss_device *omap_encoder_get_dssdev(struct drm_encoder *encoder); /* should these be made into common util helpers? */ Loading drivers/gpu/drm/omapdrm/omap_encoder.c +22 −2 Original line number Diff line number Diff line Loading @@ -41,6 +41,13 @@ struct omap_encoder { struct omap_dss_device *dssdev; }; struct omap_dss_device *omap_encoder_get_dssdev(struct drm_encoder *encoder) { struct omap_encoder *omap_encoder = to_omap_encoder(encoder); return omap_encoder->dssdev; } static void omap_encoder_destroy(struct drm_encoder *encoder) { struct omap_encoder *omap_encoder = to_omap_encoder(encoder); Loading Loading @@ -128,12 +135,25 @@ int omap_encoder_update(struct drm_encoder *encoder, dssdev->output->manager = mgr; if (dssdrv->check_timings) { ret = dssdrv->check_timings(dssdev, timings); } else { struct omap_video_timings t = {0}; dssdrv->get_timings(dssdev, &t); if (memcmp(timings, &t, sizeof(struct omap_video_timings))) ret = -EINVAL; else ret = 0; } if (ret) { dev_err(dev->dev, "could not set timings: %d\n", ret); return ret; } if (dssdrv->set_timings) dssdrv->set_timings(dssdev, timings); return 0; Loading Loading
drivers/gpu/drm/omapdrm/omap_connector.c +25 −2 Original line number Diff line number Diff line Loading @@ -110,6 +110,11 @@ static enum drm_connector_status omap_connector_detect( ret = connector_status_connected; else ret = connector_status_disconnected; } else if (dssdev->type == OMAP_DISPLAY_TYPE_DPI || dssdev->type == OMAP_DISPLAY_TYPE_DBI || dssdev->type == OMAP_DISPLAY_TYPE_SDI || dssdev->type == OMAP_DISPLAY_TYPE_DSI) { ret = connector_status_connected; } else { ret = connector_status_unknown; } Loading Loading @@ -189,12 +194,30 @@ static int omap_connector_mode_valid(struct drm_connector *connector, struct omap_video_timings timings = {0}; struct drm_device *dev = connector->dev; struct drm_display_mode *new_mode; int ret = MODE_BAD; int r, ret = MODE_BAD; copy_timings_drm_to_omap(&timings, mode); mode->vrefresh = drm_mode_vrefresh(mode); if (!dssdrv->check_timings(dssdev, &timings)) { /* * if the panel driver doesn't have a check_timings, it's most likely * a fixed resolution panel, check if the timings match with the * panel's timings */ if (dssdrv->check_timings) { r = dssdrv->check_timings(dssdev, &timings); } else { struct omap_video_timings t = {0}; dssdrv->get_timings(dssdev, &t); if (memcmp(&timings, &t, sizeof(struct omap_video_timings))) r = -EINVAL; else r = 0; } if (!r) { /* check if vrefresh is still valid */ new_mode = drm_mode_duplicate(dev, mode); new_mode->clock = timings.pixel_clock; Loading
drivers/gpu/drm/omapdrm/omap_crtc.c +14 −7 Original line number Diff line number Diff line Loading @@ -74,6 +74,13 @@ struct omap_crtc { struct work_struct page_flip_work; }; uint32_t pipe2vbl(struct drm_crtc *crtc) { struct omap_crtc *omap_crtc = to_omap_crtc(crtc); return dispc_mgr_get_vsync_irq(omap_crtc->channel); } /* * Manager-ops, callbacks from output when they need to configure * the upstream part of the video pipe. Loading Loading @@ -613,7 +620,13 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev, omap_crtc->apply.pre_apply = omap_crtc_pre_apply; omap_crtc->apply.post_apply = omap_crtc_post_apply; omap_crtc->apply_irq.irqmask = pipe2vbl(id); omap_crtc->channel = channel; omap_crtc->plane = plane; omap_crtc->plane->crtc = crtc; omap_crtc->name = channel_names[channel]; omap_crtc->pipe = id; omap_crtc->apply_irq.irqmask = pipe2vbl(crtc); omap_crtc->apply_irq.irq = omap_crtc_apply_irq; omap_crtc->error_irq.irqmask = Loading @@ -621,12 +634,6 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev, omap_crtc->error_irq.irq = omap_crtc_error_irq; omap_irq_register(dev, &omap_crtc->error_irq); omap_crtc->channel = channel; omap_crtc->plane = plane; omap_crtc->plane->crtc = crtc; omap_crtc->name = channel_names[channel]; omap_crtc->pipe = id; /* temporary: */ omap_crtc->mgr.id = channel; Loading
drivers/gpu/drm/omapdrm/omap_drv.c +133 −32 Original line number Diff line number Diff line Loading @@ -74,54 +74,53 @@ static int get_connector_type(struct omap_dss_device *dssdev) } } static bool channel_used(struct drm_device *dev, enum omap_channel channel) { struct omap_drm_private *priv = dev->dev_private; int i; for (i = 0; i < priv->num_crtcs; i++) { struct drm_crtc *crtc = priv->crtcs[i]; if (omap_crtc_channel(crtc) == channel) return true; } return false; } static int omap_modeset_init(struct drm_device *dev) { struct omap_drm_private *priv = dev->dev_private; struct omap_dss_device *dssdev = NULL; int num_ovls = dss_feat_get_num_ovls(); int id; int num_mgrs = dss_feat_get_num_mgrs(); int num_crtcs; int i, id = 0; drm_mode_config_init(dev); omap_drm_irq_install(dev); /* * Create private planes and CRTCs for the last NUM_CRTCs overlay * plus manager: * We usually don't want to create a CRTC for each manager, at least * not until we have a way to expose private planes to userspace. * Otherwise there would not be enough video pipes left for drm planes. * We use the num_crtc argument to limit the number of crtcs we create. */ for (id = 0; id < min(num_crtc, num_ovls); id++) { struct drm_plane *plane; struct drm_crtc *crtc; num_crtcs = min3(num_crtc, num_mgrs, num_ovls); plane = omap_plane_init(dev, id, true); crtc = omap_crtc_init(dev, plane, pipe2chan(id), id); BUG_ON(priv->num_crtcs >= ARRAY_SIZE(priv->crtcs)); priv->crtcs[id] = crtc; priv->num_crtcs++; priv->planes[id] = plane; priv->num_planes++; } /* * Create normal planes for the remaining overlays: */ for (; id < num_ovls; id++) { struct drm_plane *plane = omap_plane_init(dev, id, false); BUG_ON(priv->num_planes >= ARRAY_SIZE(priv->planes)); priv->planes[priv->num_planes++] = plane; } dssdev = NULL; for_each_dss_dev(dssdev) { struct drm_connector *connector; struct drm_encoder *encoder; enum omap_channel channel; if (!dssdev->driver) { dev_warn(dev->dev, "%s has no driver.. skipping it\n", dssdev->name); return 0; continue; } if (!(dssdev->driver->get_timings || Loading @@ -129,7 +128,7 @@ static int omap_modeset_init(struct drm_device *dev) dev_warn(dev->dev, "%s driver does not support " "get_timings or read_edid.. skipping it!\n", dssdev->name); return 0; continue; } encoder = omap_encoder_init(dev, dssdev); Loading Loading @@ -157,16 +156,118 @@ static int omap_modeset_init(struct drm_device *dev) drm_mode_connector_attach_encoder(connector, encoder); /* * if we have reached the limit of the crtcs we are allowed to * create, let's not try to look for a crtc for this * panel/encoder and onwards, we will, of course, populate the * the possible_crtcs field for all the encoders with the final * set of crtcs we create */ if (id == num_crtcs) continue; /* * get the recommended DISPC channel for this encoder. For now, * we only try to get create a crtc out of the recommended, the * other possible channels to which the encoder can connect are * not considered. */ channel = dssdev->output->dispc_channel; /* * if this channel hasn't already been taken by a previously * allocated crtc, we create a new crtc for it */ if (!channel_used(dev, channel)) { struct drm_plane *plane; struct drm_crtc *crtc; plane = omap_plane_init(dev, id, true); crtc = omap_crtc_init(dev, plane, channel, id); BUG_ON(priv->num_crtcs >= ARRAY_SIZE(priv->crtcs)); priv->crtcs[id] = crtc; priv->num_crtcs++; priv->planes[id] = plane; priv->num_planes++; id++; } } /* * we have allocated crtcs according to the need of the panels/encoders, * adding more crtcs here if needed */ for (; id < num_crtcs; id++) { /* find a free manager for this crtc */ for (i = 0; i < num_mgrs; i++) { if (!channel_used(dev, i)) { struct drm_plane *plane; struct drm_crtc *crtc; plane = omap_plane_init(dev, id, true); crtc = omap_crtc_init(dev, plane, i, id); BUG_ON(priv->num_crtcs >= ARRAY_SIZE(priv->crtcs)); priv->crtcs[id] = crtc; priv->num_crtcs++; priv->planes[id] = plane; priv->num_planes++; break; } else { continue; } } if (i == num_mgrs) { /* this shouldn't really happen */ dev_err(dev->dev, "no managers left for crtc\n"); return -ENOMEM; } } /* * Create normal planes for the remaining overlays: */ for (; id < num_ovls; id++) { struct drm_plane *plane = omap_plane_init(dev, id, false); BUG_ON(priv->num_planes >= ARRAY_SIZE(priv->planes)); priv->planes[priv->num_planes++] = plane; } for (i = 0; i < priv->num_encoders; i++) { struct drm_encoder *encoder = priv->encoders[i]; struct omap_dss_device *dssdev = omap_encoder_get_dssdev(encoder); /* figure out which crtc's we can connect the encoder to: */ encoder->possible_crtcs = 0; for (id = 0; id < priv->num_crtcs; id++) { enum omap_dss_output_id supported_outputs = dss_feat_get_supported_outputs(pipe2chan(id)); struct drm_crtc *crtc = priv->crtcs[id]; enum omap_channel crtc_channel; enum omap_dss_output_id supported_outputs; crtc_channel = omap_crtc_channel(crtc); supported_outputs = dss_feat_get_supported_outputs(crtc_channel); if (supported_outputs & dssdev->output->id) encoder->possible_crtcs |= (1 << id); } } DBG("registered %d planes, %d crtcs, %d encoders and %d connectors\n", priv->num_planes, priv->num_crtcs, priv->num_encoders, priv->num_connectors); dev->mode_config.min_width = 32; dev->mode_config.min_height = 32; Loading Loading @@ -303,7 +404,7 @@ static int ioctl_gem_info(struct drm_device *dev, void *data, return ret; } struct drm_ioctl_desc ioctls[DRM_COMMAND_END - DRM_COMMAND_BASE] = { static struct drm_ioctl_desc ioctls[DRM_COMMAND_END - DRM_COMMAND_BASE] = { DRM_IOCTL_DEF_DRV(OMAP_GET_PARAM, ioctl_get_param, DRM_UNLOCKED|DRM_AUTH), DRM_IOCTL_DEF_DRV(OMAP_SET_PARAM, ioctl_set_param, DRM_UNLOCKED|DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF_DRV(OMAP_GEM_NEW, ioctl_gem_new, DRM_UNLOCKED|DRM_AUTH), Loading Loading @@ -567,7 +668,7 @@ static const struct dev_pm_ops omapdrm_pm_ops = { }; #endif struct platform_driver pdev = { static struct platform_driver pdev = { .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, Loading
drivers/gpu/drm/omapdrm/omap_drv.h +4 −34 Original line number Diff line number Diff line Loading @@ -139,8 +139,8 @@ void omap_gem_describe_objects(struct list_head *list, struct seq_file *m); int omap_gem_resume(struct device *dev); #endif int omap_irq_enable_vblank(struct drm_device *dev, int crtc); void omap_irq_disable_vblank(struct drm_device *dev, int crtc); int omap_irq_enable_vblank(struct drm_device *dev, int crtc_id); void omap_irq_disable_vblank(struct drm_device *dev, int crtc_id); irqreturn_t omap_irq_handler(DRM_IRQ_ARGS); void omap_irq_preinstall(struct drm_device *dev); int omap_irq_postinstall(struct drm_device *dev); Loading Loading @@ -271,39 +271,9 @@ static inline int align_pitch(int pitch, int width, int bpp) return ALIGN(pitch, 8 * bytespp); } static inline enum omap_channel pipe2chan(int pipe) { int num_mgrs = dss_feat_get_num_mgrs(); /* * We usually don't want to create a CRTC for each manager, * at least not until we have a way to expose private planes * to userspace. Otherwise there would not be enough video * pipes left for drm planes. The higher #'d managers tend * to have more features so start in reverse order. */ return num_mgrs - pipe - 1; } /* map crtc to vblank mask */ static inline uint32_t pipe2vbl(int crtc) { enum omap_channel channel = pipe2chan(crtc); return dispc_mgr_get_vsync_irq(channel); } static inline int crtc2pipe(struct drm_device *dev, struct drm_crtc *crtc) { struct omap_drm_private *priv = dev->dev_private; int i; for (i = 0; i < ARRAY_SIZE(priv->crtcs); i++) if (priv->crtcs[i] == crtc) return i; BUG(); /* bogus CRTC ptr */ return -1; } uint32_t pipe2vbl(struct drm_crtc *crtc); struct omap_dss_device *omap_encoder_get_dssdev(struct drm_encoder *encoder); /* should these be made into common util helpers? */ Loading
drivers/gpu/drm/omapdrm/omap_encoder.c +22 −2 Original line number Diff line number Diff line Loading @@ -41,6 +41,13 @@ struct omap_encoder { struct omap_dss_device *dssdev; }; struct omap_dss_device *omap_encoder_get_dssdev(struct drm_encoder *encoder) { struct omap_encoder *omap_encoder = to_omap_encoder(encoder); return omap_encoder->dssdev; } static void omap_encoder_destroy(struct drm_encoder *encoder) { struct omap_encoder *omap_encoder = to_omap_encoder(encoder); Loading Loading @@ -128,12 +135,25 @@ int omap_encoder_update(struct drm_encoder *encoder, dssdev->output->manager = mgr; if (dssdrv->check_timings) { ret = dssdrv->check_timings(dssdev, timings); } else { struct omap_video_timings t = {0}; dssdrv->get_timings(dssdev, &t); if (memcmp(timings, &t, sizeof(struct omap_video_timings))) ret = -EINVAL; else ret = 0; } if (ret) { dev_err(dev->dev, "could not set timings: %d\n", ret); return ret; } if (dssdrv->set_timings) dssdrv->set_timings(dssdev, timings); return 0; Loading