Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 28f03607 authored by Dave Airlie's avatar Dave Airlie
Browse files

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
  ...
parents e9c5e740 4314e19e
Loading
Loading
Loading
Loading
+42 −208
Original line number Original line Diff line number Diff line
@@ -1578,194 +1578,6 @@ void intel_crt_init(struct drm_device *dev)
      To use it, a driver must provide bottom functions for all of the three KMS
      To use it, a driver must provide bottom functions for all of the three KMS
      entities.
      entities.
    </para>
    </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-&gt;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-&gt;x</literal> and
            <literal>crtc-&gt;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>
    <sect2>
      <title>Atomic Modeset Helper Functions Reference</title>
      <title>Atomic Modeset Helper Functions Reference</title>
      <sect3>
      <sect3>
@@ -3635,31 +3447,53 @@ int num_ioctls;</synopsis>
    </sect1>
    </sect1>
  </chapter>
  </chapter>


  <chapter id="pubfunctions">
  <chapter id="api">
    <title>API</title>
    <sect1>
      <title>Public functions</title>
      <title>Public functions</title>
!Edrivers/gpu/vga/vga_switcheroo.c
!Edrivers/gpu/vga/vga_switcheroo.c
  </chapter>
    </sect1>

    <sect1>
  <chapter id="pubstructures">
      <title>Public structures</title>
      <title>Public structures</title>
!Finclude/linux/vga_switcheroo.h vga_switcheroo_handler
!Finclude/linux/vga_switcheroo.h vga_switcheroo_handler
!Finclude/linux/vga_switcheroo.h vga_switcheroo_client_ops
!Finclude/linux/vga_switcheroo.h vga_switcheroo_client_ops
  </chapter>
    </sect1>

    <sect1>
  <chapter id="pubconstants">
      <title>Public constants</title>
      <title>Public constants</title>
!Finclude/linux/vga_switcheroo.h vga_switcheroo_client_id
!Finclude/linux/vga_switcheroo.h vga_switcheroo_client_id
!Finclude/linux/vga_switcheroo.h vga_switcheroo_state
!Finclude/linux/vga_switcheroo.h vga_switcheroo_state
  </chapter>
    </sect1>

    <sect1>
  <chapter id="privstructures">
      <title>Private structures</title>
      <title>Private structures</title>
!Fdrivers/gpu/vga/vga_switcheroo.c vgasr_priv
!Fdrivers/gpu/vga/vga_switcheroo.c vgasr_priv
!Fdrivers/gpu/vga/vga_switcheroo.c vga_switcheroo_client
!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>
  </chapter>


!Cdrivers/gpu/vga/vga_switcheroo.c
!Cdrivers/gpu/vga/vga_switcheroo.c
!Cinclude/linux/vga_switcheroo.h
!Cinclude/linux/vga_switcheroo.h
!Cdrivers/platform/x86/apple-gmux.c
</part>
</part>


</book>
</book>
+0 −2
Original line number Original line Diff line number Diff line
@@ -1667,8 +1667,6 @@ static int dw_hdmi_register(struct drm_device *drm, struct dw_hdmi *hdmi)
				   &dw_hdmi_connector_funcs,
				   &dw_hdmi_connector_funcs,
				   DRM_MODE_CONNECTOR_HDMIA);
				   DRM_MODE_CONNECTOR_HDMIA);


	hdmi->connector.encoder = encoder;

	drm_mode_connector_attach_encoder(&hdmi->connector, encoder);
	drm_mode_connector_attach_encoder(&hdmi->connector, encoder);


	return 0;
	return 0;
+27 −30
Original line number Original line Diff line number Diff line
@@ -508,6 +508,22 @@ static int drm_atomic_crtc_check(struct drm_crtc *crtc,
		return -EINVAL;
		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;
	return 0;
}
}


@@ -1063,10 +1079,21 @@ drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state,
{
{
	struct drm_crtc_state *crtc_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) {
	if (crtc) {
		crtc_state = drm_atomic_get_crtc_state(conn_state->state, crtc);
		crtc_state = drm_atomic_get_crtc_state(conn_state->state, crtc);
		if (IS_ERR(crtc_state))
		if (IS_ERR(crtc_state))
			return PTR_ERR(crtc_state);
			return PTR_ERR(crtc_state);

		crtc_state->connector_mask |=
			1 << drm_connector_index(conn_state->connector);
	}
	}


	conn_state->crtc = crtc;
	conn_state->crtc = crtc;
@@ -1171,36 +1198,6 @@ drm_atomic_add_affected_planes(struct drm_atomic_state *state,
}
}
EXPORT_SYMBOL(drm_atomic_add_affected_planes);
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
 * drm_atomic_legacy_backoff - locking backoff for legacy ioctls
 * @state: atomic state
 * @state: atomic state
+39 −10
Original line number Original line Diff line number Diff line
@@ -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.
	 * crtc only changed its mode but has the same set of connectors.
	 */
	 */
	for_each_crtc_in_state(state, crtc, crtc_state, i) {
	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
		 * 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)
		if (ret != 0)
			return ret;
			return ret;


		num_connectors = drm_atomic_connectors_for_crtc(state,
		if (crtc_state->enable != has_connectors) {
								crtc);

		if (crtc_state->enable != !!num_connectors) {
			DRM_DEBUG_ATOMIC("[CRTC:%d:%s] enabled/connectors mismatch\n",
			DRM_DEBUG_ATOMIC("[CRTC:%d:%s] enabled/connectors mismatch\n",
					 crtc->base.id, crtc->name);
					 crtc->base.id, crtc->name);


@@ -1754,7 +1752,7 @@ static int update_output_state(struct drm_atomic_state *state,
		if (crtc == set->crtc)
		if (crtc == set->crtc)
			continue;
			continue;


		if (!drm_atomic_connectors_for_crtc(state, crtc)) {
		if (!crtc_state->connector_mask) {
			ret = drm_atomic_set_mode_prop_for_crtc(crtc_state,
			ret = drm_atomic_set_mode_prop_for_crtc(crtc_state,
								NULL);
								NULL);
			if (ret < 0)
			if (ret < 0)
@@ -2284,6 +2282,15 @@ int drm_atomic_helper_page_flip(struct drm_crtc *crtc,
		goto fail;
		goto fail;
	drm_atomic_set_fb_for_plane(plane_state, fb);
	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);
	ret = drm_atomic_async_commit(state);
	if (ret != 0)
	if (ret != 0)
		goto fail;
		goto fail;
@@ -2605,6 +2612,28 @@ void drm_atomic_helper_plane_destroy_state(struct drm_plane *plane,
}
}
EXPORT_SYMBOL(drm_atomic_helper_plane_destroy_state);
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
 * drm_atomic_helper_connector_reset - default ->reset hook for connectors
 * @connector: drm connector
 * @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)
void drm_atomic_helper_connector_reset(struct drm_connector *connector)
{
{
	kfree(connector->state);
	struct drm_connector_state *conn_state =
	connector->state = kzalloc(sizeof(*connector->state), GFP_KERNEL);
		kzalloc(sizeof(*conn_state), GFP_KERNEL);


	if (connector->state)
	kfree(connector->state);
		connector->state->connector = connector;
	__drm_atomic_helper_connector_reset(connector, conn_state);
}
}
EXPORT_SYMBOL(drm_atomic_helper_connector_reset);
EXPORT_SYMBOL(drm_atomic_helper_connector_reset);


+14 −0
Original line number Original line Diff line number Diff line
@@ -5054,6 +5054,20 @@ int drm_mode_connector_attach_encoder(struct drm_connector *connector,
{
{
	int i;
	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++) {
	for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
		if (connector->encoder_ids[i] == 0) {
		if (connector->encoder_ids[i] == 0) {
			connector->encoder_ids[i] = encoder->base.id;
			connector->encoder_ids[i] = encoder->base.id;
Loading