Merge tag 'drm-misc-next-2019-05-24' of git://anongit.freedesktop.org/drm/drm-misc into drm-next
drm-misc-next for v5.3, try #2: UAPI Changes: - Add HDR source metadata property. - Make drm.h compile on GNU/kFreeBSD by including stdint.h - Clarify how the userspace reviewer has to review new kernel UAPI. - Clarify that for using new UAPI, merging to drm-next or drm-misc-next should be enough. Cross-subsystem Changes: - video/hdmi: Add unpack function for DRM infoframes. - Device tree bindings: * Updating a property for Mali Midgard GPUs * Updating a property for STM32 DSI panel * Adding support for FriendlyELEC HD702E 800x1280 panel * Adding support for Evervision VGG804821 800x480 5.0" WVGA TFT panel * Adding support for the EDT ET035012DM6 3.5" 320x240 QVGA 24-bit RGB TFT. * Adding support for Three Five displays TFC S9700RTWV43TR-01B 800x480 panel with resistive touch found on TI's AM335X-EVM. * Adding support for EDT ETM0430G0DH6 480x272 panel. - Add OSD101T2587-53TS driver with DT bindings. - Add Samsung S6E63M0 panel driver with DT bindings. - Add VXT VL050-8048NT-C01 800x480 panel with DT bindings. - Dma-buf: - Make mmap callback actually optional. - Documentation updates. - Fix debugfs refcount inbalance. - Remove unused sync_dump function. - Fix device tree bindings in drm-misc-next after a botched merge. Core Changes: - Add support for HDR infoframes and related EDID parsing. - Remove prime sg_table caching, now done inside dma-buf. - Add shiny new drm_gem_vram helpers for simple VRAM drivers; with some fixes to the new API on top. - Small fix to job cleanup without timeout handler. - Documentation fixes to drm_fourcc. - Replace lookups of drm_format with struct drm_format_info; remove functions that become obsolete by this conversion. - Remove double include in bridge/panel.c and some drivers. - Remove drmP.h include from drm/edid and drm/dp. - Fix null pointer deref in drm_fb_helper_hotplug_event(). - Remove most members from drm_fb_helper_crtc, only mode_set is kept. - Remove race of fb helpers with userspace; only restore mode when userspace is not master. - Move legacy setup from drm_file.c to drm_legacy_misc.c - Rework scheduler job destruction. - drm/bus was removed, remove from TODO. - Add __drm_atomic_helper_crtc_reset() to subclass crtc_state, and convert some drivers to use it (conversion is not complete yet). - Bump vblank timeout wait to 100 ms for atomic. - Docbook fix for drm_hdmi_infoframe_set_hdr_metadata. Driver Changes: - sun4i: Use DRM_GEM_CMA_VMAP_DRIVER_OPS instead of definining manually. - v3d: Small cleanups, adding support for compute shaders, reservation/synchronization fixes and job management refactoring, fixes MMU and debugfs. - lima: Fix null pointer in irq handler on startup, set default timeout for scheduled jobs. - stm/ltdc: Assorted fixes and adding FB modifier support. - amdgpu: Avoid hw reset if guilty job was already signaled. - virtio: Add seqno to fences, add trace events, use correct flags for fence allocation. - Convert AST, bochs, mgag200, vboxvideo, hisilicon to the new drm_gem_vram API. - sun6i_mipi_dsi: Support DSI GENERIC_SHORT_WRITE_2 transfers. - bochs: Small fix to use PTR_RET_OR_ZERO and driver unload. - gma500: header fixes - cirrus: Remove unused files. - mediatek: Fix compiler warning after merging the HDR series. - vc4: Rework binner bo handling. Signed-off-by: Dave Airlie <airlied@redhat.com> From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/052875a5-27ba-3832-60c2-193d950afdff@linux.intel.com
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
#include <linux/clk.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <drm/drmP.h>
|
||||
#include <drm/drm_mipi_dsi.h>
|
||||
#include <drm/bridge/dw_mipi_dsi.h>
|
||||
@@ -76,6 +77,7 @@ struct dw_mipi_dsi_stm {
|
||||
u32 hw_version;
|
||||
int lane_min_kbps;
|
||||
int lane_max_kbps;
|
||||
struct regulator *vdd_supply;
|
||||
};
|
||||
|
||||
static inline void dsi_write(struct dw_mipi_dsi_stm *dsi, u32 reg, u32 val)
|
||||
@@ -314,21 +316,36 @@ static int dw_mipi_dsi_stm_probe(struct platform_device *pdev)
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
dsi->base = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(dsi->base)) {
|
||||
DRM_ERROR("Unable to get dsi registers\n");
|
||||
return PTR_ERR(dsi->base);
|
||||
ret = PTR_ERR(dsi->base);
|
||||
DRM_ERROR("Unable to get dsi registers %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dsi->vdd_supply = devm_regulator_get(dev, "phy-dsi");
|
||||
if (IS_ERR(dsi->vdd_supply)) {
|
||||
ret = PTR_ERR(dsi->vdd_supply);
|
||||
if (ret != -EPROBE_DEFER)
|
||||
DRM_ERROR("Failed to request regulator: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = regulator_enable(dsi->vdd_supply);
|
||||
if (ret) {
|
||||
DRM_ERROR("Failed to enable regulator: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dsi->pllref_clk = devm_clk_get(dev, "ref");
|
||||
if (IS_ERR(dsi->pllref_clk)) {
|
||||
ret = PTR_ERR(dsi->pllref_clk);
|
||||
dev_err(dev, "Unable to get pll reference clock: %d\n", ret);
|
||||
return ret;
|
||||
DRM_ERROR("Unable to get pll reference clock: %d\n", ret);
|
||||
goto err_clk_get;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(dsi->pllref_clk);
|
||||
if (ret) {
|
||||
dev_err(dev, "%s: Failed to enable pllref_clk\n", __func__);
|
||||
return ret;
|
||||
DRM_ERROR("Failed to enable pllref_clk: %d\n", ret);
|
||||
goto err_clk_get;
|
||||
}
|
||||
|
||||
dw_mipi_dsi_stm_plat_data.base = dsi->base;
|
||||
@@ -338,20 +355,28 @@ static int dw_mipi_dsi_stm_probe(struct platform_device *pdev)
|
||||
|
||||
dsi->dsi = dw_mipi_dsi_probe(pdev, &dw_mipi_dsi_stm_plat_data);
|
||||
if (IS_ERR(dsi->dsi)) {
|
||||
DRM_ERROR("Failed to initialize mipi dsi host\n");
|
||||
clk_disable_unprepare(dsi->pllref_clk);
|
||||
return PTR_ERR(dsi->dsi);
|
||||
ret = PTR_ERR(dsi->dsi);
|
||||
DRM_ERROR("Failed to initialize mipi dsi host: %d\n", ret);
|
||||
goto err_dsi_probe;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_dsi_probe:
|
||||
clk_disable_unprepare(dsi->pllref_clk);
|
||||
err_clk_get:
|
||||
regulator_disable(dsi->vdd_supply);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int dw_mipi_dsi_stm_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct dw_mipi_dsi_stm *dsi = platform_get_drvdata(pdev);
|
||||
|
||||
clk_disable_unprepare(dsi->pllref_clk);
|
||||
dw_mipi_dsi_remove(dsi->dsi);
|
||||
clk_disable_unprepare(dsi->pllref_clk);
|
||||
regulator_disable(dsi->vdd_supply);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -363,6 +388,7 @@ static int __maybe_unused dw_mipi_dsi_stm_suspend(struct device *dev)
|
||||
DRM_DEBUG_DRIVER("\n");
|
||||
|
||||
clk_disable_unprepare(dsi->pllref_clk);
|
||||
regulator_disable(dsi->vdd_supply);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -370,10 +396,22 @@ static int __maybe_unused dw_mipi_dsi_stm_suspend(struct device *dev)
|
||||
static int __maybe_unused dw_mipi_dsi_stm_resume(struct device *dev)
|
||||
{
|
||||
struct dw_mipi_dsi_stm *dsi = dw_mipi_dsi_stm_plat_data.priv_data;
|
||||
int ret;
|
||||
|
||||
DRM_DEBUG_DRIVER("\n");
|
||||
|
||||
clk_prepare_enable(dsi->pllref_clk);
|
||||
ret = regulator_enable(dsi->vdd_supply);
|
||||
if (ret) {
|
||||
DRM_ERROR("Failed to enable regulator: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(dsi->pllref_clk);
|
||||
if (ret) {
|
||||
regulator_disable(dsi->vdd_supply);
|
||||
DRM_ERROR("Failed to enable pllref_clk: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -232,6 +232,11 @@ static const enum ltdc_pix_fmt ltdc_pix_fmt_a1[NB_PF] = {
|
||||
PF_ARGB4444 /* 0x07 */
|
||||
};
|
||||
|
||||
static const u64 ltdc_format_modifiers[] = {
|
||||
DRM_FORMAT_MOD_LINEAR,
|
||||
DRM_FORMAT_MOD_INVALID
|
||||
};
|
||||
|
||||
static inline u32 reg_read(void __iomem *base, u32 reg)
|
||||
{
|
||||
return readl_relaxed(base + reg);
|
||||
@@ -426,8 +431,8 @@ static void ltdc_crtc_atomic_enable(struct drm_crtc *crtc,
|
||||
/* Enable IRQ */
|
||||
reg_set(ldev->regs, LTDC_IER, IER_RRIE | IER_FUIE | IER_TERRIE);
|
||||
|
||||
/* Immediately commit the planes */
|
||||
reg_set(ldev->regs, LTDC_SRCR, SRCR_IMR);
|
||||
/* Commit shadow registers = update planes at next vblank */
|
||||
reg_set(ldev->regs, LTDC_SRCR, SRCR_VBR);
|
||||
|
||||
/* Enable LTDC */
|
||||
reg_set(ldev->regs, LTDC_GCR, GCR_LTDCEN);
|
||||
@@ -555,7 +560,7 @@ static void ltdc_crtc_mode_set_nofb(struct drm_crtc *crtc)
|
||||
if (vm.flags & DISPLAY_FLAGS_VSYNC_HIGH)
|
||||
val |= GCR_VSPOL;
|
||||
|
||||
if (vm.flags & DISPLAY_FLAGS_DE_HIGH)
|
||||
if (vm.flags & DISPLAY_FLAGS_DE_LOW)
|
||||
val |= GCR_DEPOL;
|
||||
|
||||
if (vm.flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE)
|
||||
@@ -779,7 +784,7 @@ static void ltdc_plane_atomic_update(struct drm_plane *plane,
|
||||
|
||||
/* Configures the color frame buffer pitch in bytes & line length */
|
||||
pitch_in_bytes = fb->pitches[0];
|
||||
line_length = drm_format_plane_cpp(fb->format->format, 0) *
|
||||
line_length = fb->format->cpp[0] *
|
||||
(x1 - x0 + 1) + (ldev->caps.bus_width >> 3) - 1;
|
||||
val = ((pitch_in_bytes << 16) | line_length);
|
||||
reg_update_bits(ldev->regs, LTDC_L1CFBLR + lofs,
|
||||
@@ -822,11 +827,11 @@ static void ltdc_plane_atomic_update(struct drm_plane *plane,
|
||||
|
||||
mutex_lock(&ldev->err_lock);
|
||||
if (ldev->error_status & ISR_FUIF) {
|
||||
DRM_DEBUG_DRIVER("Fifo underrun\n");
|
||||
DRM_WARN("ltdc fifo underrun: please verify display mode\n");
|
||||
ldev->error_status &= ~ISR_FUIF;
|
||||
}
|
||||
if (ldev->error_status & ISR_TERRIF) {
|
||||
DRM_DEBUG_DRIVER("Transfer error\n");
|
||||
DRM_WARN("ltdc transfer error\n");
|
||||
ldev->error_status &= ~ISR_TERRIF;
|
||||
}
|
||||
mutex_unlock(&ldev->err_lock);
|
||||
@@ -864,6 +869,16 @@ static void ltdc_plane_atomic_print_state(struct drm_printer *p,
|
||||
fpsi->counter = 0;
|
||||
}
|
||||
|
||||
static bool ltdc_plane_format_mod_supported(struct drm_plane *plane,
|
||||
u32 format,
|
||||
u64 modifier)
|
||||
{
|
||||
if (modifier == DRM_FORMAT_MOD_LINEAR)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static const struct drm_plane_funcs ltdc_plane_funcs = {
|
||||
.update_plane = drm_atomic_helper_update_plane,
|
||||
.disable_plane = drm_atomic_helper_disable_plane,
|
||||
@@ -872,6 +887,7 @@ static const struct drm_plane_funcs ltdc_plane_funcs = {
|
||||
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
|
||||
.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
|
||||
.atomic_print_state = ltdc_plane_atomic_print_state,
|
||||
.format_mod_supported = ltdc_plane_format_mod_supported,
|
||||
};
|
||||
|
||||
static const struct drm_plane_helper_funcs ltdc_plane_helper_funcs = {
|
||||
@@ -890,6 +906,7 @@ static struct drm_plane *ltdc_plane_create(struct drm_device *ddev,
|
||||
unsigned int i, nb_fmt = 0;
|
||||
u32 formats[NB_PF * 2];
|
||||
u32 drm_fmt, drm_fmt_no_alpha;
|
||||
const u64 *modifiers = ltdc_format_modifiers;
|
||||
int ret;
|
||||
|
||||
/* Get supported pixel formats */
|
||||
@@ -918,7 +935,7 @@ static struct drm_plane *ltdc_plane_create(struct drm_device *ddev,
|
||||
|
||||
ret = drm_universal_plane_init(ddev, plane, possible_crtcs,
|
||||
<dc_plane_funcs, formats, nb_fmt,
|
||||
NULL, type, NULL);
|
||||
modifiers, type, NULL);
|
||||
if (ret < 0)
|
||||
return NULL;
|
||||
|
||||
@@ -1021,10 +1038,13 @@ static int ltdc_get_caps(struct drm_device *ddev)
|
||||
struct ltdc_device *ldev = ddev->dev_private;
|
||||
u32 bus_width_log2, lcr, gc2r;
|
||||
|
||||
/* at least 1 layer must be managed */
|
||||
/*
|
||||
* at least 1 layer must be managed & the number of layers
|
||||
* must not exceed LTDC_MAX_LAYER
|
||||
*/
|
||||
lcr = reg_read(ldev->regs, LTDC_LCR);
|
||||
|
||||
ldev->caps.nb_layers = max_t(int, lcr, 1);
|
||||
ldev->caps.nb_layers = clamp((int)lcr, 1, LTDC_MAX_LAYER);
|
||||
|
||||
/* set data bus width */
|
||||
gc2r = reg_read(ldev->regs, LTDC_GC2R);
|
||||
@@ -1125,8 +1145,9 @@ int ltdc_load(struct drm_device *ddev)
|
||||
|
||||
ldev->pixel_clk = devm_clk_get(dev, "lcd");
|
||||
if (IS_ERR(ldev->pixel_clk)) {
|
||||
DRM_ERROR("Unable to get lcd clock\n");
|
||||
return -ENODEV;
|
||||
if (PTR_ERR(ldev->pixel_clk) != -EPROBE_DEFER)
|
||||
DRM_ERROR("Unable to get lcd clock\n");
|
||||
return PTR_ERR(ldev->pixel_clk);
|
||||
}
|
||||
|
||||
if (clk_prepare_enable(ldev->pixel_clk)) {
|
||||
@@ -1134,6 +1155,12 @@ int ltdc_load(struct drm_device *ddev)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (!IS_ERR(rstc)) {
|
||||
reset_control_assert(rstc);
|
||||
usleep_range(10, 20);
|
||||
reset_control_deassert(rstc);
|
||||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
ldev->regs = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(ldev->regs)) {
|
||||
@@ -1142,8 +1169,15 @@ int ltdc_load(struct drm_device *ddev)
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Disable interrupts */
|
||||
reg_clear(ldev->regs, LTDC_IER,
|
||||
IER_LIE | IER_RRIE | IER_FUIE | IER_TERRIE);
|
||||
|
||||
for (i = 0; i < MAX_IRQ; i++) {
|
||||
irq = platform_get_irq(pdev, i);
|
||||
if (irq == -EPROBE_DEFER)
|
||||
goto err;
|
||||
|
||||
if (irq < 0)
|
||||
continue;
|
||||
|
||||
@@ -1156,15 +1190,6 @@ int ltdc_load(struct drm_device *ddev)
|
||||
}
|
||||
}
|
||||
|
||||
if (!IS_ERR(rstc)) {
|
||||
reset_control_assert(rstc);
|
||||
usleep_range(10, 20);
|
||||
reset_control_deassert(rstc);
|
||||
}
|
||||
|
||||
/* Disable interrupts */
|
||||
reg_clear(ldev->regs, LTDC_IER,
|
||||
IER_LIE | IER_RRIE | IER_FUIE | IER_TERRIE);
|
||||
|
||||
ret = ltdc_get_caps(ddev);
|
||||
if (ret) {
|
||||
@@ -1203,6 +1228,8 @@ int ltdc_load(struct drm_device *ddev)
|
||||
goto err;
|
||||
}
|
||||
|
||||
ddev->mode_config.allow_fb_modifiers = true;
|
||||
|
||||
ret = ltdc_crtc_init(ddev, crtc);
|
||||
if (ret) {
|
||||
DRM_ERROR("Failed to init crtc\n");
|
||||
|
Reference in New Issue
Block a user