Merge commit 'origin/master' into projective-965
This commit is contained in:
commit
dcbdc901d6
329
src/i830_sdvo.c
329
src/i830_sdvo.c
|
|
@ -59,7 +59,7 @@ struct i830_sdvo_priv {
|
|||
int output_device;
|
||||
|
||||
/** Active outputs controlled by this SDVO output */
|
||||
uint16_t active_outputs;
|
||||
uint16_t controlled_output;
|
||||
|
||||
/**
|
||||
* Capabilities of the SDVO device returned by i830_sdvo_get_capabilities()
|
||||
|
|
@ -69,6 +69,32 @@ struct i830_sdvo_priv {
|
|||
/** Pixel clock limitations reported by the SDVO device, in kHz */
|
||||
int pixel_clock_min, pixel_clock_max;
|
||||
|
||||
/**
|
||||
* This is set if we're going to treat the device as TV-out.
|
||||
*
|
||||
* While we have these nice friendly flags for output types that ought to
|
||||
* decide this for us, the S-Video output on our HDMI+S-Video card shows
|
||||
* up as RGB1 (VGA).
|
||||
*/
|
||||
Bool is_tv;
|
||||
|
||||
/**
|
||||
* Returned SDTV resolutions allowed for the current format, if the
|
||||
* device reported it.
|
||||
*/
|
||||
struct i830_sdvo_sdtv_resolution_reply sdtv_resolutions;
|
||||
|
||||
/**
|
||||
* Current selected TV format.
|
||||
*
|
||||
* This is stored in the same structure that's passed to the device, for
|
||||
* convenience.
|
||||
*/
|
||||
struct i830_sdvo_tv_format tv_format;
|
||||
|
||||
/** DDC bus used by this SDVO output */
|
||||
uint8_t ddc_bus;
|
||||
|
||||
/** State for save/restore */
|
||||
/** @{ */
|
||||
int save_sdvo_mult;
|
||||
|
|
@ -201,11 +227,13 @@ const static struct _sdvo_cmd_name {
|
|||
SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ENCODER_POWER_STATE),
|
||||
SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_RESOLUTION_SUPPORT),
|
||||
SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CONTROL_BUS_SWITCH),
|
||||
SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT),
|
||||
SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS),
|
||||
};
|
||||
|
||||
static I2CSlaveAddr slaveAddr;
|
||||
|
||||
#define SDVO_NAME(dev_priv) ((dev_priv)->output_device == SDVOB ? "SDVO" : "SDVO")
|
||||
#define SDVO_NAME(dev_priv) ((dev_priv)->output_device == SDVOB ? "SDVOB" : "SDVOC")
|
||||
#define SDVO_PRIV(output) ((struct i830_sdvo_priv *) (output)->dev_priv)
|
||||
|
||||
/**
|
||||
|
|
@ -643,13 +671,26 @@ i830_sdvo_mode_set(xf86OutputPtr output, DisplayModePtr mode,
|
|||
uint16_t width, height;
|
||||
uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len;
|
||||
uint16_t h_sync_offset, v_sync_offset;
|
||||
struct i830_sdvo_in_out_map in_out;
|
||||
struct i830_sdvo_dtd output_dtd;
|
||||
uint16_t no_outputs;
|
||||
|
||||
no_outputs = 0;
|
||||
uint8_t status;
|
||||
|
||||
if (!mode)
|
||||
return;
|
||||
|
||||
/* First, set the input mapping for the first input to our controlled
|
||||
* output. This is only correct if we're a single-input device, in
|
||||
* which case the first input is the output from the appropriate SDVO
|
||||
* channel on the motherboard. In a two-input device, the first input
|
||||
* will be SDVOB and the second SDVOC.
|
||||
*/
|
||||
in_out.in0 = dev_priv->controlled_output;
|
||||
in_out.in1 = 0;
|
||||
|
||||
i830_sdvo_write_cmd(output, SDVO_CMD_SET_IN_OUT_MAP,
|
||||
&in_out, sizeof(in_out));
|
||||
status = i830_sdvo_read_response(output, NULL, 0);
|
||||
|
||||
width = mode->CrtcHDisplay;
|
||||
height = mode->CrtcVDisplay;
|
||||
|
||||
|
|
@ -692,7 +733,7 @@ i830_sdvo_mode_set(xf86OutputPtr output, DisplayModePtr mode,
|
|||
output_dtd.part2.reserved = 0;
|
||||
|
||||
/* Set the output timing to the screen */
|
||||
i830_sdvo_set_target_output(output, dev_priv->active_outputs);
|
||||
i830_sdvo_set_target_output(output, dev_priv->controlled_output);
|
||||
i830_sdvo_set_output_timing(output, &output_dtd);
|
||||
|
||||
/* Set the input timing to the screen. Assume always input 0. */
|
||||
|
|
@ -800,7 +841,7 @@ i830_sdvo_dpms(xf86OutputPtr output, int mode)
|
|||
|
||||
if (0)
|
||||
i830_sdvo_set_encoder_power_state(output, mode);
|
||||
i830_sdvo_set_active_outputs(output, dev_priv->active_outputs);
|
||||
i830_sdvo_set_active_outputs(output, dev_priv->controlled_output);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -818,12 +859,10 @@ i830_sdvo_save(xf86OutputPtr output)
|
|||
dev_priv->save_sdvo_mult = i830_sdvo_get_clock_rate_mult(output);
|
||||
i830_sdvo_get_active_outputs(output, &dev_priv->save_active_outputs);
|
||||
|
||||
if (dev_priv->caps.sdvo_inputs_mask & 0x1) {
|
||||
i830_sdvo_set_target_input(output, TRUE, FALSE);
|
||||
i830_sdvo_get_input_timing(output, &dev_priv->save_input_dtd_1);
|
||||
}
|
||||
i830_sdvo_set_target_input(output, TRUE, FALSE);
|
||||
i830_sdvo_get_input_timing(output, &dev_priv->save_input_dtd_1);
|
||||
|
||||
if (dev_priv->caps.sdvo_inputs_mask & 0x2) {
|
||||
if (dev_priv->caps.sdvo_input_count >= 2) {
|
||||
i830_sdvo_set_target_input(output, FALSE, TRUE);
|
||||
i830_sdvo_get_input_timing(output, &dev_priv->save_input_dtd_2);
|
||||
}
|
||||
|
|
@ -837,6 +876,9 @@ i830_sdvo_save(xf86OutputPtr output)
|
|||
i830_sdvo_get_output_timing(output, &dev_priv->save_output_dtd[o]);
|
||||
}
|
||||
}
|
||||
if (dev_priv->is_tv) {
|
||||
/* XXX: Save TV format/enhancements. */
|
||||
}
|
||||
|
||||
dev_priv->save_SDVOX = INREG(dev_priv->output_device);
|
||||
}
|
||||
|
|
@ -864,18 +906,20 @@ i830_sdvo_restore(xf86OutputPtr output)
|
|||
}
|
||||
}
|
||||
|
||||
if (dev_priv->caps.sdvo_inputs_mask & 0x1) {
|
||||
i830_sdvo_set_target_input(output, TRUE, FALSE);
|
||||
i830_sdvo_set_input_timing(output, &dev_priv->save_input_dtd_1);
|
||||
}
|
||||
i830_sdvo_set_target_input(output, TRUE, FALSE);
|
||||
i830_sdvo_set_input_timing(output, &dev_priv->save_input_dtd_1);
|
||||
|
||||
if (dev_priv->caps.sdvo_inputs_mask & 0x2) {
|
||||
if (dev_priv->caps.sdvo_input_count >= 2) {
|
||||
i830_sdvo_set_target_input(output, FALSE, TRUE);
|
||||
i830_sdvo_set_input_timing(output, &dev_priv->save_input_dtd_2);
|
||||
}
|
||||
|
||||
i830_sdvo_set_clock_rate_mult(output, dev_priv->save_sdvo_mult);
|
||||
|
||||
if (dev_priv->is_tv) {
|
||||
/* XXX: Restore TV format/enhancements. */
|
||||
}
|
||||
|
||||
i830_sdvo_write_sdvox(output, dev_priv->save_SDVOX);
|
||||
|
||||
if (dev_priv->save_SDVOX & SDVO_ENABLE)
|
||||
|
|
@ -970,8 +1014,9 @@ i830_sdvo_ddc_i2c_start(I2CBusPtr b, int timeout)
|
|||
xf86OutputPtr output = b->DriverPrivate.ptr;
|
||||
I830OutputPrivatePtr intel_output = output->driver_private;
|
||||
I2CBusPtr i2cbus = intel_output->pI2CBus;
|
||||
struct i830_sdvo_priv *dev_priv = intel_output->dev_priv;
|
||||
|
||||
i830_sdvo_set_control_bus_switch(output, SDVO_CONTROL_BUS_DDC2);
|
||||
i830_sdvo_set_control_bus_switch(output, dev_priv->ddc_bus);
|
||||
return i2cbus->I2CStart(i2cbus, timeout);
|
||||
}
|
||||
|
||||
|
|
@ -1052,6 +1097,8 @@ i830_sdvo_dump_device(xf86OutputPtr output)
|
|||
i830_sdvo_dump_cmd(output, SDVO_CMD_GET_CLOCK_RATE_MULT);
|
||||
i830_sdvo_dump_cmd(output, SDVO_CMD_GET_SUPPORTED_TV_FORMATS);
|
||||
i830_sdvo_dump_cmd(output, SDVO_CMD_GET_TV_FORMAT);
|
||||
i830_sdvo_dump_cmd(output, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT);
|
||||
i830_sdvo_dump_cmd(output, SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -1098,7 +1145,7 @@ i830_sdvo_detect(xf86OutputPtr output)
|
|||
}
|
||||
|
||||
static DisplayModePtr
|
||||
i830_sdvo_get_modes(xf86OutputPtr output)
|
||||
i830_sdvo_get_ddc_modes(xf86OutputPtr output)
|
||||
{
|
||||
ScrnInfoPtr pScrn = output->scrn;
|
||||
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
|
||||
|
|
@ -1130,6 +1177,128 @@ i830_sdvo_get_modes(xf86OutputPtr output)
|
|||
return modes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a DisplayModeRec for the given widht/height/refresh, which will
|
||||
* be programmed into the display pipe. The TV encoder's scaler will filter
|
||||
* this to the format actually required by the display.
|
||||
*/
|
||||
static void
|
||||
i830_sdvo_get_tv_mode(DisplayModePtr *head, int width, int height,
|
||||
float refresh)
|
||||
{
|
||||
DisplayModePtr mode;
|
||||
|
||||
mode = xcalloc(1, sizeof(*mode));
|
||||
if (mode == NULL)
|
||||
return;
|
||||
|
||||
mode->name = XNFprintf("%dx%d@%.2f", width, height, refresh);
|
||||
mode->HDisplay = width;
|
||||
mode->HSyncStart = width + 1;
|
||||
mode->HSyncEnd = width + 64;
|
||||
mode->HTotal = width + 96;
|
||||
|
||||
mode->VDisplay = height;
|
||||
mode->VSyncStart = height + 1;
|
||||
mode->VSyncEnd = height + 32;
|
||||
mode->VTotal = height + 33;
|
||||
|
||||
mode->Clock = (int) (refresh * mode->VTotal * mode->HTotal / 1000.0);
|
||||
mode->type = M_T_DRIVER;
|
||||
mode->next = NULL;
|
||||
mode->prev = NULL;
|
||||
|
||||
mode->next = NULL;
|
||||
mode->prev = *head;
|
||||
if (*head != NULL)
|
||||
(*head)->next = mode;
|
||||
else
|
||||
*head = mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function checks the current TV format, and chooses a default if
|
||||
* it hasn't been set.
|
||||
*/
|
||||
static void
|
||||
i830_sdvo_check_tv_format(xf86OutputPtr output)
|
||||
{
|
||||
ScrnInfoPtr pScrn = output->scrn;
|
||||
I830OutputPrivatePtr intel_output = output->driver_private;
|
||||
struct i830_sdvo_priv *dev_priv = intel_output->dev_priv;
|
||||
struct i830_sdvo_tv_format format, unset;
|
||||
uint8_t status;
|
||||
|
||||
i830_sdvo_write_cmd(output, SDVO_CMD_GET_TV_FORMAT, NULL, 0);
|
||||
status = i830_sdvo_read_response(output, &format, sizeof(format));
|
||||
if (status != SDVO_CMD_STATUS_SUCCESS)
|
||||
return;
|
||||
|
||||
memset(&unset, 0, sizeof(unset));
|
||||
if (memcmp(&format, &unset, sizeof(format))) {
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
||||
"%s: Choosing default TV format of NTSC-M\n",
|
||||
SDVO_NAME(dev_priv));
|
||||
|
||||
format.ntsc_m = TRUE;
|
||||
i830_sdvo_write_cmd(output, SDVO_CMD_SET_TV_FORMAT, NULL, 0);
|
||||
status = i830_sdvo_read_response(output, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static DisplayModePtr
|
||||
i830_sdvo_get_tv_modes(xf86OutputPtr output)
|
||||
{
|
||||
I830OutputPrivatePtr intel_output = output->driver_private;
|
||||
struct i830_sdvo_priv *dev_priv = intel_output->dev_priv;
|
||||
DisplayModePtr modes = NULL;
|
||||
struct i830_sdvo_sdtv_resolution_reply *res = &dev_priv->sdtv_resolutions;
|
||||
uint8_t status;
|
||||
float refresh = 60; /* XXX */
|
||||
|
||||
i830_sdvo_check_tv_format(output);
|
||||
|
||||
/* Read the list of supported input resolutions for the selected TV format.
|
||||
*/
|
||||
i830_sdvo_write_cmd(output, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT, NULL, 0);
|
||||
status = i830_sdvo_read_response(output, res, sizeof(*res));
|
||||
if (status != SDVO_CMD_STATUS_SUCCESS)
|
||||
return NULL;
|
||||
|
||||
if (res->res_320x200) i830_sdvo_get_tv_mode(&modes, 320, 200, refresh);
|
||||
if (res->res_320x240) i830_sdvo_get_tv_mode(&modes, 320, 240, refresh);
|
||||
if (res->res_400x300) i830_sdvo_get_tv_mode(&modes, 400, 300, refresh);
|
||||
if (res->res_640x350) i830_sdvo_get_tv_mode(&modes, 640, 350, refresh);
|
||||
if (res->res_640x400) i830_sdvo_get_tv_mode(&modes, 640, 400, refresh);
|
||||
if (res->res_640x480) i830_sdvo_get_tv_mode(&modes, 640, 480, refresh);
|
||||
if (res->res_704x480) i830_sdvo_get_tv_mode(&modes, 704, 480, refresh);
|
||||
if (res->res_704x576) i830_sdvo_get_tv_mode(&modes, 704, 576, refresh);
|
||||
if (res->res_720x350) i830_sdvo_get_tv_mode(&modes, 720, 350, refresh);
|
||||
if (res->res_720x400) i830_sdvo_get_tv_mode(&modes, 720, 400, refresh);
|
||||
if (res->res_720x480) i830_sdvo_get_tv_mode(&modes, 720, 480, refresh);
|
||||
if (res->res_720x540) i830_sdvo_get_tv_mode(&modes, 720, 540, refresh);
|
||||
if (res->res_720x576) i830_sdvo_get_tv_mode(&modes, 720, 576, refresh);
|
||||
if (res->res_800x600) i830_sdvo_get_tv_mode(&modes, 800, 600, refresh);
|
||||
if (res->res_832x624) i830_sdvo_get_tv_mode(&modes, 832, 624, refresh);
|
||||
if (res->res_920x766) i830_sdvo_get_tv_mode(&modes, 920, 766, refresh);
|
||||
if (res->res_1024x768) i830_sdvo_get_tv_mode(&modes, 1024, 768, refresh);
|
||||
if (res->res_1280x1024) i830_sdvo_get_tv_mode(&modes, 1280, 1024, refresh);
|
||||
|
||||
return modes;
|
||||
}
|
||||
|
||||
static DisplayModePtr
|
||||
i830_sdvo_get_modes(xf86OutputPtr output)
|
||||
{
|
||||
I830OutputPrivatePtr intel_output = output->driver_private;
|
||||
struct i830_sdvo_priv *dev_priv = intel_output->dev_priv;
|
||||
|
||||
if (dev_priv->is_tv)
|
||||
return i830_sdvo_get_tv_modes(output);
|
||||
else
|
||||
return i830_sdvo_get_ddc_modes(output);
|
||||
}
|
||||
|
||||
static void
|
||||
i830_sdvo_destroy (xf86OutputPtr output)
|
||||
{
|
||||
|
|
@ -1177,6 +1346,60 @@ static const xf86OutputFuncsRec i830_sdvo_output_funcs = {
|
|||
#endif
|
||||
};
|
||||
|
||||
static unsigned int count_bits(uint32_t mask)
|
||||
{
|
||||
unsigned int n;
|
||||
|
||||
for (n = 0; mask; n++)
|
||||
mask &= mask - 1;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Choose the appropriate DDC bus for control bus switch command for this
|
||||
* SDVO output based on the controlled output.
|
||||
*
|
||||
* DDC bus number assignment is in a priority order of RGB outputs, then TMDS
|
||||
* outputs, then LVDS outputs.
|
||||
*/
|
||||
static void
|
||||
i830_sdvo_select_ddc_bus(struct i830_sdvo_priv *dev_priv)
|
||||
{
|
||||
uint16_t mask = 0;
|
||||
unsigned int num_bits;
|
||||
|
||||
/* Make a mask of outputs less than or equal to our own priority in the
|
||||
* list.
|
||||
*/
|
||||
switch (dev_priv->controlled_output) {
|
||||
case SDVO_OUTPUT_LVDS1:
|
||||
mask |= SDVO_OUTPUT_LVDS1;
|
||||
case SDVO_OUTPUT_LVDS0:
|
||||
mask |= SDVO_OUTPUT_LVDS0;
|
||||
case SDVO_OUTPUT_TMDS1:
|
||||
mask |= SDVO_OUTPUT_TMDS1;
|
||||
case SDVO_OUTPUT_TMDS0:
|
||||
mask |= SDVO_OUTPUT_TMDS0;
|
||||
case SDVO_OUTPUT_RGB1:
|
||||
mask |= SDVO_OUTPUT_RGB1;
|
||||
case SDVO_OUTPUT_RGB0:
|
||||
mask |= SDVO_OUTPUT_RGB0;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Count bits to find what number we are in the priority list. */
|
||||
mask &= dev_priv->caps.output_flags;
|
||||
num_bits = count_bits(mask);
|
||||
if (num_bits > 3) {
|
||||
/* if more than 3 outputs, default to DDC bus 3 for now */
|
||||
num_bits = 3;
|
||||
}
|
||||
|
||||
/* Corresponds to SDVO_CONTROL_BUS_DDCx */
|
||||
dev_priv->ddc_bus = 1 << num_bits;
|
||||
}
|
||||
|
||||
void
|
||||
i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
|
||||
{
|
||||
|
|
@ -1294,28 +1517,34 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
|
|||
|
||||
i830_sdvo_get_capabilities(output, &dev_priv->caps);
|
||||
|
||||
memset(&dev_priv->active_outputs, 0, sizeof(dev_priv->active_outputs));
|
||||
if (dev_priv->caps.output_flags & SDVO_OUTPUT_TMDS0)
|
||||
{
|
||||
dev_priv->active_outputs = SDVO_OUTPUT_TMDS0;
|
||||
dev_priv->controlled_output = SDVO_OUTPUT_TMDS0;
|
||||
output->subpixel_order = SubPixelHorizontalRGB;
|
||||
name_prefix="TMDS";
|
||||
}
|
||||
else if (dev_priv->caps.output_flags & SDVO_OUTPUT_TMDS1)
|
||||
{
|
||||
dev_priv->active_outputs = SDVO_OUTPUT_TMDS1;
|
||||
dev_priv->controlled_output = SDVO_OUTPUT_TMDS1;
|
||||
output->subpixel_order = SubPixelHorizontalRGB;
|
||||
name_prefix="TMDS";
|
||||
}
|
||||
else if (dev_priv->caps.output_flags & SDVO_OUTPUT_SVID0)
|
||||
{
|
||||
dev_priv->controlled_output = SDVO_OUTPUT_SVID0;
|
||||
output->subpixel_order = SubPixelHorizontalRGB; /* XXX */
|
||||
name_prefix="TV";
|
||||
dev_priv->is_tv = TRUE;
|
||||
}
|
||||
else if (dev_priv->caps.output_flags & SDVO_OUTPUT_RGB0)
|
||||
{
|
||||
dev_priv->active_outputs = SDVO_OUTPUT_RGB0;
|
||||
dev_priv->controlled_output = SDVO_OUTPUT_RGB0;
|
||||
output->subpixel_order = SubPixelHorizontalRGB;
|
||||
name_prefix="VGA";
|
||||
}
|
||||
else if (dev_priv->caps.output_flags & SDVO_OUTPUT_RGB1)
|
||||
{
|
||||
dev_priv->active_outputs = SDVO_OUTPUT_RGB1;
|
||||
dev_priv->controlled_output = SDVO_OUTPUT_RGB1;
|
||||
output->subpixel_order = SubPixelHorizontalRGB;
|
||||
name_prefix="VGA";
|
||||
}
|
||||
|
|
@ -1323,13 +1552,15 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
|
|||
{
|
||||
unsigned char bytes[2];
|
||||
|
||||
dev_priv->controlled_output = 0;
|
||||
memcpy (bytes, &dev_priv->caps.output_flags, 2);
|
||||
xf86DrvMsg(intel_output->pI2CBus->scrnIndex, X_ERROR,
|
||||
"%s: No active TMDS outputs (0x%02x%02x)\n",
|
||||
xf86DrvMsg(intel_output->pI2CBus->scrnIndex, X_WARNING,
|
||||
"%s: Unknown SDVO output type (0x%02x%02x)\n",
|
||||
SDVO_NAME(dev_priv),
|
||||
bytes[0], bytes[1]);
|
||||
name_prefix="Unknown";
|
||||
}
|
||||
|
||||
strcpy (name, name_prefix);
|
||||
strcat (name, name_suffix);
|
||||
if (!xf86OutputRename (output, name))
|
||||
|
|
@ -1337,8 +1568,9 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
|
|||
xf86OutputDestroy (output);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
i830_sdvo_select_ddc_bus(dev_priv);
|
||||
|
||||
/* Set the input timing to the screen. Assume always input 0. */
|
||||
i830_sdvo_set_target_input(output, TRUE, FALSE);
|
||||
|
||||
|
|
@ -1346,17 +1578,40 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
|
|||
&dev_priv->pixel_clock_max);
|
||||
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
||||
"%s device VID/DID: %02X:%02X.%02X, "
|
||||
"clock range %.1fMHz - %.1fMHz, "
|
||||
"input 1: %c, input 2: %c, "
|
||||
"output 1: %c, output 2: %c\n",
|
||||
"%s: device VID/DID: %02X:%02X.%02X, "
|
||||
"clock range %.1fMHz - %.1fMHz\n",
|
||||
SDVO_NAME(dev_priv),
|
||||
dev_priv->caps.vendor_id, dev_priv->caps.device_id,
|
||||
dev_priv->caps.device_rev_id,
|
||||
dev_priv->pixel_clock_min / 1000.0,
|
||||
dev_priv->pixel_clock_max / 1000.0,
|
||||
(dev_priv->caps.sdvo_inputs_mask & 0x1) ? 'Y' : 'N',
|
||||
(dev_priv->caps.sdvo_inputs_mask & 0x2) ? 'Y' : 'N',
|
||||
dev_priv->caps.output_flags & (SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_TMDS0) ? 'Y' : 'N',
|
||||
dev_priv->caps.output_flags & (SDVO_OUTPUT_RGB1 | SDVO_OUTPUT_TMDS1) ? 'Y' : 'N');
|
||||
dev_priv->pixel_clock_max / 1000.0);
|
||||
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
||||
"%s: %d input channel%s\n",
|
||||
SDVO_NAME(dev_priv), dev_priv->caps.sdvo_input_count,
|
||||
dev_priv->caps.sdvo_input_count >= 2 ? "s" : "");
|
||||
|
||||
#define REPORT_OUTPUT_FLAG(flag, name) do { \
|
||||
if (dev_priv->caps.output_flags & flag) { \
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s: %s output reported\n", \
|
||||
SDVO_NAME(dev_priv), name); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
REPORT_OUTPUT_FLAG(SDVO_OUTPUT_TMDS0, "TMDS0");
|
||||
REPORT_OUTPUT_FLAG(SDVO_OUTPUT_RGB0, "RGB0");
|
||||
REPORT_OUTPUT_FLAG(SDVO_OUTPUT_CVBS0, "CVBS0");
|
||||
REPORT_OUTPUT_FLAG(SDVO_OUTPUT_SVID0, "SVID0");
|
||||
REPORT_OUTPUT_FLAG(SDVO_OUTPUT_YPRPB0, "YPRPB0");
|
||||
REPORT_OUTPUT_FLAG(SDVO_OUTPUT_SCART0, "SCART0");
|
||||
REPORT_OUTPUT_FLAG(SDVO_OUTPUT_LVDS0, "LVDS0");
|
||||
|
||||
REPORT_OUTPUT_FLAG(SDVO_OUTPUT_TMDS1, "TMDS1");
|
||||
REPORT_OUTPUT_FLAG(SDVO_OUTPUT_RGB1, "RGB1");
|
||||
REPORT_OUTPUT_FLAG(SDVO_OUTPUT_CVBS1, "CVBS1");
|
||||
REPORT_OUTPUT_FLAG(SDVO_OUTPUT_SVID1, "SVID1");
|
||||
REPORT_OUTPUT_FLAG(SDVO_OUTPUT_YPRPB1, "YPRPB1");
|
||||
REPORT_OUTPUT_FLAG(SDVO_OUTPUT_SCART1, "SCART1");
|
||||
REPORT_OUTPUT_FLAG(SDVO_OUTPUT_LVDS1, "LVDS1");
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ struct i830_sdvo_caps {
|
|||
uint8_t device_rev_id;
|
||||
uint8_t sdvo_version_major;
|
||||
uint8_t sdvo_version_minor;
|
||||
unsigned int sdvo_inputs_mask:2;
|
||||
unsigned int sdvo_input_count:2;
|
||||
unsigned int smooth_scaling:1;
|
||||
unsigned int sharp_scaling:1;
|
||||
unsigned int up_scaling:1;
|
||||
|
|
@ -174,6 +174,9 @@ struct i830_sdvo_get_trained_inputs_response {
|
|||
* Returns two struct i830_sdvo_output_flags structures.
|
||||
*/
|
||||
#define SDVO_CMD_GET_IN_OUT_MAP 0x06
|
||||
struct i830_sdvo_in_out_map {
|
||||
uint16_t in0, in1;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the current mapping of SDVO inputs to outputs on the device.
|
||||
|
|
@ -306,11 +309,107 @@ struct i830_sdvo_set_target_input_args {
|
|||
# define SDVO_CLOCK_RATE_MULT_4X (1 << 3)
|
||||
|
||||
#define SDVO_CMD_GET_SUPPORTED_TV_FORMATS 0x27
|
||||
/** 5 bytes of bit flags for TV formats shared by all TV format functions */
|
||||
struct i830_sdvo_tv_format {
|
||||
unsigned int ntsc_m:1;
|
||||
unsigned int ntsc_j:1;
|
||||
unsigned int ntsc_443:1;
|
||||
unsigned int pal_b:1;
|
||||
unsigned int pal_d:1;
|
||||
unsigned int pal_g:1;
|
||||
unsigned int pal_h:1;
|
||||
unsigned int pal_i:1;
|
||||
|
||||
unsigned int pal_m:1;
|
||||
unsigned int pal_n:1;
|
||||
unsigned int pal_nc:1;
|
||||
unsigned int pal_60:1;
|
||||
unsigned int secam_b:1;
|
||||
unsigned int secam_d:1;
|
||||
unsigned int secam_g:1;
|
||||
unsigned int secam_k:1;
|
||||
|
||||
unsigned int secam_k1:1;
|
||||
unsigned int secam_l:1;
|
||||
unsigned int secam_60:1;
|
||||
unsigned int hdtv_std_smpte_240m_1080i_59:1;
|
||||
unsigned int hdtv_std_smpte_240m_1080i_60:1;
|
||||
unsigned int hdtv_std_smpte_260m_1080i_59:1;
|
||||
unsigned int hdtv_std_smpte_260m_1080i_60:1;
|
||||
unsigned int hdtv_std_smpte_270m_1080i_50:1;
|
||||
|
||||
unsigned int hdtv_std_smpte_274m_1080i_50:1;
|
||||
unsigned int hdtv_std_smpte_274m_1080i_59:1;
|
||||
unsigned int hdtv_std_smpte_274m_1080i_60:1;
|
||||
unsigned int hdtv_std_smpte_274m_1080p_23:1;
|
||||
unsigned int hdtv_std_smpte_274m_1080p_24:1;
|
||||
unsigned int hdtv_std_smpte_274m_1080p_25:1;
|
||||
unsigned int hdtv_std_smpte_274m_1080p_29:1;
|
||||
unsigned int hdtv_std_smpte_274m_1080p_50:1;
|
||||
|
||||
unsigned int hdtv_std_smpte_274m_1080p_59:1;
|
||||
unsigned int hdtv_std_smpte_274m_1080p_60:1;
|
||||
unsigned int hdtv_std_smpte_295m_1080i_50:1;
|
||||
unsigned int hdtv_std_smpte_295m_1080p_50:1;
|
||||
unsigned int hdtv_std_smpte_296m_720p_59:1;
|
||||
unsigned int hdtv_std_smpte_296m_720p_60:1;
|
||||
unsigned int hdtv_std_smpte_296m_720p_50:1;
|
||||
unsigned int hdtv_std_smpte_293m_480p_59:1;
|
||||
|
||||
unsigned int hdtv_std_smpte_270m_480i_59:1;
|
||||
unsigned int hdtv_std_iturbt601_576i_50:1;
|
||||
unsigned int hdtv_std_iturbt601_576p_50:1;
|
||||
unsigned int hdtv_std_eia_7702a_480i_60:1;
|
||||
unsigned int hdtv_std_eia_7702a_480p_60:1;
|
||||
unsigned int pad:3;
|
||||
} __attribute__((packed));
|
||||
|
||||
#define SDVO_CMD_GET_TV_FORMAT 0x28
|
||||
|
||||
/** This command should be run before SetOutputTimingsPart[12] */
|
||||
#define SDVO_CMD_SET_TV_FORMAT 0x29
|
||||
|
||||
/** Returns the resolutiosn that can be used with the given TV format */
|
||||
#define SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT 0x83
|
||||
struct i830_sdvo_sdtv_resolution_request {
|
||||
unsigned int ntsc_m:1;
|
||||
unsigned int ntsc_j:1;
|
||||
unsigned int ntsc_443:1;
|
||||
unsigned int pal_b:1;
|
||||
unsigned int pal_d:1;
|
||||
unsigned int pal_g:1;
|
||||
unsigned int pal_h:1;
|
||||
unsigned int pal_i:1;
|
||||
|
||||
unsigned int pal_m:1;
|
||||
unsigned int pal_n:1;
|
||||
unsigned int pal_nc:1;
|
||||
unsigned int pal_60:1;
|
||||
} __attribute__((packed));
|
||||
struct i830_sdvo_sdtv_resolution_reply {
|
||||
unsigned int res_320x200:1;
|
||||
unsigned int res_320x240:1;
|
||||
unsigned int res_400x300:1;
|
||||
unsigned int res_640x350:1;
|
||||
unsigned int res_640x400:1;
|
||||
unsigned int res_640x480:1;
|
||||
unsigned int res_704x480:1;
|
||||
unsigned int res_704x576:1;
|
||||
|
||||
unsigned int res_720x350:1;
|
||||
unsigned int res_720x400:1;
|
||||
unsigned int res_720x480:1;
|
||||
unsigned int res_720x540:1;
|
||||
unsigned int res_720x576:1;
|
||||
unsigned int res_800x600:1;
|
||||
unsigned int res_832x624:1;
|
||||
|
||||
unsigned int res_920x766:1;
|
||||
unsigned int res_1024x768:1;
|
||||
unsigned int res_1280x1024:1;
|
||||
unsigned int pad:5;
|
||||
} __attribute__((packed));
|
||||
|
||||
#define SDVO_CMD_GET_SUPPORTED_POWER_STATES 0x2a
|
||||
#define SDVO_CMD_GET_ENCODER_POWER_STATE 0x2b
|
||||
#define SDVO_CMD_SET_ENCODER_POWER_STATE 0x2c
|
||||
|
|
@ -319,11 +418,96 @@ struct i830_sdvo_set_target_input_args {
|
|||
# define SDVO_ENCODER_STATE_SUSPEND (1 << 2)
|
||||
# define SDVO_ENCODER_STATE_OFF (1 << 3)
|
||||
|
||||
#define SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS 0x84
|
||||
struct i830_sdvo_enhancements_reply {
|
||||
unsigned int flicker_filter:1;
|
||||
unsigned int flicker_filter_adaptive:1;
|
||||
unsigned int flicker_filter_2d:1;
|
||||
unsigned int saturation:1;
|
||||
unsigned int hue:1;
|
||||
unsigned int brightness:1;
|
||||
unsigned int contrast:1;
|
||||
unsigned int overscan_h:1;
|
||||
|
||||
unsigned int overscan_v:1;
|
||||
unsigned int position_h:1;
|
||||
unsigned int position_v:1;
|
||||
unsigned int sharpness:1;
|
||||
unsigned int dot_crawl:1;
|
||||
unsigned int dither:1;
|
||||
unsigned int max_tv_chroma_filter:1;
|
||||
unsigned int max_tv_luma_filter:1;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Picture enhancement limits below are dependent on the current TV format,
|
||||
* and thus need to be queried and set after it.
|
||||
*/
|
||||
#define SDVO_CMD_GET_MAX_FLICKER_FITER 0x4d
|
||||
#define SDVO_CMD_GET_MAX_ADAPTIVE_FLICKER_FITER 0x7b
|
||||
#define SDVO_CMD_GET_MAX_2D_FLICKER_FITER 0x52
|
||||
#define SDVO_CMD_GET_MAX_SATURATION 0x55
|
||||
#define SDVO_CMD_GET_MAX_HUE 0x58
|
||||
#define SDVO_CMD_GET_MAX_BRIGHTNESS 0x5c
|
||||
#define SDVO_CMD_GET_MAX_CONTRAST 0x5e
|
||||
#define SDVO_CMD_GET_MAX_OVERSCAN_H 0x61
|
||||
#define SDVO_CMD_GET_MAX_OVERSCAN_V 0x64
|
||||
#define SDVO_CMD_GET_MAX_POSITION_H 0x67
|
||||
#define SDVO_CMD_GET_MAX_POSITION_V 0x6a
|
||||
#define SDVO_CMD_GET_MAX_SHARPNESS_V 0x6d
|
||||
#define SDVO_CMD_GET_MAX_TV_CHROMA 0x74
|
||||
#define SDVO_CMD_GET_MAX_TV_LUMA 0x77
|
||||
struct i830_sdvo_enhancement_limits_reply {
|
||||
uint16_t max_value;
|
||||
uint16_t default_value;
|
||||
} __attribute__((packed));
|
||||
|
||||
#define SDVO_CMD_GET_FLICKER_FITER 0x4d
|
||||
#define SDVO_CMD_SET_FLICKER_FITER 0x4e
|
||||
#define SDVO_CMD_GET_ADAPTIVE_FLICKER_FITER 0x50
|
||||
#define SDVO_CMD_SET_ADAPTIVE_FLICKER_FITER 0x51
|
||||
#define SDVO_CMD_GET_2D_FLICKER_FITER 0x53
|
||||
#define SDVO_CMD_SET_2D_FLICKER_FITER 0x54
|
||||
#define SDVO_CMD_GET_SATURATION 0x56
|
||||
#define SDVO_CMD_SET_SATURATION 0x57
|
||||
#define SDVO_CMD_GET_HUE 0x59
|
||||
#define SDVO_CMD_SET_HUE 0x5a
|
||||
#define SDVO_CMD_GET_BRIGHTNESS 0x5c
|
||||
#define SDVO_CMD_SET_BRIGHTNESS 0x5d
|
||||
#define SDVO_CMD_GET_CONTRAST 0x5f
|
||||
#define SDVO_CMD_SET_CONTRAST 0x60
|
||||
#define SDVO_CMD_GET_OVERSCAN_H 0x62
|
||||
#define SDVO_CMD_SET_OVERSCAN_H 0x63
|
||||
#define SDVO_CMD_GET_OVERSCAN_V 0x65
|
||||
#define SDVO_CMD_SET_OVERSCAN_V 0x66
|
||||
#define SDVO_CMD_GET_POSITION_H 0x68
|
||||
#define SDVO_CMD_SET_POSITION_H 0x69
|
||||
#define SDVO_CMD_GET_POSITION_V 0x6b
|
||||
#define SDVO_CMD_SET_POSITION_V 0x6c
|
||||
#define SDVO_CMD_GET_SHARPNESS 0x6e
|
||||
#define SDVO_CMD_SET_SHARPNESS 0x6f
|
||||
#define SDVO_CMD_GET_TV_CHROMA 0x75
|
||||
#define SDVO_CMD_SET_TV_CHROMA 0x76
|
||||
#define SDVO_CMD_GET_TV_LUMA 0x78
|
||||
#define SDVO_CMD_SET_TV_LUMA 0x79
|
||||
struct i830_sdvo_enhancements_arg {
|
||||
uint16_t value;
|
||||
}__attribute__((packed));
|
||||
|
||||
#define SDVO_CMD_GET_DOT_CRAWL 0x70
|
||||
#define SDVO_CMD_SET_DOT_CRAWL 0x71
|
||||
# define SDVO_DOT_CRAWL_ON (1 << 0)
|
||||
# define SDVO_DOT_CRAWL_DEFAULT_ON (1 << 1)
|
||||
|
||||
#define SDVO_CMD_GET_DITHER 0x72
|
||||
#define SDVO_CMD_SET_DITHER 0x73
|
||||
# define SDVO_DITHER_ON (1 << 0)
|
||||
# define SDVO_DITHER_DEFAULT_ON (1 << 1)
|
||||
|
||||
#define SDVO_CMD_SET_TV_RESOLUTION_SUPPORT 0x93
|
||||
|
||||
#define SDVO_CMD_SET_CONTROL_BUS_SWITCH 0x7a
|
||||
# define SDVO_CONTROL_BUS_PROM 0x0
|
||||
# define SDVO_CONTROL_BUS_DDC1 0x1
|
||||
# define SDVO_CONTROL_BUS_DDC2 0x2
|
||||
# define SDVO_CONTROL_BUS_DDC3 0x3
|
||||
# define SDVO_CONTROL_BUS_PROM (1 << 0)
|
||||
# define SDVO_CONTROL_BUS_DDC1 (1 << 1)
|
||||
# define SDVO_CONTROL_BUS_DDC2 (1 << 2)
|
||||
# define SDVO_CONTROL_BUS_DDC3 (1 << 3)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue