Commit 7781cc42 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm-misc-next-2024-02-29' of...

Merge tag 'drm-misc-next-2024-02-29' of https://anongit.freedesktop.org/git/drm/drm-misc

 into drm-next

drm-misc-next for v6.9:

UAPI Changes:

Cross-subsystem Changes:

backlight:
- corgi: include backlight header

fbdev:
- Cleanup includes in public header file
- fbtft: Include backlight header

Core Changes:

edid:
- Remove built-in EDID data

dp:
- Avoid AUX transfers on powered-down displays
- Add VSC SDP helpers

modesetting:
- Add sanity checks for polling
- Cleanups

scheduler:
- Cleanups

tests:
- Add helpers for mode-setting tests

Driver Changes:

i915:
- Use shared VSC SDP helper

mgag200:
- Work around PCI write bursts

mxsfb:
- Use managed mode config

nouveau:
- Include backlight header where necessary

qiac:
- Cleanups

sun4:
- HDMI: updates to atomic mode setting

tegra:
- Fix GEM refounting in error paths

tidss:
- Fix multi display
- Fix initial Z position

v3d:
- Support display MMU page size

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>

From: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patchwork.freedesktop.org/patch/msgid/20240229084806.GA21616@localhost.localdomain
parents 99290954 8df1ddb5
Loading
Loading
Loading
Loading
+1 −34
Original line number Diff line number Diff line
@@ -24,37 +24,4 @@ restrictions later on.
As a remedy for such situations, the kernel configuration item
CONFIG_DRM_LOAD_EDID_FIRMWARE was introduced. It allows to provide an
individually prepared or corrected EDID data set in the /lib/firmware
directory from where it is loaded via the firmware interface. The code
(see drivers/gpu/drm/drm_edid_load.c) contains built-in data sets for
commonly used screen resolutions (800x600, 1024x768, 1280x1024, 1600x1200,
1680x1050, 1920x1080) as binary blobs, but the kernel source tree does
not contain code to create these data. In order to elucidate the origin
of the built-in binary EDID blobs and to facilitate the creation of
individual data for a specific misbehaving monitor, commented sources
and a Makefile environment are given here.

To create binary EDID and C source code files from the existing data
material, simply type "make" in tools/edid/.

If you want to create your own EDID file, copy the file 1024x768.S,
replace the settings with your own data and add a new target to the
Makefile. Please note that the EDID data structure expects the timing
values in a different way as compared to the standard X11 format.

X11:
  HTimings:
    hdisp hsyncstart hsyncend htotal
  VTimings:
    vdisp vsyncstart vsyncend vtotal

EDID::

  #define XPIX hdisp
  #define XBLANK htotal-hdisp
  #define XOFFSET hsyncstart-hdisp
  #define XPULSE hsyncend-hsyncstart

  #define YPIX vdisp
  #define YBLANK vtotal-vdisp
  #define YOFFSET vsyncstart-vdisp
  #define YPULSE vsyncend-vsyncstart
directory from where it is loaded via the firmware interface.
+4 −10
Original line number Diff line number Diff line
@@ -1162,16 +1162,10 @@
			panels may send no or incorrect EDID data sets.
			This parameter allows to specify an EDID data sets
			in the /lib/firmware directory that are used instead.
			Generic built-in EDID data sets are used, if one of
			edid/1024x768.bin, edid/1280x1024.bin,
			edid/1680x1050.bin, or edid/1920x1080.bin is given
			and no file with the same name exists. Details and
			instructions how to build your own EDID data are
			available in Documentation/admin-guide/edid.rst. An EDID
			data set will only be used for a particular connector,
			if its name and a colon are prepended to the EDID
			name. Each connector may use a unique EDID data
			set by separating the files with a comma.  An EDID
			An EDID data set will only be used for a particular
			connector, if its name and a colon are prepended to
			the EDID name. Each connector may use a unique EDID
			data set by separating the files with a comma. An EDID
			data set with no connector name will be used for
			any connectors not explicitly specified.

+1 −1
Original line number Diff line number Diff line
@@ -20,7 +20,7 @@ static unsigned int mhi_timeout_ms = 2000; /* 2 sec default */
module_param(mhi_timeout_ms, uint, 0600);
MODULE_PARM_DESC(mhi_timeout_ms, "MHI controller timeout value");

static struct mhi_channel_config aic100_channels[] = {
static const struct mhi_channel_config aic100_channels[] = {
	{
		.name = "QAIC_LOOPBACK",
		.num = 0,
+132 −0
Original line number Diff line number Diff line
@@ -532,6 +532,15 @@ static int drm_dp_dpcd_access(struct drm_dp_aux *aux, u8 request,

	mutex_lock(&aux->hw_mutex);

	/*
	 * If the device attached to the aux bus is powered down then there's
	 * no reason to attempt a transfer. Error out immediately.
	 */
	if (aux->powered_down) {
		ret = -EBUSY;
		goto unlock;
	}

	/*
	 * The specification doesn't give any recommendation on how often to
	 * retry native transactions. We used to retry 7 times like for
@@ -599,6 +608,29 @@ int drm_dp_dpcd_probe(struct drm_dp_aux *aux, unsigned int offset)
}
EXPORT_SYMBOL(drm_dp_dpcd_probe);

/**
 * drm_dp_dpcd_set_powered() - Set whether the DP device is powered
 * @aux: DisplayPort AUX channel; for convenience it's OK to pass NULL here
 *       and the function will be a no-op.
 * @powered: true if powered; false if not
 *
 * If the endpoint device on the DP AUX bus is known to be powered down
 * then this function can be called to make future transfers fail immediately
 * instead of needing to time out.
 *
 * If this function is never called then a device defaults to being powered.
 */
void drm_dp_dpcd_set_powered(struct drm_dp_aux *aux, bool powered)
{
	if (!aux)
		return;

	mutex_lock(&aux->hw_mutex);
	aux->powered_down = !powered;
	mutex_unlock(&aux->hw_mutex);
}
EXPORT_SYMBOL(drm_dp_dpcd_set_powered);

/**
 * drm_dp_dpcd_read() - read a series of bytes from the DPCD
 * @aux: DisplayPort AUX channel (SST or MST)
@@ -1858,6 +1890,9 @@ static int drm_dp_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs,
	struct drm_dp_aux_msg msg;
	int err = 0;

	if (aux->powered_down)
		return -EBUSY;

	dp_aux_i2c_transfer_size = clamp(dp_aux_i2c_transfer_size, 1, DP_AUX_MAX_PAYLOAD_BYTES);

	memset(&msg, 0, sizeof(msg));
@@ -2913,6 +2948,103 @@ void drm_dp_vsc_sdp_log(struct drm_printer *p, const struct drm_dp_vsc_sdp *vsc)
}
EXPORT_SYMBOL(drm_dp_vsc_sdp_log);

/**
 * drm_dp_vsc_sdp_supported() - check if vsc sdp is supported
 * @aux: DisplayPort AUX channel
 * @dpcd: DisplayPort configuration data
 *
 * Returns true if vsc sdp is supported, else returns false
 */
bool drm_dp_vsc_sdp_supported(struct drm_dp_aux *aux, const u8 dpcd[DP_RECEIVER_CAP_SIZE])
{
	u8 rx_feature;

	if (dpcd[DP_DPCD_REV] < DP_DPCD_REV_13)
		return false;

	if (drm_dp_dpcd_readb(aux, DP_DPRX_FEATURE_ENUMERATION_LIST, &rx_feature) != 1) {
		drm_dbg_dp(aux->drm_dev, "failed to read DP_DPRX_FEATURE_ENUMERATION_LIST\n");
		return false;
	}

	return (rx_feature & DP_VSC_SDP_EXT_FOR_COLORIMETRY_SUPPORTED);
}
EXPORT_SYMBOL(drm_dp_vsc_sdp_supported);

/**
 * drm_dp_vsc_sdp_pack() - pack a given vsc sdp into generic dp_sdp
 * @vsc: vsc sdp initialized according to its purpose as defined in
 *       table 2-118 - table 2-120 in DP 1.4a specification
 * @sdp: valid handle to the generic dp_sdp which will be packed
 *
 * Returns length of sdp on success and error code on failure
 */
ssize_t drm_dp_vsc_sdp_pack(const struct drm_dp_vsc_sdp *vsc,
			    struct dp_sdp *sdp)
{
	size_t length = sizeof(struct dp_sdp);

	memset(sdp, 0, sizeof(struct dp_sdp));

	/*
	 * Prepare VSC Header for SU as per DP 1.4a spec, Table 2-119
	 * VSC SDP Header Bytes
	 */
	sdp->sdp_header.HB0 = 0; /* Secondary-Data Packet ID = 0 */
	sdp->sdp_header.HB1 = vsc->sdp_type; /* Secondary-data Packet Type */
	sdp->sdp_header.HB2 = vsc->revision; /* Revision Number */
	sdp->sdp_header.HB3 = vsc->length; /* Number of Valid Data Bytes */

	if (vsc->revision == 0x6) {
		sdp->db[0] = 1;
		sdp->db[3] = 1;
	}

	/*
	 * Revision 0x5 and revision 0x7 supports Pixel Encoding/Colorimetry
	 * Format as per DP 1.4a spec and DP 2.0 respectively.
	 */
	if (!(vsc->revision == 0x5 || vsc->revision == 0x7))
		goto out;

	/* VSC SDP Payload for DB16 through DB18 */
	/* Pixel Encoding and Colorimetry Formats  */
	sdp->db[16] = (vsc->pixelformat & 0xf) << 4; /* DB16[7:4] */
	sdp->db[16] |= vsc->colorimetry & 0xf; /* DB16[3:0] */

	switch (vsc->bpc) {
	case 6:
		/* 6bpc: 0x0 */
		break;
	case 8:
		sdp->db[17] = 0x1; /* DB17[3:0] */
		break;
	case 10:
		sdp->db[17] = 0x2;
		break;
	case 12:
		sdp->db[17] = 0x3;
		break;
	case 16:
		sdp->db[17] = 0x4;
		break;
	default:
		WARN(1, "Missing case %d\n", vsc->bpc);
		return -EINVAL;
	}

	/* Dynamic Range and Component Bit Depth */
	if (vsc->dynamic_range == DP_DYNAMIC_RANGE_CTA)
		sdp->db[17] |= 0x80;  /* DB17[7] */

	/* Content Type */
	sdp->db[18] = vsc->content_type & 0x7;

out:
	return length;
}
EXPORT_SYMBOL(drm_dp_vsc_sdp_pack);

/**
 * drm_dp_get_pcon_max_frl_bw() - maximum frl supported by PCON
 * @dpcd: DisplayPort configuration data
+1 −14
Original line number Diff line number Diff line
@@ -107,18 +107,6 @@ int drm_crtc_force_disable(struct drm_crtc *crtc)
	return drm_mode_set_config_internal(&set);
}

static unsigned int drm_num_crtcs(struct drm_device *dev)
{
	unsigned int num = 0;
	struct drm_crtc *tmp;

	drm_for_each_crtc(tmp, dev) {
		num++;
	}

	return num;
}

int drm_crtc_register_all(struct drm_device *dev)
{
	struct drm_crtc *crtc;
@@ -278,8 +266,7 @@ static int __drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *
	if (name) {
		crtc->name = kvasprintf(GFP_KERNEL, name, ap);
	} else {
		crtc->name = kasprintf(GFP_KERNEL, "crtc-%d",
				       drm_num_crtcs(dev));
		crtc->name = kasprintf(GFP_KERNEL, "crtc-%d", config->num_crtc);
	}
	if (!crtc->name) {
		drm_mode_object_unregister(dev, &crtc->base);
Loading