Skip to content

Commit

Permalink
Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux
Browse files Browse the repository at this point in the history
Pill drm updates part 2 from Dave Airlie:
 "This is the follow-up pull, 3 pieces

  a) exynos next stuff, was delayed but looks okay to me, one patch in
     v4l bits but it was acked by v4l person.
  b) UAPI disintegration bits
  c) intel fixes - DP fixes, hang fixes, other misc fixes."

* 'drm-next' of git://people.freedesktop.org/~airlied/linux: (52 commits)
  drm: exynos: hdmi: remove drm common hdmi platform data struct
  drm: exynos: hdmi: add support for exynos5 hdmi
  drm: exynos: hdmi: replace is_v13 with version check in hdmi
  drm: exynos: hdmi: add support for exynos5 mixer
  drm: exynos: hdmi: add support to disable video processor in mixer
  drm: exynos: hdmi: add support for platform variants for mixer
  drm: exynos: hdmi: add support for exynos5 hdmiphy
  drm: exynos: hdmi: add support for exynos5 ddc
  drm: exynos: remove drm hdmi platform data struct
  drm: exynos: hdmi: turn off HPD interrupt in HDMI chip
  drm: exynos: hdmi: use s5p-hdmi platform data
  drm: exynos: hdmi: fix interrupt handling
  drm: exynos: hdmi: support for platform variants
  media: s5p-hdmi: add HPD GPIO to platform data
  UAPI: (Scripted) Disintegrate include/drm
  drm/i915: Fix GT_MODE default value
  drm/i915: don't frob the vblank ts in finish_page_flip
  drm/i915: call drm_handle_vblank before finish_page_flip
  drm/i915: print warning if vmi915_gem_fault error is not handled
  drm/i915: EBUSY status handling added to i915_gem_fault().
  ...
  • Loading branch information
Linus Torvalds committed Oct 8, 2012
2 parents d43b716 + 1f31c69 commit 1929041
Show file tree
Hide file tree
Showing 52 changed files with 2,267 additions and 1,426 deletions.
3 changes: 2 additions & 1 deletion drivers/gpu/drm/drm_edid.c
Original file line number Diff line number Diff line change
Expand Up @@ -395,13 +395,14 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
* \param adapter : i2c device adaptor
* \return 1 on success
*/
static bool
bool
drm_probe_ddc(struct i2c_adapter *adapter)
{
unsigned char out;

return (drm_do_probe_ddc_edid(adapter, &out, 0, 1) == 0);
}
EXPORT_SYMBOL(drm_probe_ddc);

/**
* drm_get_edid - get EDID data, if available
Expand Down
22 changes: 17 additions & 5 deletions drivers/gpu/drm/exynos/exynos_ddc.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,29 +26,41 @@ static int s5p_ddc_probe(struct i2c_client *client,
{
hdmi_attach_ddc_client(client);

dev_info(&client->adapter->dev, "attached s5p_ddc "
"into i2c adapter successfully\n");
dev_info(&client->adapter->dev,
"attached %s into i2c adapter successfully\n",
client->name);

return 0;
}

static int s5p_ddc_remove(struct i2c_client *client)
{
dev_info(&client->adapter->dev, "detached s5p_ddc "
"from i2c adapter successfully\n");
dev_info(&client->adapter->dev,
"detached %s from i2c adapter successfully\n",
client->name);

return 0;
}

static struct i2c_device_id ddc_idtable[] = {
{"s5p_ddc", 0},
{"exynos5-hdmiddc", 0},
{ },
};

static struct of_device_id hdmiddc_match_types[] = {
{
.compatible = "samsung,exynos5-hdmiddc",
}, {
/* end node */
}
};

struct i2c_driver ddc_driver = {
.driver = {
.name = "s5p_ddc",
.name = "exynos-hdmiddc",
.owner = THIS_MODULE,
.of_match_table = hdmiddc_match_types,
},
.id_table = ddc_idtable,
.probe = s5p_ddc_probe,
Expand Down
50 changes: 46 additions & 4 deletions drivers/gpu/drm/exynos/exynos_drm_connector.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ struct exynos_drm_connector {
struct drm_connector drm_connector;
uint32_t encoder_id;
struct exynos_drm_manager *manager;
uint32_t dpms;
};

/* convert exynos_video_timings to drm_display_mode */
Expand Down Expand Up @@ -149,8 +150,12 @@ static int exynos_drm_connector_get_modes(struct drm_connector *connector)
count = drm_add_edid_modes(connector, edid);
kfree(edid);
} else {
struct drm_display_mode *mode = drm_mode_create(connector->dev);
struct exynos_drm_panel_info *panel;
struct drm_display_mode *mode = drm_mode_create(connector->dev);
if (!mode) {
DRM_ERROR("failed to create a new display mode.\n");
return 0;
}

if (display_ops->get_panel)
panel = display_ops->get_panel(manager->dev);
Expand Down Expand Up @@ -194,8 +199,7 @@ static int exynos_drm_connector_mode_valid(struct drm_connector *connector,
return ret;
}

static struct drm_encoder *exynos_drm_best_encoder(
struct drm_connector *connector)
struct drm_encoder *exynos_drm_best_encoder(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
struct exynos_drm_connector *exynos_connector =
Expand Down Expand Up @@ -224,6 +228,43 @@ static struct drm_connector_helper_funcs exynos_connector_helper_funcs = {
.best_encoder = exynos_drm_best_encoder,
};

void exynos_drm_display_power(struct drm_connector *connector, int mode)
{
struct drm_encoder *encoder = exynos_drm_best_encoder(connector);
struct exynos_drm_connector *exynos_connector;
struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder);
struct exynos_drm_display_ops *display_ops = manager->display_ops;

exynos_connector = to_exynos_connector(connector);

if (exynos_connector->dpms == mode) {
DRM_DEBUG_KMS("desired dpms mode is same as previous one.\n");
return;
}

if (display_ops && display_ops->power_on)
display_ops->power_on(manager->dev, mode);

exynos_connector->dpms = mode;
}

static void exynos_drm_connector_dpms(struct drm_connector *connector,
int mode)
{
DRM_DEBUG_KMS("%s\n", __FILE__);

/*
* in case that drm_crtc_helper_set_mode() is called,
* encoder/crtc->funcs->dpms() will be just returned
* because they already were DRM_MODE_DPMS_ON so only
* exynos_drm_display_power() will be called.
*/
drm_helper_connector_dpms(connector, mode);

exynos_drm_display_power(connector, mode);

}

static int exynos_drm_connector_fill_modes(struct drm_connector *connector,
unsigned int max_width, unsigned int max_height)
{
Expand Down Expand Up @@ -283,7 +324,7 @@ static void exynos_drm_connector_destroy(struct drm_connector *connector)
}

static struct drm_connector_funcs exynos_connector_funcs = {
.dpms = drm_helper_connector_dpms,
.dpms = exynos_drm_connector_dpms,
.fill_modes = exynos_drm_connector_fill_modes,
.detect = exynos_drm_connector_detect,
.destroy = exynos_drm_connector_destroy,
Expand Down Expand Up @@ -332,6 +373,7 @@ struct drm_connector *exynos_drm_connector_create(struct drm_device *dev,

exynos_connector->encoder_id = encoder->base.id;
exynos_connector->manager = manager;
exynos_connector->dpms = DRM_MODE_DPMS_OFF;
connector->encoder = encoder;

err = drm_mode_connector_attach_encoder(connector, encoder);
Expand Down
4 changes: 4 additions & 0 deletions drivers/gpu/drm/exynos/exynos_drm_connector.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,8 @@
struct drm_connector *exynos_drm_connector_create(struct drm_device *dev,
struct drm_encoder *encoder);

struct drm_encoder *exynos_drm_best_encoder(struct drm_connector *connector);

void exynos_drm_display_power(struct drm_connector *connector, int mode);

#endif
100 changes: 69 additions & 31 deletions drivers/gpu/drm/exynos/exynos_drm_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,33 +34,15 @@

static LIST_HEAD(exynos_drm_subdrv_list);

static int exynos_drm_subdrv_probe(struct drm_device *dev,
static int exynos_drm_create_enc_conn(struct drm_device *dev,
struct exynos_drm_subdrv *subdrv)
{
struct drm_encoder *encoder;
struct drm_connector *connector;
int ret;

DRM_DEBUG_DRIVER("%s\n", __FILE__);

if (subdrv->probe) {
int ret;

/*
* this probe callback would be called by sub driver
* after setting of all resources to this sub driver,
* such as clock, irq and register map are done or by load()
* of exynos drm driver.
*
* P.S. note that this driver is considered for modularization.
*/
ret = subdrv->probe(dev, subdrv->dev);
if (ret)
return ret;
}

if (!subdrv->manager)
return 0;

subdrv->manager->dev = subdrv->dev;

/* create and initialize a encoder for this sub driver. */
Expand All @@ -78,24 +60,22 @@ static int exynos_drm_subdrv_probe(struct drm_device *dev,
connector = exynos_drm_connector_create(dev, encoder);
if (!connector) {
DRM_ERROR("failed to create connector\n");
encoder->funcs->destroy(encoder);
return -EFAULT;
ret = -EFAULT;
goto err_destroy_encoder;
}

subdrv->encoder = encoder;
subdrv->connector = connector;

return 0;

err_destroy_encoder:
encoder->funcs->destroy(encoder);
return ret;
}

static void exynos_drm_subdrv_remove(struct drm_device *dev,
struct exynos_drm_subdrv *subdrv)
static void exynos_drm_destroy_enc_conn(struct exynos_drm_subdrv *subdrv)
{
DRM_DEBUG_DRIVER("%s\n", __FILE__);

if (subdrv->remove)
subdrv->remove(dev);

if (subdrv->encoder) {
struct drm_encoder *encoder = subdrv->encoder;
encoder->funcs->destroy(encoder);
Expand All @@ -109,9 +89,43 @@ static void exynos_drm_subdrv_remove(struct drm_device *dev,
}
}

static int exynos_drm_subdrv_probe(struct drm_device *dev,
struct exynos_drm_subdrv *subdrv)
{
if (subdrv->probe) {
int ret;

subdrv->drm_dev = dev;

/*
* this probe callback would be called by sub driver
* after setting of all resources to this sub driver,
* such as clock, irq and register map are done or by load()
* of exynos drm driver.
*
* P.S. note that this driver is considered for modularization.
*/
ret = subdrv->probe(dev, subdrv->dev);
if (ret)
return ret;
}

return 0;
}

static void exynos_drm_subdrv_remove(struct drm_device *dev,
struct exynos_drm_subdrv *subdrv)
{
DRM_DEBUG_DRIVER("%s\n", __FILE__);

if (subdrv->remove)
subdrv->remove(dev, subdrv->dev);
}

int exynos_drm_device_register(struct drm_device *dev)
{
struct exynos_drm_subdrv *subdrv, *n;
unsigned int fine_cnt = 0;
int err;

DRM_DEBUG_DRIVER("%s\n", __FILE__);
Expand All @@ -120,14 +134,36 @@ int exynos_drm_device_register(struct drm_device *dev)
return -EINVAL;

list_for_each_entry_safe(subdrv, n, &exynos_drm_subdrv_list, list) {
subdrv->drm_dev = dev;
err = exynos_drm_subdrv_probe(dev, subdrv);
if (err) {
DRM_DEBUG("exynos drm subdrv probe failed.\n");
list_del(&subdrv->list);
continue;
}

/*
* if manager is null then it means that this sub driver
* doesn't need encoder and connector.
*/
if (!subdrv->manager) {
fine_cnt++;
continue;
}

err = exynos_drm_create_enc_conn(dev, subdrv);
if (err) {
DRM_DEBUG("failed to create encoder and connector.\n");
exynos_drm_subdrv_remove(dev, subdrv);
list_del(&subdrv->list);
continue;
}

fine_cnt++;
}

if (!fine_cnt)
return -EINVAL;

return 0;
}
EXPORT_SYMBOL_GPL(exynos_drm_device_register);
Expand All @@ -143,8 +179,10 @@ int exynos_drm_device_unregister(struct drm_device *dev)
return -EINVAL;
}

list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list)
list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) {
exynos_drm_subdrv_remove(dev, subdrv);
exynos_drm_destroy_enc_conn(subdrv);
}

return 0;
}
Expand Down
20 changes: 13 additions & 7 deletions drivers/gpu/drm/exynos/exynos_drm_crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ struct exynos_drm_crtc {

static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode)
{
struct drm_device *dev = crtc->dev;
struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);

DRM_DEBUG_KMS("crtc[%d] mode[%d]\n", crtc->base.id, mode);
Expand All @@ -76,12 +75,8 @@ static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode)
return;
}

