From afd18bce6a81106a12fd750d5fa09d05c09d37a8 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 1 Apr 2015 14:32:00 +1000 Subject: [PATCH] xf86Crtc: setup tiled monitors correctly in right of This puts the tiles of the monitor in the right place at X server startup. Reviewed-by: Keith Packard Signed-off-by: Dave Airlie --- hw/xfree86/modes/xf86Crtc.c | 61 +++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c index 8a4ef5e5a..585bd9851 100644 --- a/hw/xfree86/modes/xf86Crtc.c +++ b/hw/xfree86/modes/xf86Crtc.c @@ -2128,6 +2128,8 @@ xf86TargetRightOf(ScrnInfoPtr scrn, xf86CrtcConfigPtr config, { int o; int w = 0; + Bool has_tile = FALSE; + uint32_t configured_outputs; if (scrn->preferClone) return FALSE; @@ -2149,16 +2151,75 @@ xf86TargetRightOf(ScrnInfoPtr scrn, xf86CrtcConfigPtr config, return FALSE; w = 0; + configured_outputs = 0; + for (o = -1; nextEnabledOutput(config, enabled, &o); ) { DisplayModePtr mode = xf86OutputHasPreferredMode(config->output[o], width, height); + if (configured_outputs & (1 << o)) + continue; + + if (config->output[o]->tile_info.group_id) { + has_tile = TRUE; + continue; + } + config->output[o]->initial_x = w; w += mode->HDisplay; + configured_outputs |= (1 << o); modes[o] = mode; } + if (has_tile) { + for (o = -1; nextEnabledOutput(config, enabled, &o); ) { + int ht, vt, ot; + int add_x, cur_x = w; + struct xf86CrtcTileInfo *tile_info = &config->output[o]->tile_info, *this_tile; + if (configured_outputs & (1 << o)) + continue; + if (!tile_info->group_id) + continue; + + if (tile_info->tile_h_loc != 0 && tile_info->tile_v_loc != 0) + continue; + + for (ht = 0; ht < tile_info->num_h_tile; ht++) { + int cur_y = 0; + add_x = 0; + for (vt = 0; vt < tile_info->num_v_tile; vt++) { + + for (ot = -1; nextEnabledOutput(config, enabled, &ot); ) { + + DisplayModePtr mode = + xf86OutputHasPreferredMode(config->output[ot], width, height); + if (!config->output[ot]->tile_info.group_id) + continue; + + this_tile = &config->output[ot]->tile_info; + if (this_tile->group_id != tile_info->group_id) + continue; + + if (this_tile->tile_h_loc != ht || + this_tile->tile_v_loc != vt) + continue; + + config->output[ot]->initial_x = cur_x; + config->output[ot]->initial_y = cur_y; + + if (vt == 0) + add_x = this_tile->tile_h_size; + cur_y += this_tile->tile_v_size; + configured_outputs |= (1 << ot); + modes[ot] = mode; + } + } + cur_x += add_x; + } + w = cur_x; + } + } return TRUE; }