From e439e74776b215d70d8e34e8aa9cea22179dcbc6 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 2 Jun 2008 10:05:54 +1000 Subject: [PATCH] drm/modesetting: another re-org of some internals. Move dpms into the helper functions. Move crtc into the encoder. Move disable unused functions into the helper. --- linux-core/drm_crtc.c | 62 +++++++++----------- linux-core/drm_crtc.h | 12 +--- linux-core/drm_crtc_helper.c | 136 ++++++++++++++++++++++++++----------------- linux-core/drm_crtc_helper.h | 32 +++++----- linux-core/intel_crt.c | 27 ++++----- linux-core/intel_display.c | 78 +++++++++++++------------ linux-core/intel_drv.h | 9 +-- linux-core/intel_dvo.c | 29 ++++----- linux-core/intel_fb.c | 2 +- linux-core/intel_lvds.c | 40 +++++++------ linux-core/intel_sdvo.c | 33 ++++++----- linux-core/intel_tv.c | 61 +++++++++---------- shared-core/drm.h | 3 +- 13 files changed, 274 insertions(+), 250 deletions(-) diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index bf6afd6..27bf7c2 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -83,6 +83,15 @@ static struct drm_prop_enum_list drm_encoder_enum_list[] = { DRM_MODE_ENCODER_TVDAC, "TV" }, }; +char *drm_get_encoder_name(struct drm_encoder *encoder) +{ + static char buf[32]; + + snprintf(buf, 32, "%s-%d", drm_encoder_enum_list[encoder->encoder_type].name, + encoder->id); + return buf; +} + char *drm_get_connector_name(struct drm_connector *connector) { static char buf[32]; @@ -290,11 +299,11 @@ EXPORT_SYMBOL(drm_crtc_cleanup); */ bool drm_crtc_in_use(struct drm_crtc *crtc) { - struct drm_connector *connector; + struct drm_encoder *encoder; struct drm_device *dev = crtc->dev; /* FIXME: Locking around list access? */ - list_for_each_entry(connector, &dev->mode_config.connector_list, head) - if (connector->crtc == crtc) + list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) + if (encoder->crtc == crtc) return true; return false; } @@ -407,33 +416,6 @@ EXPORT_SYMBOL(drm_crtc_probe_connector_modes); /** - * drm_disable_unused_functions - disable unused objects - * @dev: DRM device - * - * LOCKING: - * Caller must hold mode config lock. - * - * If an connector or CRTC isn't part of @dev's mode_config, it can be disabled - * by calling its dpms function, which should power it off. - */ -void drm_disable_unused_functions(struct drm_device *dev) -{ - struct drm_connector *connector; - struct drm_crtc *crtc; - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - if (!connector->crtc) - (*connector->funcs->dpms)(connector, DPMSModeOff); - } - - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - if (!crtc->enabled) - crtc->funcs->dpms(crtc, DPMSModeOff); - } -} -EXPORT_SYMBOL(drm_disable_unused_functions); - -/** * drm_mode_probed_add - add a mode to the specified connector's probed mode list * @connector: connector the new mode * @mode: mode data @@ -1059,7 +1041,7 @@ int drm_mode_getcrtc(struct drm_device *dev, crtc_resp->mode_valid = 1; ocount = 0; list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - if (connector->crtc == crtc) + if (connector->encoder->crtc == crtc) crtc_resp->connectors |= 1 << (ocount++); } @@ -1143,10 +1125,10 @@ int drm_mode_getconnector(struct drm_device *dev, out_resp->mm_height = connector->display_info.height_mm; out_resp->subpixel = connector->display_info.subpixel_order; out_resp->connection = connector->status; - if (connector->crtc) - out_resp->crtc = connector->crtc->id; + if (connector->encoder) + out_resp->encoder = connector->encoder->id; else - out_resp->crtc = 0; + out_resp->encoder = 0; if ((out_resp->count_modes >= mode_count) && mode_count) { copied = 0; @@ -1220,6 +1202,10 @@ int drm_mode_getencoder(struct drm_device *dev, goto out; } + if (encoder->crtc) + enc_resp->crtc = encoder->crtc->id; + else + enc_resp->crtc = 0; enc_resp->encoder_type = encoder->encoder_type; enc_resp->encoder_id = encoder->id; enc_resp->crtcs = encoder->possible_crtcs; @@ -1630,7 +1616,9 @@ int drm_mode_attachmode_crtc(struct drm_device *dev, struct drm_crtc *crtc, struct drm_display_mode *dup_mode; int need_dup = 0; list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - if (connector->crtc == crtc) { + if (!connector->encoder) + break; + if (connector->encoder->crtc == crtc) { if (need_dup) dup_mode = drm_mode_duplicate(dev, mode); else @@ -2200,7 +2188,7 @@ int drm_mode_connector_attach_encoder(struct drm_connector *connector, connector->encoder_ids[i] = encoder->id; /* pick the first added encoder as the current */ if (i == 0) - connector->current_encoder_id = encoder->id; + connector->encoder = encoder; return 0; } } @@ -2215,6 +2203,8 @@ void drm_mode_connector_detach_encoder(struct drm_connector *connector, for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { if (connector->encoder_ids[i] == encoder->id) { connector->encoder_ids[i] = 0; + if (connector->encoder == encoder) + connector->encoder = NULL; break; } } diff --git a/linux-core/drm_crtc.h b/linux-core/drm_crtc.h index 09886c1..14aa503 100644 --- a/linux-core/drm_crtc.h +++ b/linux-core/drm_crtc.h @@ -304,12 +304,6 @@ struct drm_encoder; * bus accessors. */ struct drm_crtc_funcs { - /* - * Control power levels on the CRTC. If the mode passed in is - * unsupported, the provider must use the next lowest power level. - */ - void (*dpms)(struct drm_crtc *crtc, int mode); - /* Save CRTC state */ void (*save)(struct drm_crtc *crtc); /* suspend? */ /* Restore CRTC state */ @@ -416,6 +410,7 @@ struct drm_encoder { uint32_t possible_crtcs; uint32_t possible_clones; + struct drm_crtc *crtc; const struct drm_encoder_funcs *funcs; void *helper_private; }; @@ -441,7 +436,6 @@ struct drm_connector { struct device kdev; struct device_attribute *attr; struct list_head head; - struct drm_crtc *crtc; int id; /* idr assigned */ int connector_type; @@ -468,7 +462,7 @@ struct drm_connector { uint32_t encoder_ids[DRM_CONNECTOR_MAX_ENCODER]; uint32_t force_encoder_id; - uint32_t current_encoder_id; + struct drm_encoder *encoder; /* currently active encoder */ }; /** @@ -582,7 +576,6 @@ extern void drm_mode_config_init(struct drm_device *dev); extern void drm_mode_config_cleanup(struct drm_device *dev); extern void drm_mode_set_name(struct drm_display_mode *mode); extern bool drm_mode_equal(struct drm_display_mode *mode1, struct drm_display_mode *mode2); -extern void drm_disable_unused_functions(struct drm_device *dev); /* for us by fb module */ extern int drm_mode_attachmode_crtc(struct drm_device *dev, @@ -631,6 +624,7 @@ extern int drm_property_add_enum(struct drm_property *property, int index, uint64_t value, const char *name); extern bool drm_create_tv_properties(struct drm_device *dev, int num_formats, char *formats[]); +extern char *drm_get_encoder_name(struct drm_encoder *encoder); extern int drm_mode_connector_attach_encoder(struct drm_connector *connector, struct drm_encoder *encoder); diff --git a/linux-core/drm_crtc_helper.c b/linux-core/drm_crtc_helper.c index e5774cc..82862b5 100644 --- a/linux-core/drm_crtc_helper.c +++ b/linux-core/drm_crtc_helper.c @@ -34,6 +34,35 @@ #include "drm_crtc.h" #include "drm_crtc_helper.h" +/** + * drm_disable_unused_functions - disable unused objects + * @dev: DRM device + * + * LOCKING: + * Caller must hold mode config lock. + * + * If an connector or CRTC isn't part of @dev's mode_config, it can be disabled + * by calling its dpms function, which should power it off. + */ +void drm_helper_disable_unused_functions(struct drm_device *dev) +{ + struct drm_encoder *encoder; + struct drm_encoder_helper_funcs *encoder_funcs; + struct drm_crtc *crtc; + + list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { + encoder_funcs = encoder->helper_private; + if (!encoder->crtc) + (*encoder_funcs->dpms)(encoder, DPMSModeOff); + } + + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; + if (!crtc->enabled) + crtc_funcs->dpms(crtc, DPMSModeOff); + } +} +EXPORT_SYMBOL(drm_helper_disable_unused_functions); /** * drm_pick_crtcs - pick crtcs for connector devices @@ -52,7 +81,7 @@ static void drm_pick_crtcs (struct drm_device *dev) int found; list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - connector->crtc = NULL; + connector->encoder->crtc = NULL; /* Don't hook up connectors that are disconnected ?? * @@ -90,9 +119,7 @@ static void drm_pick_crtcs (struct drm_device *dev) } } - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) - if (encoder->id == connector->current_encoder_id) - break; + encoder = connector->encoder; c = -1; list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { @@ -107,7 +134,7 @@ static void drm_pick_crtcs (struct drm_device *dev) continue; /* Find out if crtc has been assigned before */ - if (connector_equal->crtc == crtc) + if (connector_equal->encoder->crtc == crtc) assigned = 1; } @@ -122,14 +149,12 @@ static void drm_pick_crtcs (struct drm_device *dev) if (connector->id == connector_equal->id) continue; - list_for_each_entry(encoder_equal, &dev->mode_config.encoder_list, head) - if (encoder_equal->id == connector_equal->current_encoder_id) - break; + encoder_equal = connector_equal->encoder; list_for_each_entry(modes, &connector->modes, head) { list_for_each_entry(modes_equal, &connector_equal->modes, head) { if (drm_mode_equal (modes, modes_equal)) { - if ((encoder->possible_clones & encoder_equal->possible_clones) && (connector_equal->crtc == crtc)) { + if ((encoder->possible_clones & encoder_equal->possible_clones) && (connector_equal->encoder->crtc == crtc)) { printk("Cloning %s (0x%lx) to %s (0x%lx)\n",drm_get_connector_name(connector),encoder->possible_clones,drm_get_connector_name(connector_equal),encoder_equal->possible_clones); des_mode = modes; assigned = 0; @@ -146,8 +171,8 @@ clone: continue; /* Found a CRTC to attach to, do it ! */ - connector->crtc = crtc; - connector->crtc->desired_mode = des_mode; + connector->encoder->crtc = crtc; + connector->encoder->crtc->desired_mode = des_mode; connector->initial_x = 0; connector->initial_y = 0; DRM_DEBUG("Desired mode for CRTC %d is 0x%x:%s\n",c,des_mode->mode_id, des_mode->name); @@ -179,9 +204,9 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mo struct drm_device *dev = crtc->dev; struct drm_display_mode *adjusted_mode, saved_mode; struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; - struct drm_connector_helper_funcs *connector_funcs; + struct drm_encoder_helper_funcs *encoder_funcs; int saved_x, saved_y; - struct drm_connector *connector; + struct drm_encoder *encoder; bool ret = true; adjusted_mode = drm_mode_duplicate(dev, mode); @@ -213,12 +238,12 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mo * adjust it according to limitations or connector properties, and also * a chance to reject the mode entirely. */ - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - if (connector->crtc != crtc) + if (encoder->crtc != crtc) continue; - connector_funcs = connector->helper_private; - if (!(ret = connector_funcs->mode_fixup(connector, mode, adjusted_mode))) { + encoder_funcs = encoder->helper_private; + if (!(ret = encoder_funcs->mode_fixup(encoder, mode, adjusted_mode))) { goto done; } } @@ -227,48 +252,44 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mo goto done; } - /* Prepare the connectors and CRTCs before setting the mode. */ - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + /* Prepare the encoders and CRTCs before setting the mode. */ + list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - if (connector->crtc != crtc) + if (encoder->crtc != crtc) continue; - connector_funcs = connector->helper_private; - /* Disable the connector as the first thing we do. */ - connector_funcs->prepare(connector); + encoder_funcs = encoder->helper_private; + /* Disable the encoders as the first thing we do. */ + encoder_funcs->prepare(encoder); } crtc_funcs->prepare(crtc); - /* Set up the DPLL and any connector state that needs to adjust or depend + /* Set up the DPLL and any encoders state that needs to adjust or depend * on the DPLL. */ crtc_funcs->mode_set(crtc, mode, adjusted_mode, x, y); - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - if (connector->crtc != crtc) + if (encoder->crtc != crtc) continue; - DRM_INFO("%s: set mode %s %x\n", drm_get_connector_name(connector), mode->name, mode->mode_id); - connector_funcs = connector->helper_private; - connector_funcs->mode_set(connector, mode, adjusted_mode); + DRM_INFO("%s: set mode %s %x\n", drm_get_encoder_name(encoder), mode->name, mode->mode_id); + encoder_funcs = encoder->helper_private; + encoder_funcs->mode_set(encoder, mode, adjusted_mode); } /* Now, enable the clocks, plane, pipe, and connectors that we set up. */ crtc_funcs->commit(crtc); - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - if (connector->crtc != crtc) + if (encoder->crtc != crtc) continue; - connector_funcs = connector->helper_private; - connector_funcs->commit(connector); + encoder_funcs = encoder->helper_private; + encoder_funcs->commit(encoder); -#if 0 // TODO def RANDR_12_INTERFACE - if (connector->randr_connector) - RRPostPendingProperties (connector->randr_connector); -#endif } /* XXX free adjustedmode */ @@ -357,20 +378,23 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) } list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - save_crtcs[count++] = connector->crtc; + if (!connector->encoder) + continue; - if (connector->crtc == set->crtc) + save_crtcs[count++] = connector->encoder->crtc; + + if (connector->encoder->crtc == set->crtc) new_crtc = NULL; else - new_crtc = connector->crtc; + new_crtc = connector->encoder->crtc; for (ro = 0; ro < set->num_connectors; ro++) { if (set->connectors[ro] == connector) new_crtc = set->crtc; } - if (new_crtc != connector->crtc) { + if (new_crtc != connector->encoder->crtc) { changed = true; - connector->crtc = new_crtc; + connector->encoder->crtc = new_crtc; } } @@ -389,7 +413,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) set->crtc->enabled = save_enabled; count = 0; list_for_each_entry(connector, &dev->mode_config.connector_list, head) - connector->crtc = save_crtcs[count++]; + connector->encoder->crtc = save_crtcs[count++]; kfree(save_crtcs); return -EINVAL; } @@ -398,7 +422,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) set->crtc->desired_y = set->y; set->crtc->desired_mode = set->mode; } - drm_disable_unused_functions(dev); + drm_helper_disable_unused_functions(dev); } else if (flip_or_move) { if (set->crtc->fb != set->fb) set->crtc->fb = set->fb; @@ -444,18 +468,19 @@ bool drm_helper_initial_config(struct drm_device *dev, bool can_grow) */ list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + struct drm_crtc *crtc = connector->encoder->crtc; /* can't setup the connector if there's no assigned mode */ - if (!connector->crtc || !connector->crtc->desired_mode) + if (!crtc || !crtc->desired_mode) continue; - dev->driver->fb_probe(dev, connector->crtc, connector); + dev->driver->fb_probe(dev, crtc, connector); /* and needs an attached fb */ - if (connector->crtc->fb) - drm_crtc_helper_set_mode(connector->crtc, connector->crtc->desired_mode, 0, 0); + if (crtc->fb) + drm_crtc_helper_set_mode(crtc, crtc->desired_mode, 0, 0); } - drm_disable_unused_functions(dev); + drm_helper_disable_unused_functions(dev); mutex_unlock(&dev->mode_config.mutex); return ret; @@ -488,7 +513,7 @@ int drm_helper_hotplug_stage_two(struct drm_device *dev, struct drm_connector *c return 0; } - if (connector->crtc && connector->crtc->desired_mode) { + if (connector->encoder->crtc && connector->encoder->crtc->desired_mode) { DRM_DEBUG("drm thinks that the connector already has a config\n"); has_config = 1; } @@ -498,27 +523,28 @@ int drm_helper_hotplug_stage_two(struct drm_device *dev, struct drm_connector *c if (!has_config) drm_pick_crtcs(dev); - if (!connector->crtc || !connector->crtc->desired_mode) { + if (!connector->encoder->crtc || !connector->encoder->crtc->desired_mode) { DRM_DEBUG("could not find a desired mode or crtc for connector\n"); return 1; } /* We should really check if there is a fb using this crtc */ if (!has_config) - dev->driver->fb_probe(dev, connector->crtc, connector); + dev->driver->fb_probe(dev, connector->encoder->crtc, connector); else { - dev->driver->fb_resize(dev, connector->crtc); + dev->driver->fb_resize(dev, connector->encoder->crtc); #if 0 - if (!drm_crtc_set_mode(connector->crtc, connector->crtc->desired_mode, 0, 0)) + if (!drm_crtc_set_mode(connector->encoder->crtc, connector->encoder->crtc->desired_mode, 0, 0)) DRM_ERROR("failed to set mode after hotplug\n"); #endif } drm_sysfs_hotplug_event(dev); - drm_disable_unused_functions(dev); + drm_helper_disable_unused_functions(dev); return 0; } EXPORT_SYMBOL(drm_helper_hotplug_stage_two); + diff --git a/linux-core/drm_crtc_helper.h b/linux-core/drm_crtc_helper.h index 1042006..063d1f7 100644 --- a/linux-core/drm_crtc_helper.h +++ b/linux-core/drm_crtc_helper.h @@ -21,6 +21,11 @@ #include struct drm_crtc_helper_funcs { + /* + * Control power levels on the CRTC. If the mode passed in is + * unsupported, the provider must use the next lowest power level. + */ + void (*dpms)(struct drm_crtc *crtc, int mode); void (*prepare)(struct drm_crtc *crtc); void (*commit)(struct drm_crtc *crtc); @@ -36,26 +41,23 @@ struct drm_crtc_helper_funcs { void (*mode_set_base)(struct drm_crtc *crtc, int x, int y); }; -struct drm_connector_helper_funcs { - bool (*mode_fixup)(struct drm_connector *connector, +struct drm_encoder_helper_funcs { + void (*dpms)(struct drm_encoder *encoder, int mode); + void (*save)(struct drm_encoder *encoder); + void (*restore)(struct drm_encoder *encoder); + + bool (*mode_fixup)(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode); - void (*prepare)(struct drm_connector *connector); - void (*commit)(struct drm_connector *connector); - void (*mode_set)(struct drm_connector *connector, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode); -}; - -struct drm_encoder_helper_funcs { - void (*prepare)(struct drm_connector *connector); - void (*commit)(struct drm_connector *connector); - void (*mode_set)(struct drm_connector *connector, + void (*prepare)(struct drm_encoder *encoder); + void (*commit)(struct drm_encoder *encoder); + void (*mode_set)(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode); }; +extern void drm_helper_disable_unused_functions(struct drm_device *dev); extern int drm_helper_hotplug_stage_two(struct drm_device *dev, struct drm_connector *connector, bool connected); extern bool drm_helper_initial_config(struct drm_device *dev, bool can_grow); @@ -68,9 +70,9 @@ static inline void drm_crtc_helper_add(struct drm_crtc *crtc, const struct drm_c crtc->helper_private = (void *)funcs; } -static inline void drm_connector_helper_add(struct drm_connector *connector, const struct drm_connector_helper_funcs *funcs) +static inline void drm_encoder_helper_add(struct drm_encoder *encoder, const struct drm_encoder_helper_funcs *funcs) { - connector->helper_private = (void *)funcs; + encoder->helper_private = (void *)funcs; } diff --git a/linux-core/intel_crt.c b/linux-core/intel_crt.c index a98f700..ec4c2bf 100644 --- a/linux-core/intel_crt.c +++ b/linux-core/intel_crt.c @@ -33,9 +33,9 @@ #include "i915_drm.h" #include "i915_drv.h" -static void intel_crt_dpms(struct drm_connector *connector, int mode) +static void intel_crt_dpms(struct drm_encoder *encoder, int mode) { - struct drm_device *dev = connector->dev; + struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; u32 temp; @@ -83,19 +83,20 @@ static int intel_crt_mode_valid(struct drm_connector *connector, return MODE_OK; } -static bool intel_crt_mode_fixup(struct drm_connector *connector, +static bool intel_crt_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { return true; } -static void intel_crt_mode_set(struct drm_connector *connector, +static void intel_crt_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { - struct drm_device *dev = connector->dev; - struct drm_crtc *crtc = connector->crtc; + + struct drm_device *dev = encoder->dev; + struct drm_crtc *crtc = encoder->crtc; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct drm_i915_private *dev_priv = dev->dev_private; int dpll_md_reg; @@ -214,8 +215,8 @@ static bool intel_crt_set_property(struct drm_connector *connector, { struct drm_device *dev = connector->dev; - if (property == dev->mode_config.dpms_property) - intel_crt_dpms(connector, (uint32_t)(value & 0xf)); + if (property == dev->mode_config.dpms_property && connector->encoder) + intel_crt_dpms(connector->encoder, (uint32_t)(value & 0xf)); return true; } @@ -224,15 +225,15 @@ static bool intel_crt_set_property(struct drm_connector *connector, * Routines for controlling stuff on the analog port */ -static const struct drm_connector_helper_funcs intel_crt_helper_funcs = { +static const struct drm_encoder_helper_funcs intel_crt_helper_funcs = { + .dpms = intel_crt_dpms, .mode_fixup = intel_crt_mode_fixup, - .prepare = intel_connector_prepare, - .commit = intel_connector_commit, + .prepare = intel_encoder_prepare, + .commit = intel_encoder_commit, .mode_set = intel_crt_mode_set, }; static const struct drm_connector_funcs intel_crt_connector_funcs = { - .dpms = intel_crt_dpms, .save = intel_crt_save, .restore = intel_crt_restore, .detect = intel_crt_detect, @@ -281,7 +282,7 @@ void intel_crt_init(struct drm_device *dev) connector->interlace_allowed = 0; connector->doublescan_allowed = 0; - drm_connector_helper_add(connector, &intel_crt_helper_funcs); + drm_encoder_helper_add(&intel_output->enc, &intel_crt_helper_funcs); drm_sysfs_connector_add(connector); diff --git a/linux-core/intel_display.c b/linux-core/intel_display.c index f0cbc38..c1cb2bf 100644 --- a/linux-core/intel_display.c +++ b/linux-core/intel_display.c @@ -228,7 +228,7 @@ bool intel_pipe_has_type (struct drm_crtc *crtc, int type) struct drm_connector *l_entry; list_for_each_entry(l_entry, &mode_config->connector_list, head) { - if (l_entry->crtc == crtc) { + if (l_entry->encoder->crtc == crtc) { struct intel_output *intel_output = to_intel_output(l_entry); if (intel_output->type == type) return true; @@ -575,24 +575,28 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode) static void intel_crtc_prepare (struct drm_crtc *crtc) { - crtc->funcs->dpms(crtc, DPMSModeOff); + struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; + crtc_funcs->dpms(crtc, DPMSModeOff); } static void intel_crtc_commit (struct drm_crtc *crtc) { - crtc->funcs->dpms(crtc, DPMSModeOn); + struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; + crtc_funcs->dpms(crtc, DPMSModeOn); } -void intel_connector_prepare (struct drm_connector *connector) +void intel_encoder_prepare (struct drm_encoder *encoder) { + struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; /* lvds has its own version of prepare see intel_lvds_prepare */ - connector->funcs->dpms(connector, DPMSModeOff); + encoder_funcs->dpms(encoder, DPMSModeOff); } -void intel_connector_commit (struct drm_connector *connector) +void intel_encoder_commit (struct drm_encoder *encoder) { + struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; /* lvds has its own version of commit see intel_lvds_commit */ - connector->funcs->dpms(connector, DPMSModeOn); + encoder_funcs->dpms(encoder, DPMSModeOn); } static bool intel_crtc_mode_fixup(struct drm_crtc *crtc, @@ -721,7 +725,7 @@ static void intel_crtc_mode_set(struct drm_crtc *crtc, list_for_each_entry(connector, &mode_config->connector_list, head) { struct intel_output *intel_output = to_intel_output(connector); - if (connector->crtc != crtc) + if (!connector->encoder || connector->encoder->crtc != crtc) continue; switch (intel_output->type) { @@ -1082,18 +1086,18 @@ static struct drm_display_mode load_detect_mode = { 704, 832, 0, 480, 489, 491, 520, 0, V_NHSYNC | V_NVSYNC), }; -struct drm_crtc *intel_get_load_detect_pipe(struct drm_connector *connector, +struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output, struct drm_display_mode *mode, int *dpms_mode) { - struct drm_device *dev = connector->dev; - struct intel_output *intel_output = to_intel_output(connector); struct intel_crtc *intel_crtc; struct drm_crtc *possible_crtc; struct drm_crtc *supported_crtc =NULL; - struct drm_encoder *encoder = NULL; + struct drm_encoder *encoder = &intel_output->enc; struct drm_crtc *crtc = NULL; - struct drm_connector_helper_funcs *connector_funcs; + struct drm_device *dev = encoder->dev; + struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; + struct drm_crtc_helper_funcs *crtc_funcs; int i = -1; /* @@ -1107,22 +1111,19 @@ struct drm_crtc *intel_get_load_detect_pipe(struct drm_connector *connector, */ /* See if we already have a CRTC for this connector */ - if (connector->crtc) { - crtc = connector->crtc; + if (encoder->crtc) { + crtc = encoder->crtc; /* Make sure the crtc and connector are running */ intel_crtc = to_intel_crtc(crtc); *dpms_mode = intel_crtc->dpms_mode; if (intel_crtc->dpms_mode != DPMSModeOn) { - crtc->funcs->dpms(crtc, DPMSModeOn); - connector->funcs->dpms(connector, DPMSModeOn); + crtc_funcs = crtc->helper_private; + crtc_funcs->dpms(crtc, DPMSModeOn); + encoder_funcs->dpms(encoder, DPMSModeOn); } return crtc; } - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) - if (encoder->id == connector->current_encoder_id) - break; - /* Find an unused one (if possible) */ list_for_each_entry(possible_crtc, &dev->mode_config.crtc_list, head) { i++; @@ -1146,7 +1147,7 @@ struct drm_crtc *intel_get_load_detect_pipe(struct drm_connector *connector, return NULL; } - connector->crtc = crtc; + encoder->crtc = crtc; intel_output->load_detect_temp = TRUE; intel_crtc = to_intel_crtc(crtc); @@ -1157,13 +1158,14 @@ struct drm_crtc *intel_get_load_detect_pipe(struct drm_connector *connector, mode = &load_detect_mode; drm_crtc_helper_set_mode(crtc, mode, 0, 0); } else { - if (intel_crtc->dpms_mode != DPMSModeOn) - crtc->funcs->dpms(crtc, DPMSModeOn); + if (intel_crtc->dpms_mode != DPMSModeOn) { + crtc_funcs = crtc->helper_private; + crtc_funcs->dpms(crtc, DPMSModeOn); + } - connector_funcs = connector->helper_private; /* Add this connector to the crtc */ - connector_funcs->mode_set(connector, &crtc->mode, &crtc->mode); - connector_funcs->commit(connector); + encoder_funcs->mode_set(encoder, &crtc->mode, &crtc->mode); + encoder_funcs->commit(encoder); } /* let the connector get through one full cycle before testing */ intel_wait_for_vblank(dev); @@ -1171,24 +1173,26 @@ struct drm_crtc *intel_get_load_detect_pipe(struct drm_connector *connector, return crtc; } -void intel_release_load_detect_pipe(struct drm_connector *connector, int dpms_mode) +void intel_release_load_detect_pipe(struct intel_output *intel_output, int dpms_mode) { - struct drm_device *dev = connector->dev; - struct intel_output *intel_output = to_intel_output(connector); - struct drm_crtc *crtc = connector->crtc; + struct drm_encoder *encoder = &intel_output->enc; + struct drm_device *dev = encoder->dev; + struct drm_crtc *crtc = encoder->crtc; + struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; + struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; if (intel_output->load_detect_temp) { - connector->crtc = NULL; + encoder->crtc = NULL; intel_output->load_detect_temp = FALSE; crtc->enabled = drm_crtc_in_use(crtc); - drm_disable_unused_functions(dev); + drm_helper_disable_unused_functions(dev); } /* Switch crtc and output back off if necessary */ if (crtc->enabled && dpms_mode != DPMSModeOn) { - if (connector->crtc == crtc) - connector->funcs->dpms(connector, dpms_mode); - crtc->funcs->dpms(crtc, dpms_mode); + if (encoder->crtc == crtc) + encoder_funcs->dpms(encoder, dpms_mode); + crtc_funcs->dpms(crtc, dpms_mode); } } @@ -1311,6 +1315,7 @@ static void intel_crtc_destroy(struct drm_crtc *crtc) } static const struct drm_crtc_helper_funcs intel_helper_funcs = { + .dpms = intel_crtc_dpms, .mode_fixup = intel_crtc_mode_fixup, .mode_set = intel_crtc_mode_set, .mode_set_base = intel_pipe_set_base, @@ -1319,7 +1324,6 @@ static const struct drm_crtc_helper_funcs intel_helper_funcs = { }; static const struct drm_crtc_funcs intel_crtc_funcs = { - .dpms = intel_crtc_dpms, .cursor_set = intel_crtc_cursor_set, .cursor_move = intel_crtc_cursor_move, .gamma_set = intel_crtc_gamma_set, diff --git a/linux-core/intel_drv.h b/linux-core/intel_drv.h index 4463952..0a5e350 100644 --- a/linux-core/intel_drv.h +++ b/linux-core/intel_drv.h @@ -68,6 +68,7 @@ struct intel_crtc { #define to_intel_crtc(x) container_of(x, struct intel_crtc, base) #define to_intel_output(x) container_of(x, struct intel_output, base) +#define enc_to_intel_output(x) container_of(x, struct intel_output, enc) struct intel_i2c_chan *intel_i2c_create(struct drm_device *dev, const u32 reg, const char *name); @@ -82,16 +83,16 @@ extern void intel_tv_init(struct drm_device *dev); extern void intel_lvds_init(struct drm_device *dev); extern void intel_crtc_load_lut(struct drm_crtc *crtc); -extern void intel_connector_prepare (struct drm_connector *connector); -extern void intel_connector_commit (struct drm_connector *connector); +extern void intel_encoder_prepare (struct drm_encoder *encoder); +extern void intel_encoder_commit (struct drm_encoder *encoder); extern struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, struct drm_crtc *crtc); extern void intel_wait_for_vblank(struct drm_device *dev); extern struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe); -extern struct drm_crtc *intel_get_load_detect_pipe(struct drm_connector *connector, +extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output, struct drm_display_mode *mode, int *dpms_mode); -extern void intel_release_load_detect_pipe(struct drm_connector *connector, +extern void intel_release_load_detect_pipe(struct intel_output *intel_output, int dpms_mode); extern struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB); diff --git a/linux-core/intel_dvo.c b/linux-core/intel_dvo.c index 7fc5cce..364cd65 100644 --- a/linux-core/intel_dvo.c +++ b/linux-core/intel_dvo.c @@ -85,10 +85,10 @@ struct intel_dvo_device intel_dvo_devices[] = { } }; -static void intel_dvo_dpms(struct drm_connector *connector, int mode) +static void intel_dvo_dpms(struct drm_encoder *encoder, int mode) { - struct drm_i915_private *dev_priv = connector->dev->dev_private; - struct intel_output *intel_output = to_intel_output(connector); + struct drm_i915_private *dev_priv = encoder->dev->dev_private; + struct intel_output *intel_output = enc_to_intel_output(encoder); struct intel_dvo_device *dvo = intel_output->dev_priv; u32 dvo_reg = dvo->dvo_reg; u32 temp = I915_READ(dvo_reg); @@ -154,11 +154,11 @@ static int intel_dvo_mode_valid(struct drm_connector *connector, return dvo->dev_ops->mode_valid(dvo, mode); } -static bool intel_dvo_mode_fixup(struct drm_connector *connector, +static bool intel_dvo_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { - struct intel_output *intel_output = to_intel_output(connector); + struct intel_output *intel_output = enc_to_intel_output(encoder); struct intel_dvo_device *dvo = intel_output->dev_priv; /* If we have timings from the BIOS for the panel, put them in @@ -187,14 +187,14 @@ static bool intel_dvo_mode_fixup(struct drm_connector *connector, return true; } -static void intel_dvo_mode_set(struct drm_connector *connector, +static void intel_dvo_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { - struct drm_device *dev = connector->dev; + struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(connector->crtc); - struct intel_output *intel_output = to_intel_output(connector); + struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); + struct intel_output *intel_output = enc_to_intel_output(encoder); struct intel_dvo_device *dvo = intel_output->dev_priv; int pipe = intel_crtc->pipe; u32 dvo_val; @@ -323,15 +323,15 @@ static struct drm_crtc *intel_dvo_get_crtc(struct drm_connector *connector) } #endif -static const struct drm_connector_helper_funcs intel_dvo_helper_funcs = { +static const struct drm_encoder_helper_funcs intel_dvo_helper_funcs = { + .dpms = intel_dvo_dpms, .mode_fixup = intel_dvo_mode_fixup, - .prepare = intel_connector_prepare, + .prepare = intel_encoder_prepare, .mode_set = intel_dvo_mode_set, - .commit = intel_connector_commit, + .commit = intel_encoder_commit, }; static const struct drm_connector_funcs intel_dvo_connector_funcs = { - .dpms = intel_dvo_dpms, .save = intel_dvo_save, .restore = intel_dvo_restore, .detect = intel_dvo_detect, @@ -464,7 +464,6 @@ void intel_dvo_init(struct drm_device *dev) break; } - drm_connector_helper_add(connector, &intel_dvo_helper_funcs); connector->display_info.subpixel_order = SubPixelHorizontalRGB; connector->interlace_allowed = false; connector->doublescan_allowed = false; @@ -473,6 +472,8 @@ void intel_dvo_init(struct drm_device *dev) intel_output->i2c_bus = i2cbus; drm_encoder_init(dev, &intel_output->enc, &intel_dvo_enc_funcs, encoder_type); + drm_encoder_helper_add(&intel_output->enc, &intel_dvo_helper_funcs); + if (dvo->type == INTEL_DVO_CHIP_LVDS) { /* For our LVDS chipsets, we should hopefully be able * to dig the fixed panel mode out of the BIOS data. diff --git a/linux-core/intel_fb.c b/linux-core/intel_fb.c index 394d234..138d189 100644 --- a/linux-core/intel_fb.c +++ b/linux-core/intel_fb.c @@ -277,7 +277,7 @@ static int intelfb_set_par(struct fb_info *info) found = 0; list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - if (connector->crtc == par->set.crtc){ + if (connector->encoder->crtc == par->set.crtc){ found = 1; break; } diff --git a/linux-core/intel_lvds.c b/linux-core/intel_lvds.c index 019c45f..b83f392 100644 --- a/linux-core/intel_lvds.c +++ b/linux-core/intel_lvds.c @@ -89,9 +89,9 @@ static void intel_lvds_set_power(struct drm_device *dev, bool on) } } -static void intel_lvds_dpms(struct drm_connector *connector, int mode) +static void intel_lvds_dpms(struct drm_encoder *encoder, int mode) { - struct drm_device *dev = connector->dev; + struct drm_device *dev = encoder->dev; if (mode == DPMSModeOn) intel_lvds_set_power(dev, true); @@ -155,14 +155,14 @@ static int intel_lvds_mode_valid(struct drm_connector *connector, return MODE_OK; } -static bool intel_lvds_mode_fixup(struct drm_connector *connector, +static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { - struct drm_device *dev = connector->dev; + struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(connector->crtc); - struct drm_connector *tmp_connector; + struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); + struct drm_encoder *tmp_encoder; /* Should never happen!! */ if (!IS_I965G(dev) && intel_crtc->pipe == 0) { @@ -171,10 +171,10 @@ static bool intel_lvds_mode_fixup(struct drm_connector *connector, } /* Should never happen!! */ - list_for_each_entry(tmp_connector, &dev->mode_config.connector_list, head) { - if (tmp_connector != connector && tmp_connector->crtc == connector->crtc) { + list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list, head) { + if (tmp_encoder != encoder && tmp_encoder->crtc == encoder->crtc) { printk(KERN_ERR "Can't enable LVDS and another " - "connector on the same pipe\n"); + "encoder on the same pipe\n"); return false; } } @@ -211,9 +211,9 @@ static bool intel_lvds_mode_fixup(struct drm_connector *connector, return true; } -static void intel_lvds_prepare(struct drm_connector *connector) +static void intel_lvds_prepare(struct drm_encoder *encoder) { - struct drm_device *dev = connector->dev; + struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL); @@ -223,9 +223,9 @@ static void intel_lvds_prepare(struct drm_connector *connector) intel_lvds_set_power(dev, false); } -static void intel_lvds_commit( struct drm_connector *connector) +static void intel_lvds_commit( struct drm_encoder *encoder) { - struct drm_device *dev = connector->dev; + struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; if (dev_priv->backlight_duty_cycle == 0) @@ -235,13 +235,13 @@ static void intel_lvds_commit( struct drm_connector *connector) intel_lvds_set_power(dev, true); } -static void intel_lvds_mode_set(struct drm_connector *connector, +static void intel_lvds_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { - struct drm_device *dev = connector->dev; + struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(connector->crtc); + struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); u32 pfit_control; /* @@ -334,7 +334,8 @@ static void intel_lvds_destroy(struct drm_connector *connector) kfree(connector); } -static const struct drm_connector_helper_funcs intel_lvds_helper_funcs = { +static const struct drm_encoder_helper_funcs intel_lvds_helper_funcs = { + .dpms = intel_lvds_dpms, .mode_fixup = intel_lvds_mode_fixup, .prepare = intel_lvds_prepare, .mode_set = intel_lvds_mode_set, @@ -342,7 +343,6 @@ static const struct drm_connector_helper_funcs intel_lvds_helper_funcs = { }; static const struct drm_connector_funcs intel_lvds_connector_funcs = { - .dpms = intel_lvds_dpms, .save = intel_lvds_save, .restore = intel_lvds_restore, .detect = intel_lvds_detect, @@ -373,6 +373,7 @@ void intel_lvds_init(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; struct intel_output *intel_output; struct drm_connector *connector; + struct drm_encoder *encoder; struct drm_display_mode *scan; /* *modes, *bios_mode; */ struct drm_crtc *crtc; u32 lvds; @@ -384,6 +385,7 @@ void intel_lvds_init(struct drm_device *dev) } connector = &intel_output->base; + encoder = &intel_output->enc; drm_connector_init(dev, &intel_output->base, &intel_lvds_connector_funcs, DRM_MODE_CONNECTOR_LVDS); @@ -392,7 +394,7 @@ void intel_lvds_init(struct drm_device *dev) intel_output->type = INTEL_OUTPUT_LVDS; - drm_connector_helper_add(connector, &intel_lvds_helper_funcs); + drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs); connector->display_info.subpixel_order = SubPixelHorizontalRGB; connector->interlace_allowed = FALSE; connector->doublescan_allowed = FALSE; diff --git a/linux-core/intel_sdvo.c b/linux-core/intel_sdvo.c index 85bee96..498ad98 100644 --- a/linux-core/intel_sdvo.c +++ b/linux-core/intel_sdvo.c @@ -539,7 +539,7 @@ static bool intel_sdvo_set_clock_rate_mult(struct intel_output *intel_output, u8 return true; } -static bool intel_sdvo_mode_fixup(struct drm_connector *connector, +static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { @@ -550,15 +550,15 @@ static bool intel_sdvo_mode_fixup(struct drm_connector *connector, return true; } -static void intel_sdvo_mode_set(struct drm_connector *connector, +static void intel_sdvo_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { - struct drm_device *dev = connector->dev; + struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_crtc *crtc = connector->crtc; + struct drm_crtc *crtc = encoder->crtc; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct intel_output *intel_output = to_intel_output(connector); + struct intel_output *intel_output = enc_to_intel_output(encoder); struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; u16 width, height; u16 h_blank_len, h_sync_len, v_blank_len, v_sync_len; @@ -624,13 +624,13 @@ static void intel_sdvo_mode_set(struct drm_connector *connector, * output the preferred timing, and we don't support that currently. */ #if 0 - success = intel_sdvo_create_preferred_input_timing(connector, clock, + success = intel_sdvo_create_preferred_input_timing(intel_output, clock, width, height); if (success) { struct intel_sdvo_dtd *input_dtd; - intel_sdvo_get_preferred_input_timing(connector, &input_dtd); - intel_sdvo_set_input_timing(connector, &input_dtd); + intel_sdvo_get_preferred_input_timing(intel_output, &input_dtd); + intel_sdvo_set_input_timing(intel_output, &input_dtd); } #else intel_sdvo_set_input_timing(intel_output, &output_dtd); @@ -683,11 +683,11 @@ static void intel_sdvo_mode_set(struct drm_connector *connector, intel_sdvo_write_sdvox(intel_output, sdvox); } -static void intel_sdvo_dpms(struct drm_connector *connector, int mode) +static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) { - struct drm_device *dev = connector->dev; + struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_output *intel_output = to_intel_output(connector); + struct intel_output *intel_output = enc_to_intel_output(encoder); struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; u32 temp; @@ -971,15 +971,15 @@ static void intel_sdvo_destroy(struct drm_connector *connector) kfree(intel_output); } -static const struct drm_connector_helper_funcs intel_sdvo_helper_funcs = { +static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = { + .dpms = intel_sdvo_dpms, .mode_fixup = intel_sdvo_mode_fixup, - .prepare = intel_connector_prepare, + .prepare = intel_encoder_prepare, .mode_set = intel_sdvo_mode_set, - .commit = intel_connector_commit, + .commit = intel_encoder_commit, }; static const struct drm_connector_funcs intel_sdvo_connector_funcs = { - .dpms = intel_sdvo_dpms, .save = intel_sdvo_save, .restore = intel_sdvo_restore, .detect = intel_sdvo_detect, @@ -1022,7 +1022,7 @@ void intel_sdvo_init(struct drm_device *dev, int output_device) sdvo_priv = (struct intel_sdvo_priv *)(intel_output + 1); intel_output->type = INTEL_OUTPUT_SDVO; - drm_connector_helper_add(connector, &intel_sdvo_helper_funcs); + connector->interlace_allowed = 0; connector->doublescan_allowed = 0; @@ -1108,6 +1108,7 @@ void intel_sdvo_init(struct drm_device *dev, int output_device) } drm_encoder_init(dev, &intel_output->enc, &intel_sdvo_enc_funcs, encoder_type); + drm_encoder_helper_add(&intel_output->enc, &intel_sdvo_helper_funcs); connector->connector_type = connector_type; drm_sysfs_connector_add(connector); diff --git a/linux-core/intel_tv.c b/linux-core/intel_tv.c index c2658f1..b13b035 100644 --- a/linux-core/intel_tv.c +++ b/linux-core/intel_tv.c @@ -898,9 +898,9 @@ const static struct tv_mode tv_modes[] = { #define NUM_TV_MODES sizeof(tv_modes) / sizeof (tv_modes[0]) static void -intel_tv_dpms(struct drm_connector *connector, int mode) +intel_tv_dpms(struct drm_encoder *encoder, int mode) { - struct drm_device *dev = connector->dev; + struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; switch(mode) { @@ -972,7 +972,7 @@ intel_tv_restore(struct drm_connector *connector) struct drm_i915_private *dev_priv = dev->dev_private; struct intel_output *intel_output = to_intel_output(connector); struct intel_tv_priv *tv_priv = intel_output->dev_priv; - struct drm_crtc *crtc = connector->crtc; + struct drm_crtc *crtc = connector->encoder->crtc; struct intel_crtc *intel_crtc; int i; @@ -1088,22 +1088,22 @@ intel_tv_mode_valid(struct drm_connector *connector, struct drm_display_mode *mo static bool -intel_tv_mode_fixup(struct drm_connector *connector, struct drm_display_mode *mode, +intel_tv_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { - struct drm_device *dev = connector->dev; + struct drm_device *dev = encoder->dev; struct drm_mode_config *drm_config = &dev->mode_config; - struct intel_output *intel_output = to_intel_output(connector); + struct intel_output *intel_output = enc_to_intel_output(encoder); const struct tv_mode *tv_mode = intel_tv_mode_find (intel_output); - struct drm_connector *other_connector; + struct drm_encoder *other_encoder; if (!tv_mode) return FALSE; - /* FIXME: lock connector list */ - list_for_each_entry(other_connector, &drm_config->connector_list, head) { - if (other_connector != connector && - other_connector->crtc == connector->crtc) + /* FIXME: lock encoder list */ + list_for_each_entry(other_encoder, &drm_config->encoder_list, head) { + if (other_encoder != encoder && + other_encoder->crtc == encoder->crtc) return FALSE; } @@ -1112,14 +1112,14 @@ intel_tv_mode_fixup(struct drm_connector *connector, struct drm_display_mode *mo } static void -intel_tv_mode_set(struct drm_connector *connector, struct drm_display_mode *mode, +intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { - struct drm_device *dev = connector->dev; + struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_crtc *crtc = connector->crtc; + struct drm_crtc *crtc = encoder->crtc; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct intel_output *intel_output = to_intel_output(connector); + struct intel_output *intel_output = enc_to_intel_output(encoder); struct intel_tv_priv *tv_priv = intel_output->dev_priv; const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output); u32 tv_ctl; @@ -1356,11 +1356,11 @@ static const struct drm_display_mode reported_modes[] = { * \return FALSE if TV is disconnected. */ static int -intel_tv_detect_type (struct drm_crtc *crtc, struct drm_connector *connector) +intel_tv_detect_type (struct drm_crtc *crtc, struct intel_output *intel_output) { - struct drm_device *dev = connector->dev; + struct drm_encoder *encoder = &intel_output->enc; + struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_output *intel_output = to_intel_output(connector); u32 pipeastat, pipeastat_save; u32 tv_ctl, save_tv_ctl; u32 tv_dac, save_tv_dac; @@ -1443,19 +1443,20 @@ intel_tv_detect(struct drm_connector *connector) struct drm_display_mode mode; struct intel_output *intel_output = to_intel_output(connector); struct intel_tv_priv *tv_priv = intel_output->dev_priv; + struct drm_encoder *encoder = &intel_output->enc; int dpms_mode; int type = tv_priv->type; mode = reported_modes[0]; drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V); - if (connector->crtc) { - type = intel_tv_detect_type(connector->crtc, connector); + if (encoder->crtc) { + type = intel_tv_detect_type(encoder->crtc, intel_output); } else { - crtc = intel_get_load_detect_pipe(connector, &mode, &dpms_mode); + crtc = intel_get_load_detect_pipe(intel_output, &mode, &dpms_mode); if (crtc) { - type = intel_tv_detect_type(crtc, connector); - intel_release_load_detect_pipe(connector, dpms_mode); + type = intel_tv_detect_type(crtc, intel_output); + intel_release_load_detect_pipe(intel_output, dpms_mode); } else type = -1; } @@ -1585,26 +1586,26 @@ intel_tv_set_property(struct drm_connector *connector, struct drm_property *prop goto out; } tv_priv->tv_format = tv_modes[val].name; - intel_tv_mode_set(connector, NULL, NULL); + intel_tv_mode_set(&intel_output->enc, NULL, NULL); } else { ret = -EINVAL; goto out; } - intel_tv_mode_set(connector, NULL, NULL); + intel_tv_mode_set(&intel_output->enc, NULL, NULL); out: return ret; } -static const struct drm_connector_helper_funcs intel_tv_helper_funcs = { +static const struct drm_encoder_helper_funcs intel_tv_helper_funcs = { + .dpms = intel_tv_dpms, .mode_fixup = intel_tv_mode_fixup, - .prepare = intel_connector_prepare, + .prepare = intel_encoder_prepare, .mode_set = intel_tv_mode_set, - .commit = intel_connector_commit, + .commit = intel_encoder_commit, }; static const struct drm_connector_funcs intel_tv_connector_funcs = { - .dpms = intel_tv_dpms, .save = intel_tv_save, .restore = intel_tv_restore, .mode_valid = intel_tv_mode_valid, @@ -1693,7 +1694,7 @@ intel_tv_init(struct drm_device *dev) tv_priv->tv_format = kstrdup(tv_modes[initial_mode].name, GFP_KERNEL); - drm_connector_helper_add(connector, &intel_tv_helper_funcs); + drm_encoder_helper_add(&intel_output->enc, &intel_tv_helper_funcs); connector->interlace_allowed = FALSE; connector->doublescan_allowed = FALSE; diff --git a/shared-core/drm.h b/shared-core/drm.h index 1fcbf14..7e94fb8 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -1058,6 +1058,7 @@ struct drm_mode_get_encoder { uint32_t encoder_type; uint32_t encoder_id; + unsigned int crtc; /**< Id of crtc */ uint32_t crtcs; uint32_t clones; }; @@ -1079,8 +1080,8 @@ struct drm_mode_get_connector { int count_props; int count_encoders; + unsigned int encoder; /**< Current Encoder */ unsigned int connector; /**< Id */ - unsigned int crtc; /**< Id of crtc */ unsigned int connector_type; unsigned int connector_type_id; -- 2.7.4