Fix many inconsistencies in the SDVO code compared to the spec.
Also, fix some struct padding so that the right bits are sent out.
This commit is contained in:
parent
e7d546cac0
commit
49bbdf16c0
169
src/i830_sdvo.c
169
src/i830_sdvo.c
|
|
@ -54,21 +54,27 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
struct i830_sdvo_priv {
|
||||
/** SDVO device on SDVO I2C bus. */
|
||||
I2CDevRec d;
|
||||
|
||||
/** Register for the SDVO device: SDVOB or SDVOC */
|
||||
int output_device;
|
||||
|
||||
/** Active outputs controlled by this SDVO output */
|
||||
struct i830_sdvo_output_flags active_outputs;
|
||||
|
||||
/**
|
||||
* Capabilities of the SDVO device returned by i830_sdvo_get_capabilities()
|
||||
*/
|
||||
i830_sdvo_caps caps;
|
||||
struct i830_sdvo_caps caps;
|
||||
|
||||
/** Pixel clock limitations reported by the SDVO device */
|
||||
CARD16 pixel_clock_min, pixel_clock_max;
|
||||
|
||||
/** State for save/restore */
|
||||
/** @{ */
|
||||
int save_sdvo_mult;
|
||||
Bool save_sdvo_active_1, save_sdvo_active_2;
|
||||
struct i830_sdvo_output_flags save_active_outputs;
|
||||
struct i830_sdvo_dtd save_input_dtd_1, save_input_dtd_2;
|
||||
struct i830_sdvo_dtd save_output_dtd_1, save_output_dtd_2;
|
||||
struct i830_sdvo_dtd save_output_dtd;
|
||||
CARD32 save_SDVOX;
|
||||
/** @} */
|
||||
};
|
||||
|
|
@ -122,7 +128,7 @@ const struct _sdvo_cmd_name {
|
|||
SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HOT_PLUG_SUPPORT),
|
||||
SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ACTIVE_HOT_PLUG),
|
||||
SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ACTIVE_HOT_PLUG),
|
||||
SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INTR_EVENT_SOURCE),
|
||||
SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INTERRUPT_EVENT_SOURCE),
|
||||
SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TARGET_INPUT),
|
||||
SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TARGET_OUTPUT),
|
||||
SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_TIMINGS_PART1),
|
||||
|
|
@ -187,7 +193,7 @@ static const char *cmd_status_names[] = {
|
|||
"Not supported",
|
||||
"Invalid arg",
|
||||
"Pending",
|
||||
"Target not supported",
|
||||
"Target not specified",
|
||||
"Scaling not supported"
|
||||
};
|
||||
|
||||
|
|
@ -249,14 +255,19 @@ i830_sdvo_set_control_bus_switch(I830OutputPtr output, CARD8 target)
|
|||
}
|
||||
|
||||
static Bool
|
||||
i830_sdvo_set_target_input(I830OutputPtr output, Bool target_1, Bool target_2)
|
||||
i830_sdvo_set_target_input(I830OutputPtr output, Bool target_0, Bool target_1)
|
||||
{
|
||||
CARD8 targets[2];
|
||||
struct i830_sdvo_set_target_input_args targets = {0};
|
||||
CARD8 status;
|
||||
|
||||
targets[0] = target_1;
|
||||
targets[1] = target_2;
|
||||
i830_sdvo_write_cmd(output, SDVO_CMD_SET_TARGET_INPUT, &targets, 2);
|
||||
if (target_0 && target_1)
|
||||
return SDVO_CMD_STATUS_NOTSUPP;
|
||||
|
||||
if (target_1)
|
||||
targets.target_1 = 1;
|
||||
|
||||
i830_sdvo_write_cmd(output, SDVO_CMD_SET_TARGET_INPUT, &targets,
|
||||
sizeof(targets));
|
||||
|
||||
status = i830_sdvo_read_response(output, NULL, 0);
|
||||
|
||||
|
|
@ -272,47 +283,41 @@ i830_sdvo_set_target_input(I830OutputPtr output, Bool target_1, Bool target_2)
|
|||
static Bool
|
||||
i830_sdvo_get_trained_inputs(I830OutputPtr output, Bool *input_1, Bool *input_2)
|
||||
{
|
||||
CARD8 response[2];
|
||||
struct i830_sdvo_get_trained_inputs_response response;
|
||||
CARD8 status;
|
||||
|
||||
i830_sdvo_write_cmd(output, SDVO_CMD_GET_TRAINED_INPUTS, NULL, 0);
|
||||
|
||||
status = i830_sdvo_read_response(output, response, 2);
|
||||
status = i830_sdvo_read_response(output, &response, sizeof(response));
|
||||
if (status != SDVO_CMD_STATUS_SUCCESS)
|
||||
return FALSE;
|
||||
|
||||
*input_1 = response[0];
|
||||
*input_2 = response[1];
|
||||
*input_1 = response.input0_trained;
|
||||
*input_2 = response.input1_trained;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
i830_sdvo_get_active_outputs(I830OutputPtr output, Bool *on_1, Bool *on_2)
|
||||
i830_sdvo_get_active_outputs(I830OutputPtr output,
|
||||
struct i830_sdvo_output_flags *outputs)
|
||||
{
|
||||
CARD8 response[2];
|
||||
CARD8 status;
|
||||
|
||||
i830_sdvo_write_cmd(output, SDVO_CMD_GET_ACTIVE_OUTPUTS, NULL, 0);
|
||||
|
||||
status = i830_sdvo_read_response(output, &response, 2);
|
||||
|
||||
*on_1 = response[0];
|
||||
*on_2 = response[1];
|
||||
status = i830_sdvo_read_response(output, outputs, sizeof(*outputs));
|
||||
|
||||
return (status == SDVO_CMD_STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
static Bool
|
||||
i830_sdvo_set_active_outputs(I830OutputPtr output, Bool on_1, Bool on_2)
|
||||
i830_sdvo_set_active_outputs(I830OutputPtr output,
|
||||
struct i830_sdvo_output_flags *outputs)
|
||||
{
|
||||
CARD8 outputs[2];
|
||||
CARD8 status;
|
||||
|
||||
outputs[0] = on_1;
|
||||
outputs[1] = on_2;
|
||||
i830_sdvo_write_cmd(output, SDVO_CMD_SET_ACTIVE_OUTPUTS, &outputs, 2);
|
||||
|
||||
i830_sdvo_write_cmd(output, SDVO_CMD_SET_ACTIVE_OUTPUTS, outputs,
|
||||
sizeof(*outputs));
|
||||
status = i830_sdvo_read_response(output, NULL, 0);
|
||||
|
||||
return (status == SDVO_CMD_STATUS_SUCCESS);
|
||||
|
|
@ -339,14 +344,13 @@ i830_sdvo_get_input_pixel_clock_range(I830OutputPtr output, CARD16 *clock_min,
|
|||
}
|
||||
|
||||
static Bool
|
||||
i830_sdvo_set_target_output(I830OutputPtr output, Bool target_1, Bool target_2)
|
||||
i830_sdvo_set_target_output(I830OutputPtr output,
|
||||
struct i830_sdvo_output_flags *outputs)
|
||||
{
|
||||
CARD8 targets[2];
|
||||
CARD8 status;
|
||||
|
||||
targets[0] = target_1;
|
||||
targets[1] = target_2;
|
||||
i830_sdvo_write_cmd(output, SDVO_CMD_SET_TARGET_OUTPUT, &targets, 2);
|
||||
i830_sdvo_write_cmd(output, SDVO_CMD_SET_TARGET_OUTPUT, outputs,
|
||||
sizeof(*outputs));
|
||||
|
||||
status = i830_sdvo_read_response(output, NULL, 0);
|
||||
|
||||
|
|
@ -508,11 +512,15 @@ i830_sdvo_pre_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output,
|
|||
DisplayModePtr mode)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
struct i830_sdvo_priv *dev_priv = output->dev_priv;
|
||||
CARD16 width = mode->CrtcHDisplay;
|
||||
CARD16 height = mode->CrtcVDisplay;
|
||||
CARD16 h_blank_len, h_sync_len, v_blank_len, v_sync_len;
|
||||
CARD16 h_sync_offset, v_sync_offset;
|
||||
struct i830_sdvo_dtd output_dtd;
|
||||
struct i830_sdvo_output_flags no_outputs;
|
||||
|
||||
memset(&no_outputs, 0, sizeof(no_outputs));
|
||||
|
||||
/* do some mode translations */
|
||||
h_blank_len = mode->CrtcHBlankEnd - mode->CrtcHBlankStart;
|
||||
|
|
@ -549,13 +557,13 @@ i830_sdvo_pre_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output,
|
|||
output_dtd.part2.dtd_flags |= 0x4;
|
||||
|
||||
/* Turn off the screens before adjusting timings */
|
||||
i830_sdvo_set_active_outputs(output, FALSE, FALSE);
|
||||
i830_sdvo_set_active_outputs(output, &no_outputs);
|
||||
|
||||
/* Set the output timing to the screen */
|
||||
i830_sdvo_set_target_output(output, TRUE, FALSE);
|
||||
i830_sdvo_set_target_output(output, &dev_priv->active_outputs);
|
||||
i830_sdvo_set_output_timing(output, &output_dtd);
|
||||
|
||||
/* Set the input timing to the screen */
|
||||
/* Set the input timing to the screen. Assume always input 0. */
|
||||
i830_sdvo_set_target_input(output, TRUE, FALSE);
|
||||
|
||||
/* We would like to use i830_sdvo_create_preferred_input_timing() to
|
||||
|
|
@ -597,29 +605,15 @@ i830_sdvo_post_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output,
|
|||
DisplayModePtr mode)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
Bool out1, out2, input1, input2;
|
||||
struct i830_sdvo_priv *dev_priv = output->dev_priv;
|
||||
Bool input1, input2;
|
||||
CARD32 dpll, sdvob, sdvoc;
|
||||
int dpll_reg = (output->pipe == 0) ? DPLL_A : DPLL_B;
|
||||
int dpll_md_reg = (output->pipe == 0) ? DPLL_A_MD : DPLL_B_MD;
|
||||
int sdvo_pixel_multiply;
|
||||
int i;
|
||||
CARD8 status;
|
||||
|
||||
/* the BIOS writes out 6 commands post mode set */
|
||||
/* two 03s, 04 05, 10, 1d */
|
||||
/* these contain the height and mode clock / 10 by the looks of it */
|
||||
|
||||
status = i830_sdvo_get_trained_inputs(output, &input1, &input2);
|
||||
|
||||
/* Warn if the device reported failure to sync. */
|
||||
if (status == SDVO_CMD_STATUS_SUCCESS && !input1) {
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
||||
"First SDVO output reported failure to sync\n");
|
||||
}
|
||||
|
||||
i830_sdvo_get_active_outputs(output, &out1, &out2);
|
||||
i830_sdvo_set_active_outputs(output, TRUE, FALSE);
|
||||
i830_sdvo_set_target_input(output, FALSE, FALSE);
|
||||
|
||||
/* Set the SDVO control regs. */
|
||||
sdvob = INREG(SDVOB) & SDVOB_PRESERVE_MASK;
|
||||
sdvoc = INREG(SDVOC) & SDVOC_PRESERVE_MASK;
|
||||
|
|
@ -644,18 +638,37 @@ i830_sdvo_post_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output,
|
|||
|
||||
OUTREG(SDVOB, sdvob);
|
||||
OUTREG(SDVOC, sdvoc);
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
i830WaitForVblank(pScrn);
|
||||
|
||||
status = i830_sdvo_get_trained_inputs(output, &input1, &input2);
|
||||
|
||||
/* Warn if the device reported failure to sync. */
|
||||
if (status == SDVO_CMD_STATUS_SUCCESS && !input1) {
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
||||
"First SDVO output reported failure to sync\n");
|
||||
}
|
||||
|
||||
i830_sdvo_set_active_outputs(output, &dev_priv->active_outputs);
|
||||
i830_sdvo_set_target_input(output, TRUE, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
i830_sdvo_dpms(ScrnInfoPtr pScrn, I830OutputPtr output, int mode)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
struct i830_sdvo_priv *dev_priv = output->dev_priv;
|
||||
|
||||
if (mode != DPMSModeOn) {
|
||||
i830_sdvo_set_active_outputs(output, FALSE, FALSE);
|
||||
struct i830_sdvo_output_flags no_outputs;
|
||||
|
||||
memset(&no_outputs, 0, sizeof(no_outputs));
|
||||
|
||||
i830_sdvo_set_active_outputs(output, &no_outputs);
|
||||
OUTREG(SDVOB, INREG(SDVOB) & ~SDVO_ENABLE);
|
||||
} else {
|
||||
i830_sdvo_set_active_outputs(output, TRUE, FALSE);
|
||||
i830_sdvo_set_active_outputs(output, &dev_priv->active_outputs);
|
||||
OUTREG(SDVOB, INREG(SDVOB) | SDVO_ENABLE);
|
||||
}
|
||||
}
|
||||
|
|
@ -666,12 +679,13 @@ i830_sdvo_save(ScrnInfoPtr pScrn, I830OutputPtr output)
|
|||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
struct i830_sdvo_priv *dev_priv = output->dev_priv;
|
||||
|
||||
/* XXX: We should save the in/out mapping. */
|
||||
|
||||
dev_priv->save_sdvo_mult = i830_sdvo_get_clock_rate_mult(output);
|
||||
i830_sdvo_get_active_outputs(output, &dev_priv->save_sdvo_active_1,
|
||||
&dev_priv->save_sdvo_active_2);
|
||||
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, FALSE, FALSE);
|
||||
i830_sdvo_set_target_input(output, TRUE, FALSE);
|
||||
i830_sdvo_get_input_timing(output, &dev_priv->save_input_dtd_1);
|
||||
}
|
||||
|
||||
|
|
@ -680,15 +694,11 @@ i830_sdvo_save(ScrnInfoPtr pScrn, I830OutputPtr output)
|
|||
i830_sdvo_get_input_timing(output, &dev_priv->save_input_dtd_2);
|
||||
}
|
||||
|
||||
if (dev_priv->caps.output_0_supported) {
|
||||
i830_sdvo_set_target_output(output, TRUE, FALSE);
|
||||
i830_sdvo_get_output_timing(output, &dev_priv->save_output_dtd_1);
|
||||
}
|
||||
|
||||
if (dev_priv->caps.output_1_supported) {
|
||||
i830_sdvo_set_target_output(output, FALSE, TRUE);
|
||||
i830_sdvo_get_output_timing(output, &dev_priv->save_output_dtd_2);
|
||||
}
|
||||
/* XXX: We should really iterate over the enabled outputs and save each
|
||||
* one's state.
|
||||
*/
|
||||
i830_sdvo_set_target_output(output, &dev_priv->save_active_outputs);
|
||||
i830_sdvo_get_output_timing(output, &dev_priv->save_output_dtd);
|
||||
|
||||
dev_priv->save_SDVOX = INREG(dev_priv->output_device);
|
||||
}
|
||||
|
|
@ -700,7 +710,7 @@ i830_sdvo_restore(ScrnInfoPtr pScrn, I830OutputPtr output)
|
|||
struct i830_sdvo_priv *dev_priv = output->dev_priv;
|
||||
|
||||
if (dev_priv->caps.sdvo_inputs_mask & 0x1) {
|
||||
i830_sdvo_set_target_input(output, FALSE, FALSE);
|
||||
i830_sdvo_set_target_input(output, TRUE, FALSE);
|
||||
i830_sdvo_set_input_timing(output, &dev_priv->save_input_dtd_1);
|
||||
}
|
||||
|
||||
|
|
@ -709,22 +719,14 @@ i830_sdvo_restore(ScrnInfoPtr pScrn, I830OutputPtr output)
|
|||
i830_sdvo_set_input_timing(output, &dev_priv->save_input_dtd_2);
|
||||
}
|
||||
|
||||
if (dev_priv->caps.output_0_supported) {
|
||||
i830_sdvo_set_target_output(output, TRUE, FALSE);
|
||||
i830_sdvo_set_output_timing(output, &dev_priv->save_output_dtd_1);
|
||||
}
|
||||
|
||||
if (dev_priv->caps.output_1_supported) {
|
||||
i830_sdvo_set_target_output(output, FALSE, TRUE);
|
||||
i830_sdvo_set_output_timing(output, &dev_priv->save_output_dtd_2);
|
||||
}
|
||||
i830_sdvo_set_target_output(output, &dev_priv->save_active_outputs);
|
||||
i830_sdvo_set_output_timing(output, &dev_priv->save_output_dtd);
|
||||
|
||||
i830_sdvo_set_clock_rate_mult(output, dev_priv->save_sdvo_mult);
|
||||
|
||||
OUTREG(dev_priv->output_device, dev_priv->save_SDVOX);
|
||||
|
||||
i830_sdvo_set_active_outputs(output, dev_priv->save_sdvo_active_1,
|
||||
dev_priv->save_sdvo_active_2);
|
||||
i830_sdvo_set_active_outputs(output, &dev_priv->save_active_outputs);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -743,7 +745,7 @@ i830_sdvo_mode_valid(ScrnInfoPtr pScrn, I830OutputPtr output,
|
|||
}
|
||||
|
||||
static Bool
|
||||
i830_sdvo_get_capabilities(I830OutputPtr output, i830_sdvo_caps *caps)
|
||||
i830_sdvo_get_capabilities(I830OutputPtr output, struct i830_sdvo_caps *caps)
|
||||
{
|
||||
CARD8 status;
|
||||
|
||||
|
|
@ -866,7 +868,7 @@ i830_sdvo_dump_device(I830OutputPtr output)
|
|||
i830_sdvo_dump_cmd(output, SDVO_CMD_GET_ATTACHED_DISPLAYS);
|
||||
i830_sdvo_dump_cmd(output, SDVO_CMD_GET_HOT_PLUG_SUPPORT);
|
||||
i830_sdvo_dump_cmd(output, SDVO_CMD_GET_ACTIVE_HOT_PLUG);
|
||||
i830_sdvo_dump_cmd(output, SDVO_CMD_GET_INTR_EVENT_SOURCE);
|
||||
i830_sdvo_dump_cmd(output, SDVO_CMD_GET_INTERRUPT_EVENT_SOURCE);
|
||||
i830_sdvo_dump_cmd(output, SDVO_CMD_GET_INPUT_TIMINGS_PART1);
|
||||
i830_sdvo_dump_cmd(output, SDVO_CMD_GET_INPUT_TIMINGS_PART2);
|
||||
i830_sdvo_dump_cmd(output, SDVO_CMD_GET_OUTPUT_TIMINGS_PART1);
|
||||
|
|
@ -1023,6 +1025,9 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
|
|||
i830_sdvo_get_input_pixel_clock_range(output, &dev_priv->pixel_clock_min,
|
||||
&dev_priv->pixel_clock_max);
|
||||
|
||||
memset(&dev_priv->active_outputs, 0, sizeof(dev_priv->active_outputs));
|
||||
dev_priv->active_outputs.tmds0 = 1;
|
||||
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
||||
"SDVO device VID/DID: %02X:%02X.%02X, "
|
||||
"input 1: %c, input 2: %c, "
|
||||
|
|
@ -1031,8 +1036,8 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
|
|||
dev_priv->caps.device_rev_id,
|
||||
(dev_priv->caps.sdvo_inputs_mask & 0x1) ? 'Y' : 'N',
|
||||
(dev_priv->caps.sdvo_inputs_mask & 0x2) ? 'Y' : 'N',
|
||||
dev_priv->caps.output_0_supported ? 'Y' : 'N',
|
||||
dev_priv->caps.output_1_supported ? 'Y' : 'N');
|
||||
dev_priv->caps.output_flags.tmds0 ? 'Y' : 'N',
|
||||
dev_priv->caps.output_flags.tmds1 ? 'Y' : 'N');
|
||||
|
||||
pI830->num_outputs++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,23 @@
|
|||
*
|
||||
*/
|
||||
|
||||
typedef struct _i830_sdvo_caps {
|
||||
struct i830_sdvo_output_flags {
|
||||
unsigned int tmds0:1;
|
||||
unsigned int rgb0:1;
|
||||
unsigned int cvbs0:1;
|
||||
unsigned int svid0:1;
|
||||
unsigned int yprpb0:1;
|
||||
unsigned int scart0:1;
|
||||
unsigned int lvds0:1;
|
||||
unsigned int pad0:1;
|
||||
unsigned int tmds1:1;
|
||||
unsigned int pad1:4;
|
||||
unsigned int rgb1:1;
|
||||
unsigned int lvds1:1;
|
||||
unsigned int pad2:1;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct i830_sdvo_caps {
|
||||
CARD8 vendor_id;
|
||||
CARD8 device_id;
|
||||
CARD8 device_rev_id;
|
||||
|
|
@ -38,13 +54,13 @@ typedef struct _i830_sdvo_caps {
|
|||
unsigned int down_scaling:1;
|
||||
unsigned int stall_support:1;
|
||||
unsigned int pad:1;
|
||||
CARD8 output_0_supported;
|
||||
CARD8 output_1_supported;
|
||||
} __attribute__((packed)) i830_sdvo_caps;
|
||||
struct i830_sdvo_output_flags output_flags;
|
||||
} __attribute__((packed));
|
||||
|
||||
/** This matches the EDID DTD structure, more or less */
|
||||
struct i830_sdvo_dtd {
|
||||
struct {
|
||||
CARD16 clock;
|
||||
CARD16 clock; /**< pixel clock, in 10kHz units */
|
||||
CARD8 h_active;
|
||||
CARD8 h_blank;
|
||||
CARD8 h_high;
|
||||
|
|
@ -66,8 +82,8 @@ struct i830_sdvo_dtd {
|
|||
} __attribute__((packed));
|
||||
|
||||
struct i830_sdvo_pixel_clock_range {
|
||||
CARD16 min;
|
||||
CARD16 max;
|
||||
CARD16 min; /**< pixel clock, in 10kHz units */
|
||||
CARD16 max; /**< pixel clock, in 10kHz units */
|
||||
} __attribute__((packed));
|
||||
|
||||
struct i830_sdvo_preferred_input_timing_args {
|
||||
|
|
@ -103,7 +119,7 @@ struct i830_sdvo_preferred_input_timing_args {
|
|||
#define SDVO_CMD_STATUS_NOTSUPP 0x2
|
||||
#define SDVO_CMD_STATUS_INVALID_ARG 0x3
|
||||
#define SDVO_CMD_STATUS_PENDING 0x4
|
||||
#define SDVO_CMD_STATUS_TARGET_NOT_SUPP 0x5
|
||||
#define SDVO_CMD_STATUS_TARGET_NOT_SPECIFIED 0x5
|
||||
#define SDVO_CMD_STATUS_SCALING_NOT_SUPP 0x6
|
||||
|
||||
/* SDVO commands, argument/result registers */
|
||||
|
|
@ -116,29 +132,93 @@ struct i830_sdvo_preferred_input_timing_args {
|
|||
#define SDVO_CMD_GET_FIRMWARE_REV 0x86
|
||||
# define SDVO_DEVICE_FIRMWARE_MINOR SDVO_I2C_RETURN_0
|
||||
# define SDVO_DEVICE_FIRMWARE_MAJOR SDVO_I2C_RETURN_1
|
||||
# define SDVO_DEVICE_FIRMWARE_PATCH SDVO_I2C_RETURN_2
|
||||
|
||||
/**
|
||||
* Reports which inputs are trained (managed to sync).
|
||||
*
|
||||
* Devices must have trained within 2 vsyncs of a mode change.
|
||||
*/
|
||||
#define SDVO_CMD_GET_TRAINED_INPUTS 0x03
|
||||
struct i830_sdvo_get_trained_inputs_response {
|
||||
unsigned int input0_trained:1;
|
||||
unsigned int input1_trained:1;
|
||||
unsigned int pad:6;
|
||||
} __attribute__((packed));
|
||||
|
||||
/** Returns a struct i830_sdvo_output_flags of active outputs. */
|
||||
#define SDVO_CMD_GET_ACTIVE_OUTPUTS 0x04
|
||||
|
||||
/**
|
||||
* Sets the current set of active outputs.
|
||||
*
|
||||
* Takes a struct i830_sdvo_output_flags. Must be preceded by a SET_IN_OUT_MAP
|
||||
* on multi-output devices.
|
||||
*/
|
||||
#define SDVO_CMD_SET_ACTIVE_OUTPUTS 0x05
|
||||
|
||||
/**
|
||||
* Returns the current mapping of SDVO inputs to outputs on the device.
|
||||
*
|
||||
* Returns two struct i830_sdvo_output_flags structures.
|
||||
*/
|
||||
#define SDVO_CMD_GET_IN_OUT_MAP 0x06
|
||||
|
||||
/**
|
||||
* Sets the current mapping of SDVO inputs to outputs on the device.
|
||||
*
|
||||
* Takes two struct i380_sdvo_output_flags structures.
|
||||
*/
|
||||
#define SDVO_CMD_SET_IN_OUT_MAP 0x07
|
||||
|
||||
/**
|
||||
* Returns a struct i830_sdvo_output_flags of attached displays.
|
||||
*/
|
||||
#define SDVO_CMD_GET_ATTACHED_DISPLAYS 0x0b
|
||||
|
||||
/**
|
||||
* Returns a struct i830_sdvo_ouptut_flags of displays supporting hot plugging.
|
||||
*/
|
||||
#define SDVO_CMD_GET_HOT_PLUG_SUPPORT 0x0c
|
||||
|
||||
/**
|
||||
* Takes a struct i830_sdvo_output_flags.
|
||||
*/
|
||||
#define SDVO_CMD_SET_ACTIVE_HOT_PLUG 0x0d
|
||||
|
||||
/**
|
||||
* Returns a struct i830_sdvo_output_flags of displays with hot plug
|
||||
* interrupts enabled.
|
||||
*/
|
||||
#define SDVO_CMD_GET_ACTIVE_HOT_PLUG 0x0e
|
||||
|
||||
#define SDVO_CMD_GET_INTR_EVENT_SOURCE 0x0f
|
||||
#define SDVO_CMD_GET_INTERRUPT_EVENT_SOURCE 0x0f
|
||||
struct i830_sdvo_get_interrupt_event_source_response {
|
||||
struct i830_sdvo_output_flags interrupt_status;
|
||||
unsigned int ambient_light_interrupt:1;
|
||||
unsigned int pad:7;
|
||||
} __attribute__((packed));
|
||||
|
||||
/**
|
||||
* Selects which input is affected by future input commands.
|
||||
*
|
||||
* Commands affected include SET_INPUT_TIMINGS_PART[12],
|
||||
* GET_INPUT_TIMINGS_PART[12], GET_PREFERRED_INPUT_TIMINGS_PART[12],
|
||||
* GET_INPUT_PIXEL_CLOCK_RANGE, and CREATE_PREFERRED_INPUT_TIMINGS.
|
||||
*/
|
||||
#define SDVO_CMD_SET_TARGET_INPUT 0x10
|
||||
struct i830_sdvo_set_target_input_args {
|
||||
unsigned int target_1:1;
|
||||
unsigned int pad:7;
|
||||
} __attribute__((packed));
|
||||
|
||||
/**
|
||||
* Takes a struct i830_sdvo_output_flags of which outputs are targetted by
|
||||
* future output commands.
|
||||
*
|
||||
* Affected commands inclue SET_OUTPUT_TIMINGS_PART[12],
|
||||
* GET_OUTPUT_TIMINGS_PART[12], and GET_OUTPUT_PIXEL_CLOCK_RANGE.
|
||||
*/
|
||||
#define SDVO_CMD_SET_TARGET_OUTPUT 0x11
|
||||
|
||||
#define SDVO_CMD_GET_INPUT_TIMINGS_PART1 0x12
|
||||
|
|
@ -174,6 +254,12 @@ struct i830_sdvo_preferred_input_timing_args {
|
|||
# define SDVO_DTD_SDVO_FLAG_SCALING_MASK (3 << 4)
|
||||
# define SDVO_DTD_VSYNC_OFF_HIGH SDVO_I2C_ARG_6
|
||||
|
||||
/**
|
||||
* Generates a DTD based on the given width, height, and flags.
|
||||
*
|
||||
* This will be supported by any device supporting scaling or interlaced
|
||||
* modes.
|
||||
*/
|
||||
#define SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING 0x1a
|
||||
# define SDVO_PREFERRED_INPUT_TIMING_CLOCK_LOW SDVO_I2C_ARG_0
|
||||
# define SDVO_PREFERRED_INPUT_TIMING_CLOCK_HIGH SDVO_I2C_ARG_1
|
||||
|
|
@ -193,15 +279,16 @@ struct i830_sdvo_preferred_input_timing_args {
|
|||
/** Returns a struct i830_sdvo_pixel_clock_range */
|
||||
#define SDVO_CMD_GET_OUTPUT_PIXEL_CLOCK_RANGE 0x1e
|
||||
|
||||
/** Returns a byte bitfield containing SDVO_CLOCK_RATE_MULT_* flags */
|
||||
#define SDVO_CMD_GET_SUPPORTED_CLOCK_RATE_MULTS 0x1f
|
||||
|
||||
/** Returns a byte containing a SDVO_CLOCK_RATE_MULT_* flag */
|
||||
#define SDVO_CMD_GET_CLOCK_RATE_MULT 0x20
|
||||
/** Takes a byte containing a SDVO_CLOCK_RATE_MULT_* flag */
|
||||
#define SDVO_CMD_SET_CLOCK_RATE_MULT 0x21
|
||||
# define SDVO_CLOCK_RATE_MULT_1X (1 << 0)
|
||||
# define SDVO_CLOCK_RATE_MULT_2X (1 << 1)
|
||||
# define SDVO_CLOCK_RATE_MULT_3X (1 << 2)
|
||||
# define SDVO_CLOCK_RATE_MULT_4X (1 << 3)
|
||||
# define SDVO_CLOCK_RATE_MULT_5X (1 << 4)
|
||||
|
||||
#define SDVO_CMD_GET_SUPPORTED_TV_FORMATS 0x27
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue