mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2026-01-08 06:00:13 +01:00
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:
parent
83c3acb7da
commit
3b32ee36ae
1 changed files with 97 additions and 169 deletions
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue