提交 425a9a3a 编写于 作者: D Dave Airlie

Merge tag 'topic/core-stuff-2014-05-05' of git://anongit.freedesktop.org/drm-intel into drm-next

Update pull request with drm core patches. Mostly some polish for the
primary plane stuff and a pile of patches all over from Thierry. Has
survived a few days in drm-intel-nightly without causing ill.

I've frobbed my scripts a bit to also tag my topic branches so that you
have something stable to pull - I've accidentally pushed a bunch more
patches onto this branch before you've taken the old pull request.

* tag 'topic/core-stuff-2014-05-05' of git://anongit.freedesktop.org/drm-intel:
  drm: Make drm_crtc_helper_disable() return void
  drm: Fix indentation of closing brace
  drm/dp: Fix typo in comment
  drm: Fixup flip-work kerneldoc
  drm/fb: Fix typos
  drm/edid: Cleanup kerneldoc
  drm/edid: Drop revision argument for drm_mode_std()
  drm: Try to acquire modeset lock on panic or sysrq
  drm: remove unused argument from drm_open_helper
  drm: Handle ->disable_plane failures correctly
  drm: Simplify fb refcounting rules around ->update_plane
  drm/crtc-helper: gc usless connector loop in disable_unused_functions
  drm/plane_helper: don't disable plane in destroy function
  drm/plane-helper: Fix primary plane scaling check
  drm: make mode_valid callback optional
  drm/edid: Fill PAR in AVI infoframe based on CEA mode list
