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) {
|
||||
|
||||
/* set all modes to the unverified state */
|
||||
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);
|
||||
|
||||
|
@ -300,9 +301,7 @@ void drm_crtc_probe_output_modes(struct drm_device *dev, int maxX, int maxY)
|
|||
ret = (*output->funcs->get_modes)(output);
|
||||
|
||||
if (ret) {
|
||||
/* move the modes over to the main mode list */
|
||||
drm_mode_list_concat(&output->probed_modes,
|
||||
&output->modes);
|
||||
drm_mode_output_list_update(output);
|
||||
}
|
||||
|
||||
if (maxX && maxY)
|
||||
|
|
|
@ -59,6 +59,7 @@ enum drm_mode_status {
|
|||
MODE_ONE_HEIGHT, /* only one height is supported */
|
||||
MODE_ONE_SIZE, /* only one resolution is supported */
|
||||
MODE_NO_REDUCED, /* monitor doesn't accept reduced blanking */
|
||||
MODE_UNVERIFIED = -3, /* mode needs to reverified */
|
||||
MODE_BAD = -2, /* unspecified reason */
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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