@@ -43,12 +43,45 @@ enum tv_margin {
TV_MARGIN_RIGHT, TV_MARGIN_BOTTOM
};
+struct tv_mode {
+ const char *name;
+ int clock;
+ int refresh; /* in millihertz (for precision) */
+ u32 oversample;
+ int hsync_end, hblank_start, hblank_end, htotal;
+ bool progressive, trilevel_sync, component_only;
+ int vsync_start_f1, vsync_start_f2, vsync_len;
+ bool veq_ena;
+ int veq_start_f1, veq_start_f2, veq_len;
+ int vi_end_f1, vi_end_f2, nbr_end;
+ bool burst_ena;
+ int hburst_start, hburst_len;
+ int vburst_start_f1, vburst_end_f1;
+ int vburst_start_f2, vburst_end_f2;
+ int vburst_start_f3, vburst_end_f3;
+ int vburst_start_f4, vburst_end_f4;
+ /*
+ * subcarrier programming
+ */
+ int dda2_size, dda3_size, dda1_inc, dda2_inc, dda3_inc;
+ u32 sc_reset;
+ bool pal_burst;
+ /*
+ * blank/black levels
+ */
+ const struct video_levels *composite_levels, *svideo_levels;
+ const struct color_conversion *composite_color, *svideo_color;
+ const u32 *filter_table;
+ int max_srcw;
+};
+
+
/** Private structure for the integrated TV support */
struct intel_tv {
struct intel_encoder base;
int type;
- const char *tv_format;
+ const struct tv_mode *mode;
int margin[4];
u32 save_TV_H_CTL_1;
u32 save_TV_H_CTL_2;
@@ -349,39 +382,6 @@ static const struct video_levels component_levels = {
};
-struct tv_mode {
- const char *name;
- int clock;
- int refresh; /* in millihertz (for precision) */
- u32 oversample;
- int hsync_end, hblank_start, hblank_end, htotal;
- bool progressive, trilevel_sync, component_only;
- int vsync_start_f1, vsync_start_f2, vsync_len;
- bool veq_ena;
- int veq_start_f1, veq_start_f2, veq_len;
- int vi_end_f1, vi_end_f2, nbr_end;
- bool burst_ena;
- int hburst_start, hburst_len;
- int vburst_start_f1, vburst_end_f1;
- int vburst_start_f2, vburst_end_f2;
- int vburst_start_f3, vburst_end_f3;
- int vburst_start_f4, vburst_end_f4;
- /*
- * subcarrier programming
- */
- int dda2_size, dda3_size, dda1_inc, dda2_inc, dda3_inc;
- u32 sc_reset;
- bool pal_burst;
- /*
- * blank/black levels
- */
- const struct video_levels *composite_levels, *svideo_levels;
- const struct color_conversion *composite_color, *svideo_color;
- const u32 *filter_table;
- int max_srcw;
-};
-
-
/*
* Sub carrier DDA
*
@@ -928,32 +928,12 @@ intel_tv_dpms(struct drm_encoder *encoder, int mode)
}
}
-static const struct tv_mode *
-intel_tv_mode_lookup(const char *tv_format)
-{
- int i;
-
- for (i = 0; i < sizeof(tv_modes) / sizeof (tv_modes[0]); i++) {
- const struct tv_mode *tv_mode = &tv_modes[i];
-
- if (!strcmp(tv_format, tv_mode->name))
- return tv_mode;
- }
- return NULL;
-}
-
-static const struct tv_mode *
-intel_tv_mode_find(struct intel_tv *intel_tv)
-{
- return intel_tv_mode_lookup(intel_tv->tv_format);
-}
-
static enum drm_mode_status
intel_tv_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
struct intel_tv *intel_tv = intel_attached_tv(connector);
- const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
+ const struct tv_mode *tv_mode = intel_tv->mode;
/* Ensure TV refresh is close to desired refresh */
if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000)
@@ -971,7 +951,7 @@ intel_tv_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
struct drm_device *dev = encoder->dev;
struct drm_mode_config *drm_config = &dev->mode_config;
struct intel_tv *intel_tv = enc_to_intel_tv(encoder);
- const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
+ const struct tv_mode *tv_mode = intel_tv->mode;
struct drm_encoder *other_encoder;
if (!tv_mode)
@@ -997,7 +977,7 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
struct drm_crtc *crtc = encoder->crtc;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_tv *intel_tv = enc_to_intel_tv(encoder);
- const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
+ const struct tv_mode *tv_mode = intel_tv->mode;
u32 tv_ctl;
u32 hctl1, hctl2, hctl3;
u32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7;
@@ -1321,23 +1301,21 @@ intel_tv_detect_type (struct intel_tv *intel_tv,
static void intel_tv_find_better_format(struct drm_connector *connector)
{
struct intel_tv *intel_tv = intel_attached_tv(connector);
- const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
+ const struct tv_mode *tv_mode = intel_tv->mode;
+ bool is_component_only = intel_tv->type == DRM_MODE_CONNECTOR_Component;
int i;
- if ((intel_tv->type == DRM_MODE_CONNECTOR_Component) ==
- tv_mode->component_only)
+ if (is_component_only == tv_mode->component_only)
return;
-
- for (i = 0; i < sizeof(tv_modes) / sizeof(*tv_modes); i++) {
+ for (i = 0; i < ARRAY_SIZE(tv_modes); i++) {
tv_mode = tv_modes + i;
- if ((intel_tv->type == DRM_MODE_CONNECTOR_Component) ==
- tv_mode->component_only)
+ if (is_component_only == tv_mode->component_only)
break;
}
- intel_tv->tv_format = tv_mode->name;
+ intel_tv->mode = tv_mode;
drm_connector_property_set_value(connector,
connector->dev->mode_config.tv_mode_property, i);
}
@@ -1405,7 +1383,7 @@ intel_tv_chose_preferred_modes(struct drm_connector *connector,
struct drm_display_mode *mode_ptr)
{
struct intel_tv *intel_tv = intel_attached_tv(connector);
- const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
+ const struct tv_mode *tv_mode = intel_tv->mode;
if (tv_mode->nbr_end < 480 && mode_ptr->vdisplay == 480)
mode_ptr->type |= DRM_MODE_TYPE_PREFERRED;
@@ -1430,7 +1408,7 @@ intel_tv_get_modes(struct drm_connector *connector)
{
struct drm_display_mode *mode_ptr;
struct intel_tv *intel_tv = intel_attached_tv(connector);
- const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
+ const struct tv_mode *tv_mode = intel_tv->mode;
int j, count = 0;
u64 tmp;
@@ -1524,10 +1502,10 @@ intel_tv_set_property(struct drm_connector *connector, struct drm_property *prop
ret = -EINVAL;
goto out;
}
- if (!strcmp(intel_tv->tv_format, tv_modes[val].name))
+ if (intel_tv->mode == tv_modes + val)
goto out;
- intel_tv->tv_format = tv_modes[val].name;
+ intel_tv->mode = &tv_modes[val];
changed = true;
} else {
ret = -EINVAL;
@@ -1694,7 +1672,7 @@ intel_tv_init(struct drm_device *dev)
intel_tv->margin[TV_MARGIN_RIGHT] = 46;
intel_tv->margin[TV_MARGIN_BOTTOM] = 37;
- intel_tv->tv_format = tv_modes[initial_mode].name;
+ intel_tv->mode = &tv_modes[initial_mode];
drm_encoder_helper_add(&intel_encoder->base, &intel_tv_helper_funcs);
drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs);
Instead of scanning through the static array using strcmp to find our matching tv_mode, just keep a direct link around. The historical reason for the strcmp was to match the connection property "tv format", but now that property is translated for us into an index by the drm core. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Mathew McKernan <matmckernan@rauland.com.au> --- drivers/gpu/drm/i915/intel_tv.c | 118 ++++++++++++++++----------------------- 1 files changed, 48 insertions(+), 70 deletions(-)