mutex_lock(&dev->struct_mutex);

exynos_drm_fn_encoder(crtc, &mode, exynos_drm_encoder_crtc_dpms);
exynos_crtc->dpms = mode;

mutex_unlock(&dev->struct_mutex);
}

static void exynos_drm_crtc_prepare(struct drm_crtc *crtc)
Expand All @@ -97,6 +92,7 @@ static void exynos_drm_crtc_commit(struct drm_crtc *crtc)

DRM_DEBUG_KMS("%s\n", __FILE__);

exynos_drm_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
exynos_plane_commit(exynos_crtc->plane);
exynos_plane_dpms(exynos_crtc->plane, DRM_MODE_DPMS_ON);
}
Expand Down Expand Up @@ -126,8 +122,6 @@ exynos_drm_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,

DRM_DEBUG_KMS("%s\n", __FILE__);

exynos_drm_crtc_dpms(crtc, DRM_MODE_DPMS_ON);

/*
* copy the mode data adjusted by mode_fixup() into crtc->mode
* so that hardware can be seet to proper mode.
Expand Down Expand Up @@ -161,6 +155,12 @@ static int exynos_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,

DRM_DEBUG_KMS("%s\n", __FILE__);

/* when framebuffer changing is requested, crtc's dpms should be on */
if (exynos_crtc->dpms > DRM_MODE_DPMS_ON) {
DRM_ERROR("failed framebuffer changing request.\n");
return -EPERM;
}

crtc_w = crtc->fb->width - x;
crtc_h = crtc->fb->height - y;

Expand Down Expand Up @@ -213,6 +213,12 @@ static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc,

DRM_DEBUG_KMS("%s\n", __FILE__);

/* when the page flip is requested, crtc's dpms should be on */
if (exynos_crtc->dpms > DRM_MODE_DPMS_ON) {
DRM_ERROR("failed page flip request.\n");
return -EINVAL;
}

mutex_lock(&dev->struct_mutex);

if (event) {
Expand Down
Loading

0 comments on commit 1929041

Please sign in to comment.