mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-15 08:14:15 +08:00
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
This commit is contained in:
commit
425a9a3ad1
@ -1895,8 +1895,8 @@ void intel_crt_init(struct drm_device *dev)
|
||||
<para>
|
||||
The function filters out modes larger than
|
||||
<parameter>max_width</parameter> and <parameter>max_height</parameter>
|
||||
if specified. It then calls the connector
|
||||
<methodname>mode_valid</methodname> helper operation for each mode in
|
||||
if specified. It then calls the optional connector
|
||||
<methodname>mode_valid</methodname> helper operation for each mode in
|
||||
the probed list to check whether the mode is valid for the connector.
|
||||
</para>
|
||||
</listitem>
|
||||
@ -2257,7 +2257,7 @@ void intel_crt_init(struct drm_device *dev)
|
||||
<para>
|
||||
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_*)
|
||||
for unsupported modes. This operation is mandatory.
|
||||
for unsupported modes. This operation is optional.
|
||||
</para>
|
||||
<para>
|
||||
As the mode rejection reason is currently not used beside for
|
||||
|
@ -743,12 +743,6 @@ static int ast_get_modes(struct drm_connector *connector)
|
||||
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)
|
||||
{
|
||||
struct ast_connector *ast_connector = to_ast_connector(connector);
|
||||
@ -765,7 +759,6 @@ ast_connector_detect(struct drm_connector *connector, bool force)
|
||||
}
|
||||
|
||||
static const struct drm_connector_helper_funcs ast_connector_helper_funcs = {
|
||||
.mode_valid = ast_mode_valid,
|
||||
.get_modes = ast_get_modes,
|
||||
.best_encoder = ast_best_single_encoder,
|
||||
};
|
||||
|
@ -225,12 +225,6 @@ out:
|
||||
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 ptn3460_bridge *ptn_bridge;
|
||||
@ -242,7 +236,6 @@ struct drm_encoder *ptn3460_best_encoder(struct drm_connector *connector)
|
||||
|
||||
struct drm_connector_helper_funcs ptn3460_connector_helper_funcs = {
|
||||
.get_modes = ptn3460_get_modes,
|
||||
.mode_valid = ptn3460_mode_valid,
|
||||
.best_encoder = ptn3460_best_encoder,
|
||||
};
|
||||
|
||||
|
@ -505,13 +505,6 @@ static int cirrus_vga_get_modes(struct drm_connector *connector)
|
||||
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
|
||||
*connector)
|
||||
{
|
||||
@ -546,7 +539,6 @@ static void cirrus_connector_destroy(struct drm_connector *connector)
|
||||
|
||||
struct drm_connector_helper_funcs cirrus_vga_connector_helper_funcs = {
|
||||
.get_modes = cirrus_vga_get_modes,
|
||||
.mode_valid = cirrus_vga_mode_valid,
|
||||
.best_encoder = cirrus_connector_best_encoder,
|
||||
};
|
||||
|
||||
|
@ -363,7 +363,7 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset,
|
||||
list->master = dev->primary->master;
|
||||
*maplist = list;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int drm_addmap(struct drm_device * dev, resource_size_t offset,
|
||||
unsigned int size, enum drm_map_type type,
|
||||
|
@ -1145,16 +1145,19 @@ EXPORT_SYMBOL(drm_plane_cleanup);
|
||||
*/
|
||||
void drm_plane_force_disable(struct drm_plane *plane)
|
||||
{
|
||||
struct drm_framebuffer *old_fb = plane->fb;
|
||||
int ret;
|
||||
|
||||
if (!plane->fb)
|
||||
if (!old_fb)
|
||||
return;
|
||||
|
||||
ret = plane->funcs->disable_plane(plane);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
DRM_ERROR("failed to disable plane with busy fb\n");
|
||||
return;
|
||||
}
|
||||
/* disconnect the plane from the fb and crtc: */
|
||||
__drm_framebuffer_unreference(plane->fb);
|
||||
__drm_framebuffer_unreference(old_fb);
|
||||
plane->fb = NULL;
|
||||
plane->crtc = NULL;
|
||||
}
|
||||
@ -2122,9 +2125,13 @@ int drm_mode_setplane(struct drm_device *dev, void *data,
|
||||
if (!plane_req->fb_id) {
|
||||
drm_modeset_lock_all(dev);
|
||||
old_fb = plane->fb;
|
||||
plane->funcs->disable_plane(plane);
|
||||
plane->crtc = NULL;
|
||||
plane->fb = NULL;
|
||||
ret = plane->funcs->disable_plane(plane);
|
||||
if (!ret) {
|
||||
plane->crtc = NULL;
|
||||
plane->fb = NULL;
|
||||
} else {
|
||||
old_fb = NULL;
|
||||
}
|
||||
drm_modeset_unlock_all(dev);
|
||||
goto out;
|
||||
}
|
||||
@ -2193,16 +2200,18 @@ int drm_mode_setplane(struct drm_device *dev, void *data,
|
||||
}
|
||||
|
||||
drm_modeset_lock_all(dev);
|
||||
old_fb = plane->fb;
|
||||
ret = plane->funcs->update_plane(plane, crtc, fb,
|
||||
plane_req->crtc_x, plane_req->crtc_y,
|
||||
plane_req->crtc_w, plane_req->crtc_h,
|
||||
plane_req->src_x, plane_req->src_y,
|
||||
plane_req->src_w, plane_req->src_h);
|
||||
if (!ret) {
|
||||
old_fb = plane->fb;
|
||||
plane->crtc = crtc;
|
||||
plane->fb = fb;
|
||||
fb = NULL;
|
||||
} else {
|
||||
old_fb = NULL;
|
||||
}
|
||||
drm_modeset_unlock_all(dev);
|
||||
|
||||
@ -2245,9 +2254,7 @@ int drm_mode_set_config_internal(struct drm_mode_set *set)
|
||||
ret = crtc->funcs->set_config(set);
|
||||
if (ret == 0) {
|
||||
crtc->primary->crtc = crtc;
|
||||
|
||||
/* crtc->fb must be updated by ->set_config, enforces this. */
|
||||
WARN_ON(fb != crtc->primary->fb);
|
||||
crtc->primary->fb = fb;
|
||||
}
|
||||
|
||||
list_for_each_entry(tmp, &crtc->dev->mode_config.crtc_list, head) {
|
||||
|
@ -140,16 +140,10 @@ drm_encoder_disable(struct drm_encoder *encoder)
|
||||
static void __drm_helper_disable_unused_functions(struct drm_device *dev)
|
||||
{
|
||||
struct drm_encoder *encoder;
|
||||
struct drm_connector *connector;
|
||||
struct drm_crtc *crtc;
|
||||
|
||||
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) {
|
||||
if (!drm_helper_encoder_in_use(encoder)) {
|
||||
drm_encoder_disable(encoder);
|
||||
@ -387,8 +381,7 @@ done:
|
||||
}
|
||||
EXPORT_SYMBOL(drm_crtc_helper_set_mode);
|
||||
|
||||
|
||||
static int
|
||||
static void
|
||||
drm_crtc_helper_disable(struct drm_crtc *crtc)
|
||||
{
|
||||
struct drm_device *dev = crtc->dev;
|
||||
@ -417,7 +410,6 @@ drm_crtc_helper_disable(struct drm_crtc *crtc)
|
||||
}
|
||||
|
||||
__drm_helper_disable_unused_functions(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -468,7 +460,8 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
|
||||
(int)set->num_connectors, set->x, set->y);
|
||||
} else {
|
||||
DRM_DEBUG_KMS("[CRTC:%d] [NOFB]\n", set->crtc->base.id);
|
||||
return drm_crtc_helper_disable(set->crtc);
|
||||
drm_crtc_helper_disable(set->crtc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dev = set->crtc->dev;
|
||||
|
@ -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
|
||||
* @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
|
||||
* 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.
|
||||
|
@ -984,9 +984,13 @@ static const u8 edid_header[] = {
|
||||
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00
|
||||
};
|
||||
|
||||
/*
|
||||
* Sanity check the header of the base EDID block. Return 8 if the header
|
||||
* is perfect, down to 0 if it's totally wrong.
|
||||
/**
|
||||
* drm_edid_header_is_valid - sanity check the header of the base EDID block
|
||||
* @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)
|
||||
{
|
||||
@ -1005,9 +1009,16 @@ module_param_named(edid_fixup, edid_fixup, int, 0400);
|
||||
MODULE_PARM_DESC(edid_fixup,
|
||||
"Minimum number of valid EDID header bytes (0-8, default 6)");
|
||||
|
||||
/*
|
||||
* Sanity check the EDID block (base or extension). Return 0 if the block
|
||||
* doesn't check out, or 1 if it's valid.
|
||||
/**
|
||||
* drm_edid_block_valid - Sanity check the EDID block (base or extension)
|
||||
* @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)
|
||||
{
|
||||
@ -1077,6 +1088,8 @@ EXPORT_SYMBOL(drm_edid_block_valid);
|
||||
* @edid: EDID data
|
||||
*
|
||||
* 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)
|
||||
{
|
||||
@ -1096,18 +1109,15 @@ EXPORT_SYMBOL(drm_edid_is_valid);
|
||||
|
||||
#define DDC_SEGMENT_ADDR 0x30
|
||||
/**
|
||||
* Get EDID information via I2C.
|
||||
*
|
||||
* @adapter : i2c device adaptor
|
||||
* drm_do_probe_ddc_edid() - get EDID information via I2C
|
||||
* @adapter: I2C device adaptor
|
||||
* @buf: EDID data buffer to be filled
|
||||
* @block: 128 byte EDID block to start fetching from
|
||||
* @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
|
||||
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;
|
||||
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
|
||||
* are susceptible to errors under a heavily loaded machine and
|
||||
* generate spurious NAKs and timeouts. Retrying the transfer
|
||||
@ -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
|
||||
* monitors.
|
||||
*/
|
||||
/*
|
||||
* Avoid sending the segment addr to not upset non-compliant
|
||||
* DDC monitors.
|
||||
*/
|
||||
ret = i2c_transfer(adapter, &msgs[3 - xfers], xfers);
|
||||
|
||||
if (ret == -ENXIO) {
|
||||
@ -1246,12 +1257,10 @@ out:
|
||||
}
|
||||
|
||||
/**
|
||||
* Probe DDC presence.
|
||||
* @adapter: i2c adapter to probe
|
||||
* drm_probe_ddc() - probe DDC presence
|
||||
* @adapter: I2C adapter to probe
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* 1 on success
|
||||
* Return: True on success, false on failure.
|
||||
*/
|
||||
bool
|
||||
drm_probe_ddc(struct i2c_adapter *adapter)
|
||||
@ -1265,12 +1274,12 @@ EXPORT_SYMBOL(drm_probe_ddc);
|
||||
/**
|
||||
* drm_get_edid - get EDID data, if available
|
||||
* @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.
|
||||
*
|
||||
* 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 i2c_adapter *adapter)
|
||||
@ -1288,7 +1297,7 @@ EXPORT_SYMBOL(drm_get_edid);
|
||||
* drm_edid_duplicate - duplicate an EDID and the extensions
|
||||
* @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)
|
||||
{
|
||||
@ -1411,7 +1420,8 @@ mode_is_rb(const struct drm_display_mode *mode)
|
||||
* @rb: Mode reduced-blanking-ness
|
||||
*
|
||||
* 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,
|
||||
int hsize, int vsize, int fresh,
|
||||
@ -1595,14 +1605,13 @@ bad_std_timing(u8 a, u8 b)
|
||||
* @connector: connector of for the EDID block
|
||||
* @edid: EDID block to scan
|
||||
* @t: standard timing params
|
||||
* @revision: standard timing level
|
||||
*
|
||||
* Take the standard timing params (in this case width, aspect, and refresh)
|
||||
* and convert them into a real mode using CVT/GTF/DMT.
|
||||
*/
|
||||
static struct drm_display_mode *
|
||||
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_display_mode *m, *mode = NULL;
|
||||
@ -1623,7 +1632,7 @@ drm_mode_std(struct drm_connector *connector, struct edid *edid,
|
||||
vrefresh_rate = vfreq + 60;
|
||||
/* the vdisplay is calculated based on the aspect ratio */
|
||||
if (aspect_ratio == 0) {
|
||||
if (revision < 3)
|
||||
if (edid->revision < 3)
|
||||
vsize = hsize;
|
||||
else
|
||||
vsize = (hsize * 10) / 16;
|
||||
@ -2140,7 +2149,7 @@ do_established_modes(struct detailed_timing *timing, void *c)
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
* 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)
|
||||
struct drm_display_mode *newmode;
|
||||
|
||||
std = &data->data.timings[i];
|
||||
newmode = drm_mode_std(connector, edid, std,
|
||||
edid->revision);
|
||||
newmode = drm_mode_std(connector, edid, std);
|
||||
if (newmode) {
|
||||
drm_mode_probed_add(connector, newmode);
|
||||
closure->modes++;
|
||||
@ -2203,7 +2211,7 @@ do_standard_modes(struct detailed_timing *timing, void *c)
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
* Standard modes can be calculated using the appropriate standard (DMT,
|
||||
@ -2221,8 +2229,7 @@ add_standard_modes(struct drm_connector *connector, struct edid *edid)
|
||||
struct drm_display_mode *newmode;
|
||||
|
||||
newmode = drm_mode_std(connector, edid,
|
||||
&edid->standard_timings[i],
|
||||
edid->revision);
|
||||
&edid->standard_timings[i]);
|
||||
if (newmode) {
|
||||
drm_mode_probed_add(connector, newmode);
|
||||
modes++;
|
||||
@ -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
|
||||
* @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.
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* 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
|
||||
* specific block).
|
||||
@ -3023,11 +3046,9 @@ monitor_name(struct detailed_timing *t, void *data)
|
||||
* @connector: connector corresponding to the HDMI/DP sink
|
||||
* @edid: EDID to parse
|
||||
*
|
||||
* Fill the ELD (EDID-Like Data) buffer for passing to the audio driver.
|
||||
* Some ELD fields are left to the graphics driver caller:
|
||||
* - Conn_Type
|
||||
* - HDCP
|
||||
* - Port_ID
|
||||
* Fill the ELD (EDID-Like Data) buffer for passing to the audio driver. The
|
||||
* Conn_Type, HDCP and Port_ID ELD fields are left for the graphics driver to
|
||||
* fill in.
|
||||
*/
|
||||
void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid)
|
||||
{
|
||||
@ -3111,9 +3132,10 @@ EXPORT_SYMBOL(drm_edid_to_eld);
|
||||
* @sads: pointer that will be set to the extracted SADs
|
||||
*
|
||||
* 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)
|
||||
{
|
||||
@ -3170,9 +3192,11 @@ EXPORT_SYMBOL(drm_edid_to_sad);
|
||||
* @sadb: pointer to the speaker block
|
||||
*
|
||||
* 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)
|
||||
{
|
||||
@ -3219,9 +3243,12 @@ int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sadb)
|
||||
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
|
||||
* @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,
|
||||
struct drm_display_mode *mode)
|
||||
@ -3263,6 +3290,9 @@ EXPORT_SYMBOL(drm_av_sync_delay);
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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_display_mode *mode)
|
||||
@ -3279,11 +3309,12 @@ struct drm_connector *drm_select_eld(struct drm_encoder *encoder,
|
||||
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
|
||||
*
|
||||
* 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)
|
||||
{
|
||||
@ -3321,6 +3352,7 @@ EXPORT_SYMBOL(drm_detect_hdmi_monitor);
|
||||
* audio format, assume at least 'basic audio' support, even if 'basic
|
||||
* audio' is not defined in EDID.
|
||||
*
|
||||
* Return: True if the monitor supports audio, false otherwise.
|
||||
*/
|
||||
bool drm_detect_monitor_audio(struct edid *edid)
|
||||
{
|
||||
@ -3364,6 +3396,8 @@ EXPORT_SYMBOL(drm_detect_monitor_audio);
|
||||
* Check whether the monitor reports the RGB quantization range selection
|
||||
* as supported. The AVI infoframe can then be used to inform the monitor
|
||||
* 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)
|
||||
{
|
||||
@ -3468,11 +3502,11 @@ static void drm_add_display_info(struct edid *edid,
|
||||
/**
|
||||
* drm_add_edid_modes - add modes from EDID data, if available
|
||||
* @connector: connector we're probing
|
||||
* @edid: edid data
|
||||
* @edid: EDID data
|
||||
*
|
||||
* 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)
|
||||
{
|
||||
@ -3534,7 +3568,7 @@ EXPORT_SYMBOL(drm_add_edid_modes);
|
||||
* 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.
|
||||
*
|
||||
* 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 hdisplay, int vdisplay)
|
||||
@ -3573,13 +3607,22 @@ int drm_add_modes_noedid(struct drm_connector *connector,
|
||||
}
|
||||
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,
|
||||
int hpref, int vpref)
|
||||
{
|
||||
struct drm_display_mode *mode;
|
||||
|
||||
list_for_each_entry(mode, &connector->probed_modes, head) {
|
||||
if (mode->hdisplay == hpref &&
|
||||
if (mode->hdisplay == hpref &&
|
||||
mode->vdisplay == vpref)
|
||||
mode->type |= DRM_MODE_TYPE_PREFERRED;
|
||||
}
|
||||
@ -3592,7 +3635,7 @@ EXPORT_SYMBOL(drm_set_preferred_mode);
|
||||
* @frame: HDMI AVI infoframe
|
||||
* @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
|
||||
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->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->scan_mode = HDMI_SCAN_MODE_UNDERSCAN;
|
||||
|
||||
@ -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
|
||||
* 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
|
||||
drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame,
|
||||
|
@ -45,13 +45,13 @@ static LIST_HEAD(kernel_fb_helper_list);
|
||||
* DOC: fbdev helpers
|
||||
*
|
||||
* 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
|
||||
* interfaces.
|
||||
*
|
||||
* 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().
|
||||
* 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().
|
||||
*
|
||||
* At runtime drivers should restore the fbdev console by calling
|
||||
@ -59,7 +59,7 @@ static LIST_HEAD(kernel_fb_helper_list);
|
||||
* should also notify the fb helper code from updates to the output
|
||||
* configuration by calling drm_fb_helper_hotplug_event(). For easier
|
||||
* 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
|
||||
* implement the fbdev driver interface by the driver.
|
||||
@ -326,12 +326,21 @@ static bool drm_fb_helper_force_kernel_mode(void)
|
||||
return false;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
ret = drm_fb_helper_restore_fbdev_mode(helper);
|
||||
if (ret)
|
||||
error = true;
|
||||
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
@ -43,8 +43,7 @@
|
||||
DEFINE_MUTEX(drm_global_mutex);
|
||||
EXPORT_SYMBOL(drm_global_mutex);
|
||||
|
||||
static int drm_open_helper(struct inode *inode, struct file *filp,
|
||||
struct drm_minor *minor);
|
||||
static int drm_open_helper(struct file *filp, struct drm_minor *minor);
|
||||
|
||||
static int drm_setup(struct drm_device * dev)
|
||||
{
|
||||
@ -95,7 +94,7 @@ int drm_open(struct inode *inode, struct file *filp)
|
||||
/* share address_space across all char-devs of a single device */
|
||||
filp->f_mapping = dev->anon_inode->i_mapping;
|
||||
|
||||
retcode = drm_open_helper(inode, filp, minor);
|
||||
retcode = drm_open_helper(filp, minor);
|
||||
if (retcode)
|
||||
goto err_undo;
|
||||
if (need_setup) {
|
||||
@ -171,7 +170,6 @@ static int drm_cpu_valid(void)
|
||||
/**
|
||||
* Called whenever a process opens /dev/drm.
|
||||
*
|
||||
* \param inode device inode.
|
||||
* \param filp file pointer.
|
||||
* \param minor acquired minor-object.
|
||||
* \return zero on success or a negative number on failure.
|
||||
@ -179,8 +177,7 @@ static int drm_cpu_valid(void)
|
||||
* 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.
|
||||
*/
|
||||
static int drm_open_helper(struct inode *inode, struct file *filp,
|
||||
struct drm_minor *minor)
|
||||
static int drm_open_helper(struct file *filp, struct drm_minor *minor)
|
||||
{
|
||||
struct drm_device *dev = minor->dev;
|
||||
struct drm_file *priv;
|
||||
|
@ -124,7 +124,6 @@ int drm_primary_helper_update(struct drm_plane *plane, struct drm_crtc *crtc,
|
||||
.y2 = crtc->mode.vdisplay,
|
||||
};
|
||||
struct drm_connector **connector_list;
|
||||
struct drm_framebuffer *tmpfb;
|
||||
int num_connectors, ret;
|
||||
|
||||
if (!crtc->enabled) {
|
||||
@ -145,6 +144,8 @@ int drm_primary_helper_update(struct drm_plane *plane, struct drm_crtc *crtc,
|
||||
}
|
||||
|
||||
/* Disallow scaling */
|
||||
src_w >>= 16;
|
||||
src_h >>= 16;
|
||||
if (crtc_w != src_w || crtc_h != src_h) {
|
||||
DRM_DEBUG_KMS("Can't scale primary plane\n");
|
||||
return -EINVAL;
|
||||
@ -176,21 +177,14 @@ int drm_primary_helper_update(struct drm_plane *plane, struct drm_crtc *crtc,
|
||||
set.num_connectors = num_connectors;
|
||||
|
||||
/*
|
||||
* set_config() adjusts crtc->primary->fb; however the DRM setplane
|
||||
* 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
|
||||
* We call set_config() directly here rather than using
|
||||
* drm_mode_set_config_internal. We're reprogramming the same
|
||||
* connectors that were already in use, so we shouldn't need the extra
|
||||
* cross-CRTC fb refcounting to accomodate stealing connectors.
|
||||
* drm_mode_setplane() already handles the basic refcounting for the
|
||||
* framebuffers involved in this operation.
|
||||
*/
|
||||
tmpfb = plane->fb;
|
||||
ret = crtc->funcs->set_config(&set);
|
||||
plane->fb = tmpfb;
|
||||
|
||||
kfree(connector_list);
|
||||
return ret;
|
||||
@ -232,7 +226,6 @@ EXPORT_SYMBOL(drm_primary_helper_disable);
|
||||
*/
|
||||
void drm_primary_helper_destroy(struct drm_plane *plane)
|
||||
{
|
||||
plane->funcs->disable_plane(plane);
|
||||
drm_plane_cleanup(plane);
|
||||
kfree(plane);
|
||||
}
|
||||
|
@ -151,7 +151,7 @@ static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connect
|
||||
drm_mode_validate_flag(connector, mode_flags);
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -949,12 +949,6 @@ static int exynos_dp_get_modes(struct drm_connector *connector)
|
||||
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(
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
@ -965,7 +959,6 @@ static struct drm_encoder *exynos_dp_best_encoder(
|
||||
|
||||
static struct drm_connector_helper_funcs exynos_dp_connector_helper_funcs = {
|
||||
.get_modes = exynos_dp_get_modes,
|
||||
.mode_valid = exynos_dp_mode_valid,
|
||||
.best_encoder = exynos_dp_best_encoder,
|
||||
};
|
||||
|
||||
|
@ -94,12 +94,6 @@ static int exynos_dpi_get_modes(struct drm_connector *connector)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int exynos_dpi_mode_valid(struct drm_connector *connector,
|
||||
struct drm_display_mode *mode)
|
||||
{
|
||||
return MODE_OK;
|
||||
}
|
||||
|
||||
static struct drm_encoder *
|
||||
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 = {
|
||||
.get_modes = exynos_dpi_get_modes,
|
||||
.mode_valid = exynos_dpi_mode_valid,
|
||||
.best_encoder = exynos_dpi_best_encoder,
|
||||
};
|
||||
|
||||
|
@ -533,12 +533,6 @@ static int vidi_get_modes(struct drm_connector *connector)
|
||||
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)
|
||||
{
|
||||
struct vidi_context *ctx = ctx_from_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 = {
|
||||
.get_modes = vidi_get_modes,
|
||||
.mode_valid = vidi_mode_valid,
|
||||
.best_encoder = vidi_best_encoder,
|
||||
};
|
||||
|
||||
|
@ -57,15 +57,8 @@ static int rcar_du_lvds_connector_get_modes(struct drm_connector *connector)
|
||||
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 = {
|
||||
.get_modes = rcar_du_lvds_connector_get_modes,
|
||||
.mode_valid = rcar_du_lvds_connector_mode_valid,
|
||||
.best_encoder = rcar_du_connector_best_encoder,
|
||||
};
|
||||
|
||||
|
@ -25,15 +25,8 @@ static int rcar_du_vga_connector_get_modes(struct drm_connector *connector)
|
||||
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 = {
|
||||
.get_modes = rcar_du_vga_connector_get_modes,
|
||||
.mode_valid = rcar_du_vga_connector_mode_valid,
|
||||
.best_encoder = rcar_du_connector_best_encoder,
|
||||
};
|
||||
|
||||
|
@ -674,12 +674,6 @@ static int shmob_drm_connector_get_modes(struct drm_connector *connector)
|
||||
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 *
|
||||
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 = {
|
||||
.get_modes = shmob_drm_connector_get_modes,
|
||||
.mode_valid = shmob_drm_connector_mode_valid,
|
||||
.best_encoder = shmob_drm_connector_best_encoder,
|
||||
};
|
||||
|
||||
|
@ -200,13 +200,6 @@ static const struct file_operations imx_drm_driver_fops = {
|
||||
.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)
|
||||
{
|
||||
drm_sysfs_connector_remove(connector);
|
||||
|
@ -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,
|
||||
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_encoder_destroy(struct drm_encoder *encoder);
|
||||
|
||||
|
@ -1492,7 +1492,6 @@ static struct drm_connector_funcs imx_hdmi_connector_funcs = {
|
||||
|
||||
static struct drm_connector_helper_funcs imx_hdmi_connector_helper_funcs = {
|
||||
.get_modes = imx_hdmi_connector_get_modes,
|
||||
.mode_valid = imx_drm_connector_mode_valid,
|
||||
.best_encoder = imx_hdmi_connector_best_encoder,
|
||||
};
|
||||
|
||||
|
@ -317,7 +317,6 @@ static struct drm_connector_funcs imx_ldb_connector_funcs = {
|
||||
static struct drm_connector_helper_funcs imx_ldb_connector_helper_funcs = {
|
||||
.get_modes = imx_ldb_connector_get_modes,
|
||||
.best_encoder = imx_ldb_connector_best_encoder,
|
||||
.mode_valid = imx_drm_connector_mode_valid,
|
||||
};
|
||||
|
||||
static struct drm_encoder_funcs imx_ldb_encoder_funcs = {
|
||||
|
@ -251,10 +251,6 @@ static int imx_tve_connector_mode_valid(struct drm_connector *connector,
|
||||
unsigned long rate;
|
||||
int ret;
|
||||
|
||||
ret = imx_drm_connector_mode_valid(connector, mode);
|
||||
if (ret != MODE_OK)
|
||||
return ret;
|
||||
|
||||
/* pixel clock with 2x oversampling */
|
||||
rate = clk_round_rate(tve->clk, 2000UL * mode->clock) / 2000;
|
||||
if (rate == mode->clock)
|
||||
|
@ -148,7 +148,6 @@ static struct drm_connector_funcs imx_pd_connector_funcs = {
|
||||
static struct drm_connector_helper_funcs imx_pd_connector_helper_funcs = {
|
||||
.get_modes = imx_pd_connector_get_modes,
|
||||
.best_encoder = imx_pd_connector_best_encoder,
|
||||
.mode_valid = imx_drm_connector_mode_valid,
|
||||
};
|
||||
|
||||
static struct drm_encoder_funcs imx_pd_encoder_funcs = {
|
||||
|
@ -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,
|
||||
void *data, struct drm_file *file_priv);
|
||||
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_monitor_audio(struct edid *edid);
|
||||
extern bool drm_rgb_quant_range_selectable(struct edid *edid);
|
||||
|
@ -114,7 +114,7 @@ struct drm_encoder_helper_funcs {
|
||||
/**
|
||||
* drm_connector_helper_funcs - helper operations for connectors
|
||||
* @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.
|
||||
*/
|
||||
|
@ -57,6 +57,7 @@ typedef void (*drm_flip_func_t)(struct drm_flip_work *work, void *val);
|
||||
* @count: number of committed items
|
||||
* @func: callback fxn called for each committed item
|
||||
* @worker: worker which calls @func
|
||||
* @fifo: queue of committed items
|
||||
*/
|
||||
struct drm_flip_work {
|
||||
const char *name;
|
||||
|
Loading…
Reference in New Issue
Block a user