Merge tag 'drm-for-v4.9' of git://people.freedesktop.org/~airlied/linux
Pull drm updates from Dave Airlie: "Core: - Fence destaging work - DRIVER_LEGACY to split off legacy drm drivers - drm_mm refactoring - Splitting drm_crtc.c into chunks and documenting better - Display info fixes - rbtree support for prime buffer lookup - Simple VGA DAC driver Panel: - Add Nexus 7 panel - More simple panels i915: - Refactoring GEM naming - Refactored vma/active tracking - Lockless request lookups - Better stolen memory support - FBC fixes - SKL watermark fixes - VGPU improvements - dma-buf fencing support - Better DP dongle support amdgpu: - Powerplay for Iceland asics - Improved GPU reset support - UVD/VEC powergating support for CZ/ST - Preinitialised VRAM buffer support - Virtual display support - Initial SI support - GTT rework - PCI shutdown callback support - HPD IRQ storm fixes amdkfd: - bugfixes tilcdc: - Atomic modesetting support mediatek: - AAL + GAMMA engine support - Hook up gamma LUT - Temporal dithering support imx: - Pixel clock from devicetree - drm bridge support for LVDS bridges - active plane reconfiguration - VDIC deinterlacer support - Frame synchronisation unit support - Color space conversion support analogix: - PSR support - Better panel on/off support rockchip: - rk3399 vop/crtc support - PSR support vc4: - Interlaced vblank timing - 3D rendering CPU overhead reduction - HDMI output fixes tda998x: - HDMI audio ASoC support sunxi: - Allwinner A33 support - better TCON support msm: - DT binding cleanups - Explicit fence-fd support sti: - remove sti415/416 support etnaviv: - MMUv2 refactoring - GC3000 support exynos: - Refactoring HDMI DCC/PHY - G2D pm regression fix - Page fault issues with wait for vblank There is no nouveau work in this tree, as Ben didn't get a pull request in, and he was fighting moving to atomic and adding mst support, so maybe best it waits for a cycle" * tag 'drm-for-v4.9' of git://people.freedesktop.org/~airlied/linux: (1412 commits) drm/crtc: constify drm_crtc_index parameter drm/i915: Fix conflict resolution from backmerge of v4.8-rc8 to drm-next drm/i915/guc: Unwind GuC workqueue reservation if request construction fails drm/i915: Reset the breadcrumbs IRQ more carefully drm/i915: Force relocations via cpu if we run out of idle aperture drm/i915: Distinguish last emitted request from last submitted request drm/i915: Allow DP to work w/o EDID drm/i915: Move long hpd handling into the hotplug work drm/i915/execlists: Reinitialise context image after GPU hang drm/i915: Use correct index for backtracking HUNG semaphores drm/i915: Unalias obj->phys_handle and obj->userptr drm/i915: Just clear the mmiodebug before a register access drm/i915/gen9: only add the planes actually affected by ddb changes drm/i915: Allow PCH DPLL sharing regardless of DPLL_SDVO_HIGH_SPEED drm/i915/bxt: Fix HDMI DPLL configuration drm/i915/gen9: fix the watermark res_blocks value drm/i915/gen9: fix plane_blocks_per_line on watermarks calculations drm/i915/gen9: minimum scanlines for Y tile is not always 4 drm/i915/gen9: fix the WaWmMemoryReadLatency implementation drm/i915/kbl: KBL also needs to run the SAGV code ...
This commit is contained in:
@@ -27,10 +27,12 @@
|
||||
#include <linux/errno.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <drm/drm_dp_helper.h>
|
||||
#include <drm/drm_dp_aux_dev.h>
|
||||
#include <drm/drmP.h>
|
||||
|
||||
#include "drm_crtc_helper_internal.h"
|
||||
|
||||
/**
|
||||
* DOC: dp helpers
|
||||
*
|
||||
@@ -223,7 +225,7 @@ static int drm_dp_dpcd_access(struct drm_dp_aux *aux, u8 request,
|
||||
err = ret;
|
||||
}
|
||||
|
||||
DRM_DEBUG_KMS("too many retries, giving up\n");
|
||||
DRM_DEBUG_KMS("Too many retries, giving up. First error: %d\n", err);
|
||||
ret = err;
|
||||
|
||||
unlock:
|
||||
@@ -438,6 +440,179 @@ int drm_dp_link_configure(struct drm_dp_aux *aux, struct drm_dp_link *link)
|
||||
}
|
||||
EXPORT_SYMBOL(drm_dp_link_configure);
|
||||
|
||||
/**
|
||||
* drm_dp_downstream_max_clock() - extract branch device max
|
||||
* pixel rate for legacy VGA
|
||||
* converter or max TMDS clock
|
||||
* rate for others
|
||||
* @dpcd: DisplayPort configuration data
|
||||
* @port_cap: port capabilities
|
||||
*
|
||||
* Returns max clock in kHz on success or 0 if max clock not defined
|
||||
*/
|
||||
int drm_dp_downstream_max_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
|
||||
const u8 port_cap[4])
|
||||
{
|
||||
int type = port_cap[0] & DP_DS_PORT_TYPE_MASK;
|
||||
bool detailed_cap_info = dpcd[DP_DOWNSTREAMPORT_PRESENT] &
|
||||
DP_DETAILED_CAP_INFO_AVAILABLE;
|
||||
|
||||
if (!detailed_cap_info)
|
||||
return 0;
|
||||
|
||||
switch (type) {
|
||||
case DP_DS_PORT_TYPE_VGA:
|
||||
return port_cap[1] * 8 * 1000;
|
||||
case DP_DS_PORT_TYPE_DVI:
|
||||
case DP_DS_PORT_TYPE_HDMI:
|
||||
case DP_DS_PORT_TYPE_DP_DUALMODE:
|
||||
return port_cap[1] * 2500;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(drm_dp_downstream_max_clock);
|
||||
|
||||
/**
|
||||
* drm_dp_downstream_max_bpc() - extract branch device max
|
||||
* bits per component
|
||||
* @dpcd: DisplayPort configuration data
|
||||
* @port_cap: port capabilities
|
||||
*
|
||||
* Returns max bpc on success or 0 if max bpc not defined
|
||||
*/
|
||||
int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
|
||||
const u8 port_cap[4])
|
||||
{
|
||||
int type = port_cap[0] & DP_DS_PORT_TYPE_MASK;
|
||||
bool detailed_cap_info = dpcd[DP_DOWNSTREAMPORT_PRESENT] &
|
||||
DP_DETAILED_CAP_INFO_AVAILABLE;
|
||||
int bpc;
|
||||
|
||||
if (!detailed_cap_info)
|
||||
return 0;
|
||||
|
||||
switch (type) {
|
||||
case DP_DS_PORT_TYPE_VGA:
|
||||
case DP_DS_PORT_TYPE_DVI:
|
||||
case DP_DS_PORT_TYPE_HDMI:
|
||||
case DP_DS_PORT_TYPE_DP_DUALMODE:
|
||||
bpc = port_cap[2] & DP_DS_MAX_BPC_MASK;
|
||||
|
||||
switch (bpc) {
|
||||
case DP_DS_8BPC:
|
||||
return 8;
|
||||
case DP_DS_10BPC:
|
||||
return 10;
|
||||
case DP_DS_12BPC:
|
||||
return 12;
|
||||
case DP_DS_16BPC:
|
||||
return 16;
|
||||
}
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(drm_dp_downstream_max_bpc);
|
||||
|
||||
/**
|
||||
* drm_dp_downstream_id() - identify branch device
|
||||
* @aux: DisplayPort AUX channel
|
||||
* @id: DisplayPort branch device id
|
||||
*
|
||||
* Returns branch device id on success or NULL on failure
|
||||
*/
|
||||
int drm_dp_downstream_id(struct drm_dp_aux *aux, char id[6])
|
||||
{
|
||||
return drm_dp_dpcd_read(aux, DP_BRANCH_ID, id, 6);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_dp_downstream_id);
|
||||
|
||||
/**
|
||||
* drm_dp_downstream_debug() - debug DP branch devices
|
||||
* @m: pointer for debugfs file
|
||||
* @dpcd: DisplayPort configuration data
|
||||
* @port_cap: port capabilities
|
||||
* @aux: DisplayPort AUX channel
|
||||
*
|
||||
*/
|
||||
void drm_dp_downstream_debug(struct seq_file *m,
|
||||
const u8 dpcd[DP_RECEIVER_CAP_SIZE],
|
||||
const u8 port_cap[4], struct drm_dp_aux *aux)
|
||||
{
|
||||
bool detailed_cap_info = dpcd[DP_DOWNSTREAMPORT_PRESENT] &
|
||||
DP_DETAILED_CAP_INFO_AVAILABLE;
|
||||
int clk;
|
||||
int bpc;
|
||||
char id[6];
|
||||
int len;
|
||||
uint8_t rev[2];
|
||||
int type = port_cap[0] & DP_DS_PORT_TYPE_MASK;
|
||||
bool branch_device = dpcd[DP_DOWNSTREAMPORT_PRESENT] &
|
||||
DP_DWN_STRM_PORT_PRESENT;
|
||||
|
||||
seq_printf(m, "\tDP branch device present: %s\n",
|
||||
branch_device ? "yes" : "no");
|
||||
|
||||
if (!branch_device)
|
||||
return;
|
||||
|
||||
switch (type) {
|
||||
case DP_DS_PORT_TYPE_DP:
|
||||
seq_puts(m, "\t\tType: DisplayPort\n");
|
||||
break;
|
||||
case DP_DS_PORT_TYPE_VGA:
|
||||
seq_puts(m, "\t\tType: VGA\n");
|
||||
break;
|
||||
case DP_DS_PORT_TYPE_DVI:
|
||||
seq_puts(m, "\t\tType: DVI\n");
|
||||
break;
|
||||
case DP_DS_PORT_TYPE_HDMI:
|
||||
seq_puts(m, "\t\tType: HDMI\n");
|
||||
break;
|
||||
case DP_DS_PORT_TYPE_NON_EDID:
|
||||
seq_puts(m, "\t\tType: others without EDID support\n");
|
||||
break;
|
||||
case DP_DS_PORT_TYPE_DP_DUALMODE:
|
||||
seq_puts(m, "\t\tType: DP++\n");
|
||||
break;
|
||||
case DP_DS_PORT_TYPE_WIRELESS:
|
||||
seq_puts(m, "\t\tType: Wireless\n");
|
||||
break;
|
||||
default:
|
||||
seq_puts(m, "\t\tType: N/A\n");
|
||||
}
|
||||
|
||||
drm_dp_downstream_id(aux, id);
|
||||
seq_printf(m, "\t\tID: %s\n", id);
|
||||
|
||||
len = drm_dp_dpcd_read(aux, DP_BRANCH_HW_REV, &rev[0], 1);
|
||||
if (len > 0)
|
||||
seq_printf(m, "\t\tHW: %d.%d\n",
|
||||
(rev[0] & 0xf0) >> 4, rev[0] & 0xf);
|
||||
|
||||
len = drm_dp_dpcd_read(aux, DP_BRANCH_SW_REV, &rev, 2);
|
||||
if (len > 0)
|
||||
seq_printf(m, "\t\tSW: %d.%d\n", rev[0], rev[1]);
|
||||
|
||||
if (detailed_cap_info) {
|
||||
clk = drm_dp_downstream_max_clock(dpcd, port_cap);
|
||||
|
||||
if (clk > 0) {
|
||||
if (type == DP_DS_PORT_TYPE_VGA)
|
||||
seq_printf(m, "\t\tMax dot clock: %d kHz\n", clk);
|
||||
else
|
||||
seq_printf(m, "\t\tMax TMDS clock: %d kHz\n", clk);
|
||||
}
|
||||
|
||||
bpc = drm_dp_downstream_max_bpc(dpcd, port_cap);
|
||||
|
||||
if (bpc > 0)
|
||||
seq_printf(m, "\t\tMax bpc: %d\n", bpc);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(drm_dp_downstream_debug);
|
||||
|
||||
/*
|
||||
* I2C-over-AUX implementation
|
||||
*/
|
||||
@@ -574,7 +749,17 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
|
||||
if (ret == -EBUSY)
|
||||
continue;
|
||||
|
||||
DRM_DEBUG_KMS("transaction failed: %d\n", ret);
|
||||
/*
|
||||
* While timeouts can be errors, they're usually normal
|
||||
* behavior (for instance, when a driver tries to
|
||||
* communicate with a non-existant DisplayPort device).
|
||||
* Avoid spamming the kernel log with timeout errors.
|
||||
*/
|
||||
if (ret == -ETIMEDOUT)
|
||||
DRM_DEBUG_KMS_RATELIMITED("transaction timed out\n");
|
||||
else
|
||||
DRM_DEBUG_KMS("transaction failed: %d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user