Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 371378
b: refs/heads/master
c: 48c2169
h: refs/heads/master
v: v3
  • Loading branch information
Alexandru Gheorghiu authored and Tomi Valkeinen committed Apr 10, 2013
1 parent b6bede4 commit 4b920a5
Show file tree
Hide file tree
Showing 24 changed files with 1,143 additions and 1,502 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6717cd2937e7210321c5917f37f036895978f4d3
refs/heads/master: 48c2169fd9922314d990f944068f107a3284434e
27 changes: 2 additions & 25 deletions trunk/drivers/gpu/drm/omapdrm/omap_connector.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,6 @@ 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;
}
Expand Down Expand Up @@ -194,30 +189,12 @@ 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 r, ret = MODE_BAD;
int ret = MODE_BAD;

copy_timings_drm_to_omap(&timings, mode);
mode->vrefresh = drm_mode_vrefresh(mode);

/*
* 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) {
if (!dssdrv->check_timings(dssdev, &timings)) {
/* check if vrefresh is still valid */
new_mode = drm_mode_duplicate(dev, mode);
new_mode->clock = timings.pixel_clock;
Expand Down
21 changes: 7 additions & 14 deletions trunk/drivers/gpu/drm/omapdrm/omap_crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,6 @@ 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.
Expand Down Expand Up @@ -620,20 +613,20 @@ 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->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.irqmask = pipe2vbl(id);
omap_crtc->apply_irq.irq = omap_crtc_apply_irq;

omap_crtc->error_irq.irqmask =
dispc_mgr_get_sync_lost_irq(channel);
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;

Expand Down
165 changes: 32 additions & 133 deletions trunk/drivers/gpu/drm/omapdrm/omap_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,61 +74,62 @@ 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 num_mgrs = dss_feat_get_num_mgrs();
int num_crtcs;
int i, id = 0;
int id;

drm_mode_config_init(dev);

omap_drm_irq_install(dev);

/*
* 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.
* Create private planes and CRTCs for the last NUM_CRTCs overlay
* plus manager:
*/
num_crtcs = min3(num_crtc, num_mgrs, num_ovls);
for (id = 0; id < min(num_crtc, num_ovls); id++) {
struct drm_plane *plane;
struct drm_crtc *crtc;

plane = omap_plane_init(dev, id, true);
crtc = omap_crtc_init(dev, plane, pipe2chan(id), id);

dssdev = NULL;
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;
}

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);
continue;
return 0;
}

if (!(dssdev->driver->get_timings ||
dssdev->driver->read_edid)) {
dev_warn(dev->dev, "%s driver does not support "
"get_timings or read_edid.. skipping it!\n",
dssdev->name);
continue;
return 0;
}

encoder = omap_encoder_init(dev, dssdev);
Expand Down Expand Up @@ -156,118 +157,16 @@ 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++) {
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);

enum omap_dss_output_id supported_outputs =
dss_feat_get_supported_outputs(pipe2chan(id));
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;

Expand Down Expand Up @@ -404,7 +303,7 @@ static int ioctl_gem_info(struct drm_device *dev, void *data,
return ret;
}

static struct drm_ioctl_desc ioctls[DRM_COMMAND_END - DRM_COMMAND_BASE] = {
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),
Expand Down Expand Up @@ -668,7 +567,7 @@ static const struct dev_pm_ops omapdrm_pm_ops = {
};
#endif

static struct platform_driver pdev = {
struct platform_driver pdev = {
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
Expand Down
38 changes: 34 additions & 4 deletions trunk/drivers/gpu/drm/omapdrm/omap_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_id);
void omap_irq_disable_vblank(struct drm_device *dev, int crtc_id);
int omap_irq_enable_vblank(struct drm_device *dev, int crtc);
void omap_irq_disable_vblank(struct drm_device *dev, int crtc);
irqreturn_t omap_irq_handler(DRM_IRQ_ARGS);
void omap_irq_preinstall(struct drm_device *dev);
int omap_irq_postinstall(struct drm_device *dev);
Expand Down Expand Up @@ -271,9 +271,39 @@ 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 */
uint32_t pipe2vbl(struct drm_crtc *crtc);
struct omap_dss_device *omap_encoder_get_dssdev(struct drm_encoder *encoder);
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;
}

/* should these be made into common util helpers?
*/
Expand Down
Loading

0 comments on commit 4b920a5

Please sign in to comment.