drm: split edid handling in get_edid & add_edid_mode
This way driver can get_edid in output status detection (using all workaround which are in get_edid) and then provide this edid data in get_mode callback of output.main
parent
d983ed90cb
commit
ffb89d4c3b
|
@ -487,8 +487,9 @@ extern void drm_output_destroy(struct drm_output *output);
|
||||||
extern bool drm_output_rename(struct drm_output *output, const char *name);
|
extern bool drm_output_rename(struct drm_output *output, const char *name);
|
||||||
extern void drm_fb_release(struct file *filp);
|
extern void drm_fb_release(struct file *filp);
|
||||||
|
|
||||||
extern int drm_add_edid_modes(struct drm_output *output,
|
extern struct edid *drm_get_edid(struct drm_output *output,
|
||||||
struct i2c_adapter *adapter);
|
struct i2c_adapter *adapter);
|
||||||
|
extern int drm_add_edid_modes(struct drm_output *output, struct edid *edid);
|
||||||
extern void drm_mode_probed_add(struct drm_output *output, struct drm_display_mode *mode);
|
extern void drm_mode_probed_add(struct drm_output *output, struct drm_display_mode *mode);
|
||||||
extern void drm_mode_remove(struct drm_output *output, struct drm_display_mode *mode);
|
extern void drm_mode_remove(struct drm_output *output, struct drm_display_mode *mode);
|
||||||
extern struct drm_display_mode *drm_mode_duplicate(struct drm_device *dev,
|
extern struct drm_display_mode *drm_mode_duplicate(struct drm_device *dev,
|
||||||
|
|
|
@ -427,41 +427,51 @@ static unsigned char *drm_ddc_read(struct i2c_adapter *adapter)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* drm_add_edid_modes - add modes from EDID data, if available
|
* drm_get_edid - get EDID data, if available
|
||||||
* @output: output we're probing
|
* @output: output we're probing
|
||||||
* @adapter: i2c adapter to use for DDC
|
* @adapter: i2c adapter to use for DDC
|
||||||
*
|
*
|
||||||
* Poke the given output's i2c channel to grab EDID data if possible. If we
|
* Poke the given output's i2c channel to grab EDID data if possible.
|
||||||
* get any, add the specified modes to the output's mode list.
|
|
||||||
*
|
*
|
||||||
* Return number of modes added or 0 if we couldn't find any.
|
* Return edid data or NULL if we couldn't find any.
|
||||||
*/
|
*/
|
||||||
int drm_add_edid_modes(struct drm_output *output, struct i2c_adapter *adapter)
|
struct edid *drm_get_edid(struct drm_output *output,
|
||||||
|
struct i2c_adapter *adapter)
|
||||||
{
|
{
|
||||||
struct edid *edid;
|
struct edid *edid;
|
||||||
int num_modes = 0;
|
|
||||||
|
|
||||||
edid = (struct edid *)drm_ddc_read(adapter);
|
edid = (struct edid *)drm_ddc_read(adapter);
|
||||||
if (!edid) {
|
if (!edid) {
|
||||||
dev_warn(&output->dev->pdev->dev, "%s: no EDID data\n",
|
dev_warn(&output->dev->pdev->dev, "%s: no EDID data\n",
|
||||||
output->name);
|
output->name);
|
||||||
goto out_err;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!edid_valid(edid)) {
|
if (!edid_valid(edid)) {
|
||||||
dev_warn(&output->dev->pdev->dev, "%s: EDID invalid.\n",
|
dev_warn(&output->dev->pdev->dev, "%s: EDID invalid.\n",
|
||||||
output->name);
|
output->name);
|
||||||
goto out_err;
|
kfree(edid);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
return edid;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(drm_get_edid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* drm_add_edid_modes - add modes from EDID data, if available
|
||||||
|
* @output: output we're probing
|
||||||
|
* @edid: edid data
|
||||||
|
*
|
||||||
|
* Add the specified modes to the output's mode list.
|
||||||
|
*
|
||||||
|
* Return number of modes added or 0 if we couldn't find any.
|
||||||
|
*/
|
||||||
|
int drm_add_edid_modes(struct drm_output *output, struct edid *edid)
|
||||||
|
{
|
||||||
|
int num_modes = 0;
|
||||||
|
|
||||||
num_modes += add_established_modes(output, edid);
|
num_modes += add_established_modes(output, edid);
|
||||||
num_modes += add_standard_modes(output, edid);
|
num_modes += add_standard_modes(output, edid);
|
||||||
num_modes += add_detailed_info(output, edid);
|
num_modes += add_detailed_info(output, edid);
|
||||||
|
|
||||||
return num_modes;
|
return num_modes;
|
||||||
|
|
||||||
out_err:
|
|
||||||
kfree(edid);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_add_edid_modes);
|
EXPORT_SYMBOL(drm_add_edid_modes);
|
||||||
|
|
|
@ -50,6 +50,13 @@ bool intel_ddc_probe(struct drm_output *output)
|
||||||
int intel_ddc_get_modes(struct drm_output *output)
|
int intel_ddc_get_modes(struct drm_output *output)
|
||||||
{
|
{
|
||||||
struct intel_output *intel_output = output->driver_private;
|
struct intel_output *intel_output = output->driver_private;
|
||||||
|
struct edid *edid;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
return drm_add_edid_modes(output, &intel_output->ddc_bus->adapter);
|
edid = drm_get_edid(output, &intel_output->ddc_bus->adapter);
|
||||||
|
if (edid) {
|
||||||
|
ret = drm_add_edid_modes(output, edid);
|
||||||
|
kfree(edid);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue