Fixup Intel TV property code

Use the new TV property creation routine and fixup the set_property code
to actually do a mode set call when properties change.
This commit is contained in:
Jesse Barnes 2008-04-10 20:31:31 -07:00
parent 83c3acb7da
commit 3b32ee36ae

View file

@ -37,14 +37,6 @@
#include "i915_drm.h"
#include "i915_drv.h"
enum tv_type {
TV_TYPE_NONE,
TV_TYPE_UNKNOWN,
TV_TYPE_COMPOSITE,
TV_TYPE_SVIDEO,
TV_TYPE_COMPONENT
};
enum tv_margin {
TV_MARGIN_LEFT, TV_MARGIN_TOP,
TV_MARGIN_RIGHT, TV_MARGIN_BOTTOM
@ -1145,14 +1137,14 @@ intel_tv_mode_set(struct drm_output *output, struct drm_display_mode *mode,
switch (tv_priv->type) {
default:
case TV_TYPE_UNKNOWN:
case TV_TYPE_COMPOSITE:
case ConnectorUnknown:
case ConnectorComposite:
tv_ctl |= TV_ENC_OUTPUT_COMPOSITE;
video_levels = tv_mode->composite_levels;
color_conversion = tv_mode->composite_color;
burst_ena = tv_mode->burst_ena;
break;
case TV_TYPE_COMPONENT:
case ConnectorComponent:
tv_ctl |= TV_ENC_OUTPUT_COMPONENT;
video_levels = &component_levels;
if (tv_mode->burst_ena)
@ -1161,7 +1153,7 @@ intel_tv_mode_set(struct drm_output *output, struct drm_display_mode *mode,
color_conversion = &hdtv_csc_yprpb;
burst_ena = FALSE;
break;
case TV_TYPE_SVIDEO:
case ConnectorSVIDEO:
tv_ctl |= TV_ENC_OUTPUT_SVIDEO;
video_levels = tv_mode->svideo_levels;
color_conversion = tv_mode->svideo_color;
@ -1218,8 +1210,11 @@ intel_tv_mode_set(struct drm_output *output, struct drm_display_mode *mode,
if (tv_mode->pal_burst)
tv_ctl |= TV_PAL_BURST;
scctl1 = 0;
if (tv_mode->dda1_inc)
/* dda1 implies valid video levels */
if (tv_mode->dda1_inc) {
scctl1 |= TV_SC_DDA1_EN;
scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT;
}
if (tv_mode->dda2_inc)
scctl1 |= TV_SC_DDA2_EN;
@ -1228,7 +1223,6 @@ intel_tv_mode_set(struct drm_output *output, struct drm_display_mode *mode,
scctl1 |= TV_SC_DDA3_EN;
scctl1 |= tv_mode->sc_reset;
scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT;
scctl1 |= tv_mode->dda1_inc << TV_SCDDA1_INC_SHIFT;
scctl2 = tv_mode->dda2_size << TV_SCDDA2_SIZE_SHIFT |
@ -1255,22 +1249,26 @@ intel_tv_mode_set(struct drm_output *output, struct drm_display_mode *mode,
I915_WRITE(TV_SC_CTL_2, scctl2);
I915_WRITE(TV_SC_CTL_3, scctl3);
I915_WRITE(TV_CSC_Y, (color_conversion->ry << 16) |
color_conversion->gy);
I915_WRITE(TV_CSC_Y2,(color_conversion->by << 16) |
color_conversion->ay);
I915_WRITE(TV_CSC_U, (color_conversion->ru << 16) |
color_conversion->gu);
I915_WRITE(TV_CSC_U2, (color_conversion->bu << 16) |
color_conversion->au);
I915_WRITE(TV_CSC_V, (color_conversion->rv << 16) |
color_conversion->gv);
I915_WRITE(TV_CSC_V2, (color_conversion->bv << 16) |
color_conversion->av);
if (color_conversion) {
I915_WRITE(TV_CSC_Y, (color_conversion->ry << 16) |
color_conversion->gy);
I915_WRITE(TV_CSC_Y2,(color_conversion->by << 16) |
color_conversion->ay);
I915_WRITE(TV_CSC_U, (color_conversion->ru << 16) |
color_conversion->gu);
I915_WRITE(TV_CSC_U2, (color_conversion->bu << 16) |
color_conversion->au);
I915_WRITE(TV_CSC_V, (color_conversion->rv << 16) |
color_conversion->gv);
I915_WRITE(TV_CSC_V2, (color_conversion->bv << 16) |
color_conversion->av);
}
I915_WRITE(TV_CLR_KNOBS, 0x00606000);
I915_WRITE(TV_CLR_LEVEL, ((video_levels->black << TV_BLACK_LEVEL_SHIFT) |
(video_levels->blank << TV_BLANK_LEVEL_SHIFT)));
if (video_levels)
I915_WRITE(TV_CLR_LEVEL,
((video_levels->black << TV_BLACK_LEVEL_SHIFT) |
(video_levels->blank << TV_BLANK_LEVEL_SHIFT)));
{
int pipeconf_reg = (intel_crtc->pipe == 0) ?
PIPEACONF : PIPEBCONF;
@ -1364,7 +1362,7 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct drm_output *output)
struct intel_output *intel_output = output->driver_private;
u32 tv_ctl, save_tv_ctl;
u32 tv_dac, save_tv_dac;
int type = TV_TYPE_UNKNOWN;
int type = ConnectorUnknown;
tv_dac = I915_READ(TV_DAC);
/*
@ -1402,24 +1400,21 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct drm_output *output)
*/
if ((tv_dac & TVDAC_SENSE_MASK) == (TVDAC_B_SENSE | TVDAC_C_SENSE)) {
DRM_DEBUG("Detected Composite TV connection\n");
type = TV_TYPE_COMPOSITE;
type = ConnectorComposite;
} else if ((tv_dac & (TVDAC_A_SENSE|TVDAC_B_SENSE)) == TVDAC_A_SENSE) {
DRM_DEBUG("Detected S-Video TV connection\n");
type = TV_TYPE_SVIDEO;
type = ConnectorSVIDEO;
} else if ((tv_dac & TVDAC_SENSE_MASK) == 0) {
DRM_DEBUG("Detected Component TV connection\n");
type = TV_TYPE_COMPONENT;
type = ConnectorComponent;
} else {
DRM_DEBUG("No TV connection detected\n");
type = TV_TYPE_NONE;
type = -1;
}
return type;
}
static int
intel_tv_format_configure_property (struct drm_output *output);
/**
* Detect the TV connection.
*
@ -1446,18 +1441,18 @@ intel_tv_detect(struct drm_output *output)
}
if (type != tv_priv->type) {
struct drm_property *connector_property =
output->dev->mode_config.connector_type_property;
tv_priv->type = type;
intel_tv_format_configure_property(output);
drm_output_property_set_value(output, connector_property,
type);
}
switch (type) {
case TV_TYPE_NONE:
if (type < 0)
return output_status_disconnected;
case TV_TYPE_UNKNOWN:
return output_status_unknown;
default:
return output_status_connected;
}
return output_status_connected;
}
static struct input_res {
@ -1538,135 +1533,41 @@ intel_tv_destroy (struct drm_output *output)
DRM_MEM_DRIVER);
}
static bool
intel_tv_format_set_property(struct drm_output *output,
struct drm_property *prop, uint64_t val)
{
#if 0
struct intel_output *intel_output = output->driver_private;
struct intel_tv_priv *tv_priv = intel_output->dev_priv;
const struct tv_mode *tv_mode =
intel_tv_mode_lookup(tv_priv->tv_format);
int err;
if (!tv_mode)
tv_mode = &tv_modes[0];
err = RRChangeOutputProperty (output->randr_output, tv_format_atom,
XA_ATOM, 32, PropModeReplace, 1,
&tv_format_name_atoms[tv_mode - tv_modes],
FALSE, TRUE);
return err == Success;
#endif
return 0;
}
/**
* Configure the TV_FORMAT property to list only supported formats
*
* Unless the connector is component, list only the formats supported by
* svideo and composite
*/
static int
intel_tv_format_configure_property(struct drm_output *output)
{
#if 0
struct intel_output *intel_output = output->driver_private;
struct intel_tv_priv *tv_priv = intel_output->dev_priv;
Atom current_atoms[NUM_TV_MODES];
int num_atoms = 0;
int i;
if (!output->randr_output)
return Success;
for (i = 0; i < NUM_TV_MODES; i++)
if (!tv_modes[i].component_only ||
tv_priv->type == TV_TYPE_COMPONENT)
current_atoms[num_atoms++] = tv_format_name_atoms[i];
return RRConfigureOutputProperty(output->randr_output, tv_format_atom,
TRUE, FALSE, FALSE,
num_atoms, (INT32 *) current_atoms);
#endif
return 0;
}
static void
intel_tv_create_resources(struct drm_output *output)
{
struct drm_device *dev = output->dev;
struct intel_output *intel_output = output->driver_private;
struct intel_tv_priv *tv_priv = intel_output->dev_priv;
int i, err;
#if 0
/* Set up the tv_format property, which takes effect on mode set
* and accepts strings that match exactly
*/
tv_format_atom = MakeAtom(TV_FORMAT_NAME, sizeof(TV_FORMAT_NAME) - 1,
TRUE);
for (i = 0; i < NUM_TV_MODES; i++)
tv_format_name_atoms[i] = MakeAtom (tv_modes[i].name,
strlen (tv_modes[i].name),
TRUE);
err = intel_tv_format_configure_property (output);
if (err != 0) {
xf86DrvMsg(dev->scrnIndex, X_ERROR,
"RRConfigureOutputProperty error, %d\n", err);
}
/* Set the current value of the tv_format property */
if (!intel_tv_format_set_property (output))
xf86DrvMsg(dev->scrnIndex, X_ERROR,
"RRChangeOutputProperty error, %d\n", err);
for (i = 0; i < 4; i++)
{
INT32 range[2];
margin_atoms[i] = MakeAtom(margin_names[i], strlen (margin_names[i]),
TRUE);
range[0] = 0;
range[1] = 100;
err = RRConfigureOutputProperty(output->randr_output, margin_atoms[i],
TRUE, TRUE, FALSE, 2, range);
if (err != 0)
xf86DrvMsg(dev->scrnIndex, X_ERROR,
"RRConfigureOutputProperty error, %d\n", err);
err = RRChangeOutputProperty(output->randr_output, margin_atoms[i],
XA_INTEGER, 32, PropModeReplace,
1, &tv_priv->margin[i],
FALSE, TRUE);
if (err != 0)
xf86DrvMsg(dev->scrnIndex, X_ERROR,
"RRChangeOutputProperty error, %d\n", err);
}
#endif
}
static bool
intel_tv_set_property(struct drm_output *output, struct drm_property *property,
uint64_t val)
{
struct drm_device *dev = output->dev;
struct intel_output *intel_output = output->driver_private;
struct intel_tv_priv *tv_priv = intel_output->dev_priv;
int ret = 0;
if (property == dev->mode_config.tv_left_margin_property ||
property == dev->mode_config.tv_right_margin_property ||
property == dev->mode_config.tv_top_margin_property ||
property == dev->mode_config.tv_bottom_margin_property) {
ret = drm_output_property_set_value(output, property, val);
ret = drm_output_property_set_value(output, property, val);
if (ret < 0)
goto out;
if (property == dev->mode_config.tv_left_margin_property)
tv_priv->margin[TV_MARGIN_LEFT] = val;
else if (property == dev->mode_config.tv_right_margin_property)
tv_priv->margin[TV_MARGIN_RIGHT] = val;
else if (property == dev->mode_config.tv_top_margin_property)
tv_priv->margin[TV_MARGIN_TOP] = val;
else if (property == dev->mode_config.tv_bottom_margin_property)
tv_priv->margin[TV_MARGIN_BOTTOM] = val;
else if (property == dev->mode_config.tv_mode_property) {
if (val >= NUM_TV_MODES) {
ret = -EINVAL;
goto out;
}
tv_priv->tv_format = tv_modes[val].name;
intel_tv_mode_set(output, NULL, NULL);
} else {
/* TV mode handling here */
ret = -EINVAL;
goto out;
}
intel_tv_mode_set(output, NULL, NULL);
out:
return ret;
}
@ -1693,6 +1594,8 @@ intel_tv_init(struct drm_device *dev)
struct intel_output *intel_output;
struct intel_tv_priv *tv_priv;
u32 tv_dac_on, tv_dac_off, save_tv_dac;
char **tv_format_names;
int i, initial_mode = 0;
/* FIXME: better TV detection and/or quirks */
#if 0
@ -1743,22 +1646,47 @@ intel_tv_init(struct drm_device *dev)
output->possible_crtcs = ((1 << 0) | (1 << 1));
output->possible_clones = (1 << INTEL_OUTPUT_TVOUT);
intel_output->dev_priv = tv_priv;
tv_priv->type = TV_TYPE_UNKNOWN;
tv_priv->type = ConnectorUnknown;
tv_priv->tv_format = NULL;
/* BIOS margin values */
tv_priv->margin[TV_MARGIN_LEFT] = 54;
tv_priv->margin[TV_MARGIN_TOP] = 36;
tv_priv->margin[TV_MARGIN_RIGHT] = 46;
tv_priv->margin[TV_MARGIN_BOTTOM] = 37;
if (!tv_priv->tv_format)
tv_priv->tv_format = kstrdup(tv_modes[0].name, GFP_KERNEL);
tv_priv->tv_format = kstrdup(tv_modes[initial_mode].name, GFP_KERNEL);
output->driver_private = intel_output;
output->interlace_allowed = FALSE;
output->doublescan_allowed = FALSE;
drm_output_attach_property(output,
dev->mode_config.connector_type_property,
ConnectorUnknown);
/* Create TV properties then attach current values */
tv_format_names = drm_alloc(sizeof(char *) * NUM_TV_MODES,
DRM_MEM_DRIVER);
if (!tv_format_names)
goto out;
for (i = 0; i < NUM_TV_MODES; i++)
tv_format_names[i] = tv_modes[i].name;
drm_create_tv_properties(dev, NUM_TV_MODES, tv_format_names);
drm_output_attach_property(output, dev->mode_config.tv_mode_property,
initial_mode);
drm_output_attach_property(output,
dev->mode_config.tv_left_margin_property,
tv_priv->margin[TV_MARGIN_LEFT]);
drm_output_attach_property(output,
dev->mode_config.tv_top_margin_property,
tv_priv->margin[TV_MARGIN_TOP]);
drm_output_attach_property(output,
dev->mode_config.tv_right_margin_property,
tv_priv->margin[TV_MARGIN_RIGHT]);
drm_output_attach_property(output,
dev->mode_config.tv_bottom_margin_property,
tv_priv->margin[TV_MARGIN_BOTTOM]);
out:
drm_sysfs_output_add(output);
}