2
0
mirror of https://github.com/edk2-porting/linux-next.git synced 2024-12-18 18:23:53 +08:00

drm/i915: Set crtc/clone mask in different output devices

Based on Bspec each encoder has different sharing pipe property,
i.e. Integrated or SDVO TV both will occupy one pipe exclusively,
and sdvo-non-tv and crt are allowed to share one. The patch moves
sharing judgment into differnet output functions, and sets the right
clone bit.

This fixes both HDMI outputs choosing the same pipe.

https://bugs.freedesktop.org/show_bug.cgi?id=22247

Signed-off-by: Ma Ling <ling.ma@intel.com>
Reviewed-by : Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Zhao Yakui <yakui.zhao@intel.com>
Signed-off-by: Eric Anholt <eric@anholt.net>
This commit is contained in:
Ma Ling 2009-08-24 13:50:24 +08:00 committed by Eric Anholt
parent 27185ae1b7
commit f8aed700c6
9 changed files with 73 additions and 51 deletions

View File

@ -537,6 +537,10 @@ void intel_crt_init(struct drm_device *dev)
}
intel_output->type = INTEL_OUTPUT_ANALOG;
intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
(1 << INTEL_ANALOG_CLONE_BIT) |
(1 << INTEL_SDVO_LVDS_CLONE_BIT);
intel_output->crtc_mask = (1 << 0) | (1 << 1);
connector->interlace_allowed = 0;
connector->doublescan_allowed = 0;

View File

@ -3170,7 +3170,7 @@ static int intel_connector_clones(struct drm_device *dev, int type_mask)
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
struct intel_output *intel_output = to_intel_output(connector);
if (type_mask & (1 << intel_output->type))
if (type_mask & intel_output->clone_mask)
index_mask |= (1 << entry);
entry++;
}
@ -3253,51 +3253,10 @@ static void intel_setup_outputs(struct drm_device *dev)
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
struct intel_output *intel_output = to_intel_output(connector);
struct drm_encoder *encoder = &intel_output->enc;
int crtc_mask = 0, clone_mask = 0;
/* valid crtcs */
switch(intel_output->type) {
case INTEL_OUTPUT_HDMI:
crtc_mask = ((1 << 0)|
(1 << 1));
clone_mask = ((1 << INTEL_OUTPUT_HDMI));
break;
case INTEL_OUTPUT_DVO:
case INTEL_OUTPUT_SDVO:
crtc_mask = ((1 << 0)|
(1 << 1));
clone_mask = ((1 << INTEL_OUTPUT_ANALOG) |
(1 << INTEL_OUTPUT_DVO) |
(1 << INTEL_OUTPUT_SDVO));
break;
case INTEL_OUTPUT_ANALOG:
crtc_mask = ((1 << 0)|
(1 << 1));
clone_mask = ((1 << INTEL_OUTPUT_ANALOG) |
(1 << INTEL_OUTPUT_DVO) |
(1 << INTEL_OUTPUT_SDVO));
break;
case INTEL_OUTPUT_LVDS:
crtc_mask = (1 << 1);
clone_mask = (1 << INTEL_OUTPUT_LVDS);
break;
case INTEL_OUTPUT_TVOUT:
crtc_mask = ((1 << 0) |
(1 << 1));
clone_mask = (1 << INTEL_OUTPUT_TVOUT);
break;
case INTEL_OUTPUT_DISPLAYPORT:
crtc_mask = ((1 << 0) |
(1 << 1));
clone_mask = (1 << INTEL_OUTPUT_DISPLAYPORT);
break;
case INTEL_OUTPUT_EDP:
crtc_mask = (1 << 1);
clone_mask = (1 << INTEL_OUTPUT_EDP);
break;
}
encoder->possible_crtcs = crtc_mask;
encoder->possible_clones = intel_connector_clones(dev, clone_mask);
encoder->possible_crtcs = intel_output->crtc_mask;
encoder->possible_clones = intel_connector_clones(dev,
intel_output->clone_mask);
}
}

View File

@ -1254,6 +1254,18 @@ intel_dp_init(struct drm_device *dev, int output_reg)
else
intel_output->type = INTEL_OUTPUT_DISPLAYPORT;
if (output_reg == DP_B)
intel_output->clone_mask = (1 << INTEL_DP_B_CLONE_BIT);
else if (output_reg == DP_C)
intel_output->clone_mask = (1 << INTEL_DP_C_CLONE_BIT);
else if (output_reg == DP_D)
intel_output->clone_mask = (1 << INTEL_DP_D_CLONE_BIT);
if (IS_eDP(intel_output)) {
intel_output->crtc_mask = (1 << 1);
intel_output->clone_mask = (1 << INTEL_OUTPUT_EDP);
} else
intel_output->crtc_mask = (1 << 0) | (1 << 1);
connector->interlace_allowed = true;
connector->doublescan_allowed = 0;

View File

@ -57,6 +57,24 @@
#define INTEL_OUTPUT_DISPLAYPORT 7
#define INTEL_OUTPUT_EDP 8
/* Intel Pipe Clone Bit */
#define INTEL_HDMIB_CLONE_BIT 1
#define INTEL_HDMIC_CLONE_BIT 2
#define INTEL_HDMID_CLONE_BIT 3
#define INTEL_HDMIE_CLONE_BIT 4
#define INTEL_HDMIF_CLONE_BIT 5
#define INTEL_SDVO_NON_TV_CLONE_BIT 6
#define INTEL_SDVO_TV_CLONE_BIT 7
#define INTEL_SDVO_LVDS_CLONE_BIT 8
#define INTEL_ANALOG_CLONE_BIT 9
#define INTEL_TV_CLONE_BIT 10
#define INTEL_DP_B_CLONE_BIT 11
#define INTEL_DP_C_CLONE_BIT 12
#define INTEL_DP_D_CLONE_BIT 13
#define INTEL_LVDS_CLONE_BIT 14
#define INTEL_DVO_TMDS_CLONE_BIT 15
#define INTEL_DVO_LVDS_CLONE_BIT 16
#define INTEL_DVO_CHIP_NONE 0
#define INTEL_DVO_CHIP_LVDS 1
#define INTEL_DVO_CHIP_TMDS 2
@ -86,6 +104,8 @@ struct intel_output {
bool needs_tv_clock;
void *dev_priv;
void (*hot_plug)(struct intel_output *);
int crtc_mask;
int clone_mask;
};
struct intel_crtc {

View File

@ -435,14 +435,20 @@ void intel_dvo_init(struct drm_device *dev)
continue;
intel_output->type = INTEL_OUTPUT_DVO;
intel_output->crtc_mask = (1 << 0) | (1 << 1);
switch (dvo->type) {
case INTEL_DVO_CHIP_TMDS:
intel_output->clone_mask =
(1 << INTEL_DVO_TMDS_CLONE_BIT) |
(1 << INTEL_ANALOG_CLONE_BIT);
drm_connector_init(dev, connector,
&intel_dvo_connector_funcs,
DRM_MODE_CONNECTOR_DVII);
encoder_type = DRM_MODE_ENCODER_TMDS;
break;
case INTEL_DVO_CHIP_LVDS:
intel_output->clone_mask =
(1 << INTEL_DVO_LVDS_CLONE_BIT);
drm_connector_init(dev, connector,
&intel_dvo_connector_funcs,
DRM_MODE_CONNECTOR_LVDS);

View File

@ -230,22 +230,28 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
connector->interlace_allowed = 0;
connector->doublescan_allowed = 0;
intel_output->crtc_mask = (1 << 0) | (1 << 1);
/* Set up the DDC bus. */
if (sdvox_reg == SDVOB)
if (sdvox_reg == SDVOB) {
intel_output->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT);
intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "HDMIB");
else if (sdvox_reg == SDVOC)
} else if (sdvox_reg == SDVOC) {
intel_output->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT);
intel_output->ddc_bus = intel_i2c_create(dev, GPIOD, "HDMIC");
else if (sdvox_reg == HDMIB)
} else if (sdvox_reg == HDMIB) {
intel_output->clone_mask = (1 << INTEL_HDMID_CLONE_BIT);
intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOE,
"HDMIB");
else if (sdvox_reg == HDMIC)
} else if (sdvox_reg == HDMIC) {
intel_output->clone_mask = (1 << INTEL_HDMIE_CLONE_BIT);
intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOD,
"HDMIC");
else if (sdvox_reg == HDMID)
} else if (sdvox_reg == HDMID) {
intel_output->clone_mask = (1 << INTEL_HDMIF_CLONE_BIT);
intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOF,
"HDMID");
}
if (!intel_output->ddc_bus)
goto err_connector;

