diff options
| author | Dave Airlie <airlied@redhat.com> | 2016-01-18 07:01:16 +1000 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2016-01-18 07:01:16 +1000 |
| commit | 28f03607bb2e7a3dab71d0a377fd13f6ed3ebb9f (patch) | |
| tree | e087773adcc9fc9e64576c1a9927353c94d69beb | |
| parent | e9c5e7402dad6f4f04c2430db6f283512bcd4392 (diff) | |
| parent | 4314e19ef4ae0ba8872bd8610f6fef5e8743e236 (diff) | |
| download | linux-28f03607bb2e7a3dab71d0a377fd13f6ed3ebb9f.tar.gz linux-28f03607bb2e7a3dab71d0a377fd13f6ed3ebb9f.tar.bz2 linux-28f03607bb2e7a3dab71d0a377fd13f6ed3ebb9f.zip | |
Merge tag 'topic/drm-misc-2016-01-17' of git://anongit.freedesktop.org/drm-intel into drm-next
Since your main drm-next pull isn't out of the door yet I figured I might
as well flush out drm-misc instead of delaying for 4.6. It's really just
random stuff all over, biggest thing probably connector_mask tracking from
Maarten.
* tag 'topic/drm-misc-2016-01-17' of git://anongit.freedesktop.org/drm-intel: (24 commits)
drm/fb_cma_helper: Remove implicit call to disable_unused_functions
drm/sysfs: use kobj_to_dev()
drm/i915: Init power domains early in driver load
drm: Do not set connector->encoder in drivers
apple-gmux: Add initial documentation
drm: move MODULE_PARM_DESC to other file
drm/edid: index CEA/HDMI mode tables using the VIC
drm/atomic: Remove drm_atomic_connectors_for_crtc.
drm/i915: Update connector_mask during readout, v2.
drm: Remove opencoded drm_gem_object_release_handle()
drm: Do not set outparam on error during GEM handle allocation
drm/docs: more leftovers from the big vtable documentation pile
drm/atomic-helper: Reject legacy flips on a disabled pipe
drm/atomic: add connector mask to drm_crtc_state.
drm/tegra: Use __drm_atomic_helper_reset_connector for subclassing connector state, v2.
drm/atomic: Add __drm_atomic_helper_connector_reset, v2.
drm/i915: Set connector_state->connector using the helper.
drm: Use a normal idr allocation for the obj->name
drm: Only bump object-reference count when adding first handle
drm: Balance error path for GEM handle allocation
...
32 files changed, 437 insertions, 387 deletions
diff --git a/Documentation/DocBook/gpu.tmpl b/Documentation/DocBook/gpu.tmpl index 6c6e81a9eaf4..a8669330b456 100644 --- a/Documentation/DocBook/gpu.tmpl +++ b/Documentation/DocBook/gpu.tmpl @@ -1579,194 +1579,6 @@ void intel_crt_init(struct drm_device *dev) entities. </para> <sect2> - <title>Legacy CRTC Helper Operations</title> - <itemizedlist> - <listitem id="drm-helper-crtc-mode-fixup"> - <synopsis>bool (*mode_fixup)(struct drm_crtc *crtc, - const struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode);</synopsis> - <para> - Let CRTCs adjust the requested mode or reject it completely. This - operation returns true if the mode is accepted (possibly after being - adjusted) or false if it is rejected. - </para> - <para> - The <methodname>mode_fixup</methodname> operation should reject the - mode if it can't reasonably use it. The definition of "reasonable" - is currently fuzzy in this context. One possible behaviour would be - to set the adjusted mode to the panel timings when a fixed-mode - panel is used with hardware capable of scaling. Another behaviour - would be to accept any input mode and adjust it to the closest mode - supported by the hardware (FIXME: This needs to be clarified). - </para> - </listitem> - <listitem> - <synopsis>int (*mode_set_base)(struct drm_crtc *crtc, int x, int y, - struct drm_framebuffer *old_fb)</synopsis> - <para> - Move the CRTC on the current frame buffer (stored in - <literal>crtc->fb</literal>) to position (x,y). Any of the frame - buffer, x position or y position may have been modified. - </para> - <para> - This helper operation is optional. If not provided, the - <function>drm_crtc_helper_set_config</function> function will fall - back to the <methodname>mode_set</methodname> helper operation. - </para> - <note><para> - FIXME: Why are x and y passed as arguments, as they can be accessed - through <literal>crtc->x</literal> and - <literal>crtc->y</literal>? - </para></note> - </listitem> - <listitem> - <synopsis>void (*prepare)(struct drm_crtc *crtc);</synopsis> - <para> - Prepare the CRTC for mode setting. This operation is called after - validating the requested mode. Drivers use it to perform - device-specific operations required before setting the new mode. - </para> - </listitem> - <listitem> - <synopsis>int (*mode_set)(struct drm_crtc *crtc, struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode, int x, int y, - struct drm_framebuffer *old_fb);</synopsis> - <para> - Set a new mode, position and frame buffer. Depending on the device - requirements, the mode can be stored internally by the driver and - applied in the <methodname>commit</methodname> operation, or - programmed to the hardware immediately. - </para> - <para> - The <methodname>mode_set</methodname> operation returns 0 on success - or a negative error code if an error occurs. - </para> - </listitem> - <listitem> - <synopsis>void (*commit)(struct drm_crtc *crtc);</synopsis> - <para> - Commit a mode. This operation is called after setting the new mode. - Upon return the device must use the new mode and be fully - operational. - </para> - </listitem> - </itemizedlist> - </sect2> - <sect2> - <title>Encoder Helper Operations</title> - <itemizedlist> - <listitem> - <synopsis>bool (*mode_fixup)(struct drm_encoder *encoder, - const struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode);</synopsis> - <para> - Let encoders adjust the requested mode or reject it completely. This - operation returns true if the mode is accepted (possibly after being - adjusted) or false if it is rejected. See the - <link linkend="drm-helper-crtc-mode-fixup">mode_fixup CRTC helper - operation</link> for an explanation of the allowed adjustments. - </para> - </listitem> - <listitem> - <synopsis>void (*prepare)(struct drm_encoder *encoder);</synopsis> - <para> - Prepare the encoder for mode setting. This operation is called after - validating the requested mode. Drivers use it to perform - device-specific operations required before setting the new mode. - </para> - </listitem> - <listitem> - <synopsis>void (*mode_set)(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode);</synopsis> - <para> - Set a new mode. Depending on the device requirements, the mode can - be stored internally by the driver and applied in the - <methodname>commit</methodname> operation, or programmed to the - hardware immediately. - </para> - </listitem> - <listitem> - <synopsis>void (*commit)(struct drm_encoder *encoder);</synopsis> - <para> - Commit a mode. This operation is called after setting the new mode. - Upon return the device must use the new mode and be fully - operational. - </para> - </listitem> - </itemizedlist> - </sect2> - <sect2> - <title>Connector Helper Operations</title> - <itemizedlist> - <listitem> - <synopsis>struct drm_encoder *(*best_encoder)(struct drm_connector *connector);</synopsis> - <para> - Return a pointer to the best encoder for the connecter. Device that - map connectors to encoders 1:1 simply return the pointer to the - associated encoder. This operation is mandatory. - </para> - </listitem> - <listitem> - <synopsis>int (*get_modes)(struct drm_connector *connector);</synopsis> - <para> - Fill the connector's <structfield>probed_modes</structfield> list - by parsing EDID data with <function>drm_add_edid_modes</function>, - adding standard VESA DMT modes with <function>drm_add_modes_noedid</function>, - or calling <function>drm_mode_probed_add</function> directly for every - supported mode and return the number of modes it has detected. This - operation is mandatory. - </para> - <para> - Note that the caller function will automatically add standard VESA - DMT modes up to 1024x768 if the <methodname>get_modes</methodname> - helper operation returns no mode and if the connector status is - connector_status_connected. There is no need to call - <function>drm_add_edid_modes</function> manually in that case. - </para> - <para> - The <structfield>vrefresh</structfield> value is computed by - <function>drm_helper_probe_single_connector_modes</function>. - </para> - <para> - When parsing EDID data, <function>drm_add_edid_modes</function> fills the - connector <structfield>display_info</structfield> - <structfield>width_mm</structfield> and - <structfield>height_mm</structfield> fields. When creating modes - manually the <methodname>get_modes</methodname> helper operation must - set the <structfield>display_info</structfield> - <structfield>width_mm</structfield> and - <structfield>height_mm</structfield> fields if they haven't been set - already (for instance at initialization time when a fixed-size panel is - attached to the connector). The mode <structfield>width_mm</structfield> - and <structfield>height_mm</structfield> fields are only used internally - during EDID parsing and should not be set when creating modes manually. - </para> - </listitem> - <listitem> - <synopsis>int (*mode_valid)(struct drm_connector *connector, - struct drm_display_mode *mode);</synopsis> - <para> - Verify whether a mode is valid for the connector. Return MODE_OK for - supported modes and one of the enum drm_mode_status values (MODE_*) - for unsupported modes. This operation is optional. - </para> - <para> - As the mode rejection reason is currently not used beside for - immediately removing the unsupported mode, an implementation can - return MODE_BAD regardless of the exact reason why the mode is not - valid. - </para> - <note><para> - Note that the <methodname>mode_valid</methodname> helper operation is - only called for modes detected by the device, and - <emphasis>not</emphasis> for modes set by the user through the CRTC - <methodname>set_config</methodname> operation. - </para></note> - </listitem> - </itemizedlist> - </sect2> - <sect2> <title>Atomic Modeset Helper Functions Reference</title> <sect3> <title>Overview</title> @@ -3625,41 +3437,63 @@ int num_ioctls;</synopsis> <chapter id="modes_of_use"> <title>Modes of Use</title> - <sect1> - <title>Manual switching and manual power control</title> + <sect1> + <title>Manual switching and manual power control</title> !Pdrivers/gpu/vga/vga_switcheroo.c Manual switching and manual power control - </sect1> - <sect1> - <title>Driver power control</title> + </sect1> + <sect1> + <title>Driver power control</title> !Pdrivers/gpu/vga/vga_switcheroo.c Driver power control - </sect1> + </sect1> </chapter> - <chapter id="pubfunctions"> - <title>Public functions</title> + <chapter id="api"> + <title>API</title> + <sect1> + <title>Public functions</title> !Edrivers/gpu/vga/vga_switcheroo.c - </chapter> - - <chapter id="pubstructures"> - <title>Public structures</title> + </sect1> + <sect1> + <title>Public structures</title> !Finclude/linux/vga_switcheroo.h vga_switcheroo_handler !Finclude/linux/vga_switcheroo.h vga_switcheroo_client_ops - </chapter> - - <chapter id="pubconstants"> - <title>Public constants</title> + </sect1> + <sect1> + <title>Public constants</title> !Finclude/linux/vga_switcheroo.h vga_switcheroo_client_id !Finclude/linux/vga_switcheroo.h vga_switcheroo_state - </chapter> - - <chapter id="privstructures"> - <title>Private structures</title> + </sect1> + <sect1> + <title>Private structures</title> !Fdrivers/gpu/vga/vga_switcheroo.c vgasr_priv !Fdrivers/gpu/vga/vga_switcheroo.c vga_switcheroo_client + </sect1> + </chapter> + + <chapter id="handlers"> + <title>Handlers</title> + <sect1> + <title>apple-gmux Handler</title> +!Pdrivers/platform/x86/apple-gmux.c Overview +!Pdrivers/platform/x86/apple-gmux.c Interrupt + <sect2> + <title>Graphics mux</title> +!Pdrivers/platform/x86/apple-gmux.c Graphics mux + </sect2> + <sect2> + <title>Power control</title> +!Pdrivers/platform/x86/apple-gmux.c Power control + </sect2> + <sect2> + <title>Backlight control</title> +!Pdrivers/platform/x86/apple-gmux.c Backlight control + </sect2> + </sect1> </chapter> !Cdrivers/gpu/vga/vga_switcheroo.c !Cinclude/linux/vga_switcheroo.h +!Cdrivers/platform/x86/apple-gmux.c </part> </book> diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c index 6fbec99e59c2..b0aac4733020 100644 --- a/drivers/gpu/drm/bridge/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/dw-hdmi.c @@ -1667,8 +1667,6 @@ static int dw_hdmi_register(struct drm_device *drm, struct dw_hdmi *hdmi) &dw_hdmi_connector_funcs, DRM_MODE_CONNECTOR_HDMIA); - hdmi->connector.encoder = encoder; - drm_mode_connector_attach_encoder(&hdmi->connector, encoder); return 0; diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 6a21e5c378c1..3f74193885f1 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -508,6 +508,22 @@ static int drm_atomic_crtc_check(struct drm_crtc *crtc, return -EINVAL; } + /* + * Reject event generation for when a CRTC is off and stays off. + * It wouldn't be hard to implement this, but userspace has a track + * record of happily burning through 100% cpu (or worse, crash) when the + * display pipe is suspended. To avoid all that fun just reject updates + * that ask for events since likely that indicates a bug in the + * compositor's drawing loop. This is consistent with the vblank IOCTL + * and legacy page_flip IOCTL which also reject service on a disabled + * pipe. + */ + if (state->event && !state->active && !crtc->state->active) { + DRM_DEBUG_ATOMIC("[CRTC:%d] requesting event but off\n", + crtc->base.id); + return -EINVAL; + } + return 0; } @@ -1063,10 +1079,21 @@ drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state, { struct drm_crtc_state *crtc_state; + if (conn_state->crtc && conn_state->crtc != crtc) { + crtc_state = drm_atomic_get_existing_crtc_state(conn_state->state, + conn_state->crtc); + + crtc_state->connector_mask &= + ~(1 << drm_connector_index(conn_state->connector)); + } + if (crtc) { crtc_state = drm_atomic_get_crtc_state(conn_state->state, crtc); if (IS_ERR(crtc_state)) return PTR_ERR(crtc_state); + + crtc_state->connector_mask |= + 1 << drm_connector_index(conn_state->connector); } conn_state->crtc = crtc; @@ -1172,36 +1199,6 @@ drm_atomic_add_affected_planes(struct drm_atomic_state *state, EXPORT_SYMBOL(drm_atomic_add_affected_planes); /** - * drm_atomic_connectors_for_crtc - count number of connected outputs - * @state: atomic state - * @crtc: DRM crtc - * - * This function counts all connectors which will be connected to @crtc - * according to @state. Useful to recompute the enable state for @crtc. - */ -int -drm_atomic_connectors_for_crtc(struct drm_atomic_state *state, - struct drm_crtc *crtc) -{ - struct drm_connector *connector; - struct drm_connector_state *conn_state; - - int i, num_connected_connectors = 0; - - for_each_connector_in_state(state, connector, conn_state, i) { - if (conn_state->crtc == crtc) - num_connected_connectors++; - } - - DRM_DEBUG_ATOMIC("State %p has %i connectors for [CRTC:%d:%s]\n", - state, num_connected_connectors, - crtc->base.id, crtc->name); - - return num_connected_connectors; -} -EXPORT_SYMBOL(drm_atomic_connectors_for_crtc); - -/** * drm_atomic_legacy_backoff - locking backoff for legacy ioctls * @state: atomic state * diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 268d37f26960..57cccd68ca52 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -463,7 +463,8 @@ drm_atomic_helper_check_modeset(struct drm_device *dev, * crtc only changed its mode but has the same set of connectors. */ for_each_crtc_in_state(state, crtc, crtc_state, i) { - int num_connectors; + bool has_connectors = + !!crtc_state->connector_mask; /* * We must set ->active_changed after walking connectors for @@ -492,10 +493,7 @@ drm_atomic_helper_check_modeset(struct drm_device *dev, if (ret != 0) return ret; - num_connectors = drm_atomic_connectors_for_crtc(state, - crtc); - - if (crtc_state->enable != !!num_connectors) { + if (crtc_state->enable != has_connectors) { DRM_DEBUG_ATOMIC("[CRTC:%d:%s] enabled/connectors mismatch\n", crtc->base.id, crtc->name); @@ -1754,7 +1752,7 @@ static int update_output_state(struct drm_atomic_state *state, if (crtc == set->crtc) continue; - if (!drm_atomic_connectors_for_crtc(state, crtc)) { + if (!crtc_state->connector_mask) { ret = drm_atomic_set_mode_prop_for_crtc(crtc_state, NULL); if (ret < 0) @@ -2284,6 +2282,15 @@ retry: goto fail; drm_atomic_set_fb_for_plane(plane_state, fb); + /* Make sure we don't accidentally do a full modeset. */ + state->allow_modeset = false; + if (!crtc_state->active) { + DRM_DEBUG_ATOMIC("[CRTC:%d] disabled, rejecting legacy flip\n", + crtc->base.id); + ret = -EINVAL; + goto fail; + } + ret = drm_atomic_async_commit(state); if (ret != 0) goto fail; @@ -2606,6 +2613,28 @@ void drm_atomic_helper_plane_destroy_state(struct drm_plane *plane, EXPORT_SYMBOL(drm_atomic_helper_plane_destroy_state); /** + * __drm_atomic_helper_connector_reset - reset state on connector + * @connector: drm connector + * @conn_state: connector state to assign + * + * Initializes the newly allocated @conn_state and assigns it to + * #connector ->state, usually required when initializing the drivers + * or when called from the ->reset hook. + * + * This is useful for drivers that subclass the connector state. + */ +void +__drm_atomic_helper_connector_reset(struct drm_connector *connector, + struct drm_connector_state *conn_state) +{ + if (conn_state) + conn_state->connector = connector; + + connector->state = conn_state; +} +EXPORT_SYMBOL(__drm_atomic_helper_connector_reset); + +/** * drm_atomic_helper_connector_reset - default ->reset hook for connectors * @connector: drm connector * @@ -2615,11 +2644,11 @@ EXPORT_SYMBOL(drm_atomic_helper_plane_destroy_state); */ void drm_atomic_helper_connector_reset(struct drm_connector *connector) { - kfree(connector->state); - connector->state = kzalloc(sizeof(*connector->state), GFP_KERNEL); + struct drm_connector_state *conn_state = + kzalloc(sizeof(*conn_state), GFP_KERNEL); - if (connector->state) - connector->state->connector = connector; + kfree(connector->state); + __drm_atomic_helper_connector_reset(connector, conn_state); } EXPORT_SYMBOL(drm_atomic_helper_connector_reset); diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 62fa95fa5471..d40bab29747e 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -5054,6 +5054,20 @@ int drm_mode_connector_attach_encoder(struct drm_connector *connector, { int i; + /* + * In the past, drivers have attempted to model the static association + * of connector to encoder in simple connector/encoder devices using a + * direct assignment of connector->encoder = encoder. This connection + * is a logical one and the responsibility of the core, so drivers are + * expected not to mess with this. + * + * Note that the error return should've been enough here, but a large + * majority of drivers ignores the return value, so add in a big WARN + * to get people's attention. + */ + if (WARN_ON(connector->encoder)) + return -EINVAL; + for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { if (connector->encoder_ids[i] == 0) { connector->encoder_ids[i] = encoder->base.id; diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index bf934cdea21c..167c8d3d4a31 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -44,10 +44,6 @@ MODULE_AUTHOR(CORE_AUTHOR); MODULE_DESCRIPTION(CORE_DESC); MODULE_LICENSE("GPL and additional rights"); MODULE_PARM_DESC(debug, "Enable debug output"); -MODULE_PARM_DESC(vblankoffdelay, "Delay until vblank irq auto-disable [msecs] (0: never disable, <0: disable immediately)"); -MODULE_PARM_DESC(timestamp_precision_usec, "Max. error on timestamps [usecs]"); -MODULE_PARM_DESC(timestamp_monotonic, "Use monotonic timestamps"); - module_param_named(debug, drm_debug, int, 0600); static DEFINE_SPINLOCK(drm_minor_lock); diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index c214f1246cb4..04cb4877fabd 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -637,8 +637,12 @@ static const struct minimode extra_modes[] = { /* * Probably taken from CEA-861 spec. * This table is converted from xorg's hw/xfree86/modes/xf86EdidModes.c. + * + * Index using the VIC. */ static const struct drm_display_mode edid_cea_modes[] = { + /* 0 - dummy, VICs start at 1 */ + { }, /* 1 - 640x480@60Hz */ { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656, 752, 800, 0, 480, 490, 492, 525, 0, @@ -987,9 +991,11 @@ static const struct drm_display_mode edid_cea_modes[] = { }; /* - * HDMI 1.4 4k modes. + * HDMI 1.4 4k modes. Index using the VIC. */ static const struct drm_display_mode edid_4k_modes[] = { + /* 0 - dummy, VICs start at 1 */ + { }, /* 1 - 3840x2160@30Hz */ { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, 3840, 4016, 4104, 4400, 0, @@ -2548,13 +2554,13 @@ cea_mode_alternate_clock(const struct drm_display_mode *cea_mode) static u8 drm_match_cea_mode_clock_tolerance(const struct drm_display_mode *to_match, unsigned int clock_tolerance) { - u8 mode; + u8 vic; if (!to_match->clock) return 0; - for (mode = 0; mode < ARRAY_SIZE(edid_cea_modes); mode++) { - const struct drm_display_mode *cea_mode = &edid_cea_modes[mode]; + for (vic = 1; vic < ARRAY_SIZE(edid_cea_modes); vic++) { + const struct drm_display_mode *cea_mode = &edid_cea_modes[vic]; unsigned int clock1, clock2; /* Check both 60Hz and 59.94Hz */ @@ -2566,7 +2572,7 @@ static u8 drm_match_cea_mode_clock_tolerance(const struct drm_display_mode *to_m continue; if (drm_mode_equal_no_clocks(to_match, cea_mode)) - return mode + 1; + return vic; } return 0; @@ -2581,13 +2587,13 @@ static u8 drm_match_cea_mode_clock_tolerance(const struct drm_display_mode *to_m */ u8 drm_match_cea_mode(const struct drm_display_mode *to_match) { - u8 mode; + u8 vic; if (!to_match->clock) return 0; - for (mode = 0; mode < ARRAY_SIZE(edid_cea_modes); mode++) { - const struct drm_display_mode *cea_mode = &edid_cea_modes[mode]; + for (vic = 1; vic < ARRAY_SIZE(edid_cea_modes); vic++) { + const struct drm_display_mode *cea_mode = &edid_cea_modes[vic]; unsigned int clock1, clock2; /* Check both 60Hz and 59.94Hz */ @@ -2597,12 +2603,17 @@ u8 drm_match_cea_mode(const struct drm_display_mode *to_match) if ((KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock1) || KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock2)) && drm_mode_equal_no_clocks_no_stereo(to_match, cea_mode)) - return mode + 1; + return vic; } return 0; } EXPORT_SYMBOL(drm_match_cea_mode); +static bool drm_valid_cea_vic(u8 vic) +{ + return vic > 0 && vic < ARRAY_SIZE(edid_cea_modes); +} + /** * drm_get_cea_aspect_ratio - get the picture aspect ratio corresponding to * the input VIC from the CEA mode list @@ -2612,10 +2623,7 @@ EXPORT_SYMBOL(drm_match_cea_mode); */ enum hdmi_picture_aspect drm_get_cea_aspect_ratio(const u8 video_code) { - /* return picture aspect ratio for video_code - 1 to access the - * right array element - */ - return edid_cea_modes[video_code-1].picture_aspect_ratio; + return edid_cea_modes[video_code].picture_aspect_ratio; } EXPORT_SYMBOL(drm_get_cea_aspect_ratio); @@ -2639,13 +2647,13 @@ hdmi_mode_alternate_clock(const struct drm_display_mode *hdmi_mode) static u8 drm_match_hdmi_mode_clock_tolerance(const struct drm_display_mode *to_match, unsigned int clock_tolerance) { - u8 mode; + u8 vic; if (!to_match->clock) return 0; - for (mode = 0; mode < ARRAY_SIZE(edid_4k_modes); mode++) { - const struct drm_display_mode *hdmi_mode = &edid_4k_modes[mode]; + for (vic = 1; vic < ARRAY_SIZE(edid_4k_modes); vic++) { + const struct drm_display_mode *hdmi_mode = &edid_4k_modes[vic]; unsigned int clock1, clock2; /* Make sure to also match alternate clocks */ @@ -2657,7 +2665,7 @@ static u8 drm_match_hdmi_mode_clock_tolerance(const struct drm_display_mode *to_ continue; if (drm_mode_equal_no_clocks(to_match, hdmi_mode)) - return mode + 1; + return vic; } return 0; @@ -2673,13 +2681,13 @@ static u8 drm_match_hdmi_mode_clock_tolerance(const struct drm_display_mode *to_ */ static u8 drm_match_hdmi_mode(const struct drm_display_mode *to_match) { - u8 mode; + u8 vic; if (!to_match->clock) return 0; - for (mode = 0; mode < ARRAY_SIZE(edid_4k_modes); mode++) { - const struct drm_display_mode *hdmi_mode = &edid_4k_modes[mode]; + for (vic = 1; vic < ARRAY_SIZE(edid_4k_modes); vic++) { + const struct drm_display_mode *hdmi_mode = &edid_4k_modes[vic]; unsigned int clock1, clock2; /* Make sure to also match alternate clocks */ @@ -2689,11 +2697,16 @@ static u8 drm_match_hdmi_mode(const struct drm_display_mode *to_match) if ((KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock1) || KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock2)) && drm_mode_equal_no_clocks_no_stereo(to_match, hdmi_mode)) - r |