...@@ -1895,8 +1895,8 @@ void intel_crt_init(struct drm_device *dev) ...@@ -1895,8 +1895,8 @@ void intel_crt_init(struct drm_device *dev)
<para> <para>
The function filters out modes larger than The function filters out modes larger than
<parameter>max_width</parameter> and <parameter>max_height</parameter> <parameter>max_width</parameter> and <parameter>max_height</parameter>
if specified. It then calls the connector if specified. It then calls the optional connector
<methodname>mode_valid</methodname> helper operation for each mode in <methodname>mode_valid</methodname> helper operation for each mode in
the probed list to check whether the mode is valid for the connector. the probed list to check whether the mode is valid for the connector.
</para> </para>
</listitem> </listitem>
...@@ -2257,7 +2257,7 @@ void intel_crt_init(struct drm_device *dev) ...@@ -2257,7 +2257,7 @@ void intel_crt_init(struct drm_device *dev)
<para> <para>
Verify whether a mode is valid for the connector. Return MODE_OK for Verify whether a mode is valid for the connector. Return MODE_OK for
supported modes and one of the enum drm_mode_status values (MODE_*) supported modes and one of the enum drm_mode_status values (MODE_*)
for unsupported modes. This operation is mandatory. for unsupported modes. This operation is optional.
</para> </para>
<para> <para>
As the mode rejection reason is currently not used beside for As the mode rejection reason is currently not used beside for
......
...@@ -743,12 +743,6 @@ static int ast_get_modes(struct drm_connector *connector) ...@@ -743,12 +743,6 @@ static int ast_get_modes(struct drm_connector *connector)
return 0; return 0;
} }
static int ast_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
return MODE_OK;
}
static void ast_connector_destroy(struct drm_connector *connector) static void ast_connector_destroy(struct drm_connector *connector)
{ {
struct ast_connector *ast_connector = to_ast_connector(connector); struct ast_connector *ast_connector = to_ast_connector(connector);
...@@ -765,7 +759,6 @@ ast_connector_detect(struct drm_connector *connector, bool force) ...@@ -765,7 +759,6 @@ ast_connector_detect(struct drm_connector *connector, bool force)
} }
static const struct drm_connector_helper_funcs ast_connector_helper_funcs = { static const struct drm_connector_helper_funcs ast_connector_helper_funcs = {
.mode_valid = ast_mode_valid,
.get_modes = ast_get_modes, .get_modes = ast_get_modes,
.best_encoder = ast_best_single_encoder, .best_encoder = ast_best_single_encoder,
}; };
......
...@@ -225,12 +225,6 @@ int ptn3460_get_modes(struct drm_connector *connector) ...@@ -225,12 +225,6 @@ int ptn3460_get_modes(struct drm_connector *connector)
return num_modes; return num_modes;
} }
static int ptn3460_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
return MODE_OK;
}
struct drm_encoder *ptn3460_best_encoder(struct drm_connector *connector) struct drm_encoder *ptn3460_best_encoder(struct drm_connector *connector)
{ {
struct ptn3460_bridge *ptn_bridge; struct ptn3460_bridge *ptn_bridge;
...@@ -242,7 +236,6 @@ struct drm_encoder *ptn3460_best_encoder(struct drm_connector *connector) ...@@ -242,7 +236,6 @@ struct drm_encoder *ptn3460_best_encoder(struct drm_connector *connector)
struct drm_connector_helper_funcs ptn3460_connector_helper_funcs = { struct drm_connector_helper_funcs ptn3460_connector_helper_funcs = {
.get_modes = ptn3460_get_modes, .get_modes = ptn3460_get_modes,
.mode_valid = ptn3460_mode_valid,
.best_encoder = ptn3460_best_encoder, .best_encoder = ptn3460_best_encoder,
}; };
......
...@@ -505,13 +505,6 @@ static int cirrus_vga_get_modes(struct drm_connector *connector) ...@@ -505,13 +505,6 @@ static int cirrus_vga_get_modes(struct drm_connector *connector)
return count; return count;
} }
static int cirrus_vga_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
/* Any mode we've added is valid */
return MODE_OK;
}
static struct drm_encoder *cirrus_connector_best_encoder(struct drm_connector static struct drm_encoder *cirrus_connector_best_encoder(struct drm_connector
*connector) *connector)
{ {
...@@ -546,7 +539,6 @@ static void cirrus_connector_destroy(struct drm_connector *connector) ...@@ -546,7 +539,6 @@ static void cirrus_connector_destroy(struct drm_connector *connector)
struct drm_connector_helper_funcs cirrus_vga_connector_helper_funcs = { struct drm_connector_helper_funcs cirrus_vga_connector_helper_funcs = {
.get_modes = cirrus_vga_get_modes, .get_modes = cirrus_vga_get_modes,
.mode_valid = cirrus_vga_mode_valid,
.best_encoder = cirrus_connector_best_encoder, .best_encoder = cirrus_connector_best_encoder,
}; };
......
...@@ -363,7 +363,7 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset, ...@@ -363,7 +363,7 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset,
list->master = dev->primary->master; list->master = dev->primary->master;
*maplist = list; *maplist = list;
return 0; return 0;
} }
int drm_addmap(struct drm_device * dev, resource_size_t offset, int drm_addmap(struct drm_device * dev, resource_size_t offset,
unsigned int size, enum drm_map_type type, unsigned int size, enum drm_map_type type,
......
...@@ -1145,16 +1145,19 @@ EXPORT_SYMBOL(drm_plane_cleanup); ...@@ -1145,16 +1145,19 @@ EXPORT_SYMBOL(drm_plane_cleanup);
*/ */
void drm_plane_force_disable(struct drm_plane *plane) void drm_plane_force_disable(struct drm_plane *plane)
{ {
struct drm_framebuffer *old_fb = plane->fb;
int ret; int ret;
if (!plane->fb) if (!old_fb)
return; return;
ret = plane->funcs->disable_plane(plane); ret = plane->funcs->disable_plane(plane);
if (ret) if (ret) {
DRM_ERROR("failed to disable plane with busy fb\n"); DRM_ERROR("failed to disable plane with busy fb\n");
return;
}
/* disconnect the plane from the fb and crtc: */ /* disconnect the plane from the fb and crtc: */
__drm_framebuffer_unreference(plane->fb); __drm_framebuffer_unreference(old_fb);
plane->fb = NULL; plane->fb = NULL;
plane->crtc = NULL; plane->crtc = NULL;
} }
...@@ -2122,9 +2125,13 @@ int drm_mode_setplane(struct drm_device *dev, void *data, ...@@ -2122,9 +2125,13 @@ int drm_mode_setplane(struct drm_device *dev, void *data,
if (!plane_req->fb_id) { if (!plane_req->fb_id) {
drm_modeset_lock_all(dev); drm_modeset_lock_all(dev);
old_fb = plane->fb; old_fb = plane->fb;
plane->funcs->disable_plane(plane); ret = plane->funcs->disable_plane(plane);
plane->crtc = NULL; if (!ret) {
plane->fb = NULL; plane->crtc = NULL;
plane->fb = NULL;
} else {
old_fb = NULL;
}
drm_modeset_unlock_all(dev); drm_modeset_unlock_all(dev);
goto out; goto out;
} }
...@@ -2193,16 +2200,18 @@ int drm_mode_setplane(struct drm_device *dev, void *data, ...@@ -2193,16 +2200,18 @@ int drm_mode_setplane(struct drm_device *dev, void *data,
} }
drm_modeset_lock_all(dev); drm_modeset_lock_all(dev);
old_fb = plane->fb;
ret = plane->funcs->update_plane(plane, crtc, fb, ret = plane->funcs->update_plane(plane, crtc, fb,
plane_req->crtc_x, plane_req->crtc_y, plane_req->crtc_x, plane_req->crtc_y,
plane_req->crtc_w, plane_req->crtc_h, plane_req->crtc_w, plane_req->crtc_h,
plane_req->src_x, plane_req->src_y, plane_req->src_x, plane_req->src_y,
plane_req->src_w, plane_req->src_h); plane_req->src_w, plane_req->src_h);
if (!ret) { if (!ret) {
old_fb = plane->fb;
plane->crtc = crtc; plane->crtc = crtc;
plane->fb = fb; plane->fb = fb;
fb = NULL; fb = NULL;
} else {
old_fb = NULL;
} }
drm_modeset_unlock_all(dev); drm_modeset_unlock_all(dev);
...@@ -2245,9 +2254,7 @@ int drm_mode_set_config_internal(struct drm_mode_set *set) ...@@ -2245,9 +2254,7 @@ int drm_mode_set_config_internal(struct drm_mode_set *set)
ret = crtc->funcs->set_config(set); ret = crtc->funcs->set_config(set);
if (ret == 0) { if (ret == 0) {
crtc->primary->crtc = crtc; crtc->primary->crtc = crtc;
crtc->primary->fb = fb;
/* crtc->fb must be updated by ->set_config, enforces this. */
WARN_ON(fb != crtc->primary->fb);
} }
list_for_each_entry(tmp, &crtc->dev->mode_config.crtc_list, head) { list_for_each_entry(tmp, &crtc->dev->mode_config.crtc_list, head) {
......
...@@ -140,16 +140,10 @@ drm_encoder_disable(struct drm_encoder *encoder) ...@@ -140,16 +140,10 @@ drm_encoder_disable(struct drm_encoder *encoder)
static void __drm_helper_disable_unused_functions(struct drm_device *dev) static void __drm_helper_disable_unused_functions(struct drm_device *dev)
{ {
struct drm_encoder *encoder; struct drm_encoder *encoder;
struct drm_connector *connector;
struct drm_crtc *crtc; struct drm_crtc *crtc;
drm_warn_on_modeset_not_all_locked(dev); drm_warn_on_modeset_not_all_locked(dev);
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
if (!connector->encoder)
continue;
}
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
if (!drm_helper_encoder_in_use(encoder)) { if (!drm_helper_encoder_in_use(encoder)) {
drm_encoder_disable(encoder); drm_encoder_disable(encoder);
...@@ -387,8 +381,7 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, ...@@ -387,8 +381,7 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
} }
EXPORT_SYMBOL(drm_crtc_helper_set_mode); EXPORT_SYMBOL(drm_crtc_helper_set_mode);
static void
static int
drm_crtc_helper_disable(struct drm_crtc *crtc) drm_crtc_helper_disable(struct drm_crtc *crtc)
{ {
struct drm_device *dev = crtc->dev; struct drm_device *dev = crtc->dev;
...@@ -417,7 +410,6 @@ drm_crtc_helper_disable(struct drm_crtc *crtc) ...@@ -417,7 +410,6 @@ drm_crtc_helper_disable(struct drm_crtc *crtc)
} }
__drm_helper_disable_unused_functions(dev); __drm_helper_disable_unused_functions(dev);
return 0;
} }
/** /**
...@@ -468,7 +460,8 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) ...@@ -468,7 +460,8 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
(int)set->num_connectors, set->x, set->y); (int)set->num_connectors, set->x, set->y);
} else { } else {
DRM_DEBUG_KMS("[CRTC:%d] [NOFB]\n", set->crtc->base.id); DRM_DEBUG_KMS("[CRTC:%d] [NOFB]\n", set->crtc->base.id);
return drm_crtc_helper_disable(set->crtc); drm_crtc_helper_disable(set->crtc);
return 0;
} }
dev = set->crtc->dev; dev = set->crtc->dev;
......
...@@ -206,7 +206,7 @@ i2c_dp_aux_prepare_bus(struct i2c_adapter *adapter) ...@@ -206,7 +206,7 @@ i2c_dp_aux_prepare_bus(struct i2c_adapter *adapter)
* i2c_dp_aux_add_bus() - register an i2c adapter using the aux ch helper * i2c_dp_aux_add_bus() - register an i2c adapter using the aux ch helper
* @adapter: i2c adapter to register * @adapter: i2c adapter to register
* *
* This registers an i2c adapater that uses dp aux channel as it's underlaying * This registers an i2c adapter that uses dp aux channel as it's underlaying
* transport. The driver needs to fill out the &i2c_algo_dp_aux_data structure * transport. The driver needs to fill out the &i2c_algo_dp_aux_data structure
* and store it in the algo_data member of the @adapter argument. This will be * and store it in the algo_data member of the @adapter argument. This will be
* used by the i2c over dp aux algorithm to drive the hardware. * used by the i2c over dp aux algorithm to drive the hardware.
......
...@@ -984,9 +984,13 @@ static const u8 edid_header[] = { ...@@ -984,9 +984,13 @@ static const u8 edid_header[] = {
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00
}; };
/* /**
* Sanity check the header of the base EDID block. Return 8 if the header * drm_edid_header_is_valid - sanity check the header of the base EDID block
* is perfect, down to 0 if it's totally wrong. * @raw_edid: pointer to raw base EDID block
*
* Sanity check the header of the base EDID block.
*
* Return: 8 if the header is perfect, down to 0 if it's totally wrong.
*/ */
int drm_edid_header_is_valid(const u8 *raw_edid) int drm_edid_header_is_valid(const u8 *raw_edid)
{ {
...@@ -1005,9 +1009,16 @@ module_param_named(edid_fixup, edid_fixup, int, 0400); ...@@ -1005,9 +1009,16 @@ module_param_named(edid_fixup, edid_fixup, int, 0400);
MODULE_PARM_DESC(edid_fixup, MODULE_PARM_DESC(edid_fixup,
"Minimum number of valid EDID header bytes (0-8, default 6)"); "Minimum number of valid EDID header bytes (0-8, default 6)");
/* /**
* Sanity check the EDID block (base or extension). Return 0 if the block * drm_edid_block_valid - Sanity check the EDID block (base or extension)
* doesn't check out, or 1 if it's valid. * @raw_edid: pointer to raw EDID block
* @block: type of block to validate (0 for base, extension otherwise)
* @print_bad_edid: if true, dump bad EDID blocks to the console
*
* Validate a base or extension EDID block and optionally dump bad blocks to
* the console.
*
* Return: True if the block is valid, false otherwise.
*/ */
bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid) bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid)
{ {
...@@ -1077,6 +1088,8 @@ EXPORT_SYMBOL(drm_edid_block_valid); ...@@ -1077,6 +1088,8 @@ EXPORT_SYMBOL(drm_edid_block_valid);
* @edid: EDID data * @edid: EDID data
* *
* Sanity-check an entire EDID record (including extensions) * Sanity-check an entire EDID record (including extensions)
*
* Return: True if the EDID data is valid, false otherwise.
*/ */
bool drm_edid_is_valid(struct edid *edid) bool drm_edid_is_valid(struct edid *edid)
{ {
...@@ -1096,18 +1109,15 @@ EXPORT_SYMBOL(drm_edid_is_valid); ...@@ -1096,18 +1109,15 @@ EXPORT_SYMBOL(drm_edid_is_valid);
#define DDC_SEGMENT_ADDR 0x30 #define DDC_SEGMENT_ADDR 0x30
/** /**
* Get EDID information via I2C. * drm_do_probe_ddc_edid() - get EDID information via I2C
* * @adapter: I2C device adaptor
* @adapter : i2c device adaptor
* @buf: EDID data buffer to be filled * @buf: EDID data buffer to be filled
* @block: 128 byte EDID block to start fetching from * @block: 128 byte EDID block to start fetching from
* @len: EDID data buffer length to fetch * @len: EDID data buffer length to fetch
* *
* Returns: * Try to fetch EDID information by calling I2C driver functions.
*
* 0 on success or -1 on failure.
* *
* Try to fetch EDID information by calling i2c driver function. * Return: 0 on success or -1 on failure.
*/ */
static int static int
drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf, drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf,
...@@ -1118,7 +1128,8 @@ drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf, ...@@ -1118,7 +1128,8 @@ drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf,
unsigned char xfers = segment ? 3 : 2; unsigned char xfers = segment ? 3 : 2;
int ret, retries = 5; int ret, retries = 5;
/* The core i2c driver will automatically retry the transfer if the /*
* The core I2C driver will automatically retry the transfer if the
* adapter reports EAGAIN. However, we find that bit-banging transfers * adapter reports EAGAIN. However, we find that bit-banging transfers
* are susceptible to errors under a heavily loaded machine and * are susceptible to errors under a heavily loaded machine and
* generate spurious NAKs and timeouts. Retrying the transfer * generate spurious NAKs and timeouts. Retrying the transfer
...@@ -1144,10 +1155,10 @@ drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf, ...@@ -1144,10 +1155,10 @@ drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf,
} }
}; };
/* /*
* Avoid sending the segment addr to not upset non-compliant ddc * Avoid sending the segment addr to not upset non-compliant
* monitors. * DDC monitors.
*/ */
ret = i2c_transfer(adapter, &msgs[3 - xfers], xfers); ret = i2c_transfer(adapter, &msgs[3 - xfers], xfers);
if (ret == -ENXIO) { if (ret == -ENXIO) {
...@@ -1246,12 +1257,10 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) ...@@ -1246,12 +1257,10 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
} }
/** /**
* Probe DDC presence. * drm_probe_ddc() - probe DDC presence
* @adapter: i2c adapter to probe * @adapter: I2C adapter to probe
* *
* Returns: * Return: True on success, false on failure.
*
* 1 on success
*/ */
bool bool
drm_probe_ddc(struct i2c_adapter *adapter) drm_probe_ddc(struct i2c_adapter *adapter)
...@@ -1265,12 +1274,12 @@ EXPORT_SYMBOL(drm_probe_ddc); ...@@ -1265,12 +1274,12 @@ EXPORT_SYMBOL(drm_probe_ddc);
/** /**
* drm_get_edid - get EDID data, if available * drm_get_edid - get EDID data, if available
* @connector: connector we're probing * @connector: connector we're probing
* @adapter: i2c adapter to use for DDC * @adapter: I2C adapter to use for DDC
* *
* Poke the given i2c channel to grab EDID data if possible. If found, * Poke the given I2C channel to grab EDID data if possible. If found,
* attach it to the connector. * attach it to the connector.
* *
* Return edid data or NULL if we couldn't find any. * Return: Pointer to valid EDID or NULL if we couldn't find any.
*/ */
struct edid *drm_get_edid(struct drm_connector *connector, struct edid *drm_get_edid(struct drm_connector *connector,
struct i2c_adapter *adapter) struct i2c_adapter *adapter)
...@@ -1288,7 +1297,7 @@ EXPORT_SYMBOL(drm_get_edid); ...@@ -1288,7 +1297,7 @@ EXPORT_SYMBOL(drm_get_edid);
* drm_edid_duplicate - duplicate an EDID and the extensions * drm_edid_duplicate - duplicate an EDID and the extensions
* @edid: EDID to duplicate * @edid: EDID to duplicate
* *
* Return duplicate edid or NULL on allocation failure. * Return: Pointer to duplicated EDID or NULL on allocation failure.
*/ */
struct edid *drm_edid_duplicate(const struct edid *edid) struct edid *drm_edid_duplicate(const struct edid *edid)
{ {
...@@ -1411,7 +1420,8 @@ mode_is_rb(const struct drm_display_mode *mode) ...@@ -1411,7 +1420,8 @@ mode_is_rb(const struct drm_display_mode *mode)
* @rb: Mode reduced-blanking-ness * @rb: Mode reduced-blanking-ness
* *
* Walk the DMT mode list looking for a match for the given parameters. * Walk the DMT mode list looking for a match for the given parameters.
* Return a newly allocated copy of the mode, or NULL if not found. *
* Return: A newly allocated copy of the mode, or NULL if not found.
*/ */
struct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev, struct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev,
int hsize, int vsize, int fresh, int hsize, int vsize, int fresh,
...@@ -1595,14 +1605,13 @@ bad_std_timing(u8 a, u8 b) ...@@ -1595,14 +1605,13 @@ bad_std_timing(u8 a, u8 b)
* @connector: connector of for the EDID block * @connector: connector of for the EDID block
* @edid: EDID block to scan * @edid: EDID block to scan
* @t: standard timing params * @t: standard timing params
* @revision: standard timing level
* *
* Take the standard timing params (in this case width, aspect, and refresh) * Take the standard timing params (in this case width, aspect, and refresh)
* and convert them into a real mode using CVT/GTF/DMT. * and convert them into a real mode using CVT/GTF/DMT.
*/ */
static struct drm_display_mode * static struct drm_display_mode *
drm_mode_std(struct drm_connector *connector, struct edid *edid, drm_mode_std(struct drm_connector *connector, struct edid *edid,
struct std_timing *t, int revision) struct std_timing *t)
{ {
struct drm_device *dev = connector->dev; struct drm_device *dev = connector->dev;
struct drm_display_mode *m, *mode = NULL; struct drm_display_mode *m, *mode = NULL;
...@@ -1623,7 +1632,7 @@ drm_mode_std(struct drm_connector *connector, struct edid *edid, ...@@ -1623,7 +1632,7 @@ drm_mode_std(struct drm_connector *connector, struct edid *edid,
vrefresh_rate = vfreq + 60; vrefresh_rate = vfreq + 60;
/* the vdisplay is calculated based on the aspect ratio */ /* the vdisplay is calculated based on the aspect ratio */
if (aspect_ratio == 0) { if (aspect_ratio == 0) {
if (revision < 3) if (edid->revision < 3)
vsize = hsize; vsize = hsize;
else else
vsize = (hsize * 10) / 16; vsize = (hsize * 10) / 16;
...@@ -2140,7 +2149,7 @@ do_established_modes(struct detailed_timing *timing, void *c) ...@@ -2140,7 +2149,7 @@ do_established_modes(struct detailed_timing *timing, void *c)
/** /**
* add_established_modes - get est. modes from EDID and add them * add_established_modes - get est. modes from EDID and add them
* @connector: connector of for the EDID block * @connector: connector to add mode(s) to
* @edid: EDID block to scan * @edid: EDID block to scan
* *
* Each EDID block contains a bitmap of the supported "established modes" list * Each EDID block contains a bitmap of the supported "established modes" list
...@@ -2191,8 +2200,7 @@ do_standard_modes(struct detailed_timing *timing, void *c) ...@@ -2191,8 +2200,7 @@ do_standard_modes(struct detailed_timing *timing, void *c)
struct drm_display_mode *newmode; struct drm_display_mode *newmode;
std = &data->data.timings[i]; std = &data->data.timings[i];
newmode = drm_mode_std(connector, edid, std, newmode = drm_mode_std(connector, edid, std);
edid->revision);
if (newmode) { if (newmode) {
drm_mode_probed_add(connector, newmode); drm_mode_probed_add(connector, newmode);
closure->modes++; closure->modes++;
...@@ -2203,7 +2211,7 @@ do_standard_modes(struct detailed_timing *timing, void *c) ...@@ -2203,7 +2211,7 @@ do_standard_modes(struct detailed_timing *timing, void *c)
/** /**
* add_standard_modes - get std. modes from EDID and add them * add_standard_modes - get std. modes from EDID and add them
* @connector: connector of for the EDID block * @connector: connector to add mode(s) to
* @edid: EDID block to scan * @edid: EDID block to scan
* *
* Standard modes can be calculated using the appropriate standard (DMT, * Standard modes can be calculated using the appropriate standard (DMT,
...@@ -2221,8 +2229,7 @@ add_standard_modes(struct drm_connector *connector, struct edid *edid) ...@@ -2221,8 +2229,7 @@ add_standard_modes(struct drm_connector *connector, struct edid *edid)
struct drm_display_mode *newmode; struct drm_display_mode *newmode;
newmode = drm_mode_std(connector, edid, newmode = drm_mode_std(connector, edid,
&edid->standard_timings[i], &edid->standard_timings[i]);
edid->revision);
if (newmode) { if (newmode) {
drm_mode_probed_add(connector, newmode); drm_mode_probed_add(connector, newmode);
modes++; modes++;
...@@ -2425,7 +2432,7 @@ cea_mode_alternate_clock(const struct drm_display_mode *cea_mode) ...@@ -2425,7 +2432,7 @@ cea_mode_alternate_clock(const struct drm_display_mode *cea_mode)
* drm_match_cea_mode - look for a CEA mode matching given mode * drm_match_cea_mode - look for a CEA mode matching given mode
* @to_match: display mode * @to_match: display mode
* *
* Returns the CEA Video ID (VIC) of the mode or 0 if it isn't a CEA-861 * Return: The CEA Video ID (VIC) of the mode or 0 if it isn't a CEA-861
* mode. * mode.
*/ */
u8 drm_match_cea_mode(const struct drm_display_mode *to_match) u8 drm_match_cea_mode(const struct drm_display_mode *to_match)
...@@ -2452,6 +2459,22 @@ u8 drm_match_cea_mode(const struct drm_display_mode *to_match) ...@@ -2452,6 +2459,22 @@ u8 drm_match_cea_mode(const struct drm_display_mode *to_match)
} }
EXPORT_SYMBOL(drm_match_cea_mode); EXPORT_SYMBOL(drm_match_cea_mode);
/**
* drm_get_cea_aspect_ratio - get the picture aspect ratio corresponding to
* the input VIC from the CEA mode list
* @video_code: ID given to each of the CEA modes
*
* Returns picture aspect ratio
*/
enum hdmi_picture_aspect drm_get_cea_aspect_ratio(const u8 video_code)
{
/* return picture aspect ratio for video_code - 1 to access the
* right array element
*/
return edid_cea_modes[video_code-1].picture_aspect_ratio;
}
EXPORT_SYMBOL(drm_get_cea_aspect_ratio);
/* /*
* Calculate the alternate clock for HDMI modes (those from the HDMI vendor * Calculate the alternate clock for HDMI modes (those from the HDMI vendor
* specific block). * specific block).
...@@ -3023,11 +3046,9 @@ monitor_name(struct detailed_timing *t, void *data) ...@@ -3023,11 +3046,9 @@ monitor_name(struct detailed_timing *t, void *data)
* @connector: connector corresponding to the HDMI/DP sink * @connector: connector corresponding to the HDMI/DP sink
* @edid: EDID to parse * @edid: EDID to parse
* *
* Fill the ELD (EDID-Like Data) buffer for passing to the audio driver. * Fill the ELD (EDID-Like Data) buffer for passing to the audio driver. The
* Some ELD fields are left to the graphics driver caller: * Conn_Type, HDCP and Port_ID ELD fields are left for the graphics driver to
* - Conn_Type * fill in.
* - HDCP
* - Port_ID
*/ */
void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid) void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid)
{ {
...@@ -3111,9 +3132,10 @@ EXPORT_SYMBOL(drm_edid_to_eld); ...@@ -3111,9 +3132,10 @@ EXPORT_SYMBOL(drm_edid_to_eld);
* @sads: pointer that will be set to the extracted SADs * @sads: pointer that will be set to the extracted SADs
* *
* Looks for CEA EDID block and extracts SADs (Short Audio Descriptors) from it. * Looks for CEA EDID block and extracts SADs (Short Audio Descriptors) from it.
* Note: returned pointer needs to be kfreed
* *
* Return number of found SADs or negative number on error. * Note: The returned pointer needs to be freed using kfree().
*
* Return: The number of found SADs or negative number on error.
*/ */
int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads) int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads)
{ {
...@@ -3170,9 +3192,11 @@ EXPORT_SYMBOL(drm_edid_to_sad); ...@@ -3170,9 +3192,11 @@ EXPORT_SYMBOL(drm_edid_to_sad);
* @sadb: pointer to the speaker block * @sadb: pointer to the speaker block
* *
* Looks for CEA EDID block and extracts the Speaker Allocation Data Block from it. * Looks for CEA EDID block and extracts the Speaker Allocation Data Block from it.
* Note: returned pointer needs to be kfreed
* *
* Return number of found Speaker Allocation Blocks or negative number on error. * Note: The returned pointer needs to be freed using kfree().
*
* Return: The number of found Speaker Allocation Blocks or negative number on
* error.
*/ */
int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sadb) int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sadb)
{ {
...@@ -3219,9 +3243,12 @@ int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sadb) ...@@ -3219,9 +3243,12 @@ int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sadb)
EXPORT_SYMBOL(drm_edid_to_speaker_allocation); EXPORT_SYMBOL(drm_edid_to_speaker_allocation);
/** /**
* drm_av_sync_delay - HDMI/DP sink audio-video sync delay in millisecond * drm_av_sync_delay - compute the HDMI/DP sink audio-video sync delay
* @connector: connector associated with the HDMI/DP sink * @connector: connector associated with the HDMI/DP sink
* @mode: the display mode * @mode: the display mode
*
* Return: The HDMI/DP sink's audio-video sync delay in milliseconds or 0 if
* the sink doesn't support audio or video.
*/ */
int drm_av_sync_delay(struct drm_connector *connector, int drm_av_sync_delay(struct drm_connector *connector,
struct drm_display_mode *mode) struct drm_display_mode *mode)
...@@ -3263,6 +3290,9 @@ EXPORT_SYMBOL(drm_av_sync_delay); ...@@ -3263,6 +3290,9 @@ EXPORT_SYMBOL(drm_av_sync_delay);
* *
* It's possible for one encoder to be associated with multiple HDMI/DP sinks. * It's possible for one encoder to be associated with multiple HDMI/DP sinks.
* The policy is now hard coded to simply use the first HDMI/DP sink's ELD. * The policy is now hard coded to simply use the first HDMI/DP sink's ELD.
*
* Return: The connector associated with the first HDMI/DP sink that has ELD
* attached to it.
*/ */
struct drm_connector *drm_select_eld(struct drm_encoder *encoder, struct drm_connector *drm_select_eld(struct drm_encoder *encoder,
struct drm_display_mode *mode) struct drm_display_mode *mode)
...@@ -3279,11 +3309,12 @@ struct drm_connector *drm_select_eld(struct drm_encoder *encoder, ...@@ -3279,11 +3309,12 @@ struct drm_connector *drm_select_eld(struct drm_encoder *encoder,
EXPORT_SYMBOL(drm_select_eld); EXPORT_SYMBOL(drm_select_eld);
/** /**
* drm_detect_hdmi_monitor - detect whether monitor is hdmi. * drm_detect_hdmi_monitor - detect whether monitor is HDMI
* @edid: monitor EDID information * @edid: monitor EDID information
* *
* Parse the CEA extension according to CEA-861-B. * Parse the CEA extension according to CEA-861-B.
* Return true if HDMI, false if not or unknown. *
* Return: True if the monitor is HDMI, false if not or unknown.
*/ */
bool drm_detect_hdmi_monitor(struct edid *edid) bool drm_detect_hdmi_monitor(struct edid *edid)
{ {
...@@ -3321,6 +3352,7 @@ EXPORT_SYMBOL(drm_detect_hdmi_monitor); ...@@ -3321,6 +3352,7 @@ EXPORT_SYMBOL(drm_detect_hdmi_monitor);
* audio format, assume at least 'basic audio' support, even if 'basic * audio format, assume at least 'basic audio' support, even if 'basic
* audio' is not defined in EDID. * audio' is not defined in EDID.
* *
* Return: True if the monitor supports audio, false otherwise.
*/ */
bool drm_detect_monitor_audio(struct edid *edid) bool drm_detect_monitor_audio(struct edid *edid)
{ {
...@@ -3364,6 +3396,8 @@ EXPORT_SYMBOL(drm_detect_monitor_audio); ...@@ -3364,6 +3396,8 @@ EXPORT_SYMBOL(drm_detect_monitor_audio);
* Check whether the monitor reports the RGB quantization range selection * Check whether the monitor reports the RGB quantization range selection
* as supported. The AVI infoframe can then be used to inform the monitor * as supported. The AVI infoframe can then be used to inform the monitor
* which quantization range (full or limited) is used. * which quantization range (full or limited) is used.
*
* Return: True if the RGB quantization range is selectable, false otherwise.
*/ */
bool drm_rgb_quant_range_selectable(struct edid *edid) bool drm_rgb_quant_range_selectable(struct edid *edid)
{ {
...@@ -3468,11 +3502,11 @@ static void drm_add_display_info(struct edid *edid, ...@@ -3468,11 +3502,11 @@ static void drm_add_display_info(struct edid *edid,
/** /**
* drm_add_edid_modes - add modes from EDID data, if available * drm_add_edid_modes - add modes from EDID data, if available
* @connector: connector we're probing * @connector: connector we're probing
* @edid: edid data * @edid: EDID data
* *
* Add the specified modes to the connector's mode list. * Add the specified modes to the connector's mode list.
* *
* Return number of modes added or 0 if we couldn't find any. * Return: The number of modes added or 0 if we couldn't find any.
*/ */
int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid) int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
{ {
...@@ -3534,7 +3568,7 @@ EXPORT_SYMBOL(drm_add_edid_modes); ...@@ -3534,7 +3568,7 @@ EXPORT_SYMBOL(drm_add_edid_modes);
* Add the specified modes to the connector's mode list. Only when the * Add the specified modes to the connector's mode list. Only when the
* hdisplay/vdisplay is not beyond the given limit, it will be added. * hdisplay/vdisplay is not beyond the given limit, it will be added.
* *
* Return number of modes added or 0 if we couldn't find any. * Return: The number of modes added or 0 if we couldn't find any.
*/ */
int drm_add_modes_noedid(struct drm_connector *connector, int drm_add_modes_noedid(struct drm_connector *connector,
int hdisplay, int vdisplay) int hdisplay, int vdisplay)
...@@ -3573,13 +3607,22 @@ int drm_add_modes_noedid(struct drm_connector *connector, ...@@ -3573,13 +3607,22 @@ int drm_add_modes_noedid(struct drm_connector *connector,
} }
EXPORT_SYMBOL(drm_add_modes_noedid); EXPORT_SYMBOL(drm_add_modes_noedid);
/**
* drm_set_preferred_mode - Sets the preferred mode of a connector
* @connector: connector whose mode list should be processed
* @hpref: horizontal resolution of preferred mode
* @vpref: vertical resolution of preferred mode
*
* Marks a mode as preferred if it matches the resolution specified by @hpref
* and @vpref.
*/
void drm_set_preferred_mode(struct drm_connector *connector, void drm_set_preferred_mode(struct drm_connector *connector,
int hpref, int vpref) int hpref, int vpref)
{ {
struct drm_display_mode *mode; struct drm_display_mode *mode;
list_for_each_entry(mode, &connector->probed_modes, head) { list_for_each_entry(mode, &connector->probed_modes, head) {
if (mode->hdisplay == hpref && if (mode->hdisplay == hpref &&
mode->vdisplay == vpref) mode->vdisplay == vpref)
mode->type |= DRM_MODE_TYPE_PREFERRED; mode->type |= DRM_MODE_TYPE_PREFERRED;
} }
...@@ -3592,7 +3635,7 @@ EXPORT_SYMBOL(drm_set_preferred_mode); ...@@ -3592,7 +3635,7 @@ EXPORT_SYMBOL(drm_set_preferred_mode);
* @frame: HDMI AVI infoframe * @frame: HDMI AVI infoframe
* @mode: DRM display mode * @mode: DRM display mode
* *
* Returns 0 on success or a negative error code on failure. * Return: 0 on success or a negative error code on failure.
*/ */
int int
drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame, drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame,
...@@ -3613,6 +3656,12 @@ drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame, ...@@ -3613,6 +3656,12 @@ drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame,
frame->video_code = drm_match_cea_mode(mode); frame->video_code = drm_match_cea_mode(mode);
frame->picture_aspect = HDMI_PICTURE_ASPECT_NONE; frame->picture_aspect = HDMI_PICTURE_ASPECT_NONE;
/* Populate picture aspect ratio from CEA mode list */
if (frame->video_code > 0)
frame->picture_aspect = drm_get_cea_aspect_ratio(
frame->video_code);
frame->active_aspect = HDMI_ACTIVE_ASPECT_PICTURE; frame->active_aspect = HDMI_ACTIVE_ASPECT_PICTURE;
frame->scan_mode = HDMI_SCAN_MODE_UNDERSCAN; frame->scan_mode = HDMI_SCAN_MODE_UNDERSCAN;
...@@ -3657,7 +3706,7 @@ s3d_structure_from_display_mode(const struct drm_display_mode *mode) ...@@ -3657,7 +3706,7 @@ s3d_structure_from_display_mode(const struct drm_display_mode *mode)
* 4k or stereoscopic 3D mode. So when giving any other mode as input this * 4k or stereoscopic 3D mode. So when giving any other mode as input this
* function will return -EINVAL, error that can be safely ignored. * function will return -EINVAL, error that can be safely ignored.
* *
* Returns 0 on success or a negative error code on failure. * Return: 0 on success or a negative error code on failure.
*/ */
int int
drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame, drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame,
......
...@@ -45,13 +45,13 @@ static LIST_HEAD(kernel_fb_helper_list); ...@@ -45,13 +45,13 @@ static LIST_HEAD(kernel_fb_helper_list);
* DOC: fbdev helpers * DOC: fbdev helpers
* *
* The fb helper functions are useful to provide an fbdev on top of a drm kernel * The fb helper functions are useful to provide an fbdev on top of a drm kernel
* mode setting driver. They can be used mostly independantely from the crtc * mode setting driver. They can be used mostly independently from the crtc
* helper functions used by many drivers to implement the kernel mode setting * helper functions used by many drivers to implement the kernel mode setting
* interfaces. * interfaces.
* *
* Initialization is done as a three-step process with drm_fb_helper_init(), * Initialization is done as a three-step process with drm_fb_helper_init(),
* drm_fb_helper_single_add_all_connectors() and drm_fb_helper_initial_config(). * drm_fb_helper_single_add_all_connectors() and drm_fb_helper_initial_config().
* Drivers with fancier requirements than the default beheviour can override the * Drivers with fancier requirements than the default behaviour can override the
* second step with their own code. Teardown is done with drm_fb_helper_fini(). * second step with their own code. Teardown is done with drm_fb_helper_fini().
* *
* At runtime drivers should restore the fbdev console by calling * At runtime drivers should restore the fbdev console by calling
...@@ -59,7 +59,7 @@ static LIST_HEAD(kernel_fb_helper_list); ...@@ -59,7 +59,7 @@ static LIST_HEAD(kernel_fb_helper_list);
* should also notify the fb helper code from updates to the output * should also notify the fb helper code from updates to the output
* configuration by calling drm_fb_helper_hotplug_event(). For easier * configuration by calling drm_fb_helper_hotplug_event(). For easier
* integration with the output polling code in drm_crtc_helper.c the modeset * integration with the output polling code in drm_crtc_helper.c the modeset
* code proves a ->output_poll_changed callback. * code provides a ->output_poll_changed callback.
* *
* All other functions exported by the fb helper library can be used to * All other functions exported by the fb helper library can be used to
* implement the fbdev driver interface by the driver. * implement the fbdev driver interface by the driver.
...@@ -326,12 +326,21 @@ static bool drm_fb_helper_force_kernel_mode(void) ...@@ -326,12 +326,21 @@ static bool drm_fb_helper_force_kernel_mode(void)
return false; return false;
list_for_each_entry(helper, &kernel_fb_helper_list, kernel_fb_list) { list_for_each_entry(helper, &kernel_fb_helper_list, kernel_fb_list) {
if (helper->dev->switch_power_state == DRM_SWITCH_POWER_OFF) struct drm_device *dev = helper->dev;
if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
continue;
if (!mutex_trylock(&dev->mode_config.mutex)) {
error = true;
continue; continue;
}
ret = drm_fb_helper_restore_fbdev_mode(helper); ret = drm_fb_helper_restore_fbdev_mode(helper);
if (ret) if (ret)
error = true; error = true;
mutex_unlock(&dev->mode_config.mutex);
} }
return error; return error;
} }
......
...@@ -43,8 +43,7 @@ ...@@ -43,8 +43,7 @@
DEFINE_MUTEX(drm_global_mutex); DEFINE_MUTEX(drm_global_mutex);
EXPORT_SYMBOL(drm_global_mutex); EXPORT_SYMBOL(drm_global_mutex);
static int drm_open_helper(struct inode *inode, struct file *filp, static int drm_open_helper(struct file *filp, struct drm_minor *minor);
struct drm_minor *minor);
static int drm_setup(struct drm_device * dev) static int drm_setup(struct drm_device * dev)
{ {
...@@ -95,7 +94,7 @@ int drm_open(struct inode *inode, struct file *filp) ...@@ -95,7 +94,7 @@ int drm_open(struct inode *inode, struct file *filp)
/* share address_space across all char-devs of a single device */ /* share address_space across all char-devs of a single device */
filp->f_mapping = dev->anon_inode->i_mapping; filp->f_mapping = dev->anon_inode->i_mapping;
retcode = drm_open_helper(inode, filp, minor); retcode = drm_open_helper(filp, minor);
if (retcode) if (retcode)
goto err_undo; goto err_undo;
if (need_setup) { if (need_setup) {
...@@ -171,7 +170,6 @@ static int drm_cpu_valid(void) ...@@ -171,7 +170,6 @@ static int drm_cpu_valid(void)
/** /**
* Called whenever a process opens /dev/drm. * Called whenever a process opens /dev/drm.
* *
* \param inode device inode.
* \param filp file pointer. * \param filp file pointer.
* \param minor acquired minor-object. * \param minor acquired minor-object.
* \return zero on success or a negative number on failure. * \return zero on success or a negative number on failure.
...@@ -179,8 +177,7 @@ static int drm_cpu_valid(void) ...@@ -179,8 +177,7 @@ static int drm_cpu_valid(void)
* Creates and initializes a drm_file structure for the file private data in \p * Creates and initializes a drm_file structure for the file private data in \p
* filp and add it into the double linked list in \p dev. * filp and add it into the double linked list in \p dev.
*/ */
static int drm_open_helper(struct inode *inode, struct file *filp, static int drm_open_helper(struct file *filp, struct drm_minor *minor)
struct drm_minor *minor)
{ {
struct drm_device *dev = minor->dev; struct drm_device *dev = minor->dev;
struct drm_file *priv; struct drm_file *priv;
......
...@@ -124,7 +124,6 @@ int drm_primary_helper_update(struct drm_plane *plane, struct drm_crtc *crtc, ...@@ -124,7 +124,6 @@ int drm_primary_helper_update(struct drm_plane *plane, struct drm_crtc *crtc,
.y2 = crtc->mode.vdisplay, .y2 = crtc->mode.vdisplay,
}; };
struct drm_connector **connector_list; struct drm_connector **connector_list;
struct drm_framebuffer *tmpfb;
int num_connectors, ret; int num_connectors, ret;
if (!crtc->enabled) { if (!crtc->enabled) {
...@@ -145,6 +144,8 @@ int drm_primary_helper_update(struct drm_plane *plane, struct drm_crtc *crtc, ...@@ -145,6 +144,8 @@ int drm_primary_helper_update(struct drm_plane *plane, struct drm_crtc *crtc,
} }
/* Disallow scaling */ /* Disallow scaling */
src_w >>= 16;
src_h >>= 16;
if (crtc_w != src_w || crtc_h != src_h) { if (crtc_w != src_w || crtc_h != src_h) {
DRM_DEBUG_KMS("Can't scale primary plane\n"); DRM_DEBUG_KMS("Can't scale primary plane\n");
return -EINVAL; return -EINVAL;
...@@ -176,21 +177,14 @@ int drm_primary_helper_update(struct drm_plane *plane, struct drm_crtc *crtc, ...@@ -176,21 +177,14 @@ int drm_primary_helper_update(struct drm_plane *plane, struct drm_crtc *crtc,
set.num_connectors = num_connectors; set.num_connectors = num_connectors;
/* /*
* set_config() adjusts crtc->primary->fb; however the DRM setplane * We call set_config() directly here rather than using
* code that called us expects to handle the framebuffer update and
* reference counting; save and restore the current fb before
* calling it.
*
* N.B., we call set_config() directly here rather than using
* drm_mode_set_config_internal. We're reprogramming the same * drm_mode_set_config_internal. We're reprogramming the same
* connectors that were already in use, so we shouldn't need the extra * connectors that were already in use, so we shouldn't need the extra
* cross-CRTC fb refcounting to accomodate stealing connectors. * cross-CRTC fb refcounting to accomodate stealing connectors.
* drm_mode_setplane() already handles the basic refcounting for the * drm_mode_setplane() already handles the basic refcounting for the
* framebuffers involved in this operation. * framebuffers involved in this operation.
*/ */
tmpfb = plane->fb;
ret = crtc->funcs->set_config(&set); ret = crtc->funcs->set_config(&set);
plane->fb = tmpfb;
kfree(connector_list); kfree(connector_list);
return ret; return ret;
...@@ -232,7 +226,6 @@ EXPORT_SYMBOL(drm_primary_helper_disable); ...@@ -232,7 +226,6 @@ EXPORT_SYMBOL(drm_primary_helper_disable);
*/ */
void drm_primary_helper_destroy(struct drm_plane *plane) void drm_primary_helper_destroy(struct drm_plane *plane)
{ {
plane->funcs->disable_plane(plane);
drm_plane_cleanup(plane); drm_plane_cleanup(plane);
kfree(plane); kfree(plane);
} }
......
...@@ -151,7 +151,7 @@ static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connect ...@@ -151,7 +151,7 @@ static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connect
drm_mode_validate_flag(connector, mode_flags); drm_mode_validate_flag(connector, mode_flags);
list_for_each_entry(mode, &connector->modes, head) { list_for_each_entry(mode, &connector->modes, head) {
if (mode->status == MODE_OK) if (mode->status == MODE_OK && connector_funcs->mode_valid)
mode->status = connector_funcs->mode_valid(connector, mode->status = connector_funcs->mode_valid(connector,
mode); mode);
} }
......
...@@ -949,12 +949,6 @@ static int exynos_dp_get_modes(struct drm_connector *connector) ...@@ -949,12 +949,6 @@ static int exynos_dp_get_modes(struct drm_connector *connector)
return 1; return 1;
} }
static int exynos_dp_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
return MODE_OK;
}
static struct drm_encoder *exynos_dp_best_encoder( static struct drm_encoder *exynos_dp_best_encoder(
struct drm_connector *connector) struct drm_connector *connector)
{ {
...@@ -965,7 +959,6 @@ static struct drm_encoder *exynos_dp_best_encoder( ...@@ -965,7 +959,6 @@ static struct drm_encoder *exynos_dp_best_encoder(
static struct drm_connector_helper_funcs exynos_dp_connector_helper_funcs = { static struct drm_connector_helper_funcs exynos_dp_connector_helper_funcs = {
.get_modes = exynos_dp_get_modes, .get_modes = exynos_dp_get_modes,
.mode_valid = exynos_dp_mode_valid,
.best_encoder = exynos_dp_best_encoder, .best_encoder = exynos_dp_best_encoder,
}; };
......
...@@ -94,12 +94,6 @@ static int exynos_dpi_get_modes(struct drm_connector *connector) ...@@ -94,12 +94,6 @@ static int exynos_dpi_get_modes(struct drm_connector *connector)
return 0; return 0;
} }
static int exynos_dpi_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
return MODE_OK;
}
static struct drm_encoder * static struct drm_encoder *
exynos_dpi_best_encoder(struct drm_connector *connector) exynos_dpi_best_encoder(struct drm_connector *connector)
{ {
...@@ -110,7 +104,6 @@ exynos_dpi_best_encoder(struct drm_connector *connector) ...@@ -110,7 +104,6 @@ exynos_dpi_best_encoder(struct drm_connector *connector)
static struct drm_connector_helper_funcs exynos_dpi_connector_helper_funcs = { static struct drm_connector_helper_funcs exynos_dpi_connector_helper_funcs = {
.get_modes = exynos_dpi_get_modes, .get_modes = exynos_dpi_get_modes,
.mode_valid = exynos_dpi_mode_valid,
.best_encoder = exynos_dpi_best_encoder, .best_encoder = exynos_dpi_best_encoder,
}; };
......
...@@ -533,12 +533,6 @@ static int vidi_get_modes(struct drm_connector *connector) ...@@ -533,12 +533,6 @@ static int vidi_get_modes(struct drm_connector *connector)
return drm_add_edid_modes(connector, edid); return drm_add_edid_modes(connector, edid);
} }
static int vidi_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
return MODE_OK;
}
static struct drm_encoder *vidi_best_encoder(struct drm_connector *connector) static struct drm_encoder *vidi_best_encoder(struct drm_connector *connector)
{ {
struct vidi_context *ctx = ctx_from_connector(connector); struct vidi_context *ctx = ctx_from_connector(connector);
...@@ -548,7 +542,6 @@ static struct drm_encoder *vidi_best_encoder(struct drm_connector *connector) ...@@ -548,7 +542,6 @@ static struct drm_encoder *vidi_best_encoder(struct drm_connector *connector)
static struct drm_connector_helper_funcs vidi_connector_helper_funcs = { static struct drm_connector_helper_funcs vidi_connector_helper_funcs = {
.get_modes = vidi_get_modes, .get_modes = vidi_get_modes,
.mode_valid = vidi_mode_valid,
.best_encoder = vidi_best_encoder, .best_encoder = vidi_best_encoder,
}; };
......
...@@ -57,15 +57,8 @@ static int rcar_du_lvds_connector_get_modes(struct drm_connector *connector) ...@@ -57,15 +57,8 @@ static int rcar_du_lvds_connector_get_modes(struct drm_connector *connector)
return 1; return 1;
} }
static int rcar_du_lvds_connector_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
return MODE_OK;
}
static const struct drm_connector_helper_funcs connector_helper_funcs = { static const struct drm_connector_helper_funcs connector_helper_funcs = {
.get_modes = rcar_du_lvds_connector_get_modes, .get_modes = rcar_du_lvds_connector_get_modes,
.mode_valid = rcar_du_lvds_connector_mode_valid,
.best_encoder = rcar_du_connector_best_encoder, .best_encoder = rcar_du_connector_best_encoder,
}; };
......
...@@ -25,15 +25,8 @@ static int rcar_du_vga_connector_get_modes(struct drm_connector *connector) ...@@ -25,15 +25,8 @@ static int rcar_du_vga_connector_get_modes(struct drm_connector *connector)
return 0; return 0;
} }
static int rcar_du_vga_connector_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
return MODE_OK;
}
static const struct drm_connector_helper_funcs connector_helper_funcs = { static const struct drm_connector_helper_funcs connector_helper_funcs = {
.get_modes = rcar_du_vga_connector_get_modes, .get_modes = rcar_du_vga_connector_get_modes,
.mode_valid = rcar_du_vga_connector_mode_valid,
.best_encoder = rcar_du_connector_best_encoder, .best_encoder = rcar_du_connector_best_encoder,
}; };
......
...@@ -674,12 +674,6 @@ static int shmob_drm_connector_get_modes(struct drm_connector *connector) ...@@ -674,12 +674,6 @@ static int shmob_drm_connector_get_modes(struct drm_connector *connector)
return 1; return 1;
} }
static int shmob_drm_connector_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
return MODE_OK;
}
static struct drm_encoder * static struct drm_encoder *
shmob_drm_connector_best_encoder(struct drm_connector *connector) shmob_drm_connector_best_encoder(struct drm_connector *connector)
{ {
...@@ -690,7 +684,6 @@ shmob_drm_connector_best_encoder(struct drm_connector *connector) ...@@ -690,7 +684,6 @@ shmob_drm_connector_best_encoder(struct drm_connector *connector)
static const struct drm_connector_helper_funcs connector_helper_funcs = { static const struct drm_connector_helper_funcs connector_helper_funcs = {
.get_modes = shmob_drm_connector_get_modes, .get_modes = shmob_drm_connector_get_modes,
.mode_valid = shmob_drm_connector_mode_valid,
.best_encoder = shmob_drm_connector_best_encoder, .best_encoder = shmob_drm_connector_best_encoder,
}; };
......
...@@ -200,13 +200,6 @@ static const struct file_operations imx_drm_driver_fops = { ...@@ -200,13 +200,6 @@ static const struct file_operations imx_drm_driver_fops = {
.llseek = noop_llseek, .llseek = noop_llseek,
}; };
int imx_drm_connector_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
return MODE_OK;
}
EXPORT_SYMBOL(imx_drm_connector_mode_valid);
void imx_drm_connector_destroy(struct drm_connector *connector) void imx_drm_connector_destroy(struct drm_connector *connector)
{ {
drm_sysfs_connector_remove(connector); drm_sysfs_connector_remove(connector);
......
...@@ -50,8 +50,6 @@ int imx_drm_encoder_get_mux_id(struct device_node *node, ...@@ -50,8 +50,6 @@ int imx_drm_encoder_get_mux_id(struct device_node *node,
int imx_drm_encoder_parse_of(struct drm_device *drm, int imx_drm_encoder_parse_of(struct drm_device *drm,
struct drm_encoder *encoder, struct device_node *np); struct drm_encoder *encoder, struct device_node *np);
int imx_drm_connector_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode);
void imx_drm_connector_destroy(struct drm_connector *connector); void imx_drm_connector_destroy(struct drm_connector *connector);
void imx_drm_encoder_destroy(struct drm_encoder *encoder); void imx_drm_encoder_destroy(struct drm_encoder *encoder);
......
...@@ -1492,7 +1492,6 @@ static struct drm_connector_funcs imx_hdmi_connector_funcs = { ...@@ -1492,7 +1492,6 @@ static struct drm_connector_funcs imx_hdmi_connector_funcs = {
static struct drm_connector_helper_funcs imx_hdmi_connector_helper_funcs = { static struct drm_connector_helper_funcs imx_hdmi_connector_helper_funcs = {
.get_modes = imx_hdmi_connector_get_modes, .get_modes = imx_hdmi_connector_get_modes,
.mode_valid = imx_drm_connector_mode_valid,
.best_encoder = imx_hdmi_connector_best_encoder, .best_encoder = imx_hdmi_connector_best_encoder,
}; };
......
...@@ -317,7 +317,6 @@ static struct drm_connector_funcs imx_ldb_connector_funcs = { ...@@ -317,7 +317,6 @@ static struct drm_connector_funcs imx_ldb_connector_funcs = {
static struct drm_connector_helper_funcs imx_ldb_connector_helper_funcs = { static struct drm_connector_helper_funcs imx_ldb_connector_helper_funcs = {
.get_modes = imx_ldb_connector_get_modes, .get_modes = imx_ldb_connector_get_modes,
.best_encoder = imx_ldb_connector_best_encoder, .best_encoder = imx_ldb_connector_best_encoder,
.mode_valid = imx_drm_connector_mode_valid,
}; };
static struct drm_encoder_funcs imx_ldb_encoder_funcs = { static struct drm_encoder_funcs imx_ldb_encoder_funcs = {
......
...@@ -251,10 +251,6 @@ static int imx_tve_connector_mode_valid(struct drm_connector *connector, ...@@ -251,10 +251,6 @@ static int imx_tve_connector_mode_valid(struct drm_connector *connector,
unsigned long rate; unsigned long rate;
int ret; int ret;
ret = imx_drm_connector_mode_valid(connector, mode);
if (ret != MODE_OK)
return ret;
/* pixel clock with 2x oversampling */ /* pixel clock with 2x oversampling */
rate = clk_round_rate(tve->clk, 2000UL * mode->clock) / 2000; rate = clk_round_rate(tve->clk, 2000UL * mode->clock) / 2000;
if (rate == mode->clock) if (rate == mode->clock)
......
...@@ -148,7 +148,6 @@ static struct drm_connector_funcs imx_pd_connector_funcs = { ...@@ -148,7 +148,6 @@ static struct drm_connector_funcs imx_pd_connector_funcs = {
static struct drm_connector_helper_funcs imx_pd_connector_helper_funcs = { static struct drm_connector_helper_funcs imx_pd_connector_helper_funcs = {
.get_modes = imx_pd_connector_get_modes, .get_modes = imx_pd_connector_get_modes,
.best_encoder = imx_pd_connector_best_encoder, .best_encoder = imx_pd_connector_best_encoder,
.mode_valid = imx_drm_connector_mode_valid,
}; };
static struct drm_encoder_funcs imx_pd_encoder_funcs = { static struct drm_encoder_funcs imx_pd_encoder_funcs = {
......
...@@ -1021,6 +1021,7 @@ extern int drm_mode_gamma_get_ioctl(struct drm_device *dev, ...@@ -1021,6 +1021,7 @@ extern int drm_mode_gamma_get_ioctl(struct drm_device *dev,
extern int drm_mode_gamma_set_ioctl(struct drm_device *dev, extern int drm_mode_gamma_set_ioctl(struct drm_device *dev,
void *data, struct drm_file *file_priv); void *data, struct drm_file *file_priv);
extern u8 drm_match_cea_mode(const struct drm_display_mode *to_match); extern u8 drm_match_cea_mode(const struct drm_display_mode *to_match);
extern enum hdmi_picture_aspect drm_get_cea_aspect_ratio(const u8 video_code);
extern bool drm_detect_hdmi_monitor(struct edid *edid); extern bool drm_detect_hdmi_monitor(struct edid *edid);
extern bool drm_detect_monitor_audio(struct edid *edid); extern bool drm_detect_monitor_audio(struct edid *edid);
extern bool drm_rgb_quant_range_selectable(struct edid *edid); extern bool drm_rgb_quant_range_selectable(struct edid *edid);
......
...@@ -114,7 +114,7 @@ struct drm_encoder_helper_funcs { ...@@ -114,7 +114,7 @@ struct drm_encoder_helper_funcs {
/** /**
* drm_connector_helper_funcs - helper operations for connectors * drm_connector_helper_funcs - helper operations for connectors
* @get_modes: get mode list for this connector * @get_modes: get mode list for this connector
* @mode_valid: is this mode valid on the given connector? * @mode_valid (optional): is this mode valid on the given connector?
* *
* The helper operations are called by the mid-layer CRTC helper. * The helper operations are called by the mid-layer CRTC helper.
*/ */
......
...@@ -57,6 +57,7 @@ typedef void (*drm_flip_func_t)(struct drm_flip_work *work, void *val); ...@@ -57,6 +57,7 @@ typedef void (*drm_flip_func_t)(struct drm_flip_work *work, void *val);
* @count: number of committed items * @count: number of committed items
* @func: callback fxn called for each committed item * @func: callback fxn called for each committed item
* @worker: worker which calls @func * @worker: worker which calls @func
* @fifo: queue of committed items
*/ */
struct drm_flip_work { struct drm_flip_work {
const char *name; const char *name;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册