drm: make mode numbers no change by comparing probed modes
The mode list sets all the output modes to UNVERIFIED, then probes a new list, If a mode is on the new list and not on the old, it adds it to the old, if a mode is on the new list and old, it just updates the status to the new mode status. If a mode is on the old list and not on the new, prune invalid modes should remove all UNVERIFIED modesmain
parent
0f3c5148f0
commit
ceb44021ad
|
@ -286,8 +286,9 @@ void drm_crtc_probe_output_modes(struct drm_device *dev, int maxX, int maxY)
|
||||||
|
|
||||||
list_for_each_entry(output, &dev->mode_config.output_list, head) {
|
list_for_each_entry(output, &dev->mode_config.output_list, head) {
|
||||||
|
|
||||||
|
/* set all modes to the unverified state */
|
||||||
list_for_each_entry_safe(mode, t, &output->modes, head)
|
list_for_each_entry_safe(mode, t, &output->modes, head)
|
||||||
drm_mode_remove(output, mode);
|
mode->status = MODE_UNVERIFIED;
|
||||||
|
|
||||||
output->status = (*output->funcs->detect)(output);
|
output->status = (*output->funcs->detect)(output);
|
||||||
|
|
||||||
|
@ -300,9 +301,7 @@ void drm_crtc_probe_output_modes(struct drm_device *dev, int maxX, int maxY)
|
||||||
ret = (*output->funcs->get_modes)(output);
|
ret = (*output->funcs->get_modes)(output);
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
/* move the modes over to the main mode list */
|
drm_mode_output_list_update(output);
|
||||||
drm_mode_list_concat(&output->probed_modes,
|
|
||||||
&output->modes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (maxX && maxY)
|
if (maxX && maxY)
|
||||||
|
|
|
@ -59,6 +59,7 @@ enum drm_mode_status {
|
||||||
MODE_ONE_HEIGHT, /* only one height is supported */
|
MODE_ONE_HEIGHT, /* only one height is supported */
|
||||||
MODE_ONE_SIZE, /* only one resolution is supported */
|
MODE_ONE_SIZE, /* only one resolution is supported */
|
||||||
MODE_NO_REDUCED, /* monitor doesn't accept reduced blanking */
|
MODE_NO_REDUCED, /* monitor doesn't accept reduced blanking */
|
||||||
|
MODE_UNVERIFIED = -3, /* mode needs to reverified */
|
||||||
MODE_BAD = -2, /* unspecified reason */
|
MODE_BAD = -2, /* unspecified reason */
|
||||||
MODE_ERROR = -1 /* error condition */
|
MODE_ERROR = -1 /* error condition */
|
||||||
};
|
};
|
||||||
|
|
|
@ -517,3 +517,42 @@ void drm_mode_sort(struct list_head *mode_list)
|
||||||
{
|
{
|
||||||
list_sort(mode_list, drm_mode_compare);
|
list_sort(mode_list, drm_mode_compare);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* drm_mode_output_list_update - update the mode list for the output
|
||||||
|
* @output: the output to update
|
||||||
|
*
|
||||||
|
* LOCKING:
|
||||||
|
* Caller must hold a lock protecting @mode_list.
|
||||||
|
*
|
||||||
|
* This moves the modes from the @output probed_modes list
|
||||||
|
* to the actual mode list. It compares the probed mode against the current
|
||||||
|
* list and only adds different modes. All modes unverified after this point
|
||||||
|
* will be removed by the prune invalid modes.
|
||||||
|
*/
|
||||||
|
void drm_mode_output_list_update(struct drm_output *output)
|
||||||
|
{
|
||||||
|
struct drm_display_mode *mode, *t;
|
||||||
|
struct drm_display_mode *pmode, *pt;
|
||||||
|
int found_it;
|
||||||
|
list_for_each_entry_safe(pmode, pt, &output->probed_modes,
|
||||||
|
head) {
|
||||||
|
found_it = 0;
|
||||||
|
/* go through current modes checking for the new probed mode */
|
||||||
|
list_for_each_entry(mode, &output->modes, head) {
|
||||||
|
if (drm_mode_equal(pmode, mode)) {
|
||||||
|
found_it = 1;
|
||||||
|
/* if equal delete the probed mode */
|
||||||
|
mode->status = pmode->status;
|
||||||
|
list_del(&pmode->head);
|
||||||
|
kfree(pmode);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found_it) {
|
||||||
|
list_move_tail(&pmode->head, &output->modes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue