1
0

Merge tag 'drm-misc-next-2019-12-16' of git://anongit.freedesktop.org/drm/drm-misc into drm-next

drm-misc-next for v5.6:

UAPI Changes:
- Add support for DMA-BUF HEAPS.

Cross-subsystem Changes:
- mipi dsi definition updates, pulled into drm-intel as well.
- Add lockdep annotations for dma_resv vs mmap_sem and fs_reclaim.
- Remove support for dma-buf kmap/kunmap.
- Constify fb_ops in all fbdev drivers, including drm drivers and drm-core, and media as well.

Core Changes:
- Small cleanups to ttm.
- Fix SCDC definition.
- Assorted cleanups to core.
- Add todo to remove load/unload hooks, and use generic fbdev emulation.
- Assorted documentation updates.
- Use blocking ww lock in ttm fault handler.
- Remove drm_fb_helper_fbdev_setup/teardown.
- Warning fixes with W=1 for atomic.
- Use drm_debug_enabled() instead of drm_debug flag testing in various drivers.
- Fallback to nontiled mode in fbdev emulation when not all tiles are present. (Later on reverted)
- Various kconfig indentation fixes in core and drivers.
- Fix freeing transactions in dp-mst correctly.
- Sean Paul is steping down as core maintainer. :-(
- Add lockdep annotations for atomic locks vs dma-resv.
- Prevent use-after-free for a bad job in drm_scheduler.
- Fill out all block sizes in the P01x and P210 definitions.
- Avoid division by zero in drm/rect, and fix bounds.
- Add drm/rect selftests.
- Add aspect ratio and alternate clocks for HDMI 4k modes.
- Add todo for drm_framebuffer_funcs and fb_create cleanup.
- Drop DRM_AUTH for prime import/export ioctls.
- Clear DP-MST payload id tables downstream when initializating.
- Fix for DSC throughput definition.
- Add extra FEC definitions.
- Fix fake offset in drm_gem_object_funs.mmap.
- Stop using encoder->bridge in core directly
- Handle bridge chaining slightly better.
- Add backlight support to drm/panel, and use it in many panel drivers.
- Increase max number of y420 modes from 128 to 256, as preparation to add the new modes.

Driver Changes:
- Small fixes all over.
- Fix documentation in vkms.
- Fix mmap_sem vs dma_resv in nouveau.
- Small cleanup in komeda.
- Add page flip support in gma500 for psb/cdv.
- Add ddc symlink in the connector sysfs directory for many drivers.
- Add support for analogic an6345, and fix small bugs in it.
- Add atomic modesetting support to ast.
- Fix radeon fault handler VMA race.
- Switch udl to use generic shmem helpers.
- Unconditional vblank handling for mcde.
- Miscellaneous fixes to mcde.
- Tweak debug output from komeda using debugfs.
- Add gamma and color transform support to komeda for DOU-IPS.
- Add support for sony acx424AKP panel.
- Various small cleanups to gma500.
- Use generic fbdev emulation in udl, and replace udl_framebuffer with generic implementation.
- Add support for Logic PD Type 28 panel.
- Use drm_panel_* wrapper functions in exynos/tegra/msm.
- Add devicetree bindings for generic DSI panels.
- Don't include drm_pci.h directly in many drivers.
- Add support for begin/end_cpu_access in udmabuf.
- Stop using drm_get_pci_dev in gma500 and mga200.
- Fixes to UDL damage handling, and use dma_buf_begin/end_cpu_access.
- Add devfreq thermal support to panfrost.
- Fix hotplug with daisy chained monitors by removing VCPI when disabling topology manager.
- meson: Add support for OSD1 plane AFBC commit.
- Stop displaying garbage when toggling ast primary plane on/off.
- More cleanups and fixes to UDL.
- Add D32 suport to komeda.
- Remove globle copy of drm_dev in gma500.
- Add support for Boe Himax8279d MIPI-DSI LCD panel.
- Add support for ingenic JZ4770 panel.
- Small null pointer deference fix in ingenic.
- Remove support for the special tfp420 driver, as there is a generic way to do it.

Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>

From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/ba73535a-9334-5302-2e1f-5208bd7390bd@linux.intel.com
Este cometimento está contido em:
Daniel Vetter
2019-12-17 13:57:54 +01:00
ascendente d1eef1c619 2156873f08
cometimento 6c56e8adc0
506 ficheiros modificados com 9862 adições e 6114 eliminações

Ver ficheiro

@@ -39,7 +39,6 @@ struct mcde_dsi {
struct device *dev;
struct mcde *mcde;
struct drm_bridge bridge;
struct drm_connector connector;
struct drm_panel *panel;
struct drm_bridge *bridge_out;
struct mipi_dsi_host dsi_host;
@@ -64,11 +63,6 @@ static inline struct mcde_dsi *host_to_mcde_dsi(struct mipi_dsi_host *h)
return container_of(h, struct mcde_dsi, dsi_host);
}
static inline struct mcde_dsi *connector_to_mcde_dsi(struct drm_connector *c)
{
return container_of(c, struct mcde_dsi, connector);
}
bool mcde_dsi_irq(struct mipi_dsi_device *mdsi)
{
struct mcde_dsi *d;
@@ -124,12 +118,41 @@ bool mcde_dsi_irq(struct mipi_dsi_device *mdsi)
val = readl(d->regs + DSI_VID_MODE_STS_FLAG);
if (val)
dev_err(d->dev, "some video mode error status\n");
dev_dbg(d->dev, "DSI_VID_MODE_STS_FLAG = %08x\n", val);
if (val & DSI_VID_MODE_STS_VSG_RUNNING)
dev_dbg(d->dev, "VID mode VSG running\n");
if (val & DSI_VID_MODE_STS_ERR_MISSING_DATA)
dev_err(d->dev, "VID mode missing data\n");
if (val & DSI_VID_MODE_STS_ERR_MISSING_HSYNC)
dev_err(d->dev, "VID mode missing HSYNC\n");
if (val & DSI_VID_MODE_STS_ERR_MISSING_VSYNC)
dev_err(d->dev, "VID mode missing VSYNC\n");
if (val & DSI_VID_MODE_STS_REG_ERR_SMALL_LENGTH)
dev_err(d->dev, "VID mode less bytes than expected between two HSYNC\n");
if (val & DSI_VID_MODE_STS_REG_ERR_SMALL_HEIGHT)
dev_err(d->dev, "VID mode less lines than expected between two VSYNC\n");
if (val & (DSI_VID_MODE_STS_ERR_BURSTWRITE |
DSI_VID_MODE_STS_ERR_LINEWRITE |
DSI_VID_MODE_STS_ERR_LONGREAD))
dev_err(d->dev, "VID mode read/write error\n");
if (val & DSI_VID_MODE_STS_ERR_VRS_WRONG_LENGTH)
dev_err(d->dev, "VID mode received packets differ from expected size\n");
if (val & DSI_VID_MODE_STS_VSG_RECOVERY)
dev_err(d->dev, "VID mode VSG in recovery mode\n");
writel(val, d->regs + DSI_VID_MODE_STS_CLR);
return te_received;
}
static void mcde_dsi_attach_to_mcde(struct mcde_dsi *d)
{
d->mcde->mdsi = d->mdsi;
d->mcde->video_mode = !!(d->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO);
/* Enable use of the TE signal for all command mode panels */
d->mcde->te_sync = !d->mcde->video_mode;
}
static int mcde_dsi_host_attach(struct mipi_dsi_host *host,
struct mipi_dsi_device *mdsi)
{
@@ -148,7 +171,7 @@ static int mcde_dsi_host_attach(struct mipi_dsi_host *host,
d->mdsi = mdsi;
if (d->mcde)
d->mcde->mdsi = mdsi;
mcde_dsi_attach_to_mcde(d);
return 0;
}
@@ -223,25 +246,25 @@ static ssize_t mcde_dsi_host_transfer(struct mipi_dsi_host *host,
if (txlen > 0) {
val = 0;
for (i = 0; i < 4 && i < txlen; i++)
val |= tx[i] << (i & 3) * 8;
val |= tx[i] << (i * 8);
}
writel(val, d->regs + DSI_DIRECT_CMD_WRDAT0);
if (txlen > 4) {
val = 0;
for (i = 0; i < 4 && (i + 4) < txlen; i++)
val |= tx[i + 4] << (i & 3) * 8;
val |= tx[i + 4] << (i * 8);
writel(val, d->regs + DSI_DIRECT_CMD_WRDAT1);
}
if (txlen > 8) {
val = 0;
for (i = 0; i < 4 && (i + 8) < txlen; i++)
val |= tx[i + 8] << (i & 3) * 8;
val |= tx[i + 8] << (i * 8);
writel(val, d->regs + DSI_DIRECT_CMD_WRDAT2);
}
if (txlen > 12) {
val = 0;
for (i = 0; i < 4 && (i + 12) < txlen; i++)
val |= tx[i + 12] << (i & 3) * 8;
val |= tx[i + 12] << (i * 8);
writel(val, d->regs + DSI_DIRECT_CMD_WRDAT3);
}
@@ -336,7 +359,7 @@ void mcde_dsi_te_request(struct mipi_dsi_device *mdsi)
val |= 0 << DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_ID_SHIFT;
val |= 2 << DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_SIZE_SHIFT;
val |= DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_LP_EN;
val |= DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_HEAD_DCS_SHORT_WRITE_1 <<
val |= MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM <<
DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_HEAD_SHIFT;
writel(val, d->regs + DSI_DIRECT_CMD_MAIN_SETTINGS);
@@ -539,26 +562,6 @@ static void mcde_dsi_setup_video_mode(struct mcde_dsi *d,
DSI_VID_VCA_SETTING2_EXACT_BURST_LIMIT_SHIFT;
writel(val, d->regs + DSI_VID_VCA_SETTING2);
/* Put IF1 into video mode */
val = readl(d->regs + DSI_MCTL_MAIN_DATA_CTL);
val |= DSI_MCTL_MAIN_DATA_CTL_IF1_MODE;
writel(val, d->regs + DSI_MCTL_MAIN_DATA_CTL);
/* Disable command mode on IF1 */
val = readl(d->regs + DSI_CMD_MODE_CTL);
val &= ~DSI_CMD_MODE_CTL_IF1_LP_EN;
writel(val, d->regs + DSI_CMD_MODE_CTL);
/* Enable some error interrupts */
val = readl(d->regs + DSI_VID_MODE_STS_CTL);
val |= DSI_VID_MODE_STS_CTL_ERR_MISSING_VSYNC;
val |= DSI_VID_MODE_STS_CTL_ERR_MISSING_DATA;
writel(val, d->regs + DSI_VID_MODE_STS_CTL);
/* Enable video mode */
val = readl(d->regs + DSI_MCTL_MAIN_DATA_CTL);
val |= DSI_MCTL_MAIN_DATA_CTL_VID_EN;
writel(val, d->regs + DSI_MCTL_MAIN_DATA_CTL);
}
static void mcde_dsi_start(struct mcde_dsi *d)
@@ -670,30 +673,25 @@ static void mcde_dsi_start(struct mcde_dsi *d)
static void mcde_dsi_bridge_enable(struct drm_bridge *bridge)
{
struct mcde_dsi *d = bridge_to_mcde_dsi(bridge);
u32 val;
if (d->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO) {
/* Enable video mode */
val = readl(d->regs + DSI_MCTL_MAIN_DATA_CTL);
val |= DSI_MCTL_MAIN_DATA_CTL_VID_EN;
writel(val, d->regs + DSI_MCTL_MAIN_DATA_CTL);
}
dev_info(d->dev, "enable DSI master\n");
};
static void mcde_dsi_bridge_mode_set(struct drm_bridge *bridge,
const struct drm_display_mode *mode,
const struct drm_display_mode *adj)
static void mcde_dsi_bridge_pre_enable(struct drm_bridge *bridge)
{
struct mcde_dsi *d = bridge_to_mcde_dsi(bridge);
unsigned long pixel_clock_hz = mode->clock * 1000;
unsigned long hs_freq, lp_freq;
u32 val;
int ret;
if (!d->mdsi) {
dev_err(d->dev, "no DSI device attached to encoder!\n");
return;
}
dev_info(d->dev, "set DSI master to %dx%d %lu Hz %s mode\n",
mode->hdisplay, mode->vdisplay, pixel_clock_hz,
(d->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO) ? "VIDEO" : "CMD"
);
/* Copy maximum clock frequencies */
if (d->mdsi->lp_rate)
lp_freq = d->mdsi->lp_rate;
@@ -732,7 +730,21 @@ static void mcde_dsi_bridge_mode_set(struct drm_bridge *bridge,
d->hs_freq);
if (d->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO) {
mcde_dsi_setup_video_mode(d, mode);
/* Put IF1 into video mode */
val = readl(d->regs + DSI_MCTL_MAIN_DATA_CTL);
val |= DSI_MCTL_MAIN_DATA_CTL_IF1_MODE;
writel(val, d->regs + DSI_MCTL_MAIN_DATA_CTL);
/* Disable command mode on IF1 */
val = readl(d->regs + DSI_CMD_MODE_CTL);
val &= ~DSI_CMD_MODE_CTL_IF1_LP_EN;
writel(val, d->regs + DSI_CMD_MODE_CTL);
/* Enable some error interrupts */
val = readl(d->regs + DSI_VID_MODE_STS_CTL);
val |= DSI_VID_MODE_STS_CTL_ERR_MISSING_VSYNC;
val |= DSI_VID_MODE_STS_CTL_ERR_MISSING_DATA;
writel(val, d->regs + DSI_VID_MODE_STS_CTL);
} else {
/* Command mode, clear IF1 ID */
val = readl(d->regs + DSI_CMD_MODE_CTL);
@@ -746,6 +758,26 @@ static void mcde_dsi_bridge_mode_set(struct drm_bridge *bridge,
}
}
static void mcde_dsi_bridge_mode_set(struct drm_bridge *bridge,
const struct drm_display_mode *mode,
const struct drm_display_mode *adj)
{
struct mcde_dsi *d = bridge_to_mcde_dsi(bridge);
if (!d->mdsi) {
dev_err(d->dev, "no DSI device attached to encoder!\n");
return;
}
dev_info(d->dev, "set DSI master to %dx%d %u Hz %s mode\n",
mode->hdisplay, mode->vdisplay, mode->clock * 1000,
(d->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO) ? "VIDEO" : "CMD"
);
if (d->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO)
mcde_dsi_setup_video_mode(d, mode);
}
static void mcde_dsi_wait_for_command_mode_stop(struct mcde_dsi *d)
{
u32 val;
@@ -811,67 +843,23 @@ static void mcde_dsi_bridge_disable(struct drm_bridge *bridge)
clk_disable_unprepare(d->lp_clk);
}
/*
* This connector needs no special handling, just use the default
* helpers for everything. It's pretty dummy.
*/
static const struct drm_connector_funcs mcde_dsi_connector_funcs = {
.reset = drm_atomic_helper_connector_reset,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = drm_connector_cleanup,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
};
static int mcde_dsi_get_modes(struct drm_connector *connector)
{
struct mcde_dsi *d = connector_to_mcde_dsi(connector);
/* Just pass the question to the panel */
if (d->panel)
return drm_panel_get_modes(d->panel);
/* TODO: deal with bridges */
return 0;
}
static const struct drm_connector_helper_funcs
mcde_dsi_connector_helper_funcs = {
.get_modes = mcde_dsi_get_modes,
};
static int mcde_dsi_bridge_attach(struct drm_bridge *bridge)
{
struct mcde_dsi *d = bridge_to_mcde_dsi(bridge);
struct drm_device *drm = bridge->dev;
int ret;
drm_connector_helper_add(&d->connector,
&mcde_dsi_connector_helper_funcs);
if (!drm_core_check_feature(drm, DRIVER_ATOMIC)) {
dev_err(d->dev, "we need atomic updates\n");
return -ENOTSUPP;
}
ret = drm_connector_init(drm, &d->connector,
&mcde_dsi_connector_funcs,
DRM_MODE_CONNECTOR_DSI);
if (ret) {
dev_err(d->dev, "failed to initialize DSI bridge connector\n");
return ret;
}
d->connector.polled = DRM_CONNECTOR_POLL_CONNECT;
/* The encoder in the bridge attached to the DSI bridge */
drm_connector_attach_encoder(&d->connector, bridge->encoder);
/* Then we attach the DSI bridge to the output (panel etc) bridge */
/* Attach the DSI bridge to the output (panel etc) bridge */
ret = drm_bridge_attach(bridge->encoder, d->bridge_out, bridge);
if (ret) {
dev_err(d->dev, "failed to attach the DSI bridge\n");
return ret;
}
d->connector.status = connector_status_connected;
return 0;
}
@@ -881,6 +869,7 @@ static const struct drm_bridge_funcs mcde_dsi_bridge_funcs = {
.mode_set = mcde_dsi_bridge_mode_set,
.disable = mcde_dsi_bridge_disable,
.enable = mcde_dsi_bridge_enable,
.pre_enable = mcde_dsi_bridge_pre_enable,
};
static int mcde_dsi_bind(struct device *dev, struct device *master,
@@ -901,7 +890,7 @@ static int mcde_dsi_bind(struct device *dev, struct device *master,
d->mcde = mcde;
/* If the display attached before binding, set this up */
if (d->mdsi)
d->mcde->mdsi = d->mdsi;
mcde_dsi_attach_to_mcde(d);
/* Obtain the clocks */
d->hs_clk = devm_clk_get(dev, "hs");