View File

@ -916,6 +916,8 @@ void intel_lvds_init(struct drm_device *dev)
drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
intel_output->type = INTEL_OUTPUT_LVDS;
intel_output->clone_mask = (1 << INTEL_LVDS_CLONE_BIT);
intel_output->crtc_mask = (1 << 1);
drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs);
drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs);
connector->display_info.subpixel_order = SubPixelHorizontalRGB;

View File

@ -1967,6 +1967,9 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
intel_sdvo_set_colorimetry(intel_output,
SDVO_COLORIMETRY_RGB256);
connector->connector_type = DRM_MODE_CONNECTOR_HDMIA;
intel_output->clone_mask =
(1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
(1 << INTEL_ANALOG_CLONE_BIT);
}
} else if (flags & SDVO_OUTPUT_SVID0) {
@ -1975,11 +1978,14 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO;
sdvo_priv->is_tv = true;
intel_output->needs_tv_clock = true;
intel_output->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT;
} else if (flags & SDVO_OUTPUT_RGB0) {
sdvo_priv->controlled_output = SDVO_OUTPUT_RGB0;
encoder->encoder_type = DRM_MODE_ENCODER_DAC;
connector->connector_type = DRM_MODE_CONNECTOR_VGA;
intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
(1 << INTEL_ANALOG_CLONE_BIT);
} else if (flags & SDVO_OUTPUT_RGB1) {
sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1;
@ -1991,12 +1997,16 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
encoder->encoder_type = DRM_MODE_ENCODER_LVDS;
connector->connector_type = DRM_MODE_CONNECTOR_LVDS;
sdvo_priv->is_lvds = true;
intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) |
(1 << INTEL_SDVO_LVDS_CLONE_BIT);
} else if (flags & SDVO_OUTPUT_LVDS1) {
sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS1;
encoder->encoder_type = DRM_MODE_ENCODER_LVDS;
connector->connector_type = DRM_MODE_CONNECTOR_LVDS;
sdvo_priv->is_lvds = true;
intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) |
(1 << INTEL_SDVO_LVDS_CLONE_BIT);
} else {
unsigned char bytes[2];
@ -2009,6 +2019,7 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
bytes[0], bytes[1]);
ret = false;
}
intel_output->crtc_mask = (1 << 0) | (1 << 1);
if (ret && registered)
ret = drm_sysfs_connector_add(connector) == 0 ? true : false;

View File

@ -1718,6 +1718,7 @@ intel_tv_init(struct drm_device *dev)
if (!intel_output) {
return;
}
connector = &intel_output->base;
drm_connector_init(dev, connector, &intel_tv_connector_funcs,
@ -1729,6 +1730,7 @@ intel_tv_init(struct drm_device *dev)
drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
tv_priv = (struct intel_tv_priv *)(intel_output + 1);
intel_output->type = INTEL_OUTPUT_TVOUT;
intel_output->clone_mask = (1 << INTEL_TV_CLONE_BIT);
intel_output->enc.possible_crtcs = ((1 << 0) | (1 << 1));
intel_output->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT);
intel_output->dev_priv = tv_priv;