[PATCH 05/33] drm/omap: partial workaround for DRA7 DMM errata i878
Hi Tomi, Thank you for the patch. On Friday 19 February 2016 11:47:40 Tomi Valkeinen wrote: > Errata i878 says that MPU should not be used to access RAM and DMM at > the same time. As it's not possible to prevent MPU accessing RAM, we > need to access DMM via a proxy. > > This patch changes DMM driver to access DMM registers via sDMA. Instead > of doing a normal readl/writel call to read/write a register, we use > sDMA to copy 4 bytes from/to the DMM registers. > > This patch provides only a partial workaround for i878, as not only DMM > register reads/writes are affected, but also accesses to the DMM mapped > buffers (framebuffers, usually). Will this patch really improve the situation if the DMM mapping is accessed anyway ? > Signed-off-by: Tomi Valkeinen > --- > Documentation/devicetree/bindings/arm/omap/dmm.txt | 3 +- > drivers/gpu/drm/omapdrm/omap_dmm_priv.h| 8 ++ > drivers/gpu/drm/omapdrm/omap_dmm_tiler.c | 141 +- > 3 files changed, 149 insertions(+), 3 deletions(-) > > diff --git a/Documentation/devicetree/bindings/arm/omap/dmm.txt > b/Documentation/devicetree/bindings/arm/omap/dmm.txt index > 8bd6d0a238a8..e5fc2eb7f4da 100644 > --- a/Documentation/devicetree/bindings/arm/omap/dmm.txt > +++ b/Documentation/devicetree/bindings/arm/omap/dmm.txt > @@ -8,7 +8,8 @@ translation for initiators which need contiguous dma bus > addresses. > > Required properties: > - compatible:Should contain "ti,omap4-dmm" for OMAP4 family > - Should contain "ti,omap5-dmm" for OMAP5 and DRA7x family > + Should contain "ti,omap5-dmm" for OMAP5 family > + Should contain "ti,dra7-dmm" for DRA7x family Isn't it DRA7xx instead of DRA7x ? > - reg: Contains DMM register address range (base address and > length) > - interrupts:Should contain an interrupt-specifier for DMM_IRQ. > - ti,hwmods: Name of the hwmod associated to DMM, which is typically "dmm" > diff --git a/drivers/gpu/drm/omapdrm/omap_dmm_priv.h > b/drivers/gpu/drm/omapdrm/omap_dmm_priv.h index 9f32a83ca507..4d292ba5bcca > 100644 > --- a/drivers/gpu/drm/omapdrm/omap_dmm_priv.h > +++ b/drivers/gpu/drm/omapdrm/omap_dmm_priv.h > @@ -155,10 +155,12 @@ struct refill_engine { > > struct dmm_platform_data { > uint32_t cpu_cache_flags; > + bool errata_i878_wa; > }; > > struct dmm { > struct device *dev; > + u32 phys_base; > void __iomem *base; > int irq; > > @@ -189,6 +191,12 @@ struct dmm { > struct list_head alloc_head; > > const struct dmm_platform_data *plat_data; > + > + bool dmm_workaround; > + spinlock_t wa_lock; > + u32 *wa_dma_data; > + dma_addr_t wa_dma_handle; > + struct dma_chan *wa_dma_chan; > }; > > #endif > diff --git a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c > b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c index fe5260477b52..3ec5c6633585 > 100644 > --- a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c > +++ b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c > @@ -19,6 +19,7 @@ > #include > #include > #include > +#include > #include > #include > #include > @@ -79,14 +80,124 @@ static const uint32_t reg[][4] = { > DMM_PAT_DESCR__2, DMM_PAT_DESCR__3}, > }; > > +static int dmm_dma_copy(struct dmm *dmm, u32 src, u32 dst) Anything wrong with using dma_addr_t ? > +{ > + struct dma_device *dma_dev = dmm->wa_dma_chan->device; > + struct dma_async_tx_descriptor *tx = NULL; No need to initialize tx to NULL. > + enum dma_status status; > + dma_cookie_t cookie; > + > + tx = dma_dev->device_prep_dma_memcpy(dmm->wa_dma_chan, dst, src, 4, 0); Given that you're transferring between an I/O mapped register and system memory, I believe you should use dmaengine_prep_slave_single() instead, with a call to dmaengine_slave_config() to set the I/O mapped register physical address. You will also need to request a slave DMA channel instead of a memcpy DMA channel. > + if (!tx) { > + dev_err(dmm->dev, "Failed to prepare DMA memcpy\n"); > + return -EIO; > + } > + > + cookie = tx->tx_submit(tx); > + if (dma_submit_error(cookie)) { > + dev_err(dmm->dev, "Failed to do DMA tx_submit\n"); > + return -EIO; > + } > + > + dma_async_issue_pending(dmm->wa_dma_chan); > + status = dma_sync_wait(dmm->wa_dma_chan, cookie); > + if (status != DMA_COMPLETE) > + dev_err(dmm->dev, "i878 wa DMA copy failure\n"); > + > + dmaengine_terminate_all(dmm->wa_dma_chan); > + return 0; > +} > + > +static u32 dmm_read_wa(struct dmm *dmm, u32 reg) > +{ > + u32 src, dst; > + int r; > + > + src = (u32)(dmm->phys_base + reg); > + dst = (u32)dmm->wa_dma_handle; > + > + r = dmm_dma_copy(dmm, src, dst); > + if (r) { > + dev_err(dmm->dev, "sDMA read transfer timeout\n"); > + return readl(dmm->base + reg); > + } > + > + return
Summer of Code Ideas
Hi, I am Abheek Ghosh, sophomore from Indian Institute of Technology, Guwahati. I read the Summer of Code and DRM pages, as well as Mehul's discussion but didn't get much help. I have strong C/C++ skills and familiar with OpenCL. I have Intel CPU and Nvidia GPU of Fermi architecture. I have made small contributions to open source projects. I don't have experience in kernel level development, but very interested to get my hands dirty. It would be helpful if any developer can help me get started with some suitable projects related to available hardware or any hardware independent projects in OpenCL, OpenGL or Mesa. Awaiting a positive response. Regards, Abheek Ghosh -- next part -- An HTML attachment was scrubbed... URL: <https://lists.freedesktop.org/archives/dri-devel/attachments/20160223/1037eab6/attachment.html>
[PATCH] drm/rockchip: support prime fd import
Hi Zach, On 2 February 2016 at 23:37, Zach Reizner wrote: > The prime fd to handle ioctl was not used with rockchip before. Support > was added in order to support potential uses (e.g. zero-copy video > decode, camera). > Similar patch came around a few months ago and got this reply [1]. If the situation has changed (there is an open-source driver/user for this) it should be clearly mentioned in the commit message, as opposed to "in order to support potential uses". Regards, Emil [1] https://lists.freedesktop.org/archives/dri-devel/2015-November/094568.html
[PATCH] drm/rockchip: support prime fd import
On Tue, Feb 23, 2016 at 3:56 PM, Rob Clark wrote: > On Tue, Feb 23, 2016 at 6:29 PM, Emil Velikov > wrote: >> Hi Zach, >> >> On 2 February 2016 at 23:37, Zach Reizner wrote: >>> The prime fd to handle ioctl was not used with rockchip before. Support >>> was added in order to support potential uses (e.g. zero-copy video >>> decode, camera). >>> >> Similar patch came around a few months ago and got this reply [1]. If >> the situation has changed (there is an open-source driver/user for >> this) it should be clearly mentioned in the commit message, as opposed >> to "in order to support potential uses". > > hmm, well it is not driver specific uabi, and we have let several > other mali/img users do prime.. > > I'm not sure, maybe those platforms can do a basic v4l <-> display > thing w/ prime. Although upstream tends to hurt a bit for camera > support.. There used to be vgem, but that was reverted... Stéphane > > BR, > -R > >> Regards, >> Emil >> >> [1] >> https://lists.freedesktop.org/archives/dri-devel/2015-November/094568.html >> ___ >> dri-devel mailing list >> dri-devel at lists.freedesktop.org >> https://lists.freedesktop.org/mailman/listinfo/dri-devel > ___ > dri-devel mailing list > dri-devel at lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 04/33] drm/omap: add dmm_read() and dmm_write() wrappers
Hi Tomi, Thank you for the patch. On Friday 19 February 2016 11:47:39 Tomi Valkeinen wrote: > This patch adds wrapper functions for readl() and writel(), dmm_read() > and dmm_write(), so that we can implement workaround for errata i878. > > Signed-off-by: Tomi Valkeinen Reviewed-by: Laurent Pinchart > --- > drivers/gpu/drm/omapdrm/omap_dmm_tiler.c | 39 ++--- > 1 file changed, 24 insertions(+), 15 deletions(-) > > diff --git a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c > b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c index 4e04f9487375..fe5260477b52 > 100644 > --- a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c > +++ b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c > @@ -79,6 +79,16 @@ static const uint32_t reg[][4] = { > DMM_PAT_DESCR__2, DMM_PAT_DESCR__3}, > }; > > +static u32 dmm_read(struct dmm *dmm, u32 reg) > +{ > + return readl(dmm->base + reg); > +} > + > +static void dmm_write(struct dmm *dmm, u32 val, u32 reg) > +{ > + writel(val, dmm->base + reg); > +} > + > /* simple allocator to grab next 16 byte aligned memory from txn */ > static void *alloc_dma(struct dmm_txn *txn, size_t sz, dma_addr_t *pa) > { > @@ -108,7 +118,7 @@ static int wait_status(struct refill_engine *engine, > uint32_t wait_mask) > > i = DMM_FIXED_RETRY_COUNT; > while (true) { > - r = readl(dmm->base + reg[PAT_STATUS][engine->id]); > + r = dmm_read(dmm, reg[PAT_STATUS][engine->id]); > err = r & DMM_PATSTATUS_ERR; > if (err) > return -EFAULT; > @@ -140,11 +150,11 @@ static void release_engine(struct refill_engine > *engine) static irqreturn_t omap_dmm_irq_handler(int irq, void *arg) > { > struct dmm *dmm = arg; > - uint32_t status = readl(dmm->base + DMM_PAT_IRQSTATUS); > + uint32_t status = dmm_read(dmm, DMM_PAT_IRQSTATUS); > int i; > > /* ack IRQ */ > - writel(status, dmm->base + DMM_PAT_IRQSTATUS); > + dmm_write(dmm, status, DMM_PAT_IRQSTATUS); > > for (i = 0; i < dmm->num_engines; i++) { > if (status & DMM_IRQSTAT_LST) { > @@ -275,7 +285,7 @@ static int dmm_txn_commit(struct dmm_txn *txn, bool > wait) readl(>last_pat->next_pa); > > /* write to PAT_DESCR to clear out any pending transaction */ > - writel(0x0, dmm->base + reg[PAT_DESCR][engine->id]); > + dmm_write(dmm, 0x0, reg[PAT_DESCR][engine->id]); > > /* wait for engine ready: */ > ret = wait_status(engine, DMM_PATSTATUS_READY); > @@ -291,8 +301,7 @@ static int dmm_txn_commit(struct dmm_txn *txn, bool > wait) smp_mb(); > > /* kick reload */ > - writel(engine->refill_pa, > - dmm->base + reg[PAT_DESCR][engine->id]); > + dmm_write(dmm, engine->refill_pa, reg[PAT_DESCR][engine->id]); > > if (wait) { > if (!wait_for_completion_timeout(>compl, > @@ -659,7 +668,7 @@ static int omap_dmm_probe(struct platform_device *dev) > > omap_dmm->dev = >dev; > > - hwinfo = readl(omap_dmm->base + DMM_PAT_HWINFO); > + hwinfo = dmm_read(omap_dmm, DMM_PAT_HWINFO); > omap_dmm->num_engines = (hwinfo >> 24) & 0x1F; > omap_dmm->num_lut = (hwinfo >> 16) & 0x1F; > omap_dmm->container_width = 256; > @@ -668,7 +677,7 @@ static int omap_dmm_probe(struct platform_device *dev) > atomic_set(_dmm->engine_counter, omap_dmm->num_engines); > > /* read out actual LUT width and height */ > - pat_geom = readl(omap_dmm->base + DMM_PAT_GEOMETRY); > + pat_geom = dmm_read(omap_dmm, DMM_PAT_GEOMETRY); > omap_dmm->lut_width = ((pat_geom >> 16) & 0xF) << 5; > omap_dmm->lut_height = ((pat_geom >> 24) & 0xF) << 5; > > @@ -678,12 +687,12 @@ static int omap_dmm_probe(struct platform_device *dev) > omap_dmm->num_lut++; > > /* initialize DMM registers */ > - writel(0x, omap_dmm->base + DMM_PAT_VIEW__0); > - writel(0x, omap_dmm->base + DMM_PAT_VIEW__1); > - writel(0x80808080, omap_dmm->base + DMM_PAT_VIEW_MAP__0); > - writel(0x8000, omap_dmm->base + DMM_PAT_VIEW_MAP_BASE); > - writel(0x, omap_dmm->base + DMM_TILER_OR__0); > - writel(0x, omap_dmm->base + DMM_TILER_OR__1); > + dmm_write(omap_dmm, 0x, DMM_PAT_VIEW__0); > + dmm_write(omap_dmm, 0x, DMM_PAT_VIEW__1); > + dmm_write(omap_dmm, 0x80808080, DMM_PAT_VIEW_MAP__0); > + dmm_write(omap_dmm, 0x8000, DMM_PAT_VIEW_MAP_BASE); > + dmm_write(omap_dmm, 0x, DMM_TILER_OR__0); > + dmm_write(omap_dmm, 0x, DMM_TILER_OR__1); > > ret = request_irq(omap_dmm->irq, omap_dmm_irq_handler, IRQF_SHARED, > "omap_dmm_irq_handler", omap_dmm); > @@ -701,7 +710,7 @@ static int omap_dmm_probe(struct platform_device *dev) >* buffers for accelerated pan/scroll) and FILL_DSC which >* we just generally don't care about. >*/ > - writel(0x7e7e7e7e, omap_dmm->base + DMM_PAT_IRQENABLE_SET);
[PATCH 03/33] HACK: drm/omap: fix memory barrier bug in DMM driver
Hi Tomi, Thank you for the patch. On Friday 19 February 2016 11:47:38 Tomi Valkeinen wrote: > A DMM timeout "timed out waiting for done" has been observed on DRA7 > devices. The timeout happens rarely, and only when the system is under > heavy load. > > Debugging showed that the timeout can be made to happen much more > frequently by optimizing the DMM driver, so that there's almost no code > between writing the last DMM descriptors to RAM, and writing to DMM > register which starts the DMM transaction. > > The current theory is that a wmb() does not properly ensure that the > data written to RAM is observable by all the components in the system. > > This DMM timeout has caused interesting (and rare) bugs as the error > handling was not functioning properly (the error handling has been fixed > in previous commits): > > * If a DMM timeout happened when a GEM buffer was being pinned for >display on the screen, a timeout error would be shown, but the driver >would continue programming DSS HW with broken buffer, leading to >SYNCLOST floods and possible crashes. > > * If a DMM timeout happened when other user (say, video decoder) was >pinning a GEM buffer, a timeout would be shown but if the user >handled the error properly, no other issues followed. > > * If a DMM timeout happened when a GEM buffer was being released, the >driver does not even notice the error, leading to crashes or hang >later. > > This patch adds wmb() and readl() calls after the last bit is written to > RAM, which should ensure that the execution proceeds only after the data > is actually in RAM, and thus observable by DMM. > > This patch is a HACK, as a read-back should not be needed. Further study > is required to understand if DMM is somehow special case and read-back > is ok, or if DRA7's memory barriers do not work correctly. CONFIG_SOC_DRA7XX selects OMAP_INTERCONNECT and OMAP_INTERCONNECT_BARRIER, but dra7xx_map_io() doesn't call omap_barriers_init(). Could that be the root cause of the issue ? I don't have access to a DRA7xx system, would you be able to test that ? > Signed-off-by: Tomi Valkeinen > --- > drivers/gpu/drm/omapdrm/omap_dmm_tiler.c | 11 +++ > 1 file changed, 11 insertions(+) > > diff --git a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c > b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c index 80526dec7b2c..4e04f9487375 > 100644 > --- a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c > +++ b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c > @@ -262,6 +262,17 @@ static int dmm_txn_commit(struct dmm_txn *txn, bool > wait) } > > txn->last_pat->next_pa = 0; > + /* ensure that the written descriptors are visible to DMM */ > + wmb(); > + > + /* > + * NOTE: the wmb() above should be enough, but there seems to be a bug > + * in OMAP's memory barrier implementation, which in some rare cases may > + * cause the writes not to be observable after wmb(). > + */ > + > + /* read back to ensure the data is in RAM */ > + readl(>last_pat->next_pa); > > /* write to PAT_DESCR to clear out any pending transaction */ > writel(0x0, dmm->base + reg[PAT_DESCR][engine->id]); -- Regards, Laurent Pinchart
Summer of Code Ideas
Hello Abheek, On 23 February 2016 at 18:08, Abheek Ghosh wrote: > Hi, > I am Abheek Ghosh, sophomore from Indian Institute of Technology, Guwahati. > I read the Summer of Code and DRM pages, as well as Mehul's discussion but > didn't get much help. I have strong C/C++ skills and familiar with OpenCL. I > have Intel CPU and Nvidia GPU of Fermi architecture. I have made small > contributions to open source projects. I don't have experience in kernel > level development, but very interested to get my hands dirty. > > It would be helpful if any developer can help me get started with some > suitable projects related to available hardware or any hardware independent > projects in OpenCL, OpenGL or Mesa. > > Awaiting a positive response. > As you've noticed in the thread started by Mehul, people here are keen on getting to know what your interest and strengths are. Thus listing those would be beneficial. This way people can come up with more 'personalised' ideas, should the ones on the wikis (short of links atm, sorry) do not suit you. Regards, Emil
[Bug 94231] Problems compiling libdrm since glibc 2.23
https://bugs.freedesktop.org/show_bug.cgi?id=94231 --- Comment #17 from Emil Velikov --- Well I never meant that Gentoo people should update anything bth. As the deprecation is a joint effort (hopefully musl and others are involved) someone from the team involved should ping/update the man-pages. As is, it's a case of the cart going before the horse - fix the code first, then document the new requirement :-\ The "pointing fingers" quote is metaphorical, no offence meant towards anyone. -- You are receiving this mail because: You are the assignee for the bug. -- next part -- An HTML attachment was scrubbed... URL: <https://lists.freedesktop.org/archives/dri-devel/attachments/20160223/a9c07185/attachment-0001.html>
[PATCH 1/2] drm/exynos: add exynos5420 support for fimd
Picked it up. Thanks, Inki Dae 2016ë 02ì 12ì¼ 22:31ì Chanho Park ì´(ê°) ì´ ê¸: > This patch adds a exynos5420 driver data to support mic_bypass > option to bypass the mic from display out path. > The mic(Mobile image compressor) compresses RGB data from fimd > and send the compressed data to the mipi dsi. > The bypass option can be founded from system register and the bit > is 11. The option bit has been introduced since exynos5420. The > only difference between exynos5250 and exynos5420/exynos5422 is > existence of the bit. Until the MIC is defined and enabled from > device tree, the bypass mic will be default option. > > Cc: Inki Dae > Cc: Joonyoung Shim > Cc: Seung-Woo Kim > Signed-off-by: Chanho Park > --- > .../bindings/display/exynos/samsung-fimd.txt | 3 ++- > drivers/gpu/drm/exynos/exynos_drm_fimd.c | 31 > +- > 2 files changed, 32 insertions(+), 2 deletions(-) > > diff --git > a/Documentation/devicetree/bindings/display/exynos/samsung-fimd.txt > b/Documentation/devicetree/bindings/display/exynos/samsung-fimd.txt > index 27c3ce0..c7c6b9a 100644 > --- a/Documentation/devicetree/bindings/display/exynos/samsung-fimd.txt > +++ b/Documentation/devicetree/bindings/display/exynos/samsung-fimd.txt > @@ -12,7 +12,8 @@ Required properties: > "samsung,exynos3250-fimd"; /* for Exynos3250/3472 SoCs */ > "samsung,exynos4210-fimd"; /* for Exynos4 SoCs */ > "samsung,exynos4415-fimd"; /* for Exynos4415 SoC */ > - "samsung,exynos5250-fimd"; /* for Exynos5 SoCs */ > + "samsung,exynos5250-fimd"; /* for Exynos5250 SoCs */ > + "samsung,exynos5420-fimd"; /* for Exynos5420/5422/5800 SoCs */ > > - reg: physical base address and length of the FIMD registers set. > > diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c > b/drivers/gpu/drm/exynos/exynos_drm_fimd.c > index 70194d0..41c3bb2 100644 > --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c > +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c > @@ -94,12 +94,14 @@ struct fimd_driver_data { > unsigned int lcdblk_offset; > unsigned int lcdblk_vt_shift; > unsigned int lcdblk_bypass_shift; > + unsigned int lcdblk_mic_bypass_shift; > > unsigned int has_shadowcon:1; > unsigned int has_clksel:1; > unsigned int has_limited_fmt:1; > unsigned int has_vidoutcon:1; > unsigned int has_vtsel:1; > + unsigned int has_mic_bypass:1; > }; > > static struct fimd_driver_data s3c64xx_fimd_driver_data = { > @@ -145,6 +147,18 @@ static struct fimd_driver_data exynos5_fimd_driver_data > = { > .has_vtsel = 1, > }; > > +static struct fimd_driver_data exynos5420_fimd_driver_data = { > + .timing_base = 0x2, > + .lcdblk_offset = 0x214, > + .lcdblk_vt_shift = 24, > + .lcdblk_bypass_shift = 15, > + .lcdblk_mic_bypass_shift = 11, > + .has_shadowcon = 1, > + .has_vidoutcon = 1, > + .has_vtsel = 1, > + .has_mic_bypass = 1, > +}; > + > struct fimd_context { > struct device *dev; > struct drm_device *drm_dev; > @@ -184,6 +198,8 @@ static const struct of_device_id fimd_driver_dt_match[] = > { > .data = _fimd_driver_data }, > { .compatible = "samsung,exynos5250-fimd", > .data = _fimd_driver_data }, > + { .compatible = "samsung,exynos5420-fimd", > + .data = _fimd_driver_data }, > {}, > }; > MODULE_DEVICE_TABLE(of, fimd_driver_dt_match); > @@ -461,6 +477,18 @@ static void fimd_commit(struct exynos_drm_crtc *crtc) > return; > } > > + /* TODO: When MIC is enabled for display path, the lcdblk_mic_bypass > + * bit should be cleared. > + */ > + if (driver_data->has_mic_bypass && ctx->sysreg && > + regmap_update_bits(ctx->sysreg, > + driver_data->lcdblk_offset, > + 0x1 << driver_data->lcdblk_mic_bypass_shift, > + 0x1 << driver_data->lcdblk_mic_bypass_shift)) { > + DRM_ERROR("Failed to update sysreg for bypass mic.\n"); > + return; > + } > + > /* setup horizontal and vertical display size. */ > val = VIDTCON2_LINEVAL(mode->vdisplay - 1) | > VIDTCON2_HOZVAL(mode->hdisplay - 1) | > @@ -861,7 +889,8 @@ static void fimd_dp_clock_enable(struct exynos_drm_crtc > *crtc, bool enable) >* clock. On these SoCs the bootloader may enable it but any >* power domain off/on will reset it to disable state. >*/ > - if (ctx->driver_data != _fimd_driver_data) > + if (ctx->driver_data != _fimd_driver_data || > + ctx->driver_data != _fimd_driver_data) > return; > > val = enable ? DP_MIE_CLK_DP_ENABLE : DP_MIE_CLK_DISABLE; >
[PATCH] drm/rockchip: support prime fd import
On Tue, Feb 23, 2016 at 6:29 PM, Emil Velikov wrote: > Hi Zach, > > On 2 February 2016 at 23:37, Zach Reizner wrote: >> The prime fd to handle ioctl was not used with rockchip before. Support >> was added in order to support potential uses (e.g. zero-copy video >> decode, camera). >> > Similar patch came around a few months ago and got this reply [1]. If > the situation has changed (there is an open-source driver/user for > this) it should be clearly mentioned in the commit message, as opposed > to "in order to support potential uses". hmm, well it is not driver specific uabi, and we have let several other mali/img users do prime.. I'm not sure, maybe those platforms can do a basic v4l <-> display thing w/ prime. Although upstream tends to hurt a bit for camera support.. BR, -R > Regards, > Emil > > [1] https://lists.freedesktop.org/archives/dri-devel/2015-November/094568.html > ___ > dri-devel mailing list > dri-devel at lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 4/4] drm/i915: Determine DP++ type 1 DVI adaptor presence based on VBT
From: Ville SyrjäläDP dual mode type 1 DVI adaptors aren't required to implement any registers, so it's a bit hard to detect them. The best way would be to check the state of the CONFIG1 pin, but we have no way to do that. So as a last resort, check the VBT to see if the HDMI port is in fact a dual mode capable DP port. Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/intel_bios.h | 3 +++ drivers/gpu/drm/i915/intel_dp.c | 28 drivers/gpu/drm/i915/intel_drv.h | 1 + drivers/gpu/drm/i915/intel_hdmi.c | 23 +-- 4 files changed, 53 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h index 350d4e0f75a4..50d1659efe47 100644 --- a/drivers/gpu/drm/i915/intel_bios.h +++ b/drivers/gpu/drm/i915/intel_bios.h @@ -730,6 +730,7 @@ struct bdb_psr { #define DEVICE_TYPE_INT_TV 0x1009 #define DEVICE_TYPE_HDMI 0x60D2 #define DEVICE_TYPE_DP 0x68C6 +#define DEVICE_TYPE_DP_DUAL_MODE 0x60D6 #define DEVICE_TYPE_eDP0x78C6 #define DEVICE_TYPE_CLASS_EXTENSION (1 << 15) @@ -764,6 +765,8 @@ struct bdb_psr { DEVICE_TYPE_DISPLAYPORT_OUTPUT | \ DEVICE_TYPE_ANALOG_OUTPUT) +#define DEVICE_TYPE_DP_DUAL_MODE_BITS ~DEVICE_TYPE_NOT_HDMI_OUTPUT + /* define the DVO port for HDMI output type */ #defineDVO_B 1 #defineDVO_C 2 diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index cbc06596659a..f3edacf517ac 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -5104,6 +5104,34 @@ bool intel_dp_is_edp(struct drm_device *dev, enum port port) return false; } +bool intel_dp_is_dual_mode(struct drm_i915_private *dev_priv, enum port port) +{ + const union child_device_config *p_child; + int i; + static const short port_mapping[] = { + [PORT_B] = DVO_PORT_DPB, + [PORT_C] = DVO_PORT_DPC, + [PORT_D] = DVO_PORT_DPD, + [PORT_E] = DVO_PORT_DPE, + }; + + if (port == PORT_A || port >= ARRAY_SIZE(port_mapping)) + return false; + + if (!dev_priv->vbt.child_dev_num) + return false; + + for (i = 0; i < dev_priv->vbt.child_dev_num; i++) { + p_child = _priv->vbt.child_dev[i]; + + if (p_child->common.dvo_port == port_mapping[port] && + (p_child->common.device_type & DEVICE_TYPE_DP_DUAL_MODE_BITS) == + (DEVICE_TYPE_DP_DUAL_MODE & DEVICE_TYPE_DP_DUAL_MODE_BITS)) + return true; + } + return false; +} + void intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connector) { diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 3ca29a181e64..c7d1ea4dbe42 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1248,6 +1248,7 @@ int intel_dp_sink_crc(struct intel_dp *intel_dp, u8 *crc); bool intel_dp_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config); bool intel_dp_is_edp(struct drm_device *dev, enum port port); +bool intel_dp_is_dual_mode(struct drm_i915_private *dev_priv, enum port port); enum irqreturn intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd); void intel_edp_backlight_on(struct intel_dp *intel_dp); diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 660a65f48fd8..1476f3afb7e2 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1390,14 +1390,33 @@ intel_hdmi_unset_edid(struct drm_connector *connector) } static void -intel_hdmi_dp_dual_mode_detect(struct drm_connector *connector) +intel_hdmi_dp_dual_mode_detect(struct drm_connector *connector, bool has_edid) { struct drm_i915_private *dev_priv = to_i915(connector->dev); struct intel_hdmi *hdmi = intel_attached_hdmi(connector); + enum port port = hdmi_to_dig_port(hdmi)->port; struct i2c_adapter *adapter = intel_gmbus_get_adapter(dev_priv, hdmi->ddc_bus); enum drm_dp_dual_mode_type type = drm_dp_dual_mode_detect(adapter); + /* +* Type 1 DVI adaptors are not required to implement any +* registers, so we can't always detect their presence. +* Ideally we should be able to check the state of the +* CONFIG1 pin, but no such luck on our hardware. +* +* The only method left to us is to check the VBT to see +* if the port is a dual mode capable DP port. But let's +* only do that when we sucesfully read the EDID, to avoid +* confusing log messages about DP dual mode adaptors when +* there's
[PATCH 3/4] drm/i915: Enable/disable TMDS output buffers in DP++ adaptor as needed
From: Ville SyrjäläTo save a bit of power, let's try to turn off the TMDS output buffers in DP++ adaptors when we're not driving the port. Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/intel_drv.h | 1 + drivers/gpu/drm/i915/intel_hdmi.c | 27 +-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 944eacbfb6a9..3ca29a181e64 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -706,6 +706,7 @@ struct intel_hdmi { int ddc_bus; struct { int max_tmds_clock; + bool tmds_output_control; } dp_dual_mode; bool limited_color_range; bool color_range_auto; diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 1e8cfdb18dc7..660a65f48fd8 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -846,6 +846,13 @@ static void intel_hdmi_prepare(struct intel_encoder *encoder) const struct drm_display_mode *adjusted_mode = >config->base.adjusted_mode; u32 hdmi_val; + if (intel_hdmi->dp_dual_mode.tmds_output_control) { + struct i2c_adapter *adapter = + intel_gmbus_get_adapter(dev_priv, intel_hdmi->ddc_bus); + + drm_dp_dual_mode_set_tmds_output(adapter, true); + } + hdmi_val = SDVO_ENCODING_HDMI; if (!HAS_PCH_SPLIT(dev) && crtc->config->limited_color_range) hdmi_val |= HDMI_COLOR_RANGE_16_235; @@ -1144,6 +1151,13 @@ static void intel_disable_hdmi(struct intel_encoder *encoder) } intel_hdmi->set_infoframes(>base, false, NULL); + + if (intel_hdmi->dp_dual_mode.tmds_output_control) { + struct i2c_adapter *adapter = + intel_gmbus_get_adapter(dev_priv, intel_hdmi->ddc_bus); + + drm_dp_dual_mode_set_tmds_output(adapter, false); + } } static void g4x_disable_hdmi(struct intel_encoder *encoder) @@ -1369,6 +1383,7 @@ intel_hdmi_unset_edid(struct drm_connector *connector) intel_hdmi->rgb_quant_range_selectable = false; intel_hdmi->dp_dual_mode.max_tmds_clock = 0; + intel_hdmi->dp_dual_mode.tmds_output_control = false; kfree(to_intel_connector(connector)->detect_edid); to_intel_connector(connector)->detect_edid = NULL; @@ -1392,15 +1407,23 @@ intel_hdmi_dp_dual_mode_detect(struct drm_connector *connector) */ if (type == DRM_DP_DUAL_MODE_TYPE2_DVI || type == DRM_DP_DUAL_MODE_TYPE2_HDMI) { + bool tmds_enabled; + hdmi->dp_dual_mode.max_tmds_clock = drm_dp_dual_mode_max_tmds_clock(adapter); + + hdmi->dp_dual_mode.tmds_output_control = + drm_dp_dual_mode_get_tmds_output(adapter, _enabled) == 0 && + drm_dp_dual_mode_set_tmds_output(adapter, tmds_enabled) == 0; } else { hdmi->dp_dual_mode.max_tmds_clock = 165000; + hdmi->dp_dual_mode.tmds_output_control = false; } - DRM_DEBUG_KMS("DP dual mode adaptor (%s) detected (max TMDS clock: %d kHz)\n", + DRM_DEBUG_KMS("DP dual mode adaptor (%s) detected (max TMDS clock: %d kHz, TMDS OE# control: %s)\n", drm_dp_get_dual_mode_type_name(type), - hdmi->dp_dual_mode.max_tmds_clock); + hdmi->dp_dual_mode.max_tmds_clock, + yesno(hdmi->dp_dual_mode.tmds_output_control)); } static bool -- 2.4.10
[PATCH 2/4] drm/i915: Respect DP++ adaptor TMDS clock limit
From: Ville SyrjäläTry to detect the max TMDS clock limit for the DP++ adaptor (if any) and take it into account when checking the port clock. Note that as with the sink (HDMI vs. DVI) TMDS clock limit we'll ignore the adaptor TMDS clock limit in the modeset path, in case users are already "overclocking" their TMDS links. One subtle change here is that we'll have to respect the adaptor TMDS clock limit when we decide whether to do 12bpc or 8bpc, otherwise we might end up picking 12bpc and accidentally driving the TMDS link out of spec even when the user chose a mode that fits wihting the limits at 8bpc. This means you can't "overclock" your DP++ dongle at 12bpc anymore, but you can continue to do so at 8bpc. Note that for simplicity we'll use the I2C access method for all dual mode adaptors including type 2. Otherwise we'd have to start mixing DP AUX and HDMI together. In the future we may need to do that if we come across any board designs that don't hook up the DDC pins to the DP++ connectors. Such boards would obviously only work with type 2 dual mode adaptors, and not type 1. Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/intel_drv.h | 3 ++ drivers/gpu/drm/i915/intel_hdmi.c | 65 ++- 2 files changed, 60 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 4852049c9ab3..944eacbfb6a9 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -704,6 +704,9 @@ struct cxsr_latency { struct intel_hdmi { i915_reg_t hdmi_reg; int ddc_bus; + struct { + int max_tmds_clock; + } dp_dual_mode; bool limited_color_range; bool color_range_auto; bool has_hdmi_sink; diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 80b44c054087..1e8cfdb18dc7 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "intel_drv.h" #include #include "i915_drv.h" @@ -1168,27 +1169,42 @@ static void pch_post_disable_hdmi(struct intel_encoder *encoder) intel_disable_hdmi(encoder); } -static int hdmi_port_clock_limit(struct intel_hdmi *hdmi, bool respect_dvi_limit) +static int intel_hdmi_source_max_tmds_clock(struct drm_i915_private *dev_priv) { - struct drm_device *dev = intel_hdmi_to_dev(hdmi); - - if ((respect_dvi_limit && !hdmi->has_hdmi_sink) || IS_G4X(dev)) + if (IS_G4X(dev_priv)) return 165000; - else if (IS_HASWELL(dev) || INTEL_INFO(dev)->gen >= 8) + else if (IS_HASWELL(dev_priv) || INTEL_INFO(dev_priv)->gen >= 8) return 30; else return 225000; } +static int hdmi_port_clock_limit(struct intel_hdmi *hdmi, +bool respect_downstream_limits) +{ + struct drm_device *dev = intel_hdmi_to_dev(hdmi); + int max_tmds_clock = intel_hdmi_source_max_tmds_clock(to_i915(dev)); + + if (respect_downstream_limits) { + if (hdmi->dp_dual_mode.max_tmds_clock) + max_tmds_clock = min(max_tmds_clock, +hdmi->dp_dual_mode.max_tmds_clock); + if (!hdmi->has_hdmi_sink) + max_tmds_clock = min(max_tmds_clock, 165000); + } + + return max_tmds_clock; +} + static enum drm_mode_status hdmi_port_clock_valid(struct intel_hdmi *hdmi, - int clock, bool respect_dvi_limit) + int clock, bool respect_downstream_limits) { struct drm_device *dev = intel_hdmi_to_dev(hdmi); if (clock < 25000) return MODE_CLOCK_LOW; - if (clock > hdmi_port_clock_limit(hdmi, respect_dvi_limit)) + if (clock > hdmi_port_clock_limit(hdmi, respect_downstream_limits)) return MODE_CLOCK_HIGH; /* BXT DPLL can't generate 223-240 MHz */ @@ -1312,7 +1328,7 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder, * within limits. */ if (pipe_config->pipe_bpp > 8*3 && pipe_config->has_hdmi_sink && - hdmi_port_clock_valid(intel_hdmi, clock_12bpc, false) == MODE_OK && + hdmi_port_clock_valid(intel_hdmi, clock_12bpc, true) == MODE_OK && hdmi_12bpc_possible(pipe_config)) { DRM_DEBUG_KMS("picking bpc to 12 for HDMI output\n"); desired_bpp = 12*3; @@ -1352,10 +1368,41 @@ intel_hdmi_unset_edid(struct drm_connector *connector) intel_hdmi->has_audio = false; intel_hdmi->rgb_quant_range_selectable = false; + intel_hdmi->dp_dual_mode.max_tmds_clock = 0; + kfree(to_intel_connector(connector)->detect_edid); to_intel_connector(connector)->detect_edid = NULL; } +static void +intel_hdmi_dp_dual_mode_detect(struct
[PATCH 1/4] drm: Add helper for DP++ adaptors
From: Ville SyrjäläAdd a helper which aids in he identification of DP dual mode (aka. DP++) adaptors. There are several types of adaptors specified: type 1 DVI, type 1 HDMI, type 2 DVI, type 2 HDMI Type 1 adaptors have a max TMDS clock limit of 165MHz, type 2 adaptors may go as high as 300MHz and they provide a register informing the source device what the actual limit is. Supposedly also type 1 adaptors may optionally implement this register. This TMDS clock limit is the main reason why we need to identify these adaptors. Type 1 adaptors provide access to their internal registers and the sink DDC bus through I2C. Type 2 adaptors provide this access both via I2C and I2C-over-AUX. A type 2 source device may choose to implement either or both of these methods. If a source device implements only the I2C-over-AUX method, then the driver will obviously need specific support for such adaptors since the port is driven like an HDMI port, but DDC communication happes over the AUX channel. This helper should be enough to identify the adaptor type (some type 1 DVI adaptors may be a slight exception) and the maximum TMDS clock limit. Another feature that may be available is control over the TMDS output buffers on the adaptor, possibly allowing for some power saving when the TMDS link is down. Other user controllable features that may be available in the adaptors are downstream i2c bus speed control when using i2c-over-aux, and some control over the CEC pin. I chose not to provide any helper functions for those since I have no use for them in i915 at this time. The rest of the registers in the adaptor are mostly just information, eg. IEEE OUI, hardware and firmware revision, etc. Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/Makefile | 2 +- drivers/gpu/drm/drm_dp_dual_mode_helper.c | 328 ++ include/drm/drm_dp_dual_mode_helper.h | 80 3 files changed, 409 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/drm_dp_dual_mode_helper.c create mode 100644 include/drm/drm_dp_dual_mode_helper.h diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 6eb94fc561dc..8ef50f36 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -23,7 +23,7 @@ drm-$(CONFIG_AGP) += drm_agpsupport.o drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \ drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o \ - drm_kms_helper_common.o + drm_kms_helper_common.o drm_dp_dual_mode_helper.o drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o diff --git a/drivers/gpu/drm/drm_dp_dual_mode_helper.c b/drivers/gpu/drm/drm_dp_dual_mode_helper.c new file mode 100644 index ..bfe511c09568 --- /dev/null +++ b/drivers/gpu/drm/drm_dp_dual_mode_helper.c @@ -0,0 +1,328 @@ +/* + * Copyright © 2016 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include + +/** + * DOC: DP dual mode (aka. DP++) adaptor helpers + * + * Helper functions to deal with DP dual mode adaptors. + * + * Type 1: + * Adaptor registers (if any) and the sink DDC bus may be accessed via I2C. + * + * Type 2: + * Adaptor registers and sink DDC bus can be accessed either via I2C or + * I2C-over-AUX. Source devices may choose to implement either one or + * both of these access methods. + */ + +#define DP_DUAL_MODE_SLAVE_ADDRESS 0x40 + +/** + * drm_dp_dual_mode_read - Read from the DP dual mode adaptor register(s) + * adapter: I2C adapter for the DDC bus + * offset: register offset + * buffer: buffer for return data + * size: sizo of the buffer + * + * Reads @size bytes from the DP dual mode adaptor registers + * starting at @offset. + * + * Returns: + * 0 on
[PATCH 0/4] drm: DP++ adaptor support
From: Ville SyrjäläWhile looking at a regression caused by i915's use of 12bpc HDMI mode, I ended up reading the DP dual mode spec, and that lead to this patch series. I intentionally made the basics of the helper look somewhat like Thierry's HDMI 2.0 SCDC stuff [1], except with a few less bugs :P The entire series is available here: git://github.com/vsyrjala/linux.git dp_dual_mode_2 [1] https://lists.freedesktop.org/archives/dri-devel/2015-September/090929.html Ville Syrjälä (4): drm: Add helper for DP++ adaptors drm/i915: Respect DP++ adaptor TMDS clock limit drm/i915: Enable/disable TMDS output buffers in DP++ adaptor as needed drm/i915: Determine DP++ type 1 DVI adaptor presence based on VBT drivers/gpu/drm/Makefile | 2 +- drivers/gpu/drm/drm_dp_dual_mode_helper.c | 324 ++ drivers/gpu/drm/i915/intel_bios.h | 3 + drivers/gpu/drm/i915/intel_dp.c | 28 +++ drivers/gpu/drm/i915/intel_drv.h | 5 + drivers/gpu/drm/i915/intel_hdmi.c | 107 +- include/drm/drm_dp_dual_mode_helper.h | 80 7 files changed, 540 insertions(+), 9 deletions(-) create mode 100644 drivers/gpu/drm/drm_dp_dual_mode_helper.c create mode 100644 include/drm/drm_dp_dual_mode_helper.h -- 2.4.10
[PATCH v5 01/11] drm/hisilicon: Add device tree binding for hi6220 display subsystem
On Tue, Feb 23, 2016 at 11:00:21AM +0800, Xinliang Liu wrote: > Add ADE display controller binding doc. > Add DesignWare DSI Host Controller v1.20a binding doc. > > v5: > - Remove endpoint unit address of dsi output port. > - Add "hisilicon,noc-syscon" property for ADE NOC QoS syscon. > - Add "resets" property for ADE reset. > v4: > - Describe more specific of clocks and ports. > - Fix indentation. > v3: > - Make ade as the drm master node. > - Use assigned-clocks to set clock rate. > - Use ports to connect display relavant nodes. > v2: > - Move dt binding docs to bindings/display/hisilicon directory. > > Signed-off-by: Xinwei Kong > Signed-off-by: Xinliang Liu > --- > .../bindings/display/hisilicon/dw-dsi.txt | 72 > ++ > .../bindings/display/hisilicon/hisi-ade.txt| 64 +++ > 2 files changed, 136 insertions(+) > create mode 100644 > Documentation/devicetree/bindings/display/hisilicon/dw-dsi.txt > create mode 100644 > Documentation/devicetree/bindings/display/hisilicon/hisi-ade.txt > > diff --git a/Documentation/devicetree/bindings/display/hisilicon/dw-dsi.txt > b/Documentation/devicetree/bindings/display/hisilicon/dw-dsi.txt > new file mode 100644 > index ..0d234b5e19af > --- /dev/null > +++ b/Documentation/devicetree/bindings/display/hisilicon/dw-dsi.txt > @@ -0,0 +1,72 @@ > +Device-Tree bindings for DesignWare DSI Host Controller v1.20a driver > + > +A DSI Host Controller resides in the middle of display controller and > external > +HDMI converter or panel. > + > +Required properties: > +- compatible: value should be "hisilicon,hi6220-dsi". > +- reg: physical base address and length of dsi controller's registers. > +- clocks: the clocks needed. > +- clock-names: the name of the clocks. You _must_ specify the precise set of clock names you expect here. Per the example, you seem to expect "pclk_dsi". Is that the name given in the DSI controller manual? Or is it just "pclk"? It's already specific to the DSI controller... > diff --git a/Documentation/devicetree/bindings/display/hisilicon/hisi-ade.txt > b/Documentation/devicetree/bindings/display/hisilicon/hisi-ade.txt > new file mode 100644 > index ..c1844b3ff878 > --- /dev/null > +++ b/Documentation/devicetree/bindings/display/hisilicon/hisi-ade.txt > @@ -0,0 +1,64 @@ > +Device-Tree bindings for hisilicon ADE display controller driver > + > +ADE (Advanced Display Engine) is the display controller which grab image > +data from memory, do composition, do post image processing, generate RGB > +timing stream and transfer to DSI. > + > +Required properties: > +- compatible: value should be "hisilicon,hi6220-ade". > +- reg: physical base address and length of the ADE controller's registers. > + Value should be "<0x0 0xf410 0x0 0x7800>". Get rid of the "Value should be ... " part. It is nonsensical to describe this in the binding. Just describe what this is with relation to _this_ IP block. > +- reg-names: name of physical base. Value should be "ade_base". That obviously doesn't apply to *-names propertiesm which must all be specified in the binding (they're local to the device rather than remote). > +- hisilicon,noc-syscon: ADE NOC QoS syscon. Value should be "<_ade>" > +- resets: The ADE reset controller node. Value should be "<_ctrl > + MEDIA_ADE>". Likewise. > +- interrupt: the ldi vblank interrupt number used. > +- clocks: the clocks needed. Three clocks are used in ADE driver: > + ADE core clock, value should be "<_ctrl HI6220_ADE_CORE>"; > + ADE pixel clok, value should be "<_ctrl HI6220_ADE_PIX_SRC>"; > + media NOC QoS clock, value should be "<_ctrl HI6220_CODEC_JPEG>". > +- clock-names: the name of the clocks. Values should be "clk_ade_core", > + "clk_codec_jpeg" and "clk_ade_pix". Likewise, don't specify the value. Jsut define clocks in terms of clock-names, e.g. - clocks: a list of phandle + clock-specifier pairs, one for each entry in clock-names. - clock-names: should contain: * "clk_ade_core" for the ADE ciore clock * ... * ... > +- assigned-clocks: clocks to be assigned rate. > +- assigned-clock-rates: clock rates which are assigned to assigned-clocks. > + The rate of <_ctrl HI6220_ADE_CORE> could be "36000" or > + "18000"; > + The rate of <_ctrl HI6220_CODEC_JPEG> could be less than > "144000". Is this strictly necessary? Why can the druiver not configure this? Does this have to match some pre-existing boot-time configuration? Thanks, Mark.
[PATCH v3 21/22] drm/tilcdc: Initialize crtc->port
On 02/23/16 17:32, Tomi Valkeinen wrote: > On 23/02/16 17:26, Jyri Sarha wrote: > >>> You didn't comment on why this is not an error? Why should the driver >>> continue even if crtc->port is missing? >>> >> >> At least for the time being if the drm_of_find_possible_crtcs() fails >> the tda998x driver assumes the first crtc with a warning. So for that >> part everything will work just fine still. >> >> Then it is another question how priv->is_componentized could be set and >> probing has gotten this far while there is no port node to be found. The >> WARN_ON() should really never happen as long as the code is the way it >> currently is. > > Ok. But I think it's either ok to not have crtc->port, and in that case > no print is needed, or it's not ok, and it's better to print an error > and fail. > > Now it's kind of vague: the driver continues without crtc->port, but > gives a scary WARN. > The scary WARN is not for not having crtc->port initialized, but for breached internal sanity when a componentized probe has somehow reached this point without a port node to be found.
[PATCH v3 21/22] drm/tilcdc: Initialize crtc->port
On 23/02/16 17:26, Jyri Sarha wrote: >> You didn't comment on why this is not an error? Why should the driver >> continue even if crtc->port is missing? >> > > At least for the time being if the drm_of_find_possible_crtcs() fails > the tda998x driver assumes the first crtc with a warning. So for that > part everything will work just fine still. > > Then it is another question how priv->is_componentized could be set and > probing has gotten this far while there is no port node to be found. The > WARN_ON() should really never happen as long as the code is the way it > currently is. Ok. But I think it's either ok to not have crtc->port, and in that case no print is needed, or it's not ok, and it's better to print an error and fail. Now it's kind of vague: the driver continues without crtc->port, but gives a scary WARN. Tomi -- next part -- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: OpenPGP digital signature URL: <https://lists.freedesktop.org/archives/dri-devel/attachments/20160223/8d0d5743/attachment.sig>
[PATCH 2/2] drm/tegra: Set the DMA mask
On Tue, Feb 23, 2016 at 08:18:26AM -0800, Terje Bergstrom wrote: > > > On 02/23/2016 08:04 AM, Thierry Reding wrote: > >* PGP Signed by an unknown key > > On Tue, Feb 23, 2016 at 03:25:54PM > >+0900, Alexandre Courbot wrote: > >> The default DMA mask covers a 32 bits address range, but tegradrm >> can > address more than that. Set the DMA mask to the actual >> addressable range > to avoid the use of unneeded bounce buffers. >> >> Signed-off-by: Alexandre > Courbot --- Thierry, >> I am not absolutely sure > whether the size is correct and applies to >> all Tegra generations - please > let me know if this needs to be >> reworked. >> >> > drivers/gpu/drm/tegra/drm.c | 1 + 1 file changed, 1 insertion(+) > > This > kind of depends on whether or not the device is behind an IOMMU. > If it is, > then the IOMMU DMA MASK would apply, which can be derived > from the number > of address bits that the IOMMU can handle. The SMMU > supports 32 address > bits on Tegra30 and Tegra114, 34 address bits on > more recent generations. > > > I think for now it's safer to leave the DMA mask at the default (32 > > bit) to avoid the need to distinguish between IOMMU and non-IOMMU > devices. > > The GPUs after Tegra114 can choose per access whether they're using IOMMU > or not. The interface is 34 bits wide, so the physical addresses can be 34 > bits. > IOMMU addresses are limited by Tegra SMMU to 32-bit for gk20a. gm20b can use > 34-bit if SMMU is configured to combine four ASIDs together. This particular patch sets up the DMA mask for the display engines. But yes, most of the above holds true for that case as well, except that as far as I know there is no mechanism to have the display engines choose per access, whether or not to use the SMMU. Thierry -- next part -- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: not available URL: <https://lists.freedesktop.org/archives/dri-devel/attachments/20160223/4309c13b/attachment.sig>
[Bug 94231] Problems compiling libdrm since glibc 2.23
https://bugs.freedesktop.org/show_bug.cgi?id=94231 --- Comment #16 from Mike Frysinger --- (In reply to Emil Velikov from comment #13) that is happening in upstream glibc. i'm not going to bother in Gentoo. no one is "pointing fingers". we detected an error in libdrm in Gentoo, hence you guys got a patch. i don't know why you're upset about this. -- You are receiving this mail because: You are the assignee for the bug. -- next part -- An HTML attachment was scrubbed... URL: <https://lists.freedesktop.org/archives/dri-devel/attachments/20160223/5a8ca865/attachment.html>
[PATCH v3 21/22] drm/tilcdc: Initialize crtc->port
On 02/23/16 17:19, Tomi Valkeinen wrote: > > > On 23/02/16 17:03, Jyri Sarha wrote: >> Initialize port device node pointer in the tilcdc crtc. Fixes "Falling >> back to first CRTC" warning from tda998x driver. >> >> The tda998x encoder driver calls drm_of_find_possible_crtcs() to >> initialize possible_crtcs of struct drm_encoder. The crtc->port needs >> to be initialized for drm_of_find_possible_crtcs() to work. >> >> Signed-off-by: Jyri Sarha >> --- >> drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 16 >> 1 file changed, 16 insertions(+) >> >> diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c >> b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c >> index 248e3ea..1eb4e0e 100644 >> --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c >> +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c >> @@ -124,6 +124,7 @@ static void tilcdc_crtc_destroy(struct drm_crtc *crtc) >> >> tilcdc_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); >> >> +of_node_put(crtc->port); >> drm_crtc_cleanup(crtc); >> drm_flip_work_cleanup(_crtc->unref_work); >> >> @@ -749,6 +750,7 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc) >> >> struct drm_crtc *tilcdc_crtc_create(struct drm_device *dev) >> { >> +struct tilcdc_drm_private *priv = dev->dev_private; >> struct tilcdc_crtc *tilcdc_crtc; >> struct drm_crtc *crtc; >> int ret; >> @@ -775,6 +777,20 @@ struct drm_crtc *tilcdc_crtc_create(struct drm_device >> *dev) >> >> drm_crtc_helper_add(crtc, _crtc_helper_funcs); >> >> +if (priv->is_componentized) { >> +struct device_node *ports = >> +of_get_child_by_name(dev->dev->of_node, "ports"); >> + >> +if (ports) { >> +crtc->port = of_get_child_by_name(ports, "port"); >> +of_node_put(ports); >> +} else { >> +crtc->port = >> +of_get_child_by_name(dev->dev->of_node, "port"); >> +} >> +WARN_ON(!crtc->port); >> +} > > You didn't comment on why this is not an error? Why should the driver > continue even if crtc->port is missing? > At least for the time being if the drm_of_find_possible_crtcs() fails the tda998x driver assumes the first crtc with a warning. So for that part everything will work just fine still. Then it is another question how priv->is_componentized could be set and probing has gotten this far while there is no port node to be found. The WARN_ON() should really never happen as long as the code is the way it currently is. BR, Jyri
[PATCH v3 21/22] drm/tilcdc: Initialize crtc->port
On 23/02/16 17:03, Jyri Sarha wrote: > Initialize port device node pointer in the tilcdc crtc. Fixes "Falling > back to first CRTC" warning from tda998x driver. > > The tda998x encoder driver calls drm_of_find_possible_crtcs() to > initialize possible_crtcs of struct drm_encoder. The crtc->port needs > to be initialized for drm_of_find_possible_crtcs() to work. > > Signed-off-by: Jyri Sarha > --- > drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 16 > 1 file changed, 16 insertions(+) > > diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c > b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c > index 248e3ea..1eb4e0e 100644 > --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c > +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c > @@ -124,6 +124,7 @@ static void tilcdc_crtc_destroy(struct drm_crtc *crtc) > > tilcdc_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); > > + of_node_put(crtc->port); > drm_crtc_cleanup(crtc); > drm_flip_work_cleanup(_crtc->unref_work); > > @@ -749,6 +750,7 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc) > > struct drm_crtc *tilcdc_crtc_create(struct drm_device *dev) > { > + struct tilcdc_drm_private *priv = dev->dev_private; > struct tilcdc_crtc *tilcdc_crtc; > struct drm_crtc *crtc; > int ret; > @@ -775,6 +777,20 @@ struct drm_crtc *tilcdc_crtc_create(struct drm_device > *dev) > > drm_crtc_helper_add(crtc, _crtc_helper_funcs); > > + if (priv->is_componentized) { > + struct device_node *ports = > + of_get_child_by_name(dev->dev->of_node, "ports"); > + > + if (ports) { > + crtc->port = of_get_child_by_name(ports, "port"); > + of_node_put(ports); > + } else { > + crtc->port = > + of_get_child_by_name(dev->dev->of_node, "port"); > + } > + WARN_ON(!crtc->port); > + } You didn't comment on why this is not an error? Why should the driver continue even if crtc->port is missing? Tomi -- next part -- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: OpenPGP digital signature URL: <https://lists.freedesktop.org/archives/dri-devel/attachments/20160223/8c70bd99/attachment-0001.sig>
[PATCH] drm/i915: Resume DP MST before doing any kind of modesetting
As it turns out, resuming DP MST is racey since we don't make sure MST is ready before we start modesetting, it just usually happens to be ready in time. This isn't the case on all systems, particularly a ThinkPad T560 with displays connected through the dock. On these systems, resuming the laptop while connected to the dock usually results in blank monitors. Making sure MST is ready before doing any kind of modesetting fixes this issue. We originally changed the resume order in commit e7d6f7d70829 ("drm/i915: resume MST after reading back hw state") to fix a ton of WARN_ON's after resume, but this doesn't seem to be an issue now anyhow. CC: stable at vger.kernel.org Signed-off-by: Lyude --- drivers/gpu/drm/i915/i915_drv.c | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index f357058..4dcf3dd 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -733,6 +733,14 @@ static int i915_drm_resume(struct drm_device *dev) intel_opregion_setup(dev); intel_init_pch_refclk(dev); + + /* +* We need to make sure that we resume MST before doing anything +* display related, otherwise we risk trying to bring up a display on +* MST before the hub is actually ready +*/ + intel_dp_mst_resume(dev); + drm_mode_config_reset(dev); /* @@ -765,8 +773,6 @@ static int i915_drm_resume(struct drm_device *dev) intel_display_resume(dev); drm_modeset_unlock_all(dev); - intel_dp_mst_resume(dev); - /* * ... but also need to make sure that hotplug processing * doesn't cause havoc. Like in the driver load code we don't -- 2.5.0
[REGRESSION] i915: No HDMI output with 4.4
On Mon, Feb 22, 2016 at 02:32:32PM +0200, Oleksandr Natalenko wrote: > Ville, Daniel, > > any additional info I could provide? I have to return dual-link DVI > cable back, so let me know if I could reveal more details if necessary. Unfortunately I'm out of ideas for now. Daniel is on vacation. Anyone else? VPG folks should take the ball here since they broke it. In the meantime I think as a workaround I think you could use something like video=HDMI-A-1:e on the kernel command line (not sure I got the connector name right for your system). I think that should result in the live status check to be skipped, at least when populating the mode list. Might be a good idea to collect all the information here and put in a bug report (https://bugs.freedesktop.org/ -> DRI -> DRM/Intel) so that all the logs and such would be in one place. > > Regards, >Oleksandr > > 16.02.2016 14:54, Daniel Vetter напиÑав: > > On Tue, Feb 16, 2016 at 12:58:56PM +0200, Oleksandr Natalenko wrote: > >> Ville, Daniel, > >> > >> I've just got another monitor and another DVI-HDMI cable, and here > >> what I've > >> got. > >> > >> ===Single Link DVI-D cable with 3 different monitors=== > >> > >> Computer DVI âââ DVI-D (Single Link)/HDMI cable âââ HDMI LG > >> 23MP65HQ-P > >> === > >> not working > > > > I presume the above LG screen is what you've called previously "old > > monitor"? > > > >> Computer DVI âââ DVI-D (Single Link)/HDMI cable âââ HDMI LG > >> 23MP67HQ-P > >> === > >> not working > >> Computer DVI âââ DVI-D (Single Link)/HDMI cable âââ HDMI LG > >> 23MP55HQ-P > >> === > >> works! > >> > >> ===Dual Link DVI-D cable with monitor that doesn't work with Single > >> Link > >> cable=== > >> > >> Computer DVI âââ DVI-D (Dual Link)/HDMI cable âââ HDMI LG > >> 23MP65HQ-P > >> === > >> works! > > > > Funky. Can you pls grab the debug logs (with the special patches from > > Ville) for this case? I wonder why suddenly different cable and it > > works. > > > > Also: Is this one of these older-ish screens where you must have a > > dual-link cable to drive it at full resolution rate? > > -Daniel > > > > > >> ===Laptop with HDMI output=== > >> > >> Laptop HDMI âââ HDMI/HDMI cable âââ HDMI LG 23MP65HQ-P === > >> works! > >> > >> I'd say that single link DVI cables are broken with new kernel, but > >> one of > >> monitors could work with such a cable. So I have no idea :(. > >> > >> Regards, > >> Oleksandr. > >> > >> 15.02.2016 17:42, Daniel Vetter wrote: > >> >The other downside is that it'll make us non-compliant, which was the > >> >point of this entire ordeal: HDMI spec forbids us from starting any i2c > >> >transactions when the hpd isn't signalling a present screen. > >> > > >> >So maybe we need to buy one of these broken screens. > >> > > >> >Oleksandr, what exact model are you using? And any chance that you could > >> >test this on some other machine with intel gfx and latest kernel, just to > >> >make sure this really is some issue with the sink and not with the machine > >> >itself? And I guess you've tested with some other hdmi sink, and that > >> >works? -- Ville Syrjälä Intel OTC
[PATCH 2/2] drm/tegra: Set the DMA mask
On Tue, Feb 23, 2016 at 03:25:54PM +0900, Alexandre Courbot wrote: > The default DMA mask covers a 32 bits address range, but tegradrm can > address more than that. Set the DMA mask to the actual addressable range > to avoid the use of unneeded bounce buffers. > > Signed-off-by: Alexandre Courbot > --- > Thierry, I am not absolutely sure whether the size is correct and applies > to all Tegra generations - please let me know if this needs to be > reworked. > > drivers/gpu/drm/tegra/drm.c | 1 + > 1 file changed, 1 insertion(+) This kind of depends on whether or not the device is behind an IOMMU. If it is, then the IOMMU DMA MASK would apply, which can be derived from the number of address bits that the IOMMU can handle. The SMMU supports 32 address bits on Tegra30 and Tegra114, 34 address bits on more recent generations. I think for now it's safer to leave the DMA mask at the default (32 bit) to avoid the need to distinguish between IOMMU and non-IOMMU devices. Thierry -- next part -- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: not available URL: <https://lists.freedesktop.org/archives/dri-devel/attachments/20160223/f427c76b/attachment.sig>
[PATCH v3 22/22] drm/tilcdc: Use devm_kzalloc() and devm_kcalloc() for private data
Use devm_kzalloc() and devm_kcalloc() for private data allocation at driver load time. Signed-off-by: Jyri Sarha --- drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 4 +--- drivers/gpu/drm/tilcdc/tilcdc_drv.c| 19 +++ drivers/gpu/drm/tilcdc/tilcdc_panel.c | 20 ++-- drivers/gpu/drm/tilcdc/tilcdc_tfp410.c | 24 +++- 4 files changed, 21 insertions(+), 46 deletions(-) diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c index 1eb4e0e..7dab668 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c @@ -127,8 +127,6 @@ static void tilcdc_crtc_destroy(struct drm_crtc *crtc) of_node_put(crtc->port); drm_crtc_cleanup(crtc); drm_flip_work_cleanup(_crtc->unref_work); - - kfree(tilcdc_crtc); } static int tilcdc_verify_fb(struct drm_crtc *crtc, struct drm_framebuffer *fb) @@ -755,7 +753,7 @@ struct drm_crtc *tilcdc_crtc_create(struct drm_device *dev) struct drm_crtc *crtc; int ret; - tilcdc_crtc = kzalloc(sizeof(*tilcdc_crtc), GFP_KERNEL); + tilcdc_crtc = devm_kzalloc(dev->dev, sizeof(*tilcdc_crtc), GFP_KERNEL); if (!tilcdc_crtc) { dev_err(dev->dev, "allocation failed\n"); return NULL; diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c index 41ec890..709bc90 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c @@ -143,9 +143,6 @@ static int tilcdc_unload(struct drm_device *dev) pm_runtime_disable(dev->dev); - kfree(priv->saved_register); - kfree(priv); - return 0; } @@ -161,13 +158,12 @@ static int tilcdc_load(struct drm_device *dev, unsigned long flags) u32 bpp = 0; int ret; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = devm_kzalloc(dev->dev, sizeof(*priv), GFP_KERNEL); if (priv) - priv->saved_register = kcalloc(tilcdc_num_regs(), - sizeof(*priv->saved_register), - GFP_KERNEL); + priv->saved_register = + devm_kcalloc(dev->dev, tilcdc_num_regs(), +sizeof(*priv->saved_register), GFP_KERNEL); if (!priv || !priv->saved_register) { - kfree(priv); dev_err(dev->dev, "failed to allocate private data\n"); return -ENOMEM; } @@ -180,7 +176,7 @@ static int tilcdc_load(struct drm_device *dev, unsigned long flags) priv->wq = alloc_ordered_workqueue("tilcdc", 0); if (!priv->wq) { ret = -ENOMEM; - goto fail_free_priv; + goto fail_unset_priv; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -346,10 +342,9 @@ fail_free_wq: flush_workqueue(priv->wq); destroy_workqueue(priv->wq); -fail_free_priv: +fail_unset_priv: dev->dev_private = NULL; - kfree(priv->saved_register); - kfree(priv); + return ret; } diff --git a/drivers/gpu/drm/tilcdc/tilcdc_panel.c b/drivers/gpu/drm/tilcdc/tilcdc_panel.c index 8dcf02a..ff7774c 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_panel.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_panel.c @@ -45,14 +45,6 @@ struct panel_encoder { }; #define to_panel_encoder(x) container_of(x, struct panel_encoder, base) - -static void panel_encoder_destroy(struct drm_encoder *encoder) -{ - struct panel_encoder *panel_encoder = to_panel_encoder(encoder); - drm_encoder_cleanup(encoder); - kfree(panel_encoder); -} - static void panel_encoder_dpms(struct drm_encoder *encoder, int mode) { struct panel_encoder *panel_encoder = to_panel_encoder(encoder); @@ -90,7 +82,7 @@ static void panel_encoder_mode_set(struct drm_encoder *encoder, } static const struct drm_encoder_funcs panel_encoder_funcs = { - .destroy= panel_encoder_destroy, + .destroy= drm_encoder_cleanup, }; static const struct drm_encoder_helper_funcs panel_encoder_helper_funcs = { @@ -107,7 +99,8 @@ static struct drm_encoder *panel_encoder_create(struct drm_device *dev, struct drm_encoder *encoder; int ret; - panel_encoder = kzalloc(sizeof(*panel_encoder), GFP_KERNEL); + panel_encoder = devm_kzalloc(dev->dev, sizeof(*panel_encoder), +GFP_KERNEL); if (!panel_encoder) { dev_err(dev->dev, "allocation failed\n"); return NULL; @@ -128,7 +121,7 @@ static struct drm_encoder *panel_encoder_create(struct drm_device *dev, return encoder; fail: - panel_encoder_destroy(encoder); + drm_encoder_cleanup(encoder); return NULL; } @@ -147,10 +140,8 @@ struct panel_connector { static void panel_connector_destroy(struct drm_connector
[PATCH v3 21/22] drm/tilcdc: Initialize crtc->port
Initialize port device node pointer in the tilcdc crtc. Fixes "Falling back to first CRTC" warning from tda998x driver. The tda998x encoder driver calls drm_of_find_possible_crtcs() to initialize possible_crtcs of struct drm_encoder. The crtc->port needs to be initialized for drm_of_find_possible_crtcs() to work. Signed-off-by: Jyri Sarha --- drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 16 1 file changed, 16 insertions(+) diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c index 248e3ea..1eb4e0e 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c @@ -124,6 +124,7 @@ static void tilcdc_crtc_destroy(struct drm_crtc *crtc) tilcdc_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); + of_node_put(crtc->port); drm_crtc_cleanup(crtc); drm_flip_work_cleanup(_crtc->unref_work); @@ -749,6 +750,7 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc) struct drm_crtc *tilcdc_crtc_create(struct drm_device *dev) { + struct tilcdc_drm_private *priv = dev->dev_private; struct tilcdc_crtc *tilcdc_crtc; struct drm_crtc *crtc; int ret; @@ -775,6 +777,20 @@ struct drm_crtc *tilcdc_crtc_create(struct drm_device *dev) drm_crtc_helper_add(crtc, _crtc_helper_funcs); + if (priv->is_componentized) { + struct device_node *ports = + of_get_child_by_name(dev->dev->of_node, "ports"); + + if (ports) { + crtc->port = of_get_child_by_name(ports, "port"); + of_node_put(ports); + } else { + crtc->port = + of_get_child_by_name(dev->dev->of_node, "port"); + } + WARN_ON(!crtc->port); + } + return crtc; fail: -- 1.9.1
[PATCH v3 20/22] drm/tilcdc: Disable sync lost interrupt if it fires on every frame
Disable the sync lost interrupt if it fires on every frame for 50 consecutive frames in a row. This is relatively sure sign of the sync lost interrupt being stuck and firing on every frame even if the display otherwise appears to work OK. Signed-off-by: Jyri Sarha --- drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 21 - 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c index 5ee22c6..248e3ea 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c @@ -43,6 +43,9 @@ struct tilcdc_crtc { /* Only set if an external encoder is connected */ bool simulate_vesa_sync; + + int sync_lost_count; + bool frame_intact; }; #define to_tilcdc_crtc(x) container_of(x, struct tilcdc_crtc, base) @@ -662,6 +665,8 @@ out: pm_runtime_put_sync(dev->dev); } +#define SYNC_LOST_COUNT_LIMIT 50 + irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc) { struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); @@ -707,6 +712,11 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc) spin_unlock_irqrestore(>event_lock, flags); } + + if (tilcdc_crtc->frame_intact) + tilcdc_crtc->sync_lost_count = 0; + else + tilcdc_crtc->frame_intact = true; } if (priv->rev == 2) { @@ -717,9 +727,18 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc) tilcdc_write(dev, LCDC_END_OF_INT_IND_REG, 0); } - if (stat & LCDC_SYNC_LOST) + if (stat & LCDC_SYNC_LOST) { dev_err_ratelimited(dev->dev, "%s(0x%08x): Sync lost", __func__, stat); + tilcdc_crtc->frame_intact = false; + if (tilcdc_crtc->sync_lost_count++ > SYNC_LOST_COUNT_LIMIT) { + dev_err(dev->dev, + "%s(0x%08x): Sync lost flood detected, disabling the interrupt", + __func__, stat); + tilcdc_write(dev, LCDC_INT_ENABLE_CLR_REG, +LCDC_SYNC_LOST); + } + } if (stat & LCDC_FIFO_UNDERFLOW) dev_err_ratelimited(dev->dev, "%s(0x%08x): FIFO underfow", -- 1.9.1
[PATCH v3 19/22] drm/tilcdc: Add prints on sync lost and FIFO underrun interrupts
Add ratelimited prints on sync lost and FIFO underrun interrupts. Signed-off-by: Jyri Sarha --- drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 8 drivers/gpu/drm/tilcdc/tilcdc_drv.c | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c index b1df046..5ee22c6 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c @@ -717,6 +717,14 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc) tilcdc_write(dev, LCDC_END_OF_INT_IND_REG, 0); } + if (stat & LCDC_SYNC_LOST) + dev_err_ratelimited(dev->dev, "%s(0x%08x): Sync lost", + __func__, stat); + + if (stat & LCDC_FIFO_UNDERFLOW) + dev_err_ratelimited(dev->dev, "%s(0x%08x): FIFO underfow", + __func__, stat); + return IRQ_HANDLED; } diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c index d96083d..41ec890 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c @@ -382,7 +382,7 @@ static int tilcdc_irq_postinstall(struct drm_device *dev) tilcdc_write(dev, LCDC_INT_ENABLE_SET_REG, LCDC_V2_UNDERFLOW_INT_ENA | LCDC_V2_END_OF_FRAME0_INT_ENA | - LCDC_FRAME_DONE); + LCDC_FRAME_DONE | LCDC_SYNC_LOST); } return 0; @@ -401,7 +401,7 @@ static void tilcdc_irq_uninstall(struct drm_device *dev) tilcdc_write(dev, LCDC_INT_ENABLE_CLR_REG, LCDC_V2_UNDERFLOW_INT_ENA | LCDC_V2_PL_INT_ENA | LCDC_V2_END_OF_FRAME0_INT_ENA | - LCDC_FRAME_DONE); + LCDC_FRAME_DONE | LCDC_SYNC_LOST); } } -- 1.9.1
[PATCH v3 18/22] drm/tilcdc: Remove the duplicate LCDC_INT_ENABLE_SET_REG in registers[]
Removes the duplicate LCDC_INT_ENABLE_SET_REG-entry in registers array. Signed-off-by: Jyri Sarha --- drivers/gpu/drm/tilcdc/tilcdc_drv.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c index 964e192..d96083d 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c @@ -439,11 +439,10 @@ static const struct { /* new in revision 2: */ REG(2, false, LCDC_RAW_STAT_REG), REG(2, false, LCDC_MASKED_STAT_REG), - REG(2, false, LCDC_INT_ENABLE_SET_REG), + REG(2, true, LCDC_INT_ENABLE_SET_REG), REG(2, false, LCDC_INT_ENABLE_CLR_REG), REG(2, false, LCDC_END_OF_INT_IND_REG), REG(2, true, LCDC_CLK_ENABLE_REG), - REG(2, true, LCDC_INT_ENABLE_SET_REG), #undef REG }; -- 1.9.1
[PATCH v3 17/22] drm/tilcdc: Fix interrupt enable/disable code for version 2 tilcdc
Fix interrupt enable/disable code for version 2 tilcdc. In version 2 tilcdc there is a separate register for disabling interrupts. Writing 0 to enable registers bits does not have any effect. The interrupt clear register works the same way, writing 1 to specific bit disables the interrupt and writing 0 does not have any effect. The "bug" that is fixed here does not really do any harm since the interrupts are enabled only once in the power up and disabled before power down. Signed-off-by: Jyri Sarha --- drivers/gpu/drm/tilcdc/tilcdc_drv.c | 11 ++- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c index c5d9e3a..964e192 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c @@ -376,13 +376,14 @@ static int tilcdc_irq_postinstall(struct drm_device *dev) struct tilcdc_drm_private *priv = dev->dev_private; /* enable FIFO underflow irq: */ - if (priv->rev == 1) + if (priv->rev == 1) { tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_V1_UNDERFLOW_INT_ENA); - else - tilcdc_set(dev, LCDC_INT_ENABLE_SET_REG, + } else { + tilcdc_write(dev, LCDC_INT_ENABLE_SET_REG, LCDC_V2_UNDERFLOW_INT_ENA | LCDC_V2_END_OF_FRAME0_INT_ENA | LCDC_FRAME_DONE); + } return 0; } @@ -397,7 +398,7 @@ static void tilcdc_irq_uninstall(struct drm_device *dev) LCDC_V1_UNDERFLOW_INT_ENA | LCDC_V1_PL_INT_ENA); tilcdc_clear(dev, LCDC_DMA_CTRL_REG, LCDC_V1_END_OF_FRAME_INT_ENA); } else { - tilcdc_clear(dev, LCDC_INT_ENABLE_SET_REG, + tilcdc_write(dev, LCDC_INT_ENABLE_CLR_REG, LCDC_V2_UNDERFLOW_INT_ENA | LCDC_V2_PL_INT_ENA | LCDC_V2_END_OF_FRAME0_INT_ENA | LCDC_FRAME_DONE); @@ -442,7 +443,7 @@ static const struct { REG(2, false, LCDC_INT_ENABLE_CLR_REG), REG(2, false, LCDC_END_OF_INT_IND_REG), REG(2, true, LCDC_CLK_ENABLE_REG), - REG(2, true, LCDC_INT_ENABLE_SET_REG), + REG(2, true, LCDC_INT_ENABLE_SET_REG), #undef REG }; -- 1.9.1
[PATCH v3 16/22] drm/tilcdc: Do not update the next frame buffer close to vertical blank
From: Tomi ValkeinenDo not update the next frame buffer close to vertical blank. This is to avoid situation when the frame changes between writing of LCDC_DMA_FB_BASE_ADDR_0_REG and LCDC_DMA_FB_CEILING_ADDR_0_REG. Signed-off-by: Tomi Valkeinen [Added description to the patch] Signed-off-by: Jyri Sarha --- drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 61 +++- 1 file changed, 53 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c index 32572285..b1df046 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c @@ -21,6 +21,8 @@ #include "tilcdc_drv.h" #include "tilcdc_regs.h" +#define TILCDC_VBLANK_SAFETY_THRESHOLD_US 1000 + struct tilcdc_crtc { struct drm_crtc base; @@ -29,8 +31,12 @@ struct tilcdc_crtc { int dpms; wait_queue_head_t frame_done_wq; bool frame_done; + spinlock_t irq_lock; + + ktime_t last_vblank; struct drm_framebuffer *curr_fb; + struct drm_framebuffer *next_fb; /* for deferred fb unref's: */ struct drm_flip_work unref_work; @@ -146,6 +152,8 @@ static int tilcdc_crtc_page_flip(struct drm_crtc *crtc, struct drm_device *dev = crtc->dev; int r; unsigned long flags; + s64 tdiff; + ktime_t next_vblank; r = tilcdc_verify_fb(crtc, fb); if (r) @@ -162,12 +170,21 @@ static int tilcdc_crtc_page_flip(struct drm_crtc *crtc, pm_runtime_get_sync(dev->dev); + spin_lock_irqsave(_crtc->irq_lock, flags); + + next_vblank = ktime_add_us(tilcdc_crtc->last_vblank, + 100 / crtc->hwmode.vrefresh); - set_scanout(crtc, fb); + tdiff = ktime_to_us(ktime_sub(next_vblank, ktime_get())); + + if (tdiff >= TILCDC_VBLANK_SAFETY_THRESHOLD_US) + set_scanout(crtc, fb); + else + tilcdc_crtc->next_fb = fb; - spin_lock_irqsave(>event_lock, flags); tilcdc_crtc->event = event; - spin_unlock_irqrestore(>event_lock, flags); + + spin_unlock_irqrestore(_crtc->irq_lock, flags); pm_runtime_put_sync(dev->dev); @@ -211,6 +228,12 @@ void tilcdc_crtc_dpms(struct drm_crtc *crtc, int mode) pm_runtime_put_sync(dev->dev); + if (tilcdc_crtc->next_fb) { + drm_flip_work_queue(_crtc->unref_work, + tilcdc_crtc->next_fb); + tilcdc_crtc->next_fb = NULL; + } + if (tilcdc_crtc->curr_fb) { drm_flip_work_queue(_crtc->unref_work, tilcdc_crtc->curr_fb); @@ -651,19 +674,39 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc) if (stat & LCDC_END_OF_FRAME0) { unsigned long flags; + bool skip_event = false; + ktime_t now; + + now = ktime_get(); drm_flip_work_commit(_crtc->unref_work, priv->wq); + spin_lock_irqsave(_crtc->irq_lock, flags); + + tilcdc_crtc->last_vblank = now; + + if (tilcdc_crtc->next_fb) { + set_scanout(crtc, tilcdc_crtc->next_fb); + tilcdc_crtc->next_fb = NULL; + skip_event = true; + } + + spin_unlock_irqrestore(_crtc->irq_lock, flags); + drm_handle_vblank(dev, 0); - spin_lock_irqsave(>event_lock, flags); + if (!skip_event) { + struct drm_pending_vblank_event *event; - if (tilcdc_crtc->event) { - drm_send_vblank_event(dev, 0, tilcdc_crtc->event); + spin_lock_irqsave(>event_lock, flags); + + event = tilcdc_crtc->event; tilcdc_crtc->event = NULL; - } + if (event) + drm_send_vblank_event(dev, 0, event); - spin_unlock_irqrestore(>event_lock, flags); + spin_unlock_irqrestore(>event_lock, flags); + } } if (priv->rev == 2) { @@ -697,6 +740,8 @@ struct drm_crtc *tilcdc_crtc_create(struct drm_device *dev) drm_flip_work_init(_crtc->unref_work, "unref", unref_worker); + spin_lock_init(_crtc->irq_lock); + ret = drm_crtc_init(dev, crtc, _crtc_funcs); if (ret < 0) goto fail; -- 1.9.1
[PATCH v3 15/22] drm/tilcdc: Get rid of complex ping-pong mechanism
From: Tomi ValkeinenGet rid of complex ping-pong mechanism and replace it with simpler single buffer flipping code. The LCDC HW appears to be designed mainly static framebuffers in mind. There are two modes of operation, either static single buffer, or ping pong double buffering with two static buffers switching back and forth. Luckily the framebuffer start address is fetched only in the beginning of the frame and changing the address after that only takes effect after the next vertical blank. The page flipping code can simply write the address of the new framebuffer and the page is flipped automatically after the next vertical blank. Using the ping pong double buffering makes the flipping code way more complex and it does not provide any benefit, so it is better to switch to single buffer operation. There is still one problem in updating the framebuffer dma address on the fly. There are two registers defining the framebuffer dma area and things may break if the dma address is fetched in while the registers are are being updated. Signed-off-by: Tomi Valkeinen [Added description to the patch] Signed-off-by: Jyri Sarha --- drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 121 +++ drivers/gpu/drm/tilcdc/tilcdc_drv.c | 27 +--- 2 files changed, 53 insertions(+), 95 deletions(-) diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c index a6ef737..32572285 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c @@ -25,15 +25,12 @@ struct tilcdc_crtc { struct drm_crtc base; const struct tilcdc_panel_info *info; - uint32_t dirty; - dma_addr_t start, end; struct drm_pending_vblank_event *event; int dpms; wait_queue_head_t frame_done_wq; bool frame_done; - /* fb currently set to scanout 0/1: */ - struct drm_framebuffer *scanout[2]; + struct drm_framebuffer *curr_fb; /* for deferred fb unref's: */ struct drm_flip_work unref_work; @@ -54,62 +51,31 @@ static void unref_worker(struct drm_flip_work *work, void *val) mutex_unlock(>mode_config.mutex); } -static void set_scanout(struct drm_crtc *crtc, int n) -{ - static const uint32_t base_reg[] = { - LCDC_DMA_FB_BASE_ADDR_0_REG, - LCDC_DMA_FB_BASE_ADDR_1_REG, - }; - static const uint32_t ceil_reg[] = { - LCDC_DMA_FB_CEILING_ADDR_0_REG, - LCDC_DMA_FB_CEILING_ADDR_1_REG, - }; - static const uint32_t stat[] = { - LCDC_END_OF_FRAME0, LCDC_END_OF_FRAME1, - }; - struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); - struct drm_device *dev = crtc->dev; - struct tilcdc_drm_private *priv = dev->dev_private; - - tilcdc_write(dev, base_reg[n], tilcdc_crtc->start); - tilcdc_write(dev, ceil_reg[n], tilcdc_crtc->end); - if (tilcdc_crtc->scanout[n]) { - drm_flip_work_queue(_crtc->unref_work, tilcdc_crtc->scanout[n]); - drm_flip_work_commit(_crtc->unref_work, priv->wq); - } - tilcdc_crtc->scanout[n] = crtc->primary->fb; - drm_framebuffer_reference(tilcdc_crtc->scanout[n]); - tilcdc_crtc->dirty &= ~stat[n]; -} - -static void update_scanout(struct drm_crtc *crtc) +static void set_scanout(struct drm_crtc *crtc, struct drm_framebuffer *fb) { struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); struct drm_device *dev = crtc->dev; - struct drm_framebuffer *fb = crtc->primary->fb; struct drm_gem_cma_object *gem; unsigned int depth, bpp; + dma_addr_t start, end; drm_fb_get_bpp_depth(fb->pixel_format, , ); gem = drm_fb_cma_get_gem_obj(fb, 0); - tilcdc_crtc->start = gem->paddr + fb->offsets[0] + - (crtc->y * fb->pitches[0]) + (crtc->x * bpp/8); + start = gem->paddr + fb->offsets[0] + + crtc->y * fb->pitches[0] + + crtc->x * bpp / 8; - tilcdc_crtc->end = tilcdc_crtc->start + - (crtc->mode.vdisplay * fb->pitches[0]); + end = start + (crtc->mode.vdisplay * fb->pitches[0]); - if (tilcdc_crtc->dpms == DRM_MODE_DPMS_ON) { - /* already enabled, so just mark the frames that need -* updating and they will be updated on vblank: -*/ - tilcdc_crtc->dirty |= LCDC_END_OF_FRAME0 | LCDC_END_OF_FRAME1; - drm_vblank_get(dev, 0); - } else { - /* not enabled yet, so update registers immediately: */ - set_scanout(crtc, 0); - set_scanout(crtc, 1); - } + tilcdc_write(dev, LCDC_DMA_FB_BASE_ADDR_0_REG, start); + tilcdc_write(dev, LCDC_DMA_FB_CEILING_ADDR_0_REG, end); + + if (tilcdc_crtc->curr_fb) +
[PATCH v3 14/22] drm/tilcdc: cleanup irq handling
From: Tomi ValkeinenCleanup irq handling. Clear the irq status unconditionally and restructure the status bit conditions. Signed-off-by: Tomi Valkeinen [Added description to the patch] Signed-off-by: Jyri Sarha --- drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c index 61aead2..a6ef737 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c @@ -656,11 +656,12 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc) struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); struct drm_device *dev = crtc->dev; struct tilcdc_drm_private *priv = dev->dev_private; - uint32_t stat = tilcdc_read_irqstatus(dev); + uint32_t stat; - if (stat & LCDC_PL_LOAD_DONE) { - tilcdc_clear_irqstatus(dev, stat); - } else { + stat = tilcdc_read_irqstatus(dev); + tilcdc_clear_irqstatus(dev, stat); + + if ((stat & LCDC_END_OF_FRAME0) || (stat & LCDC_END_OF_FRAME1)) { struct drm_pending_vblank_event *event; unsigned long flags; uint32_t dirty = tilcdc_crtc->dirty & stat; -- 1.9.1
[PATCH v3 13/22] drm/tilcdc: remove broken error handling
From: Tomi ValkeinenRemove broken error handling. The condition for handling the LCDC_SYNC_LOST and LCDC_FIFO_UNDERFLOW could never be satisfied as the LCDC_SYNC_LOST interrupt is not enabled. Also the requirement to have both LCDC_SYNC_LOST and LCDC_FIFO_UNDERFLOW fired at once before handling the error looks weird. Signed-off-by: Tomi Valkeinen [Added description to the patch] Signed-off-by: Jyri Sarha --- drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 7 +-- 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c index e62a950..61aead2 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c @@ -658,12 +658,7 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc) struct tilcdc_drm_private *priv = dev->dev_private; uint32_t stat = tilcdc_read_irqstatus(dev); - if ((stat & LCDC_SYNC_LOST) && (stat & LCDC_FIFO_UNDERFLOW)) { - stop(crtc); - dev_err(dev->dev, "error: %08x\n", stat); - tilcdc_clear_irqstatus(dev, stat); - start(crtc); - } else if (stat & LCDC_PL_LOAD_DONE) { + if (stat & LCDC_PL_LOAD_DONE) { tilcdc_clear_irqstatus(dev, stat); } else { struct drm_pending_vblank_event *event; -- 1.9.1
[PATCH v3 12/22] drm/tilcdc: split reset to a separate function
From: Tomi ValkeinenSplit reset to a separate function and use usleep_range(250, 1000) instead of msleep(1) to to keep the reset bit on long enough. Signed-off-by: Tomi Valkeinen [Added description to the patch, changed mdelay(500) to usleep_range(250, 1000)] Signed-off-by: Jyri Sarha --- drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 21 ++--- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c index 08b1e03..e62a950 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c @@ -112,17 +112,24 @@ static void update_scanout(struct drm_crtc *crtc) } } -static void start(struct drm_crtc *crtc) +static void reset(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; struct tilcdc_drm_private *priv = dev->dev_private; - if (priv->rev == 2) { - tilcdc_set(dev, LCDC_CLK_RESET_REG, LCDC_CLK_MAIN_RESET); - msleep(1); - tilcdc_clear(dev, LCDC_CLK_RESET_REG, LCDC_CLK_MAIN_RESET); - msleep(1); - } + if (priv->rev != 2) + return; + + tilcdc_set(dev, LCDC_CLK_RESET_REG, LCDC_CLK_MAIN_RESET); + usleep_range(250, 1000); + tilcdc_clear(dev, LCDC_CLK_RESET_REG, LCDC_CLK_MAIN_RESET); +} + +static void start(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + + reset(crtc); tilcdc_set(dev, LCDC_DMA_CTRL_REG, LCDC_DUAL_FRAME_BUFFER_ENABLE); tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_PALETTE_LOAD_MODE(DATA_ONLY)); -- 1.9.1
[PATCH v3 11/22] drm/tilcdc: disable crtc on unload
From: Tomi ValkeinenDisable crtc on unload. Call tilcdc_crtc_dpms() with DRM_MODE_DPMS_OFF in the beginning of unload function. Signed-off-by: Tomi Valkeinen [Added description to the patch] Signed-off-by: Jyri Sarha --- drivers/gpu/drm/tilcdc/tilcdc_drv.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c index 47f0e02..e1f6979 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c @@ -112,6 +112,8 @@ static int tilcdc_unload(struct drm_device *dev) { struct tilcdc_drm_private *priv = dev->dev_private; + tilcdc_crtc_dpms(priv->crtc, DRM_MODE_DPMS_OFF); + tilcdc_remove_external_encoders(dev); drm_fbdev_cma_fini(priv->fbdev); -- 1.9.1
[PATCH v3 10/22] drm/tilcdc: cleanup runtime PM handling
From: Tomi ValkeinenCleanup runtime PM handling. Before the patch the usage of pm_runtime calls was inconsistent and hard to follow. After the update the pm_runtime calls are removed from set_scanout() and called around major operations that access the HW. After the patch the DPMS code does not have pm_runtime_forbid/allow calls any more and pm_runtime_irq_safe() is not set anymore. Signed-off-by: Tomi Valkeinen [Added description to the patch] Signed-off-by: Jyri Sarha --- drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 19 +++ drivers/gpu/drm/tilcdc/tilcdc_drv.c | 1 - 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c index 465fd04..08b1e03 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c @@ -71,7 +71,6 @@ static void set_scanout(struct drm_crtc *crtc, int n) struct drm_device *dev = crtc->dev; struct tilcdc_drm_private *priv = dev->dev_private; - pm_runtime_get_sync(dev->dev); tilcdc_write(dev, base_reg[n], tilcdc_crtc->start); tilcdc_write(dev, ceil_reg[n], tilcdc_crtc->end); if (tilcdc_crtc->scanout[n]) { @@ -81,7 +80,6 @@ static void set_scanout(struct drm_crtc *crtc, int n) tilcdc_crtc->scanout[n] = crtc->primary->fb; drm_framebuffer_reference(tilcdc_crtc->scanout[n]); tilcdc_crtc->dirty &= ~stat[n]; - pm_runtime_put_sync(dev->dev); } static void update_scanout(struct drm_crtc *crtc) @@ -186,8 +184,13 @@ static int tilcdc_crtc_page_flip(struct drm_crtc *crtc, crtc->primary->fb = fb; tilcdc_crtc->event = event; + + pm_runtime_get_sync(dev->dev); + update_scanout(crtc); + pm_runtime_put_sync(dev->dev); + return 0; } @@ -206,10 +209,8 @@ void tilcdc_crtc_dpms(struct drm_crtc *crtc, int mode) tilcdc_crtc->dpms = mode; - pm_runtime_get_sync(dev->dev); - if (mode == DRM_MODE_DPMS_ON) { - pm_runtime_forbid(dev->dev); + pm_runtime_get_sync(dev->dev); start(crtc); } else { tilcdc_crtc->frame_done = false; @@ -227,10 +228,9 @@ void tilcdc_crtc_dpms(struct drm_crtc *crtc, int mode) if (ret == 0) dev_err(dev->dev, "timeout waiting for framedone\n"); } - pm_runtime_allow(dev->dev); - } - pm_runtime_put_sync(dev->dev); + pm_runtime_put_sync(dev->dev); + } } static bool tilcdc_crtc_mode_fixup(struct drm_crtc *crtc, @@ -455,13 +455,16 @@ static int tilcdc_crtc_mode_set(struct drm_crtc *crtc, static int tilcdc_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, struct drm_framebuffer *old_fb) { + struct drm_device *dev = crtc->dev; int r; r = tilcdc_verify_fb(crtc, crtc->primary->fb); if (r) return r; + pm_runtime_get_sync(dev->dev); update_scanout(crtc); + pm_runtime_put_sync(dev->dev); return 0; } diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c index 47096b1..47f0e02 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c @@ -230,7 +230,6 @@ static int tilcdc_load(struct drm_device *dev, unsigned long flags) DBG("Maximum Pixel Clock Value %dKHz", priv->max_pixelclock); pm_runtime_enable(dev->dev); - pm_runtime_irq_safe(dev->dev); /* Determine LCD IP Version */ pm_runtime_get_sync(dev->dev); -- 1.9.1
[PATCH v3 09/22] drm/tilcdc: Allocate register storage based on the actual number registers
Allocate suspend/resume register storage based on the actual number registers the driver is aware of. The static allocation for register storage had fallen behind badly. Reported-by: Michael Bode Signed-off-by: Jyri Sarha --- drivers/gpu/drm/tilcdc/tilcdc_drv.c | 21 - drivers/gpu/drm/tilcdc/tilcdc_drv.h | 2 +- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c index 977c843..47096b1 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c @@ -141,11 +141,14 @@ static int tilcdc_unload(struct drm_device *dev) pm_runtime_disable(dev->dev); + kfree(priv->saved_register); kfree(priv); return 0; } +static size_t tilcdc_num_regs(void); + static int tilcdc_load(struct drm_device *dev, unsigned long flags) { struct platform_device *pdev = dev->platformdev; @@ -157,7 +160,12 @@ static int tilcdc_load(struct drm_device *dev, unsigned long flags) int ret; priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) { + if (priv) + priv->saved_register = kcalloc(tilcdc_num_regs(), + sizeof(*priv->saved_register), + GFP_KERNEL); + if (!priv || !priv->saved_register) { + kfree(priv); dev_err(dev->dev, "failed to allocate private data\n"); return -ENOMEM; } @@ -339,6 +347,7 @@ fail_free_wq: fail_free_priv: dev->dev_private = NULL; + kfree(priv->saved_register); kfree(priv); return ret; } @@ -456,6 +465,16 @@ static const struct { REG(2, true, LCDC_INT_ENABLE_SET_REG), #undef REG }; + +static size_t tilcdc_num_regs(void) +{ + return ARRAY_SIZE(registers); +} +#else +static size_t tilcdc_num_regs(void) +{ + return 0; +} #endif #ifdef CONFIG_DEBUG_FS diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.h b/drivers/gpu/drm/tilcdc/tilcdc_drv.h index 95324f1..c1de18b 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h @@ -66,7 +66,7 @@ struct tilcdc_drm_private { uint32_t max_width; /* register contents saved across suspend/resume: */ - u32 saved_register[12]; + u32 *saved_register; bool ctx_valid; #ifdef CONFIG_CPU_FREQ -- 1.9.1
[PATCH v3 08/22] drm/tilcdc: fix build error when !CONFIG_CPU_FREQ
From: Grygorii StrashkoFix build error when !CONFIG_CPU_FREQ drivers/gpu/drm/tilcdc/tilcdc_drv.c: In function 'tilcdc_load': drivers/gpu/drm/tilcdc/tilcdc_drv.c:327:1: error: label 'fail_put_clk' defined but not used [-Werror=unused-label] fail_put_clk: ^ Signed-off-by: Grygorii Strashko Signed-off-by: Jyri Sarha --- drivers/gpu/drm/tilcdc/tilcdc_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c index c204359..977c843 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c @@ -325,9 +325,9 @@ fail_cpufreq_unregister: #ifdef CONFIG_CPU_FREQ cpufreq_unregister_notifier(>freq_transition, CPUFREQ_TRANSITION_NOTIFIER); -#endif fail_put_clk: +#endif clk_put(priv->clk); fail_iounmap: -- 1.9.1
[PATCH v3 07/22] drm/tilcdc: Implement dma-buf support for tilcdc
There is nothing special about tilcdc HW when the video memory is concerned. Just using the standard drm helpers for implementation is enough. Signed-off-by: Jyri Sarha --- drivers/gpu/drm/tilcdc/tilcdc_drv.c | 13 - 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c index 30d8ac6..c204359 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c @@ -542,7 +542,8 @@ static const struct file_operations fops = { }; static struct drm_driver tilcdc_driver = { - .driver_features= DRIVER_HAVE_IRQ | DRIVER_GEM | DRIVER_MODESET, + .driver_features= (DRIVER_HAVE_IRQ | DRIVER_GEM | DRIVER_MODESET | + DRIVER_PRIME), .load = tilcdc_load, .unload = tilcdc_unload, .lastclose = tilcdc_lastclose, @@ -559,6 +560,16 @@ static struct drm_driver tilcdc_driver = { .dumb_create= drm_gem_cma_dumb_create, .dumb_map_offset= drm_gem_cma_dumb_map_offset, .dumb_destroy = drm_gem_dumb_destroy, + + .prime_handle_to_fd = drm_gem_prime_handle_to_fd, + .prime_fd_to_handle = drm_gem_prime_fd_to_handle, + .gem_prime_import = drm_gem_prime_import, + .gem_prime_export = drm_gem_prime_export, + .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table, + .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table, + .gem_prime_vmap = drm_gem_cma_prime_vmap, + .gem_prime_vunmap = drm_gem_cma_prime_vunmap, + .gem_prime_mmap = drm_gem_cma_prime_mmap, #ifdef CONFIG_DEBUG_FS .debugfs_init = tilcdc_debugfs_init, .debugfs_cleanup= tilcdc_debugfs_cleanup, -- 1.9.1
[PATCH v3 06/22] drm/tilcdc: disable the lcd controller/dma engine when suspend invoked
From: Darren EtheridgeThe LCD controller must be deactivated and all DMA transactions stopped when the suspend power state is entered otherwise the PRCM causes the L3 bus to get stuck in transition state. This commit forces the lcdc to be shut down and waits for all pending DMA transactions to complete as part of the suspend handler for this driver. Signed-off-by: Darren Etheridge Tested-by: Dave Gerlach Signed-off-by: Jyri Sarha --- drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 3 +-- drivers/gpu/drm/tilcdc/tilcdc_drv.c | 3 +++ drivers/gpu/drm/tilcdc/tilcdc_drv.h | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c index 6485e1c..465fd04 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c @@ -138,7 +138,6 @@ static void stop(struct drm_crtc *crtc) tilcdc_clear(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE); } -static void tilcdc_crtc_dpms(struct drm_crtc *crtc, int mode); static void tilcdc_crtc_destroy(struct drm_crtc *crtc) { struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); @@ -192,7 +191,7 @@ static int tilcdc_crtc_page_flip(struct drm_crtc *crtc, return 0; } -static void tilcdc_crtc_dpms(struct drm_crtc *crtc, int mode) +void tilcdc_crtc_dpms(struct drm_crtc *crtc, int mode) { struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); struct drm_device *dev = crtc->dev; diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c index 7c39362..30d8ac6 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c @@ -592,6 +592,9 @@ static int tilcdc_pm_suspend(struct device *dev) return 0; } + /* Disable the LCDC controller, to avoid locking up the PRCM */ + tilcdc_crtc_dpms(priv->crtc, DRM_MODE_DPMS_OFF); + /* Save register state: */ for (i = 0; i < ARRAY_SIZE(registers); i++) if (registers[i].save && (priv->rev >= registers[i].rev)) diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.h b/drivers/gpu/drm/tilcdc/tilcdc_drv.h index 55d17b3..95324f1 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h @@ -171,5 +171,6 @@ void tilcdc_crtc_set_simulate_vesa_sync(struct drm_crtc *crtc, bool simulate_vesa_sync); int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode); int tilcdc_crtc_max_width(struct drm_crtc *crtc); +void tilcdc_crtc_dpms(struct drm_crtc *crtc, int mode); #endif /* __TILCDC_DRV_H__ */ -- 1.9.1
[PATCH v3 05/22] drm/tilcdc: make frame_done interrupt active at all times
From: Darren EtheridgeThe frame_done interrupt was only being enabled when the vsync interrupts were being enabled by DRM. However the frame_done is used to determine if the LCD controller has successfully completed the raster_enable, raster_disable commands and the vsync interrupts are not always enabled during these operations. Signed-off-by: Darren Etheridge Tested-by: Dave Gerlach Signed-off-by: Jyri Sarha --- drivers/gpu/drm/tilcdc/tilcdc_drv.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c index 67ed9f7..7c39362 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c @@ -369,7 +369,9 @@ static int tilcdc_irq_postinstall(struct drm_device *dev) if (priv->rev == 1) tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_V1_UNDERFLOW_INT_ENA); else - tilcdc_set(dev, LCDC_INT_ENABLE_SET_REG, LCDC_V2_UNDERFLOW_INT_ENA); + tilcdc_set(dev, LCDC_INT_ENABLE_SET_REG, + LCDC_V2_UNDERFLOW_INT_ENA | + LCDC_FRAME_DONE); return 0; } @@ -403,7 +405,7 @@ static void enable_vblank(struct drm_device *dev, bool enable) } else { reg = LCDC_INT_ENABLE_SET_REG; mask = LCDC_V2_END_OF_FRAME0_INT_ENA | - LCDC_V2_END_OF_FRAME1_INT_ENA | LCDC_FRAME_DONE; + LCDC_V2_END_OF_FRAME1_INT_ENA; } if (enable) -- 1.9.1
[PATCH v3 04/22] drm/tilcdc: fix kernel panic on suspend when no hdmi monitor connected
From: Darren EtheridgeOn BeagleBone Black if no HDMI monitor is connected and suspend is requested a kernel panic will result: root at am335x-evm:~# echo mem > /sys/power/state [ 65.548710] PM: Syncing filesystems ... done. [ 65.631311] Freezing user space processes ... (elapsed 0.006 seconds) done. [ 65.648619] Freezing remaining freezable tasks ... (elapsed 0.005 seconds) done. [ 65.833500] Unhandled fault: external abort on non-linefetch (0x1028) at 0xfa30e004 [ 65.841692] Internal error: : 1028 [#1] SMP ARM [ 66.105287] [] (platform_pm_suspend) from [] (dpm_run_callback+0x34/0x70) [ 66.114370] [] (dpm_run_callback) from [] (__device_suspend+0x10c/0x2f4) [ 66.123357] [] (__device_suspend) from [] (dpm_suspend+0x58/0x218) [ 66.131796] [] (dpm_suspend) from [] (suspend_devices_and_enter+0x9c/0x3c0) [ 66.141055] [] (suspend_devices_and_enter) from [] (pm_suspend+0x210/0x24c) [ 66.150312] [] (pm_suspend) from [] (state_store+0x68/0xb8) [ 66.158103] [] (state_store) from [] (kobj_attr_store+0x14/0x20) [ 66.166355] [] (kobj_attr_store) from [] (sysfs_kf_write+0x4c/0x50) [ 66.174883] [] (sysfs_kf_write) from [] (kernfs_fop_write+0xb4/0x150) [ 66.183598] [] (kernfs_fop_write) from [] (vfs_write+0xa8/0x180) [ 66.191846] [] (vfs_write) from [] (SyS_write+0x40/0x8c) [ 66.199365] [] (SyS_write) from [] (ret_fast_syscall+0x0/0x48) [ 66.207426] Code: e595c210 e5932000 e59cc000 e08c2002 (e592c000) This is because the lcdc module is not enabled when no monitor is detected to save power. However the suspend handler just blindly tries to save the lcdc state by copying out the pertinent registers. However module is off so no good things happen when you try and access it. This patch only saves off the registers if the module is enabled, and then only restores the registers on resume if they were saved off during suspend. Signed-off-by: Darren Etheridge Tested-by: Dave Gerlach Acked-by: Felipe Balbi Signed-off-by: Jyri Sarha --- drivers/gpu/drm/tilcdc/tilcdc_drv.c | 23 +-- drivers/gpu/drm/tilcdc/tilcdc_drv.h | 1 + 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c index 420a237..67ed9f7 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c @@ -582,13 +582,20 @@ static int tilcdc_pm_suspend(struct device *dev) drm_kms_helper_poll_disable(ddev); + /* Select sleep pin state */ + pinctrl_pm_select_sleep_state(dev); + + if (pm_runtime_suspended(dev)) { + priv->ctx_valid = false; + return 0; + } + /* Save register state: */ for (i = 0; i < ARRAY_SIZE(registers); i++) if (registers[i].save && (priv->rev >= registers[i].rev)) priv->saved_register[n++] = tilcdc_read(ddev, registers[i].reg); - /* Select sleep pin state */ - pinctrl_pm_select_sleep_state(dev); + priv->ctx_valid = true; return 0; } @@ -602,10 +609,14 @@ static int tilcdc_pm_resume(struct device *dev) /* Select default pin state */ pinctrl_pm_select_default_state(dev); - /* Restore register state: */ - for (i = 0; i < ARRAY_SIZE(registers); i++) - if (registers[i].save && (priv->rev >= registers[i].rev)) - tilcdc_write(ddev, registers[i].reg, priv->saved_register[n++]); + if (priv->ctx_valid == true) { + /* Restore register state: */ + for (i = 0; i < ARRAY_SIZE(registers); i++) + if (registers[i].save && + (priv->rev >= registers[i].rev)) + tilcdc_write(ddev, registers[i].reg, +priv->saved_register[n++]); + } drm_kms_helper_poll_enable(ddev); diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.h b/drivers/gpu/drm/tilcdc/tilcdc_drv.h index 62a1d68..55d17b3 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h @@ -67,6 +67,7 @@ struct tilcdc_drm_private { /* register contents saved across suspend/resume: */ u32 saved_register[12]; + bool ctx_valid; #ifdef CONFIG_CPU_FREQ struct notifier_block freq_transition; -- 1.9.1
[PATCH v3 03/22] drm/tilcdc: adopt pinctrl support
From: Dave GerlachUpdate tilcdc driver to set the state of the pins to: - "default on resume - "sleep" on suspend By optionally putting the pins into sleep state in the suspend callback we can accomplish two things. - minimize current leakage from pins and thus save power, - prevent the IP from driving pins output in an uncontrolled manner, which may happen if the power domain drops the domain regulator. Signed-off-by: Dave Gerlach Signed-off-by: Darren Etheridge Signed-off-by: Jyri Sarha --- drivers/gpu/drm/tilcdc/tilcdc_drv.c | 8 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c index b3dbbe9..420a237 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c @@ -18,6 +18,8 @@ /* LCDC DRM driver, based on da8xx-fb */ #include +#include +#include #include "tilcdc_drv.h" #include "tilcdc_regs.h" @@ -585,6 +587,9 @@ static int tilcdc_pm_suspend(struct device *dev) if (registers[i].save && (priv->rev >= registers[i].rev)) priv->saved_register[n++] = tilcdc_read(ddev, registers[i].reg); + /* Select sleep pin state */ + pinctrl_pm_select_sleep_state(dev); + return 0; } @@ -594,6 +599,9 @@ static int tilcdc_pm_resume(struct device *dev) struct tilcdc_drm_private *priv = ddev->dev_private; unsigned i, n = 0; + /* Select default pin state */ + pinctrl_pm_select_default_state(dev); + /* Restore register state: */ for (i = 0; i < ARRAY_SIZE(registers); i++) if (registers[i].save && (priv->rev >= registers[i].rev)) -- 1.9.1
[PATCH v3 02/22] drm/tilcdc: verify fb pitch
From: Tomi ValkeinenLCDC hardware does not support fb pitch that is different (i.e. larger) than the screen size. The driver currently does no checks for this, and the results of too big pitch are are flickering and lower fps. This issue easily happens when using libdrm's modetest tool with non-32 bpp modes. As modetest always allocated 4 bytes per pixel, it implies a bigger pitch for 16 or 24 bpp modes. This patch adds a check to reject pitches the hardware cannot support. Signed-off-by: Tomi Valkeinen Signed-off-by: Darren Etheridge Signed-off-by: Jyri Sarha --- drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 31 +++ 1 file changed, 31 insertions(+) diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c index aaf8989..6485e1c 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c @@ -151,6 +151,22 @@ static void tilcdc_crtc_destroy(struct drm_crtc *crtc) kfree(tilcdc_crtc); } +static int tilcdc_verify_fb(struct drm_crtc *crtc, struct drm_framebuffer *fb) +{ + struct drm_device *dev = crtc->dev; + unsigned int depth, bpp; + + drm_fb_get_bpp_depth(fb->pixel_format, , ); + + if (fb->pitches[0] != crtc->mode.hdisplay * bpp / 8) { + dev_err(dev->dev, + "Invalid pitch: fb and crtc widths must be the same"); + return -EINVAL; + } + + return 0; +} + static int tilcdc_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, struct drm_pending_vblank_event *event, @@ -158,6 +174,11 @@ static int tilcdc_crtc_page_flip(struct drm_crtc *crtc, { struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); struct drm_device *dev = crtc->dev; + int r; + + r = tilcdc_verify_fb(crtc, fb); + if (r) + return r; if (tilcdc_crtc->event) { dev_err(dev->dev, "already pending page flip!\n"); @@ -272,6 +293,10 @@ static int tilcdc_crtc_mode_set(struct drm_crtc *crtc, if (WARN_ON(!info)) return -EINVAL; + ret = tilcdc_verify_fb(crtc, crtc->primary->fb); + if (ret) + return ret; + pm_runtime_get_sync(dev->dev); /* Configure the Burst Size and fifo threshold of DMA: */ @@ -431,6 +456,12 @@ static int tilcdc_crtc_mode_set(struct drm_crtc *crtc, static int tilcdc_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, struct drm_framebuffer *old_fb) { + int r; + + r = tilcdc_verify_fb(crtc, crtc->primary->fb); + if (r) + return r; + update_scanout(crtc); return 0; } -- 1.9.1
[PATCH v3 01/22] drm/tilcdc: rewrite pixel clock calculation
From: Darren EtheridgeUpdating the tilcdc DRM driver code to calculate the LCD controller pixel clock more accurately. Based on a suggested implementation by Tomi Valkeinen. The current code does not work correctly and produces wrong results with many requested clock rates. It also oddly uses two different clocks, a display pll clock and a divider clock (child of display pll), instead of just using the clock coming to the lcdc. This patch removes the use of the display pll clock, and rewrites the code to calculate the clock rates. The idea is simply to request a clock rate of pixelclock*2, as the LCD controller has an internal divider which we set to 2. Signed-off-by: Darren Etheridge [Rewrapped description] Signed-off-by: Jyri Sarha --- drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 16 drivers/gpu/drm/tilcdc/tilcdc_drv.c | 11 +-- drivers/gpu/drm/tilcdc/tilcdc_drv.h | 1 - 3 files changed, 9 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c index 4802da8..aaf8989 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c @@ -573,7 +573,8 @@ void tilcdc_crtc_update_clk(struct drm_crtc *crtc) struct drm_device *dev = crtc->dev; struct tilcdc_drm_private *priv = dev->dev_private; int dpms = tilcdc_crtc->dpms; - unsigned int lcd_clk, div; + unsigned long lcd_clk; + const unsigned clkdiv = 2; /* using a fixed divider of 2 */ int ret; pm_runtime_get_sync(dev->dev); @@ -581,22 +582,21 @@ void tilcdc_crtc_update_clk(struct drm_crtc *crtc) if (dpms == DRM_MODE_DPMS_ON) tilcdc_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); - /* in raster mode, minimum divisor is 2: */ - ret = clk_set_rate(priv->disp_clk, crtc->mode.clock * 1000 * 2); - if (ret) { + /* mode.clock is in KHz, set_rate wants parameter in Hz */ + ret = clk_set_rate(priv->clk, crtc->mode.clock * 1000 * clkdiv); + if (ret < 0) { dev_err(dev->dev, "failed to set display clock rate to: %d\n", crtc->mode.clock); goto out; } lcd_clk = clk_get_rate(priv->clk); - div = lcd_clk / (crtc->mode.clock * 1000); - DBG("lcd_clk=%u, mode clock=%d, div=%u", lcd_clk, crtc->mode.clock, div); - DBG("fck=%lu, dpll_disp_ck=%lu", clk_get_rate(priv->clk), clk_get_rate(priv->disp_clk)); + DBG("lcd_clk=%lu, mode clock=%d, div=%u", + lcd_clk, crtc->mode.clock, clkdiv); /* Configure the LCD clock divisor. */ - tilcdc_write(dev, LCDC_CTRL_REG, LCDC_CLK_DIVISOR(div) | + tilcdc_write(dev, LCDC_CTRL_REG, LCDC_CLK_DIVISOR(clkdiv) | LCDC_RASTER_MODE); if (priv->rev == 2) diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c index 8190ac3..b3dbbe9 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c @@ -192,13 +192,6 @@ static int tilcdc_load(struct drm_device *dev, unsigned long flags) goto fail_iounmap; } - priv->disp_clk = clk_get(dev->dev, "dpll_disp_ck"); - if (IS_ERR(priv->clk)) { - dev_err(dev->dev, "failed to get display clock\n"); - ret = -ENODEV; - goto fail_put_clk; - } - #ifdef CONFIG_CPU_FREQ priv->lcd_fck_rate = clk_get_rate(priv->clk); priv->freq_transition.notifier_call = cpufreq_transition; @@ -206,7 +199,7 @@ static int tilcdc_load(struct drm_device *dev, unsigned long flags) CPUFREQ_TRANSITION_NOTIFIER); if (ret) { dev_err(dev->dev, "failed to register cpufreq notifier\n"); - goto fail_put_disp_clk; + goto fail_put_clk; } #endif @@ -330,8 +323,6 @@ fail_cpufreq_unregister: #ifdef CONFIG_CPU_FREQ cpufreq_unregister_notifier(>freq_transition, CPUFREQ_TRANSITION_NOTIFIER); -fail_put_disp_clk: - clk_put(priv->disp_clk); #endif fail_put_clk: diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.h b/drivers/gpu/drm/tilcdc/tilcdc_drv.h index 66105d8..62a1d68 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h @@ -49,7 +49,6 @@ struct tilcdc_drm_private { void __iomem *mmio; - struct clk *disp_clk;/* display dpll */ struct clk *clk; /* functional clock */ int rev; /* IP revision */ -- 1.9.1
[PATCH v3 00/22] drm/ticdc: Accumulated fixes over the past couple of years
One more round to fix the last issues commented by Tomi Valkeinen. Changes since v2: - 09/22 "drm/tilcdc: Allocate register storage based on the actual number registers" - Fixed typo in the description - 21/22 "drm/tilcdc: Initialize crtc->port" - Changed the code to handle a port-node that is put in side a ports-node - Removed dev_warn(), and use WARN_ON() instead - Added more details in description - 22/22 "Use devm_kzalloc() and devm_kcalloc() for private data" - New patch Changes since the first version of the series: - Dropped: "drm/tilcdc: disable console switching during pm operations" - Changed: "drm/tilcdc: Allocate register storage based on the actual number.." - Reversed kcalloc() nmemb and size parameters to correct order - Added: "drm/tilcdc: Initialize crtc->port" We have not been too active in pushing the tilcdc fixes to mainline. This series tries to bring the mainline tilcdc upto same level with TI ti-linux tree. Some patches that touch the same place over and over again have been squashed into one, leaving author of the last rewrite on top. Best regards, Jyri Darren Etheridge (4): drm/tilcdc: rewrite pixel clock calculation drm/tilcdc: fix kernel panic on suspend when no hdmi monitor connected drm/tilcdc: make frame_done interrupt active at all times drm/tilcdc: disable the lcd controller/dma engine when suspend invoked Dave Gerlach (1): drm/tilcdc: adopt pinctrl support Grygorii Strashko (1): drm/tilcdc: fix build error when !CONFIG_CPU_FREQ Jyri Sarha (8): drm/tilcdc: Implement dma-buf support for tilcdc drm/tilcdc: Allocate register storage based on the actual number registers drm/tilcdc: Fix interrupt enable/disable code for version 2 tilcdc drm/tilcdc: Remove the duplicate LCDC_INT_ENABLE_SET_REG in registers[] drm/tilcdc: Add prints on sync lost and FIFO underrun interrupts drm/tilcdc: Disable sync lost interrupt if it fires on every frame drm/tilcdc: Initialize crtc->port drm/tilcdc: Use devm_kzalloc() and devm_kcalloc() for private data Tomi Valkeinen (8): drm/tilcdc: verify fb pitch drm/tilcdc: cleanup runtime PM handling drm/tilcdc: disable crtc on unload drm/tilcdc: split reset to a separate function drm/tilcdc: remove broken error handling drm/tilcdc: cleanup irq handling drm/tilcdc: Get rid of complex ping-pong mechanism drm/tilcdc: Do not update the next frame buffer close to vertical blank drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 309 ++--- drivers/gpu/drm/tilcdc/tilcdc_drv.c| 130 -- drivers/gpu/drm/tilcdc/tilcdc_drv.h| 5 +- drivers/gpu/drm/tilcdc/tilcdc_panel.c | 20 +-- drivers/gpu/drm/tilcdc/tilcdc_tfp410.c | 24 +-- 5 files changed, 296 insertions(+), 192 deletions(-) -- 1.9.1
[PATCH 1/2] drm/tegra: Set DMA ops
On Tue, Feb 23, 2016 at 03:25:53PM +0900, Alexandre Courbot wrote: > The current settings leaves the DRM device's dma_ops field NULL, which > makes it use the dummy DMA ops on arm64 and return an error whenever we > try to import a buffer. Call of_dma_configure() with a NULL node (since > the device is not spawn from the device tree) so that > arch_setup_dma_ops() is called and sets the default ioswtlb DMA ops. > > Signed-off-by: Alexandre Courbot > --- > drivers/gpu/drm/tegra/drm.c | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c > index d347188bf8f4..bc0555adecaf 100644 > --- a/drivers/gpu/drm/tegra/drm.c > +++ b/drivers/gpu/drm/tegra/drm.c > @@ -9,6 +9,7 @@ > > #include > #include > +#include > > #include > #include > @@ -990,6 +991,7 @@ static int host1x_drm_probe(struct host1x_device *dev) > return -ENOMEM; > > dev_set_drvdata(>dev, drm); > + of_dma_configure(drm->dev, NULL); Looking at the various pieces, I think this really belongs in host1x_device_add() (see drivers/gpu/host1x/bus.c) where it can replace the open-coded setting of DMA and coherent DMA masks. Also why can't we pass the correct device tree node here? The DRM device is a virtual device that hangs off the host1x device, so I think it could use the same device tree node as the host1x device. Something like the below (untested). Thierry --- >8 --- diff --git a/drivers/gpu/host1x/bus.c b/drivers/gpu/host1x/bus.c index c2e7fba370bb..d46d26a574da 100644 --- a/drivers/gpu/host1x/bus.c +++ b/drivers/gpu/host1x/bus.c @@ -17,6 +17,7 @@ #include #include +#include #include #include "bus.h" @@ -393,9 +394,8 @@ static int host1x_device_add(struct host1x *host1x, INIT_LIST_HEAD(>list); device->driver = driver; - device->dev.coherent_dma_mask = host1x->dev->coherent_dma_mask; - device->dev.dma_mask = >dev.coherent_dma_mask; dev_set_name(>dev, "%s", driver->driver.name); + of_dma_configure(>dev, host1x->dev->of_node); device->dev.release = host1x_device_release; device->dev.bus = _bus_type; device->dev.parent = host1x->dev; -- next part -- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: not available URL: <https://lists.freedesktop.org/archives/dri-devel/attachments/20160223/be4d871e/attachment.sig>
[PATCH v11 2/2] drm/bridge: Add I2C based driver for ps8640 bridge
Hi Jitao, [auto build test ERROR on drm/drm-next] [also build test ERROR on v4.5-rc5 next-20160223] [if your patch is applied to the wrong git tree, please drop us a note to help improving the system] url: https://github.com/0day-ci/linux/commits/Jitao-Shi/Documentation-bridge-Add-documentation-for-ps8640-DT-properties/20160223-153819 base: git://people.freedesktop.org/~airlied/linux.git drm-next config: i386-allmodconfig (attached as .config) reproduce: # save the attached .config to linux build tree make ARCH=i386 All errors (new ones prefixed by >>): drivers/gpu/drm/bridge/parade-ps8640.c: In function 'ps8640_bridge_attach': >> drivers/gpu/drm/bridge/parade-ps8640.c:435:10: error: implicit declaration >> of function 'of_find_mipi_dsi_host_by_node' >> [-Werror=implicit-function-declaration] host = of_find_mipi_dsi_host_by_node(dsi_node); ^ drivers/gpu/drm/bridge/parade-ps8640.c:435:8: warning: assignment makes pointer from integer without a cast [-Wint-conversion] host = of_find_mipi_dsi_host_by_node(dsi_node); ^ cc1: some warnings being treated as errors vim +/of_find_mipi_dsi_host_by_node +435 drivers/gpu/drm/bridge/parade-ps8640.c 429 if (in_ep) { 430 dsi_node = of_graph_get_remote_port_parent(in_ep); 431 of_node_put(in_ep); 432 } 433 } 434 if (dsi_node) { > 435 host = of_find_mipi_dsi_host_by_node(dsi_node); 436 of_node_put(dsi_node); 437 if (!host) 438 return -ENODEV; --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation -- next part -- A non-text attachment was scrubbed... Name: .config.gz Type: application/octet-stream Size: 53317 bytes Desc: not available URL: <https://lists.freedesktop.org/archives/dri-devel/attachments/20160223/4a6b5bb3/attachment-0001.obj>
[PATCH 6/6] drm/msm/dsi: Parse DSI lanes via DT
On 02/23/2016 02:48 PM, Tomi Valkeinen wrote: > > On 22/02/16 22:10, Rob Herring wrote: > >>> If we want all DSI host controllers to use a common binding to describe >>> lanes, we'd need to go with the most flexible one, and the driver >>> restricts it to the subsets that we support. > > True, but I wonder if that's necessary. The lane property for the SoC > should be read by the SoC specific driver, right? So the DT property can > be anything. I'm not sure if there's ever a reason for a generic code to > observe the DSI lane setup. Yeah, it is very SoC specific. The only place where it might matter is if a panel/bridge ever needs to know what pins implement what lanes on the platform. A common binding there might help us keep the panel driver generic. Although, this need itself is a bit hypothetical. > > That said, if we do have a common binding, it's perhaps easier for > people to understand the setups for different SoCs. > > +a limited number of physical to logical mappings possible: > + > + "0123": Logic 0->Phys 0; Logic 1->Phys 1; Logic 2->Phys 2; Logic > 3->Phys 3; > + "3012": Logic 3->Phys 0; Logic 0->Phys 1; Logic 1->Phys 2; Logic > 2->Phys 3; > + "2301": Logic 2->Phys 0; Logic 3->Phys 1; Logic 0->Phys 2; Logic > 1->Phys 3; > + "1230": Logic 1->Phys 0; Logic 2->Phys 1; Logic 3->Phys 2; Logic > 0->Phys 3; > + "0321": Logic 0->Phys 0; Logic 3->Phys 1; Logic 2->Phys 2; Logic > 1->Phys 3; > + "1032": Logic 1->Phys 0; Logic 0->Phys 1; Logic 3->Phys 2; Logic > 2->Phys 3; > + "2103": Logic 2->Phys 0; Logic 1->Phys 1; Logic 0->Phys 2; Logic > 3->Phys 3; > + "3210": Logic 3->Phys 0; Logic 2->Phys 1; Logic 1->Phys 2; Logic > 0->Phys 3; > + > + Here, a "3012" mapping will be represented by: > + lanes = <0 1 8 9 2 3 4 5 6 7>; I'm lost here. What does 8 mean for example. The index represents? >>> >>> >>> The numbers here describe the logical lanes. I.e, the way in which the >>> DSI controller pushes out data to the PHY. The ordering is as follows: > > If I read you right, I think that's vice versa. At least the OMAP > version. The OMAP doc says: > > "- lanes: list of pin numbers for the DSI lanes: CLK+, CLK-, DATA0+, > DATA0-, DATA1+, DATA1-, ..." > > This means that the first value in the array is the pin number for CLK+. > In other words, CLK+ wire going to the panel/encoder is connected to pin > number X. > > What the pin number means is SoC specific. CLK+ could be connected to, > say, SoC pin number 123, and then you'd enter 123 as the first value. On > OMAP we use DSI block specific pin numbers, so they start at 0. You're right. I have it the other way round. Yours describes the hardware better. I'll change to yours if we decide to have a common binding. > >> Okay, so the confusing part is the description is all about lanes >> (0-3) but the binding (index and value) is all about pin/signal >> numbers. Either simplify the binding to be lanes or describe the >> binding in terms of pins. > > Perhaps "lane-pins" or something would be more descriptive. If we want > to make the description common, I could change the OMAP implementation > to accept the new property name too. > > But, I'm not sure if a common description helps much. Any thoughts? If having a common binding doesn't bring any benefit, then a common description doesn't help much. I could then move to a simpler binding too. Archit -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
[PATCH v2 2/2] drm/panel: Support for LG lp120up1 panel with eDP input
t; > > + .size = { > > > > + .width = 267, > > > > + .height = 183, > > > > + }, > > > > +}; > > > > + > > > > static const struct drm_display_mode lg_lp129qe_mode = { > > > > .clock = 285250, > > > > .hdisplay = 2560, > > > > @@ -1256,6 +1279,9 @@ static const struct of_device_id > > platform_of_match[] > > > > = { > > > > .compatible = "lg,lb070wv8", > > > > .data = _lb070wv8, > > > > }, { > > > > + .compatible = "lg,lp120up1", > > > > + .data = _lp120up1, > > > > + }, { > > > > .compatible = "lg,lp129qe", > > > > .data = _lp129qe, > > > > }, { > > > > -- > > > > 1.7.9.5 > > > > > > > > > > > > ___ > > > > linux-arm-kernel mailing list > > > > linux-arm-kernel at lists.infradead.org > > > > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel > > > > > > -- next part -- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: not available URL: <https://lists.freedesktop.org/archives/dri-devel/attachments/20160223/84469bc0/attachment.sig>
[Bug 94242] [radeonsi] Crash while running Fedora mock tool for prompting root (gtksu)
https://bugs.freedesktop.org/show_bug.cgi?id=94242 --- Comment #4 from Shawn Starr --- Attempting to attach gdb to X, I am unable to break out of gdb. X info: X.Org X Server 1.18.0 Release Date: 2015-11-09 X Protocol Version 11, Revision 0 -- You are receiving this mail because: You are the assignee for the bug. -- next part -- An HTML attachment was scrubbed... URL: <https://lists.freedesktop.org/archives/dri-devel/attachments/20160223/565bd0f3/attachment.html>
[PATCH v11 2/2] drm/bridge: Add I2C based driver for ps8640 bridge
This patch adds drm_bridge driver for parade DSI to eDP bridge chip. Signed-off-by: Jitao Shi --- Changes since v10: - Tuning PS8640 reset sleep pins squence The following patches are needed to support dsi host through none dsi bus: https://patchwork.kernel.org/patch/8289181/ ("drm/dsi: check for CONFIG_OF when defining") https://patchwork.kernel.org/patch/8289051/ ("drm/dsi: Use mipi_dsi_device_register_full for DSI device") https://patchwork.kernel.org/patch/8289081/ ("drm/dsi: Try to match non-DT DSI devices") https://patchwork.kernel.org/patch/8289121/ ("drm/dsi: Add routine to unregister a DSI device") https://patchwork.kernel.org/patch/8289091/ ("drm/dsi: Get DSI host by DT device node") --- drivers/gpu/drm/bridge/Kconfig | 11 + drivers/gpu/drm/bridge/Makefile|1 + drivers/gpu/drm/bridge/parade-ps8640.c | 1060 3 files changed, 1072 insertions(+) create mode 100644 drivers/gpu/drm/bridge/parade-ps8640.c diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index 27e2022..b4edd8c 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -40,4 +40,15 @@ config DRM_PARADE_PS8622 ---help--- Parade eDP-LVDS bridge chip driver. +config DRM_PARADE_PS8640 + tristate "Parade PS8640 MIPI DSI to eDP Converter" + depends on OF && I2C + select DRM_KMS_HELPER + select DRM_MIPI_DSI + select DRM_PANEL + ---help--- + Choose this option if you have PS8640 for display + The PS8640 is a high-performance and low-power + MIPI DSI to eDP converter + endmenu diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile index f13c33d..fbe38dc 100644 --- a/drivers/gpu/drm/bridge/Makefile +++ b/drivers/gpu/drm/bridge/Makefile @@ -4,3 +4,4 @@ obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o +obj-$(CONFIG_DRM_PARADE_PS8640) += parade-ps8640.o diff --git a/drivers/gpu/drm/bridge/parade-ps8640.c b/drivers/gpu/drm/bridge/parade-ps8640.c new file mode 100644 index 000..d7410df --- /dev/null +++ b/drivers/gpu/drm/bridge/parade-ps8640.c @@ -0,0 +1,1060 @@ +/* + * Copyright (c) 2014 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#define PAGE2_SPI_CFG3 0x82 +#define I2C_TO_SPI_RESET 0x20 +#define PAGE2_ROMADD_BYTE1 0x8e +#define PAGE2_ROMADD_BYTE2 0x8f +#define PAGE2_SWSPI_WDATA 0x90 +#define PAGE2_SWSPI_RDATA 0x91 +#define PAGE2_SWSPI_LEN0x92 +#define PAGE2_SWSPI_CTL0x93 +#define TRIGGER_NO_READBACK0x05 +#define TRIGGER_READBACK 0x01 +#define PAGE2_SPI_STATUS 0x9e +#define PAGE2_GPIO_L 0xa6 +#define PAGE2_GPIO_H 0xa7 +#define PS_GPIO9 BIT(1) +#define PAGE2_IROM_CTRL0xb0 +#define IROM_ENABLE0xc0 +#define IROM_DISABLE 0x80 +#define PAGE2_SW_REST 0xbc +#define SPI_SW_RESET BIT(7) +#define MPU_SW_RESET BIT(6) +#define PAGE2_ENCTLSPI_WR 0xda +#define PAGE2_I2C_BYPASS 0xea +#define I2C_BYPASS_EN 0xd0 +#define PAGE3_SET_ADD 0xfe +#define PAGE3_SET_VAL 0xff +#define VDO_CTL_ADD0x13 +#define VDO_DIS0x18 +#define VDO_EN 0x1c +#define PAGE4_REV_L0xf0 +#define PAGE4_REV_H0xf1 +#define PAGE4_CHIP_L 0xf2 +#define PAGE4_CHIP_H 0xf3 + +/* Firmware */ +#define SPI_MAX_RETRY_CNT 8 +#define PS_FW_NAME "ps864x_fw.bin" + +#define FW_CHIP_ID_OFFSET 0 +#define FW_VERSION_OFFSET 2 +#define EDID_I2C_ADDR 0x50 + +#define WRITE_STATUS_REG_CMD 0x01 +#define READ_STATUS_REG_CMD0x05 +#define CLEAR_ALL_PROTECT 0x00 +#define BLK_PROTECT_BITS 0x0c +#define STATUS_REG_PROTECT BIT(7) +#define WRITE_ENABLE_CMD 0x06 +#define CHIP_ERASE_CMD 0xc7 + +#define bridge_to_ps8640(e)container_of(e, struct ps8640, bridge) +#define connector_to_ps8640(e) container_of(e, struct ps8640, connector) + +struct ps8640_info { + u8 family_id; + u8 variant_id; + u16 version; +}; + +struct ps8640 { +
[PATCH v11 1/2] Documentation: bridge: Add documentation for ps8640 DT properties
Add documentation for DT properties supported by ps8640 DSI-eDP converter. Signed-off-by: Jitao Shi Acked-by: Rob Herring Reviewed-by: Philipp Zabel --- Chnages since v10: - set sleep reset pin as GPIO_ACTIVE_LOW --- .../devicetree/bindings/display/bridge/ps8640.txt | 43 1 file changed, 43 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/bridge/ps8640.txt diff --git a/Documentation/devicetree/bindings/display/bridge/ps8640.txt b/Documentation/devicetree/bindings/display/bridge/ps8640.txt new file mode 100644 index 000..022b33f --- /dev/null +++ b/Documentation/devicetree/bindings/display/bridge/ps8640.txt @@ -0,0 +1,43 @@ +ps8640-bridge bindings + +Required properties: + - compatible: "parade,ps8640" + - reg: first page address of the bridge. + - sleep-gpios: OF device-tree gpio specification for PD pin. + - reset-gpios: OF device-tree gpio specification for reset pin. + - mode-sel-gpios: OF device-tree gpio specification for mode-sel pin. + - vdd12-supply: OF device-tree regulator specification for 1.2V power. + - vdd33-supply: OF device-tree regulator specification for 3.3V power. + - ports: The device node can contain video interface port nodes per +the video-interfaces bind[1]. For port at 0,set the reg = <0> as +ps8640 dsi in and port at 1,set the reg = <1> as ps8640 eDP out. + +[1]: Documentation/devicetree/bindings/media/video-interfaces.txt + +Example: + edp-bridge at 18 { + compatible = "parade,ps8640"; + reg = <0x18>; + sleep-gpios = < 116 GPIO_ACTIVE_LOW>; + reset-gpios = < 115 GPIO_ACTIVE_LOW>; + mode-sel-gpios = < 92 GPIO_ACTIVE_HIGH>; + vdd12-supply = <_fixed_1v2>; + vdd33-supply = <_vgp2_reg>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + port at 0 { + reg = <0>; + ps8640_in: endpoint { + remote-endpoint = <_out>; + }; + }; + port at 1 { + reg = <1>; + ps8640_out: endpoint { + remote-endpoint = <_in>; + }; + }; + }; + }; -- 1.7.9.5
[PATCH v2 0/3] drm: introduce bus_flags for pixel clock polarity
Any comments on this? Also added Manfred, Tomi and Boris to CC which previously attended in similar discussions. Previous discussions: http://thread.gmane.org/gmane.linux.kernel.api/12830 http://thread.gmane.org/gmane.comp.video.dri.devel/96240/ I think one of the main observation so far was that the pixel clock polarity is not a property of the mode, and therefor does not fit into the DRM_MODE_FLAG. This has been pointed out nicely by Russel: http://thread.gmane.org/gmane.comp.video.dri.devel/96240/focus=96260 Embedded displays connected through parallel bus make use of the bus_formats field in drm_display_mode. This field defines what kind of bus format the display requires. This patch follows that idea and adds bus_flags. bus_flags can be used to define specific bus properties required by the display, such as pixel clock or data enable polarity... On 2016-02-08 13:57, Stefan Agner wrote: > Hi, > > This is a new & split out version of the last patch of my > "drm/fsl-dcu: fixes and enhancements" patchset: > https://lkml.org/lkml/2015/11/18/949 > > Instead of using struct drm_display_mode to convey the pixel clock > polarity information, this patchset introduces a new field called > bus_flags stored in struct drm_display_info. Note that this solution has been briefly discussed on IRC: https://people.freedesktop.org/~cbrill/dri-log/?channel=dri-devel_names==2016-02-08 -- Stefan > > Changes since v1: > - Introduce bus_flags to convey the pixel clock polarity from > panel-simple.c to the driver. > > Stefan Agner (3): > drm/fsl-dcu: use mode flags for hsync/vsync polarity > drm: introduce bus_flags in drm_display_info > drm/fsl-dcu: use bus_flags for pixel clock polarity > > drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c | 16 +--- > drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h | 4 ++-- > drivers/gpu/drm/panel/panel-simple.c | 6 +- > include/drm/drm_crtc.h | 9 + > 4 files changed, 29 insertions(+), 6 deletions(-)
[PATCH 2/2] drm/tegra: Set the DMA mask
The default DMA mask covers a 32 bits address range, but tegradrm can address more than that. Set the DMA mask to the actual addressable range to avoid the use of unneeded bounce buffers. Signed-off-by: Alexandre Courbot --- Thierry, I am not absolutely sure whether the size is correct and applies to all Tegra generations - please let me know if this needs to be reworked. drivers/gpu/drm/tegra/drm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index bc0555adecaf..503fc9e73521 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c @@ -992,6 +992,7 @@ static int host1x_drm_probe(struct host1x_device *dev) dev_set_drvdata(>dev, drm); of_dma_configure(drm->dev, NULL); + dma_set_mask(drm->dev, DMA_BIT_MASK(34)); err = drm_dev_register(drm, 0); if (err < 0) -- 2.7.1
[PATCH 1/2] drm/tegra: Set DMA ops
The current settings leaves the DRM device's dma_ops field NULL, which makes it use the dummy DMA ops on arm64 and return an error whenever we try to import a buffer. Call of_dma_configure() with a NULL node (since the device is not spawn from the device tree) so that arch_setup_dma_ops() is called and sets the default ioswtlb DMA ops. Signed-off-by: Alexandre Courbot --- drivers/gpu/drm/tegra/drm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index d347188bf8f4..bc0555adecaf 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -990,6 +991,7 @@ static int host1x_drm_probe(struct host1x_device *dev) return -ENOMEM; dev_set_drvdata(>dev, drm); + of_dma_configure(drm->dev, NULL); err = drm_dev_register(drm, 0); if (err < 0) -- 2.7.1
[Bug 112921] Lock-up after screensaver on radeon
https://bugzilla.kernel.org/show_bug.cgi?id=112921 Alex Deucher changed: What|Removed |Added CC||alexdeucher at gmail.com --- Comment #4 from Alex Deucher --- This looks like the vblank regression bug. See this thread for more info: https://lists.freedesktop.org/archives/dri-devel/2016-January/098823.html and the fdo bug: https://bugs.freedesktop.org/show_bug.cgi?id=93746 -- You are receiving this mail because: You are watching the assignee of the bug.
[PATCH 02/33] HACK: drm/omap: always use blocking DMM fill
On 23/02/16 12:27, Laurent Pinchart wrote: > Hi Tomi, > > Thank you for the patch. > > On Friday 19 February 2016 11:47:37 Tomi Valkeinen wrote: >> The current driver uses non-blocking DMM fill when releasing memory. >> This gives us a small performance increase as we don't have to wait for >> the fill operation to finish. >> >> However, the driver does not have any error handling for non-blocking >> fill. In case of an error, the fill operation may silently fail, leading >> to leaking DMM engines, which may eventually lead to deadlock if we run >> out of DMM engines. >> >> This patch makes the DMM driver always use blocking fills, so that we >> can catch the errors. A more complex option would be to allow >> non-blocking fills, and implement proper error handling, but that is >> left for the future. >> >> This patch is a HACK, as the proper fix is to either decide to always >> use sync fills and remove all the async related code, or fix the async >> code. > > Could you capture this in the comment in the source code below ? I'd also > replace with either FIXME or TODO. Yes, the comment was a bit lacking. Here's an updated comment: /* * FIXME * * Asynchronous fill does not work reliably, as the driver does not * handle errors in the async code paths. The fill operation may * silently fail, leading to leaking DMM engines, which may eventually * lead to deadlock if we run out of DMM engines. * * For now, always set 'wait' so that we only use sync fills. Async * fills should be fixed, or alternatively we could decide to only * support sync fills and so the whole async code path could be removed. */ Tomi -- next part -- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: OpenPGP digital signature URL: <https://lists.freedesktop.org/archives/dri-devel/attachments/20160223/8dd16c2a/attachment.sig>
[PATCH v2 13/13] dt-bindings: msm/hdmi: Add HDMI PHY bindings
On 02/23/2016 12:57 AM, Rob Herring wrote: > On Mon, Feb 22, 2016 at 5:07 AM, Archit Taneja > wrote: >> >> >> On 02/22/2016 08:24 AM, Rob Herring wrote: >>> >>> On Mon, Feb 15, 2016 at 12:23:26PM +0530, Archit Taneja wrote: Add HDMI PHY bindings. Update the example to use HDMI PHY. Add a missing power-domains property in the HDMI core bindings. Cc: devicetree at vger.kernel.org Cc: Rob Herring Signed-off-by: Archit Taneja --- .../devicetree/bindings/display/msm/hdmi.txt | 39 +- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/display/msm/hdmi.txt b/Documentation/devicetree/bindings/display/msm/hdmi.txt index 379ee2e..4d71910 100644 --- a/Documentation/devicetree/bindings/display/msm/hdmi.txt +++ b/Documentation/devicetree/bindings/display/msm/hdmi.txt @@ -11,6 +11,7 @@ Required properties: - reg: Physical base address and length of the controller's registers - reg-names: "core_physical" - interrupts: The interrupt signal from the hdmi block. +- power-domains: Should be < MDSS_GDSC>. - clocks: device clocks See ../clocks/clock-bindings.txt for details. - qcom,hdmi-tx-ddc-clk-gpio: ddc clk pin @@ -18,6 +19,7 @@ Required properties: - qcom,hdmi-tx-hpd-gpio: hpd pin - core-vdda-supply: phandle to supply regulator - hdmi-mux-supply: phandle to mux regulator +- qcom,hdmi-phy: phandle to HDMI PHY device node >>> >>> >>> Why not use the generic phy binding? >> >> >> You'd asked about this in the first version of this patch. You >> probably missed reading my reply. Partially my fault since I >> missed out putting the "In-Reply-to" when posting this set. I've >> mentioned the reason again here: >> >> The PHY in the HDMI and DSI blocks can't be implemented using the >> common phy framework. The PHY blocks have a PLL sub-block within >> them which acts as a pixel clock source for the display processor >> block. > > That sounds like a problem with the common phy framework, not the DT > binding. Nothing says you have to use the common phy f/w if you use > the phy binding. I say that as the binding maintainer. As a kernel > developer, I would say fix the common phy framework to handle this > case. However, I don't think anything prevents the phy driver from > registering both a phy and a clock. Okay. For some reason, I thought it would be wrong to use the same common phy bindings but use our own phy driver. I will convert the bindings to the generic phy binding. > >> This dependency causes the need to split the phy power on sequence >> into 2 parts (one to enable resources to enable the PLL, and the >> other to enable the phy itself), which the phy framework can't >> do. That's the main reason not to use it. There are some more >> complex use cases for DSI PHY (drive two PHYs with the same >> DSI PLL) which the phy framework can't support. > > Doesn't the phy framework already support the former? It has power on > and init calls. Personally, I find the split there ill-defined. I always assumed that the init/exit ops were something that you would call just once (during probe/remove) and then forget about it. I only now noticed that init and power_on are often paired together (as are power_off and exit). I went through the common phy framework code in more detail, but I realized I would face the following issue: I was looking for the sequence: 1. enable PHY resources (enables clocks/regulators/pm_runtime_get_sync) 2. set_rate/enable the PLL clock provided by PHY 3. enable PHY (configure some PHY registers) I can achieve this using the common phy framework if I tie step 1) to phy_power_on(), and step 3) to phy_init(). The other way round won't work because phy_init() seems to disable runtime pm as it exits. If I use the phy framework in its current state, I'll end up stuffing the phy ops and use them in a weird way just to make sure my PHY works. Copying Kishon if he has any opinions. > Optional properties: - qcom,hdmi-tx-mux-en-gpio: hdmi mux enable pin @@ -27,6 +29,27 @@ Optional properties: - pinctrl-0: the default pinctrl state (active) - pinctrl-1: the "sleep" pinctrl state +HDMI PHY: +Required properties: +- compatible: Could be the following + * "qcom,hdmi-phy-8x60" + * "qcom,hdmi-phy-8960" + * "qcom,hdmi-phy-8x74" >>> >>> >>> No wildcards please. Where's 8994? >> >> >> I'll remove the wildcards. 8994 PHY isn't supported by the driver at >> the moment. I could keep the 8994 compatible string, the driver will >> bail out with an error. But that's something we already do for 8x74 >> since it doesn't have full PHY support either. > > You can document it later if you want. I just asked 'cause I knew the > 8994 had one. Okay. Thanks, Archit -- The Qualcomm
[PATCH 0/3] Deferr load of radeon/amdgpu until amdkfd is loaded
On 23 February 2016 at 14:51, Oded Gabbay wrote: > On Tue, Feb 23, 2016 at 5:10 AM, Xinliang Liu > wrote: >> On 15 February 2016 at 19:04, Oded Gabbay wrote: >>> On Sun, Feb 14, 2016 at 2:58 PM, Daniel Vetter wrote: On Sun, Feb 14, 2016 at 11:16:52AM +0200, Oded Gabbay wrote: > Following Daniel's request, I spent some time removing the hard > requirement > that radeon and amdgpu will always appear _after_ amdkfd in the drm > Makefile. > > This was done by modifing radeon/amdgpu to defer their loading if they > detect > that amdkfd is not loaded yet, in case the drivers are built inside the > kernel image. > > See the patch's individiual commit messages for more explanation. > > This patch-set was tested on a KAVERI machine, with multiple > configurations: > > 1. radeon + amdgpu (CIK disabled) + amdkfd as kernel modules > 2. radeon + amdgpu (CIK disabled) + amdkfd inside the kernel image > 3. amdgpu (CIK enabled) + amdkfd inside the kernel image (radeon not > compiled) > 4. amdgpu (CIK enabled) inside the kernel image (radeon + amdkfd not > compiled) > 5. radeon + amdgpu (CIK disabled) as kernel modules (amdkfd not compiled) Care to throw one patch on top (maybe on top of the patch floating around) to reorder amdkfd to be alphabetical? Just to make sure this doesn't get broken again accidentally. Or maybe just pick up the other patch and adapt it so it's all in one series. Thanks, Daniel >>> >>> Hi Daniel, >>> >>> I thought about it and I think I prefer to leave the current order as >>> it is, for the reason that I observed the boot-up process is a little >>> bit faster when the deferred probing doesn't occur. This is probably >>> because all the moves between pending drivers list and active driver >>> list. >>> >>> Although this patch-set ensure that the kernel will boot successfully >>> with no regard to the order of amdkfd/radeon/amdgpu in the drm >> >> So, my drm make clean up patch should keep amdkfd in front of radeon/amdgpu? >> >> Best, >> -xinliang > > As I wrote to Daniel, I think that for the sake of a faster boot time, > we should keep amdkfd before radeon/amdgpu. This patch is to make sure > that if someone will change it without us watching, everything will > still work (and that's why its an important patch as Daniel said) > OK, got it. > Oded > >> >>> makefile, I think that if the current order gives us a bit less boot >>> time then it is better to keep things as they are. >>> >>> Thanks, >>> >>> Oded >>> > > Thanks, > > Oded > > Oded Gabbay (3): > drm/amdkfd: Track when module's init is complete > drm/radeon: Return -EPROBE_DEFER when amdkfd not loaded > drm/amdgpu: Return -EPROBE_DEFER when amdkfd not loaded > > drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c | 57 > + > drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h | 2 +- > drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 10 - > drivers/gpu/drm/amd/amdkfd/kfd_module.c | 15 +-- > drivers/gpu/drm/amd/include/kgd_kfd_interface.h | 2 +- > drivers/gpu/drm/radeon/radeon_drv.c | 10 - > drivers/gpu/drm/radeon/radeon_kfd.c | 25 ++- > drivers/gpu/drm/radeon/radeon_kfd.h | 2 +- > 8 files changed, 64 insertions(+), 59 deletions(-) > > -- > 2.5.0 > -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch >>> ___ >>> dri-devel mailing list >>> dri-devel at lists.freedesktop.org >>> https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 4/5] drm/i915: Implement color management on bdw/skl/bxt/kbl
On 23/02/16 00:52, Matt Roper wrote: > On Mon, Feb 22, 2016 at 02:18:10PM +, Lionel Landwerlin wrote: >> Patch based on a previous series by Shashank Sharma. >> >> v2: Do not read GAMMA_MODE register to figure what mode we're in >> >> v3: Program PREC_PAL_GC_MAX to clamp pixel values > 1.0 >> >> Add documentation on how the Broadcast RGB property is affected by CTM >> >> v4: Update contributors >> >> v5: Refactor degamma/gamma LUTs load into a single function >> >> v6: Fix missing intel_crtc variable (bisect issue) > Not sure if you saw me feedback on v4 or not: > https://lists.freedesktop.org/archives/intel-gfx/2016-February/088043.html > > It looks like most of those comments still apply here. If you disagree > with my comments, that's fine too, I just wanted to make sure it didn't > get overlooked. :-) > > > Matt Sorry for that, completely missed on the first 3/4 comments. You're right the limited range multiplication was wrong (input[i] vs result[i]...). Fixed that and simplified it as you suggested. Thanks a lot! - Lionel
[Bug 94231] Problems compiling libdrm since glibc 2.23
https://bugs.freedesktop.org/show_bug.cgi?id=94231 --- Comment #15 from Emil Velikov --- Mike L adding a reference to the updated docs or a mention "since man-pages version X" plus a bugzilla link (if applicable) would be amazing. Thanks ! -- You are receiving this mail because: You are the assignee for the bug. -- next part -- An HTML attachment was scrubbed... URL: <https://lists.freedesktop.org/archives/dri-devel/attachments/20160223/37693658/attachment.html>
[PATCH 5/5] drm/i915: Implement color management on chv
Patch based on a previous series by Shashank Sharma. v2: Update contributors v3: Refactor degamma/gamma LUTs load into a single function v4: Remove unused variable Signed-off-by: Shashank Sharma Signed-off-by: Lionel Landwerlin Signed-off-by: Kumar, Kiran S Signed-off-by: Kausal Malladi --- drivers/gpu/drm/i915/i915_drv.c| 3 + drivers/gpu/drm/i915/i915_reg.h| 31 + drivers/gpu/drm/i915/intel_color.c | 133 +++-- 3 files changed, 161 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 3807b73..8a2aaa7 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -68,6 +68,8 @@ static struct drm_driver driver; #define BDW_COLORS \ .color = { .degamma_lut_size = 512, .gamma_lut_size = 512 } +#define CHV_COLORS \ + .color = { .degamma_lut_size = 65, .gamma_lut_size = 257 } static const struct intel_device_info intel_i830_info = { .gen = 2, .is_mobile = 1, .cursor_needs_physical = 1, .num_pipes = 2, @@ -325,6 +327,7 @@ static const struct intel_device_info intel_cherryview_info = { .display_mmio_offset = VLV_DISPLAY_BASE, GEN_CHV_PIPEOFFSETS, CURSOR_OFFSETS, + CHV_COLORS, }; static const struct intel_device_info intel_skylake_info = { diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 8ce76d7..effd79e 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -7672,6 +7672,37 @@ enum skl_disp_power_wells { #define PREC_PAL_GC_MAX(pipe, i) _MMIO(_PIPE(pipe, _PAL_PREC_GC_MAX_A, _PAL_PREC_GC_MAX_B) + (i) * 4) #define PREC_PAL_EXT_GC_MAX(pipe, i) _MMIO(_PIPE(pipe, _PAL_PREC_EXT_GC_MAX_A, _PAL_PREC_EXT_GC_MAX_B) + (i) * 4) +/* pipe CSC & degamma/gamma LUTs on CHV */ +#define _CGM_PIPE_A_CSC_COEFF01(VLV_DISPLAY_BASE + 0x67900) +#define _CGM_PIPE_A_CSC_COEFF23(VLV_DISPLAY_BASE + 0x67904) +#define _CGM_PIPE_A_CSC_COEFF45(VLV_DISPLAY_BASE + 0x67908) +#define _CGM_PIPE_A_CSC_COEFF67(VLV_DISPLAY_BASE + 0x6790C) +#define _CGM_PIPE_A_CSC_COEFF8 (VLV_DISPLAY_BASE + 0x67910) +#define _CGM_PIPE_A_DEGAMMA(VLV_DISPLAY_BASE + 0x66000) +#define _CGM_PIPE_A_GAMMA (VLV_DISPLAY_BASE + 0x67000) +#define _CGM_PIPE_A_MODE (VLV_DISPLAY_BASE + 0x67A00) +#define CGM_PIPE_MODE_GAMMA (1 << 2) +#define CGM_PIPE_MODE_CSC(1 << 1) +#define CGM_PIPE_MODE_DEGAMMA(1 << 0) + +#define _CGM_PIPE_B_CSC_COEFF01(VLV_DISPLAY_BASE + 0x69900) +#define _CGM_PIPE_B_CSC_COEFF23(VLV_DISPLAY_BASE + 0x69904) +#define _CGM_PIPE_B_CSC_COEFF45(VLV_DISPLAY_BASE + 0x69908) +#define _CGM_PIPE_B_CSC_COEFF67(VLV_DISPLAY_BASE + 0x6990C) +#define _CGM_PIPE_B_CSC_COEFF8 (VLV_DISPLAY_BASE + 0x69910) +#define _CGM_PIPE_B_DEGAMMA(VLV_DISPLAY_BASE + 0x68000) +#define _CGM_PIPE_B_GAMMA (VLV_DISPLAY_BASE + 0x69000) +#define _CGM_PIPE_B_MODE (VLV_DISPLAY_BASE + 0x69A00) + +#define CGM_PIPE_CSC_COEFF01(pipe) _MMIO_PIPE(pipe, _CGM_PIPE_A_CSC_COEFF01, _CGM_PIPE_B_CSC_COEFF01) +#define CGM_PIPE_CSC_COEFF23(pipe) _MMIO_PIPE(pipe, _CGM_PIPE_A_CSC_COEFF23, _CGM_PIPE_B_CSC_COEFF23) +#define CGM_PIPE_CSC_COEFF45(pipe) _MMIO_PIPE(pipe, _CGM_PIPE_A_CSC_COEFF45, _CGM_PIPE_B_CSC_COEFF45) +#define CGM_PIPE_CSC_COEFF67(pipe) _MMIO_PIPE(pipe, _CGM_PIPE_A_CSC_COEFF67, _CGM_PIPE_B_CSC_COEFF67) +#define CGM_PIPE_CSC_COEFF8(pipe) _MMIO_PIPE(pipe, _CGM_PIPE_A_CSC_COEFF8, _CGM_PIPE_B_CSC_COEFF8) +#define CGM_PIPE_DEGAMMA(pipe, i, w) _MMIO(_PIPE(pipe, _CGM_PIPE_A_DEGAMMA, _CGM_PIPE_B_DEGAMMA) + (i) * 8 + (w) * 4) +#define CGM_PIPE_GAMMA(pipe, i, w) _MMIO(_PIPE(pipe, _CGM_PIPE_A_GAMMA, _CGM_PIPE_B_GAMMA) + (i) * 8 + (w) * 4) +#define CGM_PIPE_MODE(pipe)_MMIO_PIPE(pipe, _CGM_PIPE_A_MODE, _CGM_PIPE_B_MODE) + /* MIPI DSI registers */ #define _MIPI_PORT(port, a, c) _PORT3(port, a, 0, c) /* ports A and C only */ diff --git a/drivers/gpu/drm/i915/intel_color.c b/drivers/gpu/drm/i915/intel_color.c index 97a047b..6999fd3 100644 --- a/drivers/gpu/drm/i915/intel_color.c +++ b/drivers/gpu/drm/i915/intel_color.c @@ -29,6 +29,7 @@ #define CTM_COEFF_1_0 (1ULL << 32) #define CTM_COEFF_2_0 (CTM_COEFF_1_0 << 1) #define CTM_COEFF_4_0 (CTM_COEFF_2_0 << 1) +#define CTM_COEFF_8_0 (CTM_COEFF_4_0 << 1) #define CTM_COEFF_0_5 (CTM_COEFF_1_0 >> 1) #define CTM_COEFF_0_25 (CTM_COEFF_0_5 >> 1) #define CTM_COEFF_0_125(CTM_COEFF_0_25 >> 1) @@ -199,6 +200,58 @@ static void i9xx_load_csc_matrix(struct drm_crtc *crtc) } } +/* + * Set up the pipe CSC unit on CherryView. + */ +static void cherryview_load_csc_matrix(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_crtc_state *state = crtc->state; + struct drm_i915_private *dev_priv = dev->dev_private; + int pipe = to_intel_crtc(crtc)->pipe; + uint32_t mode; + +
[PATCH 4/5] drm/i915: Implement color management on bdw/skl/bxt/kbl
Patch based on a previous series by Shashank Sharma. v2: Do not read GAMMA_MODE register to figure what mode we're in v3: Program PREC_PAL_GC_MAX to clamp pixel values > 1.0 Add documentation on how the Broadcast RGB property is affected by CTM v4: Update contributors v5: Refactor degamma/gamma LUTs load into a single function v6: Fix missing intel_crtc variable (bisect issue) v7: Fix & simplify limited range matrix multiplication Signed-off-by: Shashank Sharma Signed-off-by: Lionel Landwerlin Signed-off-by: Kumar, Kiran S Signed-off-by: Kausal Malladi --- Documentation/DocBook/gpu.tmpl | 6 +- drivers/gpu/drm/i915/i915_drv.c | 24 ++- drivers/gpu/drm/i915/i915_drv.h | 6 + drivers/gpu/drm/i915/i915_reg.h | 22 +++ drivers/gpu/drm/i915/intel_color.c | 343 ++- drivers/gpu/drm/i915/intel_display.c | 22 ++- drivers/gpu/drm/i915/intel_drv.h | 3 +- drivers/gpu/drm/i915/intel_fbdev.c | 8 + 8 files changed, 371 insertions(+), 63 deletions(-) diff --git a/Documentation/DocBook/gpu.tmpl b/Documentation/DocBook/gpu.tmpl index 1692c4d..430e99b 100644 --- a/Documentation/DocBook/gpu.tmpl +++ b/Documentation/DocBook/gpu.tmpl @@ -2153,7 +2153,11 @@ void intel_crt_init(struct drm_device *dev) ENUM { "Automatic", "Full", "Limited 16:235" } Connector - TBD + When this property is set to Limited 16:235 + and CTM is set, the hardware will be programmed with the + result of the multiplication of CTM by the limited range + matrix to ensure the pixels normaly in the range 0..1.0 are + remapped to the range 16/255..235/255. âaudioâ diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 20e8200..3807b73 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -66,6 +66,9 @@ static struct drm_driver driver; #define IVB_CURSOR_OFFSETS \ .cursor_offsets = { CURSOR_A_OFFSET, IVB_CURSOR_B_OFFSET, IVB_CURSOR_C_OFFSET } +#define BDW_COLORS \ + .color = { .degamma_lut_size = 512, .gamma_lut_size = 512 } + static const struct intel_device_info intel_i830_info = { .gen = 2, .is_mobile = 1, .cursor_needs_physical = 1, .num_pipes = 2, .has_overlay = 1, .overlay_needs_physical = 1, @@ -288,24 +291,28 @@ static const struct intel_device_info intel_haswell_m_info = { .is_mobile = 1, }; +#define BDW_FEATURES \ + HSW_FEATURES, \ + BDW_COLORS + static const struct intel_device_info intel_broadwell_d_info = { - HSW_FEATURES, + BDW_FEATURES, .gen = 8, }; static const struct intel_device_info intel_broadwell_m_info = { - HSW_FEATURES, + BDW_FEATURES, .gen = 8, .is_mobile = 1, }; static const struct intel_device_info intel_broadwell_gt3d_info = { - HSW_FEATURES, + BDW_FEATURES, .gen = 8, .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING, }; static const struct intel_device_info intel_broadwell_gt3m_info = { - HSW_FEATURES, + BDW_FEATURES, .gen = 8, .is_mobile = 1, .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING, }; @@ -321,13 +328,13 @@ static const struct intel_device_info intel_cherryview_info = { }; static const struct intel_device_info intel_skylake_info = { - HSW_FEATURES, + BDW_FEATURES, .is_skylake = 1, .gen = 9, }; static const struct intel_device_info intel_skylake_gt3_info = { - HSW_FEATURES, + BDW_FEATURES, .is_skylake = 1, .gen = 9, .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING, @@ -345,17 +352,18 @@ static const struct intel_device_info intel_broxton_info = { .has_fbc = 1, GEN_DEFAULT_PIPEOFFSETS, IVB_CURSOR_OFFSETS, + BDW_COLORS, }; static const struct intel_device_info intel_kabylake_info = { - HSW_FEATURES, + BDW_FEATURES, .is_preliminary = 1, .is_kabylake = 1, .gen = 9, }; static const struct intel_device_info intel_kabylake_gt3_info = { - HSW_FEATURES, + BDW_FEATURES, .is_preliminary = 1, .is_kabylake = 1, .gen = 9, diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 6634c09..7627a4e 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -660,6 +660,7 @@ struct drm_i915_display_funcs { /* display clock increase/decrease */ /* pll clock increase/decrease */ + void (*load_csc_matrix)(struct drm_crtc *crtc); void (*load_luts)(struct drm_crtc *crtc); }; @@ -808,6 +809,11 @@ struct intel_device_info { u8 has_slice_pg:1; u8 has_subslice_pg:1; u8 has_eu_pg:1; + + struct color_luts { + u16 degamma_lut_size; +
[PATCH 3/5] drm: introduce pipe color correction properties
Patch based on a previous series by Shashank Sharma. This introduces optional properties to enable color correction at the pipe level. It relies on 3 transformations applied to every pixels displayed. First a lookup into a degamma table, then a multiplication of the rgb components by a 3x3 matrix and finally another lookup into a gamma table. The following properties can be added to a pipe : - DEGAMMA_LUT : blob containing degamma LUT - DEGAMMA_LUT_SIZE : number of elements in DEGAMMA_LUT - CTM : transformation matrix applied after the degamma LUT - GAMMA_LUT : blob containing gamma LUT - GAMMA_LUT_SIZE : number of elements in GAMMA_LUT DEGAMMA_LUT_SIZE and GAMMA_LUT_SIZE are read only properties, set by the driver to tell userspace applications what sizes should be the lookup tables in DEGAMMA_LUT and GAMMA_LUT. A helper is also provided so legacy gamma correction is redirected through these new properties. v2: Register LUT size properties as range v3: Fix round in drm_color_lut_get_value() helper More docs on how degamma/gamma properties are used v4: Update contributors v5: Rename CTM_MATRIX property to CTM (Doh!) Add legacy gamma_set atomic helper Describe CTM/LUT acronyms in the kernel doc Signed-off-by: Shashank Sharma Signed-off-by: Lionel Landwerlin Signed-off-by: Kumar, Kiran S Signed-off-by: Kausal Malladi Reviewed-by: Matt Roper --- Documentation/DocBook/gpu.tmpl | 59 - drivers/gpu/drm/drm_atomic.c| 86 +- drivers/gpu/drm/drm_atomic_helper.c | 103 drivers/gpu/drm/drm_crtc.c | 35 drivers/gpu/drm/drm_crtc_helper.c | 33 include/drm/drm_atomic_helper.h | 3 ++ include/drm/drm_crtc.h | 46 +++- include/drm/drm_crtc_helper.h | 3 ++ include/uapi/drm/drm_mode.h | 15 ++ 9 files changed, 378 insertions(+), 5 deletions(-) diff --git a/Documentation/DocBook/gpu.tmpl b/Documentation/DocBook/gpu.tmpl index fe6b36a..1692c4d 100644 --- a/Documentation/DocBook/gpu.tmpl +++ b/Documentation/DocBook/gpu.tmpl @@ -1816,7 +1816,7 @@ void intel_crt_init(struct drm_device *dev) Description/Restrictions - DRM + DRM Generic ârotationâ BITMASK @@ -2068,7 +2068,7 @@ void intel_crt_init(struct drm_device *dev) property to suggest an Y offset for a connector - Optional + Optional âscaling modeâ ENUM { "None", "Full", "Center", "Full aspect" } @@ -2092,6 +2092,61 @@ void intel_crt_init(struct drm_device *dev) TBD + âDEGAMMA_LUTâ + BLOB + 0 + CRTC + DRM property to set the degamma lookup table + (LUT) mapping pixel data from the framebuffer before it is + given to the transformation matrix. The data is an interpreted + as an array of struct drm_color_lut elements. Hardware might + choose not to use the full precision of the LUT elements nor + use all the elements of the LUT (for example the hardware + might choose to interpolate between LUT[0] and LUT[4]). + + + âDEGAMMA_LUT_SIZEâ + RANGE | IMMUTABLE + Min=0, Max=UINT_MAX + CRTC + DRM property to gives the size of the lookup + table to be set on the DEGAMMA_LUT property (the size depends + on the underlying hardware). + + + âCTMâ + BLOB + 0 + CRTC + DRM property to set the current + transformation matrix (CTM) apply to pixel data after the + lookup through the degamma LUT and before the lookup through + the gamma LUT. The data is an interpreted as a struct + drm_color_ctm. + + + âGAMMA_LUTâ + BLOB + 0 + CRTC + DRM property to set the gamma lookup table + (LUT) mapping pixel data after to the transformation matrix to + data sent to the connector. The data is an interpreted as an + array of struct drm_color_lut elements. Hardware might choose + not to use the full precision of the LUT elements nor use all + the elements of the LUT (for example the hardware might choose + to interpolate between LUT[0] and LUT[4]). + + + âGAMMA_LUT_SIZEâ + RANGE | IMMUTABLE + Min=0, Max=UINT_MAX + CRTC + DRM property to gives the size of the lookup + table to be set on the GAMMA_LUT property (the size depends on + the underlying hardware). + + i915 Generic "Broadcast RGB" diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 092620c..b767a4f 100644 ---
[PATCH 2/5] drm/i915: Do not read GAMMA_MODE register
Implement Daniel Stone's recommendation to not read registers to infer the hardware's state. v2: Read GAMMA_MODE register value at init Signed-off-by: Lionel Landwerlin --- drivers/gpu/drm/i915/intel_color.c | 17 + drivers/gpu/drm/i915/intel_drv.h | 3 +++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_color.c b/drivers/gpu/drm/i915/intel_color.c index 5e0b997..f6bf9f1 100644 --- a/drivers/gpu/drm/i915/intel_color.c +++ b/drivers/gpu/drm/i915/intel_color.c @@ -121,6 +121,8 @@ static void haswell_load_luts(struct drm_crtc *crtc) struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + struct intel_crtc_state *intel_crtc_state = + to_intel_crtc_state(crtc->state); bool reenable_ips = false; /* @@ -128,11 +130,12 @@ static void haswell_load_luts(struct drm_crtc *crtc) * GAMMA_MODE is configured for split gamma and IPS_CTL has IPS enabled. */ if (IS_HASWELL(dev) && intel_crtc->config->ips_enabled && - ((I915_READ(GAMMA_MODE(intel_crtc->pipe)) & GAMMA_MODE_MODE_MASK) == -GAMMA_MODE_MODE_SPLIT)) { + (intel_crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT)) { hsw_disable_ips(intel_crtc); reenable_ips = true; } + + intel_crtc_state->gamma_mode = GAMMA_MODE_MODE_8BIT; I915_WRITE(GAMMA_MODE(intel_crtc->pipe), GAMMA_MODE_MODE_8BIT); i9xx_load_luts(crtc); @@ -173,6 +176,8 @@ void intel_color_init(struct drm_crtc *crtc) struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + struct intel_crtc_state *intel_crtc_state = + to_intel_crtc_state(crtc->state); int i; drm_mode_crtc_set_gamma_size(crtc, 256); @@ -183,8 +188,12 @@ void intel_color_init(struct drm_crtc *crtc) } if (IS_HASWELL(dev) || - (INTEL_INFO(dev)->gen >= 8 && !IS_CHERRYVIEW(dev))) + (INTEL_INFO(dev)->gen >= 8 && !IS_CHERRYVIEW(dev))) { dev_priv->display.load_luts = haswell_load_luts; - else + + intel_crtc_state->gamma_mode = + I915_READ(GAMMA_MODE(intel_crtc->pipe)); + } else { dev_priv->display.load_luts = i9xx_load_luts; + } } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 40fc486..9742d5b 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -517,6 +517,9 @@ struct intel_crtc_state { struct skl_pipe_wm skl; } optimal; } wm; + + /* Gamma mode programmed on the pipe */ + uint32_t gamma_mode; }; struct vlv_wm_state { -- 2.7.0
[PATCH 1/5] drm/i915: Extract out gamma table and CSC to their own file
The moves a couple of functions programming the gamma LUT and CSC units into their own file. On generations prior to Haswell there is only a gamma LUT. From haswell on there is also a new enhanced color correction unit that isn't used yet. This is why we need to set the GAMMA_MODE register, either we're using the legacy 8bits LUT or enhanced LUTs (of 10 or 12bits). The CSC unit is only available from Haswell on. We also need to make a special case for CherryView which is recognized as a gen 8 but doesn't have the same enhanced color correction unit from Haswell on. v2: Fix access to GAMMA_MODE register on older generations than Haswell (from Matt Roper's comments) Signed-off-by: Lionel Landwerlin Reviewed-by: Matt Roper --- drivers/gpu/drm/i915/Makefile| 1 + drivers/gpu/drm/i915/i915_drv.h | 2 + drivers/gpu/drm/i915/intel_color.c | 190 +++ drivers/gpu/drm/i915/intel_display.c | 163 +++--- drivers/gpu/drm/i915/intel_drv.h | 10 ++ 5 files changed, 215 insertions(+), 151 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_color.c diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 0851de07..0516300 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -55,6 +55,7 @@ i915-y += intel_audio.o \ intel_atomic.o \ intel_atomic_plane.o \ intel_bios.o \ + intel_color.o \ intel_display.o \ intel_fbc.o \ intel_fifo_underrun.o \ diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 6644c2e..6634c09 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -659,6 +659,8 @@ struct drm_i915_display_funcs { /* render clock increase/decrease */ /* display clock increase/decrease */ /* pll clock increase/decrease */ + + void (*load_luts)(struct drm_crtc *crtc); }; enum forcewake_domain_id { diff --git a/drivers/gpu/drm/i915/intel_color.c b/drivers/gpu/drm/i915/intel_color.c new file mode 100644 index 000..5e0b997 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_color.c @@ -0,0 +1,190 @@ +/* + * Copyright © 2016 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "intel_drv.h" + +/* + * Set up the pipe CSC unit. + * + * Currently only full range RGB to limited range RGB conversion + * is supported, but eventually this should handle various + * RGB<->YCbCr scenarios as well. + */ +static void i9xx_load_csc_matrix(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + int pipe = intel_crtc->pipe; + uint16_t coeff = 0x7800; /* 1.0 */ + + /* +* TODO: Check what kind of values actually come out of the pipe +* with these coeff/postoff values and adjust to get the best +* accuracy. Perhaps we even need to take the bpc value into +* consideration. +*/ + + if (intel_crtc->config->limited_color_range) + coeff = ((235 - 16) * (1 << 12) / 255) & 0xff8; /* 0.xxx... */ + + I915_WRITE(PIPE_CSC_COEFF_RY_GY(pipe), coeff << 16); + I915_WRITE(PIPE_CSC_COEFF_BY(pipe), 0); + + I915_WRITE(PIPE_CSC_COEFF_RU_GU(pipe), coeff); + I915_WRITE(PIPE_CSC_COEFF_BU(pipe), 0); + + I915_WRITE(PIPE_CSC_COEFF_RV_GV(pipe), 0); + I915_WRITE(PIPE_CSC_COEFF_BV(pipe), coeff << 16); + + I915_WRITE(PIPE_CSC_PREOFF_HI(pipe), 0); + I915_WRITE(PIPE_CSC_PREOFF_ME(pipe), 0); + I915_WRITE(PIPE_CSC_PREOFF_LO(pipe), 0); + + if (INTEL_INFO(dev)->gen > 6) { + uint16_t postoff = 0; + + if (intel_crtc->config->limited_color_range) + postoff =
[PATCH 0/5] Pipe level color management V7
This series introduces pipe level color management through a set of properties attached to the CRTC. It also provides an implementation for some Intel platforms. This series is based of a previous set of patches by Shashank Sharma. Cheers, Lionel Lionel Landwerlin (5): drm/i915: Extract out gamma table and CSC to their own file drm/i915: Do not read GAMMA_MODE register drm: introduce pipe color correction properties drm/i915: Implement color management on bdw/skl/bxt/kbl drm/i915: Implement color management on chv Documentation/DocBook/gpu.tmpl | 65 +++- drivers/gpu/drm/drm_atomic.c | 86 +- drivers/gpu/drm/drm_atomic_helper.c | 103 +++ drivers/gpu/drm/drm_crtc.c | 35 +++ drivers/gpu/drm/drm_crtc_helper.c| 33 ++ drivers/gpu/drm/i915/Makefile| 1 + drivers/gpu/drm/i915/i915_drv.c | 27 +- drivers/gpu/drm/i915/i915_drv.h | 8 + drivers/gpu/drm/i915/i915_reg.h | 53 drivers/gpu/drm/i915/intel_color.c | 563 +++ drivers/gpu/drm/i915/intel_display.c | 181 ++- drivers/gpu/drm/i915/intel_drv.h | 12 + drivers/gpu/drm/i915/intel_fbdev.c | 8 + include/drm/drm_atomic_helper.h | 3 + include/drm/drm_crtc.h | 46 ++- include/drm/drm_crtc_helper.h| 3 + include/uapi/drm/drm_mode.h | 15 + 17 files changed, 1077 insertions(+), 165 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_color.c -- 2.7.0
[Bug 94231] Problems compiling libdrm since glibc 2.23
https://bugs.freedesktop.org/show_bug.cgi?id=94231 --- Comment #14 from Mike Lothian --- I'll get the patches created for libdrm, mesa & xorg-server, Mike F please can you provide the location of where the updated docs are and I'll include it in the commit message Emil is there anything else you'd like? I'm going to mention the I provided above too -- You are receiving this mail because: You are the assignee for the bug. -- next part -- An HTML attachment was scrubbed... URL: <https://lists.freedesktop.org/archives/dri-devel/attachments/20160223/5b876d0d/attachment.html>
[PATCH] drm/rockchip: support prime fd import
Reviewed-by: Stéphane Marchesin On Tue, Feb 2, 2016 at 3:37 PM, Zach Reizner wrote: > The prime fd to handle ioctl was not used with rockchip before. Support > was added in order to support potential uses (e.g. zero-copy video > decode, camera). > > Signed-off-by: Zach Reizner > --- > drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 1 + > drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 92 > ++--- > drivers/gpu/drm/rockchip/rockchip_drm_gem.h | 7 ++- > 3 files changed, 91 insertions(+), 9 deletions(-) > > diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c > b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c > index dbfec29..4a01d92 100644 > --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c > +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c > @@ -307,6 +307,7 @@ static struct drm_driver rockchip_drm_driver = { > .gem_prime_import = drm_gem_prime_import, > .gem_prime_export = drm_gem_prime_export, > .gem_prime_get_sg_table = rockchip_gem_prime_get_sg_table, > + .gem_prime_import_sg_table = rockchip_gem_prime_import_sg_table, > .gem_prime_vmap = rockchip_gem_prime_vmap, > .gem_prime_vunmap = rockchip_gem_prime_vunmap, > .gem_prime_mmap = rockchip_gem_mmap_buf, > diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c > b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c > index a5c512e..cf6b50b 100644 > --- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c > +++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c > @@ -19,6 +19,7 @@ > #include > > #include > +#include > > #include "rockchip_drm_drv.h" > #include "rockchip_drm_gem.h" > @@ -105,13 +106,11 @@ int rockchip_gem_mmap(struct file *filp, struct > vm_area_struct *vma) > return rockchip_drm_gem_object_mmap(obj, vma); > } > > -struct rockchip_gem_object * > - rockchip_gem_create_object(struct drm_device *drm, unsigned int size, > - bool alloc_kmap) > +static struct rockchip_gem_object * > + rockchip_gem_alloc_object(struct drm_device *drm, unsigned int size) > { > struct rockchip_gem_object *rk_obj; > struct drm_gem_object *obj; > - int ret; > > size = round_up(size, PAGE_SIZE); > > @@ -123,6 +122,20 @@ struct rockchip_gem_object * > > drm_gem_private_object_init(drm, obj, size); > > + return rk_obj; > +} > + > +struct rockchip_gem_object * > + rockchip_gem_create_object(struct drm_device *drm, unsigned int size, > + bool alloc_kmap) > +{ > + struct rockchip_gem_object *rk_obj; > + int ret; > + > + rk_obj = rockchip_gem_alloc_object(drm, size); > + if (IS_ERR(rk_obj)) > + return rk_obj; > + > ret = rockchip_gem_alloc_buf(rk_obj, alloc_kmap); > if (ret) > goto err_free_rk_obj; > @@ -140,13 +153,18 @@ err_free_rk_obj: > */ > void rockchip_gem_free_object(struct drm_gem_object *obj) > { > - struct rockchip_gem_object *rk_obj; > + struct drm_device *drm = obj->dev; > + struct rockchip_gem_object *rk_obj = to_rockchip_obj(obj); > > drm_gem_free_mmap_offset(obj); > > - rk_obj = to_rockchip_obj(obj); > - > - rockchip_gem_free_buf(rk_obj); > + if (rk_obj->sg) { > + dma_unmap_sg(drm->dev, rk_obj->sg->sgl, rk_obj->sg->nents, > +DMA_BIDIRECTIONAL); > + drm_prime_gem_destroy(obj, rk_obj->sg); > + } else { > + rockchip_gem_free_buf(rk_obj); > + } > > kfree(rk_obj); > } > @@ -289,6 +307,64 @@ struct sg_table *rockchip_gem_prime_get_sg_table(struct > drm_gem_object *obj) > return sgt; > } > > +static unsigned long rockchip_sg_get_contiguous_size(struct sg_table *sgt, > +int count) > +{ > + struct scatterlist *s; > + dma_addr_t expected = sg_dma_address(sgt->sgl); > + unsigned int i; > + unsigned long size = 0; > + > + for_each_sg(sgt->sgl, s, count, i) { > + if (sg_dma_address(s) != expected) > + break; > + expected = sg_dma_address(s) + sg_dma_len(s); > + size += sg_dma_len(s); > + } > + return size; > +} > + > + > +struct drm_gem_object * > +rockchip_gem_prime_import_sg_table(struct drm_device *drm, > + struct dma_buf_attachment *attach, > + struct sg_table *sg) > +{ > + struct rockchip_gem_object *rk_obj; > + size_t size = attach->dmabuf->size; > + int count; > + int ret; > + > + rk_obj = rockchip_gem_alloc_object(drm, size); > + if (IS_ERR(rk_obj)) > + return ERR_CAST(rk_obj); > + > + count = dma_map_sg(drm->dev, sg->sgl, sg->nents, > + DMA_BIDIRECTIONAL); > + > + if (!count) { > +
[PATCH 6/6] drm/msm/dsi: Parse DSI lanes via DT
On Tue, Feb 23, 2016 at 01:11:24PM +0200, Tomi Valkeinen wrote: > > > On 23/02/16 12:43, Archit Taneja wrote: > > > > > > On 02/23/2016 02:48 PM, Tomi Valkeinen wrote: > >> > >> On 22/02/16 22:10, Rob Herring wrote: > >> > If we want all DSI host controllers to use a common binding to describe > lanes, we'd need to go with the most flexible one, and the driver > restricts it to the subsets that we support. > >> > >> True, but I wonder if that's necessary. The lane property for the SoC > >> should be read by the SoC specific driver, right? So the DT property can > >> be anything. I'm not sure if there's ever a reason for a generic code to > >> observe the DSI lane setup. > > > > Yeah, it is very SoC specific. Agreed. > > The only place where it might matter is if a panel/bridge ever needs to > > know what pins implement what lanes on the platform. A common binding > > there might help us keep the panel driver generic. Although, this need > > itself is a bit hypothetical. > > My opinion here is that if the panel/bridge needs to know something > about the DSI lanes/pins, we should have that data in the > panel's/bridge's endpoint data. > > So if both SoC and the DSI peripheral need complex DSI pin/lane setup, > you might have very similar data on both sides. There's possibly some > duplication there, but I think it keeps things much simpler. > > For example, if the SoC needs OMAP style DSI pin data, and the DSI > peripheral needs to know the amount of DSI lanes used (but nothing > else), you might think it's nice if the DSI peripheral would peek at the > SoC side data, finding out about the DSI lanes. > > But I think in that case you should just add a "num-lanes" property to > the DSI peripheral. The DT data for a device should be private to the > driver handling the device, except for some special cases like following > the graph. num-lanes might not be enough. You could need to have a mask instead. Not sure if there is really any h/w like that though. Also, I think it is fine for a parent to look at standard properties in a child. Rob
[Bug 94231] Problems compiling libdrm since glibc 2.23
https://bugs.freedesktop.org/show_bug.cgi?id=94231 --- Comment #13 from Emil Velikov --- Your suggestion is not unreasonable my any means. Yes, it's not hard to test (and include) the header, but it's unnecessary according to the documentation. I'll repeat my request - please update documentation, provide warnings and deprecation _period_. Do not just remove the include and then point fingers at projects because "they're not doing X" when there is no official information that say they should :-) TL DR; as soon as the manual is updated I'll be more than happy to get this in. -- You are receiving this mail because: You are the assignee for the bug. -- next part -- An HTML attachment was scrubbed... URL: <https://lists.freedesktop.org/archives/dri-devel/attachments/20160223/53ad5d08/attachment.html>
[PATCH 4/4 RESEND] ARC: axs10x: Update defconfigs so that I2S is enabled
The defconfigs for the AXS boards were updated to enable Designware I2S driver. Signed-off-by: Jose Abreu --- arch/arc/configs/axs101_defconfig | 1 + arch/arc/configs/axs103_defconfig | 1 + arch/arc/configs/axs103_smp_defconfig | 1 + 3 files changed, 3 insertions(+) diff --git a/arch/arc/configs/axs101_defconfig b/arch/arc/configs/axs101_defconfig index 7c22163..dd38d03 100644 --- a/arch/arc/configs/axs101_defconfig +++ b/arch/arc/configs/axs101_defconfig @@ -116,3 +116,4 @@ CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=10 CONFIG_SOUND=y CONFIG_SND=y CONFIG_SND_SOC=y +CONFIG_SND_DESIGNWARE_I2S=y diff --git a/arch/arc/configs/axs103_defconfig b/arch/arc/configs/axs103_defconfig index d63aef0..ff7162e 100644 --- a/arch/arc/configs/axs103_defconfig +++ b/arch/arc/configs/axs103_defconfig @@ -119,3 +119,4 @@ CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=10 CONFIG_SOUND=y CONFIG_SND=y CONFIG_SND_SOC=y +CONFIG_SND_DESIGNWARE_I2S=y diff --git a/arch/arc/configs/axs103_smp_defconfig b/arch/arc/configs/axs103_smp_defconfig index f4b51ce..b9f4671 100644 --- a/arch/arc/configs/axs103_smp_defconfig +++ b/arch/arc/configs/axs103_smp_defconfig @@ -120,3 +120,4 @@ CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=10 CONFIG_SOUND=y CONFIG_SND=y CONFIG_SND_SOC=y +CONFIG_SND_DESIGNWARE_I2S=y -- 1.9.1
[PATCH 3/4 RESEND] ASoC: dwc: Add I2S HDMI audio support using custom platform driver
HDMI audio support was added to the AXS board using an I2S cpu driver and a custom platform driver. The platform driver supports two channels @ 16 bits with rates 32k, 44.1k and 48k. ALSA Simple audio card is used to glue the cpu, platform and codec driver (adv7511). Signed-off-by: Jose Abreu --- arch/arc/boot/dts/axs10x_mb.dtsi | 20 ++- sound/soc/dwc/Kconfig| 1 + sound/soc/dwc/Makefile | 4 +- sound/soc/dwc/designware_i2s.c | 139 +++-- sound/soc/dwc/designware_pcm.c | 264 +++ sound/soc/dwc/designware_pcm.h | 21 6 files changed, 430 insertions(+), 19 deletions(-) create mode 100644 sound/soc/dwc/designware_pcm.c create mode 100644 sound/soc/dwc/designware_pcm.h diff --git a/arch/arc/boot/dts/axs10x_mb.dtsi b/arch/arc/boot/dts/axs10x_mb.dtsi index e00e5bb..c137376 100644 --- a/arch/arc/boot/dts/axs10x_mb.dtsi +++ b/arch/arc/boot/dts/axs10x_mb.dtsi @@ -130,12 +130,23 @@ interrupts = <14>; }; - i2c at 0x1e000 { - compatible = "snps,designware-i2c"; + i2s: i2s at 0x1e000 { + compatible = "snps,designware-i2s"; reg = <0x1e000 0x100>; - clock-frequency = <40>; - clocks = <>; interrupts = <15>; + #sound-dai-cells = <0>; + }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "AXS10X HDMI Audio"; + simple-audio-card,format = "i2s"; + simple-audio-card,cpu { + sound-dai = <>; + }; + simple-audio-card,codec { + sound-dai = <>; + }; }; i2c at 0x1f000 { @@ -155,6 +166,7 @@ adi,input-colorspace = "rgb"; adi,input-clock = "1x"; adi,clock-delay = <0x03>; + #sound-dai-cells = <0>; ports { #address-cells = <1>; diff --git a/sound/soc/dwc/Kconfig b/sound/soc/dwc/Kconfig index d50e085..bc3fae7 100644 --- a/sound/soc/dwc/Kconfig +++ b/sound/soc/dwc/Kconfig @@ -2,6 +2,7 @@ config SND_DESIGNWARE_I2S tristate "Synopsys I2S Device Driver" depends on CLKDEV_LOOKUP select SND_SOC_GENERIC_DMAENGINE_PCM + select SND_SIMPLE_CARD help Say Y or M if you want to add support for I2S driver for Synopsys desigwnware I2S device. The device supports upto diff --git a/sound/soc/dwc/Makefile b/sound/soc/dwc/Makefile index 319371f..4d8f869 100644 --- a/sound/soc/dwc/Makefile +++ b/sound/soc/dwc/Makefile @@ -1,3 +1,3 @@ # SYNOPSYS Platform Support -obj-$(CONFIG_SND_DESIGNWARE_I2S) += designware_i2s.o - +obj-$(CONFIG_SND_DESIGNWARE_I2S) += dwc_i2s.o +dwc_i2s-y := designware_i2s.o designware_pcm.o diff --git a/sound/soc/dwc/designware_i2s.c b/sound/soc/dwc/designware_i2s.c index bff258d..db9aced 100644 --- a/sound/soc/dwc/designware_i2s.c +++ b/sound/soc/dwc/designware_i2s.c @@ -25,6 +25,8 @@ #include #include +#include "designware_pcm.h" + /* common register for all channel */ #define IER0x000 #define IRER 0x004 @@ -84,6 +86,11 @@ #define MAX_CHANNEL_NUM8 #define MIN_CHANNEL_NUM2 +/* PLL registers addresses */ +#define PLL_IDIV_ADDR 0xE00100A0 +#define PLL_FBDIV_ADDR 0xE00100A4 +#define PLL_ODIV_ADDR 0xE00100A8 + union dw_i2s_snd_dma_data { struct i2s_dma_data pd; struct snd_dmaengine_dai_dma_data dt; @@ -100,12 +107,32 @@ struct dw_i2s_dev { struct device *dev; u32 ccr; u32 xfer_resolution; + u32 xfer_bytes; + u32 fifo_th; /* data related to DMA transfers b/w i2s and DMAC */ union dw_i2s_snd_dma_data play_dma_data; union dw_i2s_snd_dma_data capture_dma_data; struct i2s_clk_config_data config; int (*i2s_clk_cfg)(struct i2s_clk_config_data *config); + int (*pcm_get)(u32 *lsample, u32 *rsample, int bytes, int buf_size); +}; + +struct dw_i2s_pll { + unsigned int rate; + unsigned int data_width; + unsigned int idiv; + unsigned int fbdiv; + unsigned int odiv; +}; + +static const struct dw_i2s_pll dw_i2s_pll_cfg[] = { + { 32000, 16, 0x104, 0x451, 0x10E38 }, /* 32 kHz */ + { 32000, 32, 0x82, 0x451, 0x10E38 }, + { 44100, 16, 0x104, 0x596, 0x10D35},/* 44.1 kHz */ + { 44100, 32, 0x82, 0x596, 0x10D35 }, + { 48000, 16, 0x208, 0xA28, 0x10B2C }, /* 48 kHz */ + { 48000, 32, 0x104, 0xA28, 0x10B2C }, }; static inline void i2s_write_reg(void
[PATCH 2/4 RESEND] ARC: axs10x: Update defconfigs so that audio is enabled
The defconfigs for the AXS boards were updated so that ALSA SoC is enabled and also the audio for the ADV7511 HDMI transmitter. Signed-off-by: Jose Abreu --- arch/arc/configs/axs101_defconfig | 3 +++ arch/arc/configs/axs103_defconfig | 5 + arch/arc/configs/axs103_smp_defconfig | 5 + 3 files changed, 13 insertions(+) diff --git a/arch/arc/configs/axs101_defconfig b/arch/arc/configs/axs101_defconfig index e359099..7c22163 100644 --- a/arch/arc/configs/axs101_defconfig +++ b/arch/arc/configs/axs101_defconfig @@ -113,3 +113,6 @@ CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=10 # CONFIG_SCHED_DEBUG is not set # CONFIG_DEBUG_PREEMPT is not set # CONFIG_FTRACE is not set +CONFIG_SOUND=y +CONFIG_SND=y +CONFIG_SND_SOC=y diff --git a/arch/arc/configs/axs103_defconfig b/arch/arc/configs/axs103_defconfig index 323486d..d63aef0 100644 --- a/arch/arc/configs/axs103_defconfig +++ b/arch/arc/configs/axs103_defconfig @@ -76,12 +76,14 @@ CONFIG_SERIAL_OF_PLATFORM=y CONFIG_I2C=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_DESIGNWARE_PLATFORM=y +CONFIG_DRM=y # CONFIG_HWMON is not set CONFIG_FB=y # CONFIG_VGA_CONSOLE is not set CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y CONFIG_LOGO=y +CONFIG_DRM_I2C_ADV7511=y # CONFIG_LOGO_LINUX_MONO is not set # CONFIG_LOGO_LINUX_VGA16 is not set # CONFIG_LOGO_LINUX_CLUT224 is not set @@ -114,3 +116,6 @@ CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=10 # CONFIG_SCHED_DEBUG is not set # CONFIG_DEBUG_PREEMPT is not set # CONFIG_FTRACE is not set +CONFIG_SOUND=y +CONFIG_SND=y +CONFIG_SND_SOC=y diff --git a/arch/arc/configs/axs103_smp_defconfig b/arch/arc/configs/axs103_smp_defconfig index 66191cd..f4b51ce 100644 --- a/arch/arc/configs/axs103_smp_defconfig +++ b/arch/arc/configs/axs103_smp_defconfig @@ -77,12 +77,14 @@ CONFIG_SERIAL_OF_PLATFORM=y CONFIG_I2C=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_DESIGNWARE_PLATFORM=y +CONFIG_DRM=y # CONFIG_HWMON is not set CONFIG_FB=y # CONFIG_VGA_CONSOLE is not set CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y CONFIG_LOGO=y +CONFIG_DRM_I2C_ADV7511=y # CONFIG_LOGO_LINUX_MONO is not set # CONFIG_LOGO_LINUX_VGA16 is not set # CONFIG_LOGO_LINUX_CLUT224 is not set @@ -115,3 +117,6 @@ CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=10 # CONFIG_SCHED_DEBUG is not set # CONFIG_DEBUG_PREEMPT is not set # CONFIG_FTRACE is not set +CONFIG_SOUND=y +CONFIG_SND=y +CONFIG_SND_SOC=y -- 1.9.1
[PATCH 0/4 RESEND] Add I2S/ADV7511 audio support for ARC AXS10x boards
ARC AXS10x platforms consist of a mainboard with several peripherals. One of those peripherals is an HDMI output port controlled by ADV7511 transmitter. This patch set adds audio for the ADV7511 transmitter and I2S audio for the AXS10x platform. Jose Abreu (4): [adv7511] Add audio support [adv7511] Update defconfigs so that audio is enabled [dwc] Add I2S HDMI audio support using custom platform driver [dwc] Update defconfigs so that I2S is enabled arch/arc/boot/dts/axs10x_mb.dtsi | 20 +- arch/arc/configs/axs101_defconfig |4 + arch/arc/configs/axs103_defconfig |6 + arch/arc/configs/axs103_smp_defconfig |6 + drivers/gpu/drm/i2c/Kconfig |8 + drivers/gpu/drm/i2c/Makefile |2 + drivers/gpu/drm/i2c/adv7511.c | 1024 - drivers/gpu/drm/i2c/adv7511.h | 41 ++ drivers/gpu/drm/i2c/adv7511_audio.c | 310 ++ drivers/gpu/drm/i2c/adv7511_core.c| 1005 include/sound/soc-dai.h |1 + sound/soc/dwc/Kconfig |1 + sound/soc/dwc/Makefile|4 +- sound/soc/dwc/designware_i2s.c| 139 - sound/soc/dwc/designware_pcm.c| 264 + sound/soc/dwc/designware_pcm.h| 21 + 16 files changed, 1813 insertions(+), 1043 deletions(-) delete mode 100644 drivers/gpu/drm/i2c/adv7511.c create mode 100644 drivers/gpu/drm/i2c/adv7511_audio.c create mode 100644 drivers/gpu/drm/i2c/adv7511_core.c create mode 100644 sound/soc/dwc/designware_pcm.c create mode 100644 sound/soc/dwc/designware_pcm.h -- 1.9.1
[PATCH 01/33] drm/omap: HDMI: change enable/disable to avoid sync-losts
On 23/02/16 12:22, Laurent Pinchart wrote: > Hi Tomi, > > Thank you for the patch. > > On Friday 19 February 2016 11:47:36 Tomi Valkeinen wrote: >> We occasionally see DISPC sync-lost errors when enabling and disabling >> HDMI. Sometimes we get only a few, which get handled (ignored) by the >> driver, but sometimes there's a flood of the errors which doesn't seem >> to stop. >> >> The HW team has root caused this to the order in which HDMI and DISPC >> are enabled/disabled. Currently we enable HDMI first, and then DISPC, >> and vice versa when disabling. HW team's suggestion is to do it the >> other way around. >> >> This patch changes the order, but this has two side effects as the pixel >> clock is produced by HDMI, and the clock is not running when we >> enable/disable DISPC: >> >> * When enabling DISPC first, we don't get vertical sync events >> * When disabling DISPC last, we don't get FRAMEDONE event >> >> At the moment we use both of those to verify that DISPC has been >> enabled/disabled properly. Thus this patch also needs to change the >> omapdrm and omapdss which handle the DISPC side. >> +if (omap_crtc->mgr->output->output_type == OMAP_DISPLAY_TYPE_HDMI) { >> +dispc_mgr_enable(channel, enable); >> +return; >> +} > > This effectively bypasses the wait until the DISPC outputs the first vsync > interrupt below. How does HDMI differ from other outputs in such a way to > make > the wait unneeded ? There's to parts here. Enabling the output and disabling the output. Enable: We don't strictly need the wait after enable for any output. The output works after setting the enable bit. There are two reasons for the waiting: 1) A sanity check that the configuration is ok. If the config is broken (which shouldn't happen, of course, as the driver should verify the config), we won't see vsync. At the moment we only print an error in that case. 2) OMAP_DSS_CHANNEL_DIGIT is a bit problematic. That channel is used for analog tv-out (VENC) in older DSS versions, and for HDMI for more recent ones. With VENC we always get a few sync lost errors when enabling the output, so with the wait we can ignore those errors (this sync-lost ignoring is only done for OMAP_DSS_CHANNEL_DIGIT). We have seen similar sync losts with HDMI too, but apparently it is possible to support HDMI without any sync losts. That's what this patch is doing. With this patch we lose both 1) and 2) above, but 1) is not strictly needed and 2) shouldn't happen for HDMI after this patch. We could implement 1) in the HDMI driver too, using the HDMI IP's VSYNC interrupt, but I don't think it's really necessary. Disable: When disabling the output, we do want to wait until the DSS has finished the work at the end of the frame. This is done in the omap_crtc_set_enabled() function for all outputs, using FRAMEDONE interrupt when available, or VSYNC if not. For HDMI we can do it also in the HDMI driver. The HDMI IP has its own FRAMEDONE interrupt, which we wait for in hdmi_wp_video_stop(). Tomi -- next part -- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: OpenPGP digital signature URL: <https://lists.freedesktop.org/archives/dri-devel/attachments/20160223/db02d166/attachment.sig>
[PATCH 6/6] drm/msm/dsi: Parse DSI lanes via DT
On 23/02/16 12:43, Archit Taneja wrote: > > > On 02/23/2016 02:48 PM, Tomi Valkeinen wrote: >> >> On 22/02/16 22:10, Rob Herring wrote: >> >>>> If we want all DSI host controllers to use a common binding to describe >>>> lanes, we'd need to go with the most flexible one, and the driver >>>> restricts it to the subsets that we support. >> >> True, but I wonder if that's necessary. The lane property for the SoC >> should be read by the SoC specific driver, right? So the DT property can >> be anything. I'm not sure if there's ever a reason for a generic code to >> observe the DSI lane setup. > > Yeah, it is very SoC specific. > > The only place where it might matter is if a panel/bridge ever needs to > know what pins implement what lanes on the platform. A common binding > there might help us keep the panel driver generic. Although, this need > itself is a bit hypothetical. My opinion here is that if the panel/bridge needs to know something about the DSI lanes/pins, we should have that data in the panel's/bridge's endpoint data. So if both SoC and the DSI peripheral need complex DSI pin/lane setup, you might have very similar data on both sides. There's possibly some duplication there, but I think it keeps things much simpler. For example, if the SoC needs OMAP style DSI pin data, and the DSI peripheral needs to know the amount of DSI lanes used (but nothing else), you might think it's nice if the DSI peripheral would peek at the SoC side data, finding out about the DSI lanes. But I think in that case you should just add a "num-lanes" property to the DSI peripheral. The DT data for a device should be private to the driver handling the device, except for some special cases like following the graph. Tomi -- next part -- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: OpenPGP digital signature URL: <https://lists.freedesktop.org/archives/dri-devel/attachments/20160223/e34fcbd9/attachment.sig>
[PATCH] amdgpu: fix NULL pointer dereference at tonga_check_states_equal
Applied. thanks! Alex On Mon, Feb 22, 2016 at 9:21 PM, Zhu, Rex wrote: > > Reviewed-by: Rex Zhu > > Best Regards > Rex Zhu > > -Original Message- > From: Bradley Pankow [mailto:btpankow at gmail.com] > Sent: Tuesday, February 23, 2016 9:12 AM > To: Deucher, Alexander; Zhu, Rex; Zhou, Jammy > Cc: dri-devel at lists.freedesktop.org; linux-kernel at vger.kernel.org; > Bradley Pankow > Subject: [PATCH] amdgpu: fix NULL pointer dereference at > tonga_check_states_equal > > The event_data passed from pem_fini was not cleared upon initialization. > This caused NULL checks to pass and cast_const_phw_tonga_power_state to > attempt to dereference an invalid pointer. Clear the event_data in pem_init > and pem_fini before calling pem_handle_event. > > Signed-off-by: Bradley Pankow > --- > drivers/gpu/drm/amd/powerplay/eventmgr/eventmgr.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/amd/powerplay/eventmgr/eventmgr.c > b/drivers/gpu/drm/amd/powerplay/eventmgr/eventmgr.c > index 52a3efc..46410e3 100644 > --- a/drivers/gpu/drm/amd/powerplay/eventmgr/eventmgr.c > +++ b/drivers/gpu/drm/amd/powerplay/eventmgr/eventmgr.c > @@ -31,7 +31,7 @@ > static int pem_init(struct pp_eventmgr *eventmgr) { > int result = 0; > - struct pem_event_data event_data; > + struct pem_event_data event_data = { {0} }; > > /* Initialize PowerPlay feature info */ > pem_init_feature_info(eventmgr); > @@ -52,7 +52,7 @@ static int pem_init(struct pp_eventmgr *eventmgr) > > static void pem_fini(struct pp_eventmgr *eventmgr) { > - struct pem_event_data event_data; > + struct pem_event_data event_data = { {0} }; > > pem_uninit_featureInfo(eventmgr); > pem_unregister_interrupts(eventmgr); > -- > 2.7.1 > > ___ > dri-devel mailing list > dri-devel at lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 02/33] HACK: drm/omap: always use blocking DMM fill
Hi Tomi, Thank you for the patch. On Friday 19 February 2016 11:47:37 Tomi Valkeinen wrote: > The current driver uses non-blocking DMM fill when releasing memory. > This gives us a small performance increase as we don't have to wait for > the fill operation to finish. > > However, the driver does not have any error handling for non-blocking > fill. In case of an error, the fill operation may silently fail, leading > to leaking DMM engines, which may eventually lead to deadlock if we run > out of DMM engines. > > This patch makes the DMM driver always use blocking fills, so that we > can catch the errors. A more complex option would be to allow > non-blocking fills, and implement proper error handling, but that is > left for the future. > > This patch is a HACK, as the proper fix is to either decide to always > use sync fills and remove all the async related code, or fix the async > code. Could you capture this in the comment in the source code below ? I'd also replace with either FIXME or TODO. > Signed-off-by: Tomi Valkeinen > --- > drivers/gpu/drm/omapdrm/omap_dmm_tiler.c | 6 ++ > 1 file changed, 6 insertions(+) > > diff --git a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c > b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c index dfebdc4aa0f2..80526dec7b2c > 100644 > --- a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c > +++ b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c > @@ -309,6 +309,12 @@ static int fill(struct tcm_area *area, struct page > **pages, struct tcm_area slice, area_s; > struct dmm_txn *txn; > > + /* > + * XXX async wait doesn't work, as it does not handle timeout errors > + * properly > + */ > + wait = true; > + > txn = dmm_txn_init(omap_dmm, area->tcm); > if (IS_ERR_OR_NULL(txn)) > return -ENOMEM; -- Regards, Laurent Pinchart
[PATCH 01/33] drm/omap: HDMI: change enable/disable to avoid sync-losts
Hi Tomi, Thank you for the patch. On Friday 19 February 2016 11:47:36 Tomi Valkeinen wrote: > We occasionally see DISPC sync-lost errors when enabling and disabling > HDMI. Sometimes we get only a few, which get handled (ignored) by the > driver, but sometimes there's a flood of the errors which doesn't seem > to stop. > > The HW team has root caused this to the order in which HDMI and DISPC > are enabled/disabled. Currently we enable HDMI first, and then DISPC, > and vice versa when disabling. HW team's suggestion is to do it the > other way around. > > This patch changes the order, but this has two side effects as the pixel > clock is produced by HDMI, and the clock is not running when we > enable/disable DISPC: > > * When enabling DISPC first, we don't get vertical sync events > * When disabling DISPC last, we don't get FRAMEDONE event > > At the moment we use both of those to verify that DISPC has been > enabled/disabled properly. Thus this patch also needs to change the > omapdrm and omapdss which handle the DISPC side. > > Signed-off-by: Tomi Valkeinen > --- > drivers/gpu/drm/omapdrm/dss/hdmi4.c | 16 > drivers/gpu/drm/omapdrm/dss/hdmi5.c | 16 > drivers/gpu/drm/omapdrm/omap_crtc.c | 5 + > 3 files changed, 21 insertions(+), 16 deletions(-) > > diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c > b/drivers/gpu/drm/omapdrm/dss/hdmi4.c index 7103c659a534..b09ce9ee82fa > 100644 > --- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c > +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c > @@ -214,22 +214,22 @@ static int hdmi_power_on_full(struct omap_dss_device > *dssdev) /* tv size */ > dss_mgr_set_timings(mgr, p); > > - r = hdmi_wp_video_start(); > - if (r) > - goto err_vid_enable; > - > r = dss_mgr_enable(mgr); > if (r) > goto err_mgr_enable; > > + r = hdmi_wp_video_start(); > + if (r) > + goto err_vid_enable; > + > hdmi_wp_set_irqenable(wp, > HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT); > > return 0; > > -err_mgr_enable: > - hdmi_wp_video_stop(); > err_vid_enable: > + dss_mgr_disable(mgr); > +err_mgr_enable: > hdmi_wp_set_phy_pwr(, HDMI_PHYPWRCMD_OFF); > err_phy_pwr: > err_phy_cfg: > @@ -246,10 +246,10 @@ static void hdmi_power_off_full(struct omap_dss_device > *dssdev) > > hdmi_wp_clear_irqenable(, 0x); > > - dss_mgr_disable(mgr); > - > hdmi_wp_video_stop(); > > + dss_mgr_disable(mgr); > + > hdmi_wp_set_phy_pwr(, HDMI_PHYPWRCMD_OFF); > > dss_pll_disable(); > diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5.c > b/drivers/gpu/drm/omapdrm/dss/hdmi5.c index a955a2c4c061..4485a1c37bd8 > 100644 > --- a/drivers/gpu/drm/omapdrm/dss/hdmi5.c > +++ b/drivers/gpu/drm/omapdrm/dss/hdmi5.c > @@ -231,22 +231,22 @@ static int hdmi_power_on_full(struct omap_dss_device > *dssdev) /* tv size */ > dss_mgr_set_timings(mgr, p); > > - r = hdmi_wp_video_start(); > - if (r) > - goto err_vid_enable; > - > r = dss_mgr_enable(mgr); > if (r) > goto err_mgr_enable; > > + r = hdmi_wp_video_start(); > + if (r) > + goto err_vid_enable; > + > hdmi_wp_set_irqenable(, > HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT); > > return 0; > > -err_mgr_enable: > - hdmi_wp_video_stop(); > err_vid_enable: > + dss_mgr_disable(mgr); > +err_mgr_enable: > hdmi_wp_set_phy_pwr(, HDMI_PHYPWRCMD_OFF); > err_phy_pwr: > err_phy_cfg: > @@ -263,10 +263,10 @@ static void hdmi_power_off_full(struct omap_dss_device > *dssdev) > > hdmi_wp_clear_irqenable(, 0x); > > - dss_mgr_disable(mgr); > - > hdmi_wp_video_stop(); > > + dss_mgr_disable(mgr); > + > hdmi_wp_set_phy_pwr(, HDMI_PHYPWRCMD_OFF); > > dss_pll_disable(); > diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c > b/drivers/gpu/drm/omapdrm/omap_crtc.c index 2ed0754ed19e..7dd3d44a93e5 > 100644 > --- a/drivers/gpu/drm/omapdrm/omap_crtc.c > +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c > @@ -138,6 +138,11 @@ static void omap_crtc_set_enabled(struct drm_crtc > *crtc, bool enable) u32 framedone_irq, vsync_irq; > int ret; > > + if (omap_crtc->mgr->output->output_type == OMAP_DISPLAY_TYPE_HDMI) { > + dispc_mgr_enable(channel, enable); > + return; > + } This effectively bypasses the wait until the DISPC outputs the first vsync interrupt below. How does HDMI differ from other outputs in such a way to make the wait unneeded ? > if (dispc_mgr_is_enabled(channel) == enable) > return; -- Regards, Laurent Pinchart
GSoC 2016
Hi Mehul, Am 22.02.2016 um 13:28 schrieb Mehul Sawarkar: > Hello, > > I am Mehul Sawarkar from India .I want to be part of X.Org during GSoC > 2016.I know C/C++.Please help me getting started with some easy task > you might have in mind.What are some of prospective project ideas for > GSoC 2016. > I'll be happy to have your help and suggestions. If you want to get your hands dirty with working on a the kernel driver I could come up with a task or two for Radeon/Amdgpu. If you prefer some work on the userspace part of the stack I could probably come up with some video related tasks for Mesa. Depends a bit on you're interests, background and what graphics hardware you have available. Regards, Christian. > > Thanks > Mehul Sawarkar > > > ___ > dri-devel mailing list > dri-devel at lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel -- next part -- An HTML attachment was scrubbed... URL: <https://lists.freedesktop.org/archives/dri-devel/attachments/20160223/7b6682e1/attachment-0001.html>
[PATCH 1/2] drm/panel: simple: Add support for Sharp LQ101K1LY04
On Tue, 12 Jan 2016 13:55:35 -0800 Joshua Clayton wrote: Ping? FYI The dts for the board using this panel is now in linux-next. Is there something more I need to do to get it queued? They are my first patches for the drm subsystem, so I may be unfamiliar with the customs. I just checked; the patches still apply cleanly against linux-next. > Add simple-panel support for the Sharp LQ101K1LY04i, which is > a 10 inch WXGA (1280x800) lvds panel. > > Signed-off-by: Joshua Clayton > --- > drivers/gpu/drm/panel/panel-simple.c | 27 +++ > 1 file changed, 27 insertions(+) > > diff --git a/drivers/gpu/drm/panel/panel-simple.c > b/drivers/gpu/drm/panel/panel-simple.c index f97b73e..e01eacb 100644 > --- a/drivers/gpu/drm/panel/panel-simple.c > +++ b/drivers/gpu/drm/panel/panel-simple.c > @@ -1073,6 +1073,30 @@ static const struct panel_desc > samsung_ltn140at29_301 = { }, > }; > > +static const struct display_timing sharp_lq101k1ly04_timing = { > + .pixelclock = { 6000, 6500, 8000 }, > + .hactive = { 1280, 1280, 1280 }, > + .hfront_porch = { 20, 20, 20 }, > + .hback_porch = { 20, 20, 20 }, > + .hsync_len = { 10, 10, 10 }, > + .vactive = { 800, 800, 800 }, > + .vfront_porch = { 4, 4, 4 }, > + .vback_porch = { 4, 4, 4 }, > + .vsync_len = { 4, 4, 4 }, > + .flags = DISPLAY_FLAGS_PIXDATA_POSEDGE, > +}; > + > +static const struct panel_desc sharp_lq101k1ly04 = { > + .timings = _lq101k1ly04_timing, > + .num_timings = 1, > + .bpc = 8, > + .size = { > + .width = 217, > + .height = 136, > + }, > + .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA, > +}; > + > static const struct drm_display_mode shelly_sca07010_bfn_lnn_mode = { > .clock = 33300, > .hdisplay = 800, > @@ -1188,6 +1212,9 @@ static const struct of_device_id > platform_of_match[] = { .compatible = "samsung,ltn140at29-301", > .data = _ltn140at29_301, > }, { > + .compatible = "sharp,lq101k1ly04", > + .data = _lq101k1ly04, > + }, { > .compatible = "shelly,sca07010-bfn-lnn", > .data = _sca07010_bfn_lnn, > }, {
[PATCH 6/6] drm/msm/dsi: Parse DSI lanes via DT
On 22/02/16 22:10, Rob Herring wrote: >> If we want all DSI host controllers to use a common binding to describe >> lanes, we'd need to go with the most flexible one, and the driver >> restricts it to the subsets that we support. True, but I wonder if that's necessary. The lane property for the SoC should be read by the SoC specific driver, right? So the DT property can be anything. I'm not sure if there's ever a reason for a generic code to observe the DSI lane setup. That said, if we do have a common binding, it's perhaps easier for people to understand the setups for different SoCs. >>>> +a limited number of physical to logical mappings possible: >>>> + >>>> + "0123": Logic 0->Phys 0; Logic 1->Phys 1; Logic 2->Phys 2; Logic >>>> 3->Phys 3; >>>> + "3012": Logic 3->Phys 0; Logic 0->Phys 1; Logic 1->Phys 2; Logic >>>> 2->Phys 3; >>>> + "2301": Logic 2->Phys 0; Logic 3->Phys 1; Logic 0->Phys 2; Logic >>>> 1->Phys 3; >>>> + "1230": Logic 1->Phys 0; Logic 2->Phys 1; Logic 3->Phys 2; Logic >>>> 0->Phys 3; >>>> + "0321": Logic 0->Phys 0; Logic 3->Phys 1; Logic 2->Phys 2; Logic >>>> 1->Phys 3; >>>> + "1032": Logic 1->Phys 0; Logic 0->Phys 1; Logic 3->Phys 2; Logic >>>> 2->Phys 3; >>>> + "2103": Logic 2->Phys 0; Logic 1->Phys 1; Logic 0->Phys 2; Logic >>>> 3->Phys 3; >>>> + "3210": Logic 3->Phys 0; Logic 2->Phys 1; Logic 1->Phys 2; Logic >>>> 0->Phys 3; >>>> + >>>> + Here, a "3012" mapping will be represented by: >>>> + lanes = <0 1 8 9 2 3 4 5 6 7>; >>> >>> >>> I'm lost here. What does 8 mean for example. The index represents? >> >> >> The numbers here describe the logical lanes. I.e, the way in which the >> DSI controller pushes out data to the PHY. The ordering is as follows: If I read you right, I think that's vice versa. At least the OMAP version. The OMAP doc says: "- lanes: list of pin numbers for the DSI lanes: CLK+, CLK-, DATA0+, DATA0-, DATA1+, DATA1-, ..." This means that the first value in the array is the pin number for CLK+. In other words, CLK+ wire going to the panel/encoder is connected to pin number X. What the pin number means is SoC specific. CLK+ could be connected to, say, SoC pin number 123, and then you'd enter 123 as the first value. On OMAP we use DSI block specific pin numbers, so they start at 0. > Okay, so the confusing part is the description is all about lanes > (0-3) but the binding (index and value) is all about pin/signal > numbers. Either simplify the binding to be lanes or describe the > binding in terms of pins. Perhaps "lane-pins" or something would be more descriptive. If we want to make the description common, I could change the OMAP implementation to accept the new property name too. But, I'm not sure if a common description helps much. Any thoughts? Tomi -- next part -- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: OpenPGP digital signature URL: <https://lists.freedesktop.org/archives/dri-devel/attachments/20160223/fd80c3e3/attachment.sig>
[PATCH v2] drm: Clean up drm Makefile
On 9 February 2016 at 17:50, Daniel Vetter wrote: > On Fri, Feb 05, 2016 at 11:10:30AM +0800, Xinliang Liu wrote: >> This patch cleans up the Makefile of drm root directory. >> Make core and device drivers configuration list sorted Alphabetically. >> >> Signed-off-by: Xinliang Liu >> Reviewed-by: Xinwei Kong >> Reviewed-by: Yifan Liu >> --- >> drivers/gpu/drm/Makefile | 102 >> --- >> 1 file changed, 52 insertions(+), 50 deletions(-) >> >> diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile >> index 61766dec6a8d..23e57948f68f 100644 >> --- a/drivers/gpu/drm/Makefile >> +++ b/drivers/gpu/drm/Makefile >> @@ -2,6 +2,9 @@ >> # Makefile for the drm device driver. This driver provides support for the >> # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. >> >> +CFLAGS_drm_trace_points.o := -I$(src) >> + >> +# core. Please keep this list sorted alphabetically >> drm-y := drm_auth.o drm_bufs.o drm_cache.o \ >> drm_context.o drm_dma.o \ >> drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \ >> @@ -13,64 +16,63 @@ drm-y :=drm_auth.o drm_bufs.o drm_cache.o \ >> drm_trace_points.o drm_global.o drm_prime.o \ >> drm_rect.o drm_vma_manager.o drm_flip_work.o \ >> drm_modeset_lock.o drm_atomic.o drm_bridge.o >> - >> -drm-$(CONFIG_COMPAT) += drm_ioc32.o >> -drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o >> drm-$(CONFIG_PCI) += ati_pcigart.o >> -drm-$(CONFIG_DRM_PANEL) += drm_panel.o >> -drm-$(CONFIG_OF) += drm_of.o >> drm-$(CONFIG_AGP) += drm_agpsupport.o >> +drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o >> +drm-$(CONFIG_COMPAT) += drm_ioc32.o >> +drm-$(CONFIG_OF) += drm_of.o >> +drm-$(CONFIG_DRM_PANEL) += drm_panel.o >> +obj-$(CONFIG_DRM)+= drm.o >> + >> +obj-$(CONFIG_DRM_MIPI_DSI) += drm_mipi_dsi.o >> >> drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \ >> drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o >> drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o >> -drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o >> drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o >> - >> +drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o >> obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o >> >> -CFLAGS_drm_trace_points.o := -I$(src) >> +obj-$(CONFIG_DRM_TTM) += ttm/ >> >> -obj-$(CONFIG_DRM)+= drm.o >> -obj-$(CONFIG_DRM_MIPI_DSI) += drm_mipi_dsi.o >> -obj-$(CONFIG_DRM_TTM)+= ttm/ >> -obj-$(CONFIG_DRM_TDFX) += tdfx/ >> -obj-$(CONFIG_DRM_R128) += r128/ >> -obj-$(CONFIG_HSA_AMD) += amd/amdkfd/ >> -obj-$(CONFIG_DRM_RADEON)+= radeon/ >> -obj-$(CONFIG_DRM_AMDGPU)+= amd/amdgpu/ >> -obj-$(CONFIG_DRM_MGA)+= mga/ >> -obj-$(CONFIG_DRM_I810) += i810/ >> -obj-$(CONFIG_DRM_I915) += i915/ >> -obj-$(CONFIG_DRM_MGAG200) += mgag200/ >> -obj-$(CONFIG_DRM_VC4) += vc4/ >> -obj-$(CONFIG_DRM_CIRRUS_QEMU) += cirrus/ >> -obj-$(CONFIG_DRM_SIS) += sis/ >> -obj-$(CONFIG_DRM_SAVAGE)+= savage/ >> -obj-$(CONFIG_DRM_VMWGFX)+= vmwgfx/ >> -obj-$(CONFIG_DRM_VIA)+=via/ >> -obj-$(CONFIG_DRM_VGEM) += vgem/ >> -obj-$(CONFIG_DRM_NOUVEAU) +=nouveau/ >> -obj-$(CONFIG_DRM_EXYNOS) +=exynos/ >> -obj-$(CONFIG_DRM_ROCKCHIP) +=rockchip/ >> -obj-$(CONFIG_DRM_GMA500) += gma500/ >> -obj-$(CONFIG_DRM_UDL) += udl/ >> -obj-$(CONFIG_DRM_AST) += ast/ >> -obj-$(CONFIG_DRM_ARMADA) += armada/ >> +# device drivers. Please keep this list sorted alphabetically >> +obj-$(CONFIG_HSA_AMD)+= amd/amdkfd/ > > No mention of this exception (needs a comment), and no mention of what you > changed in v2 of the patch. Please fix and resend. will fix and resend. Best, -xinliang > -Daniel > >> +obj-$(CONFIG_DRM_AMDGPU) += amd/amdgpu/ >> +obj-$(CONFIG_DRM_ARMADA) += armada/ >> +obj-$(CONFIG_DRM_AST)+= ast/ >> obj-$(CONFIG_DRM_ATMEL_HLCDC)+= atmel-hlcdc/ >> -obj-$(CONFIG_DRM_RCAR_DU) += rcar-du/ >> -obj-$(CONFIG_DRM_SHMOBILE) +=shmobile/ >> -obj-y+= omapdrm/ >> -obj-y+= tilcdc/ >> -obj-$(CONFIG_DRM_QXL) += qxl/ >> -obj-$(CONFIG_DRM_BOCHS) += bochs/ >> -obj-$(CONFIG_DRM_VIRTIO_GPU) += virtio/ >> -obj-$(CONFIG_DRM_MSM) += msm/ >> -obj-$(CONFIG_DRM_TEGRA) += tegra/ >> -obj-$(CONFIG_DRM_STI) += sti/ >> -obj-$(CONFIG_DRM_IMX) += imx/ >> -obj-y+= i2c/ >> -obj-y+= panel/ >> -obj-y+= bridge/ >> -obj-$(CONFIG_DRM_FSL_DCU) += fsl-dcu/ >> -obj-$(CONFIG_DRM_ETNAVIV) += etnaviv/ >> +obj-$(CONFIG_DRM_BOCHS) += bochs/ >> +obj-y+= bridge/ >> +obj-$(CONFIG_DRM_CIRRUS_QEMU)+= cirrus/ >> +obj-$(CONFIG_DRM_ETNAVIV)+= etnaviv/ >> +obj-$(CONFIG_DRM_EXYNOS) += exynos/ >> +obj-$(CONFIG_DRM_FSL_DCU)+= fsl-dcu/ >> +obj-$(CONFIG_DRM_GMA500) +=
[PATCH 0/3] Deferr load of radeon/amdgpu until amdkfd is loaded
On 15 February 2016 at 19:04, Oded Gabbay wrote: > On Sun, Feb 14, 2016 at 2:58 PM, Daniel Vetter wrote: >> On Sun, Feb 14, 2016 at 11:16:52AM +0200, Oded Gabbay wrote: >>> Following Daniel's request, I spent some time removing the hard requirement >>> that radeon and amdgpu will always appear _after_ amdkfd in the drm >>> Makefile. >>> >>> This was done by modifing radeon/amdgpu to defer their loading if they >>> detect >>> that amdkfd is not loaded yet, in case the drivers are built inside the >>> kernel image. >>> >>> See the patch's individiual commit messages for more explanation. >>> >>> This patch-set was tested on a KAVERI machine, with multiple configurations: >>> >>> 1. radeon + amdgpu (CIK disabled) + amdkfd as kernel modules >>> 2. radeon + amdgpu (CIK disabled) + amdkfd inside the kernel image >>> 3. amdgpu (CIK enabled) + amdkfd inside the kernel image (radeon not >>> compiled) >>> 4. amdgpu (CIK enabled) inside the kernel image (radeon + amdkfd not >>> compiled) >>> 5. radeon + amdgpu (CIK disabled) as kernel modules (amdkfd not compiled) >> >> Care to throw one patch on top (maybe on top of the patch floating around) >> to reorder amdkfd to be alphabetical? Just to make sure this doesn't get >> broken again accidentally. Or maybe just pick up the other patch and adapt >> it so it's all in one series. >> >> Thanks, Daniel > > Hi Daniel, > > I thought about it and I think I prefer to leave the current order as > it is, for the reason that I observed the boot-up process is a little > bit faster when the deferred probing doesn't occur. This is probably > because all the moves between pending drivers list and active driver > list. > > Although this patch-set ensure that the kernel will boot successfully > with no regard to the order of amdkfd/radeon/amdgpu in the drm So, my drm make clean up patch should keep amdkfd in front of radeon/amdgpu? Best, -xinliang > makefile, I think that if the current order gives us a bit less boot > time then it is better to keep things as they are. > > Thanks, > > Oded > >>> >>> Thanks, >>> >>> Oded >>> >>> Oded Gabbay (3): >>> drm/amdkfd: Track when module's init is complete >>> drm/radeon: Return -EPROBE_DEFER when amdkfd not loaded >>> drm/amdgpu: Return -EPROBE_DEFER when amdkfd not loaded >>> >>> drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c | 57 >>> + >>> drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h | 2 +- >>> drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 10 - >>> drivers/gpu/drm/amd/amdkfd/kfd_module.c | 15 +-- >>> drivers/gpu/drm/amd/include/kgd_kfd_interface.h | 2 +- >>> drivers/gpu/drm/radeon/radeon_drv.c | 10 - >>> drivers/gpu/drm/radeon/radeon_kfd.c | 25 ++- >>> drivers/gpu/drm/radeon/radeon_kfd.h | 2 +- >>> 8 files changed, 64 insertions(+), 59 deletions(-) >>> >>> -- >>> 2.5.0 >>> >> >> -- >> Daniel Vetter >> Software Engineer, Intel Corporation >> http://blog.ffwll.ch > ___ > dri-devel mailing list > dri-devel at lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 0/3] Deferr load of radeon/amdgpu until amdkfd is loaded
On 15 February 2016 at 19:04, Oded Gabbay wrote: > On Sun, Feb 14, 2016 at 2:58 PM, Daniel Vetter wrote: >> On Sun, Feb 14, 2016 at 11:16:52AM +0200, Oded Gabbay wrote: >>> Following Daniel's request, I spent some time removing the hard requirement >>> that radeon and amdgpu will always appear _after_ amdkfd in the drm >>> Makefile. >>> >>> This was done by modifing radeon/amdgpu to defer their loading if they >>> detect >>> that amdkfd is not loaded yet, in case the drivers are built inside the >>> kernel image. >>> >>> See the patch's individiual commit messages for more explanation. >>> >>> This patch-set was tested on a KAVERI machine, with multiple configurations: >>> >>> 1. radeon + amdgpu (CIK disabled) + amdkfd as kernel modules >>> 2. radeon + amdgpu (CIK disabled) + amdkfd inside the kernel image >>> 3. amdgpu (CIK enabled) + amdkfd inside the kernel image (radeon not >>> compiled) >>> 4. amdgpu (CIK enabled) inside the kernel image (radeon + amdkfd not >>> compiled) >>> 5. radeon + amdgpu (CIK disabled) as kernel modules (amdkfd not compiled) >> >> Care to throw one patch on top (maybe on top of the patch floating around) >> to reorder amdkfd to be alphabetical? Just to make sure this doesn't get >> broken again accidentally. Or maybe just pick up the other patch and adapt >> it so it's all in one series. >> >> Thanks, Daniel > > Hi Daniel, > > I thought about it and I think I prefer to leave the current order as > it is, for the reason that I observed the boot-up process is a little > bit faster when the deferred probing doesn't occur. This is probably > because all the moves between pending drivers list and active driver > list. > > Although this patch-set ensure that the kernel will boot successfully > with no regard to the order of amdkfd/radeon/amdgpu in the drm > makefile, I think that if the current order gives us a bit less boot > time then it is better to keep things as they are. > > Thanks, > > Oded > >>> >>> Thanks, >>> >>> Oded >>> >>> Oded Gabbay (3): >>> drm/amdkfd: Track when module's init is complete >>> drm/radeon: Return -EPROBE_DEFER when amdkfd not loaded >>> drm/amdgpu: Return -EPROBE_DEFER when amdkfd not loaded >>> >>> drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c | 57 >>> + >>> drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h | 2 +- >>> drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 10 - >>> drivers/gpu/drm/amd/amdkfd/kfd_module.c | 15 +-- >>> drivers/gpu/drm/amd/include/kgd_kfd_interface.h | 2 +- >>> drivers/gpu/drm/radeon/radeon_drv.c | 10 - >>> drivers/gpu/drm/radeon/radeon_kfd.c | 25 ++- >>> drivers/gpu/drm/radeon/radeon_kfd.h | 2 +- >>> 8 files changed, 64 insertions(+), 59 deletions(-) >>> >>> -- >>> 2.5.0 >>> >> >> -- >> Daniel Vetter >> Software Engineer, Intel Corporation >> http://blog.ffwll.ch > ___ > dri-devel mailing list > dri-devel at lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH] dma-buf/fence: fix fence_is_later v2
On 23.02.2016 04:32, Alex Deucher wrote: > From: Christian König > > A fence is never later than itself. This caused a bunch of overhead for > AMDGPU. > > v2: simplify check as suggested by Michel. > > Signed-off-by: Christian König > Reviewed-by: Michel Dänzer > Reviewed-by: Alex Deucher > Signed-off-by: Alex Deucher > --- > include/linux/fence.h | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/include/linux/fence.h b/include/linux/fence.h > index bb52201..5aa95eb 100644 > --- a/include/linux/fence.h > +++ b/include/linux/fence.h > @@ -292,7 +292,7 @@ static inline bool fence_is_later(struct fence *f1, > struct fence *f2) > if (WARN_ON(f1->context != f2->context)) > return false; > > - return f1->seqno - f2->seqno < INT_MAX; > + return (int)(f1->seqno - f2->seqno) > 0; > } > > /** > According to scripts/get_maintainer.pl include/linux/fence.h this patch should be sent to: Sumit Semwal (maintainer:DMA BUFFER SHARING FRAMEWORK) linux-media at vger.kernel.org (open list:DMA BUFFER SHARING FRAMEWORK) dri-devel at lists.freedesktop.org (open list:DMA BUFFER SHARING FRAMEWORK) linaro-mm-sig at lists.linaro.org (moderated list:DMA BUFFER SHARING FRAMEWORK) linux-kernel at vger.kernel.org (open list) I'd add at least Sumit and the linaro-mm-sig list. -- Earthling Michel Dänzer | http://www.amd.com Libre software enthusiast | Mesa and X developer
[PATCH v5 11/11] arm64: dts: hisilicon: Add display subsystem DT nodes for hi6220
Add ade, dsi and adv7533 DT nodes for hikey board. Signed-off-by: Xinliang Liu --- arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts | 40 +++ arch/arm64/boot/dts/hisilicon/hi6220.dtsi | 55 ++ 2 files changed, 95 insertions(+) diff --git a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts index 818525197508..40239fba0572 100644 --- a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts +++ b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts @@ -39,3 +39,43 @@ { label = "LS-UART1"; }; + + { + status = "okay"; +}; + + { + status = "ok"; + + ports { + /* 1 for output port */ + port at 1 { + reg = <1>; + + dsi_out0: endpoint at 0 { + remote-endpoint = <_in>; + }; + }; + }; +}; + + { + #address-cells = <1>; + #size-cells = <0>; + status = "ok"; + + adv7533: adv7533 at 39 { + compatible = "adi,adv7533"; + reg = <0x39>; + interrupt-parent = <>; + interrupts = <1 2>; + pd-gpio = < 4 0>; + adi,dsi-lanes = <4>; + + port { + adv7533_in: endpoint { + remote-endpoint = <_out0>; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi index ad1f1ebcb05c..920ea68e791d 100644 --- a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi +++ b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi @@ -162,6 +162,11 @@ #clock-cells = <1>; }; + medianoc_ade: medianoc_ade at f452 { + compatible = "syscon"; + reg = <0x0 0xf452 0x0 0x4000>; + }; + uart0: uart at f8015000 { /* console */ compatible = "arm,pl011", "arm,primecell"; reg = <0x0 0xf8015000 0x0 0x1000>; @@ -209,5 +214,55 @@ clock-names = "uartclk", "apb_pclk"; status = "disabled"; }; + + ade: ade at f410 { + compatible = "hisilicon,hi6220-ade"; + reg = <0x0 0xf410 0x0 0x7800>; + reg-names = "ade_base"; + hisilicon,noc-syscon = <_ade>; + resets = <_ctrl MEDIA_ADE>; + interrupts = <0 115 4>; /* ldi interrupt */ + + clocks = <_ctrl HI6220_ADE_CORE>, +<_ctrl HI6220_CODEC_JPEG>, +<_ctrl HI6220_ADE_PIX_SRC>; + /*clock name*/ + clock-names = "clk_ade_core", + "clk_codec_jpeg", + "clk_ade_pix"; + + assigned-clocks = <_ctrl HI6220_ADE_CORE>, + <_ctrl HI6220_CODEC_JPEG>; + assigned-clock-rates = <36000>, <28800>; + dma-coherent; + status = "disabled"; + + port { + ade_out: endpoint { + remote-endpoint = <_in>; + }; + }; + }; + + dsi: dsi at f4107800 { + compatible = "hisilicon,hi6220-dsi"; + reg = <0x0 0xf4107800 0x0 0x100>; + clocks = <_ctrl HI6220_DSI_PCLK>; + clock-names = "pclk_dsi"; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + /* 0 for input port */ + port at 0 { + reg = <0>; + dsi_in: endpoint { + remote-endpoint = <_out>; + }; + }; + }; + }; }; }; -- 1.9.1
[PATCH v5 10/11] MAINTAINERS: Add maintainer for hisilicon DRM driver
Add maintainer and reviewer for hisilicon DRM driver. v5: None. v4: - Add Chen Feng as Designated reviewer. v3: First version. Signed-off-by: Xinliang Liu --- MAINTAINERS | 10 ++ 1 file changed, 10 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 4978dc19a4d2..b94ac713916a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3774,6 +3774,16 @@ S: Maintained F: drivers/gpu/drm/gma500 F: include/drm/gma500* +DRM DRIVERS FOR HISILICON +M: Xinliang Liu +R: Xinwei Kong +R: Chen Feng +L: dri-devel at lists.freedesktop.org +T: git git://github.com/xin3liang/linux.git +S: Maintained +F: drivers/gpu/drm/hisilicon +F: Documentation/devicetree/bindings/display/hisilicon + DRM DRIVERS FOR NVIDIA TEGRA M: Thierry Reding M: Terje Bergström -- 1.9.1
[PATCH v5 09/11] drm/hisilicon: Add support for external bridge
Add support for external HDMI bridge. v5: None. v4: None. v3: - Fix a typo: s/exteranl/external. v2: - Remove abtraction layer. Signed-off-by: Xinliang Liu --- drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c | 52 1 file changed, 52 insertions(+) diff --git a/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c b/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c index 2837af01e935..1342d84d7c68 100644 --- a/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c +++ b/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c @@ -79,6 +79,7 @@ struct dsi_hw_ctx { struct dw_dsi { struct drm_encoder encoder; + struct drm_bridge *bridge; struct mipi_dsi_host host; struct drm_display_mode cur_mode; struct dsi_hw_ctx *ctx; @@ -688,6 +689,25 @@ static int dsi_host_init(struct device *dev, struct dw_dsi *dsi) return 0; } +static int dsi_bridge_init(struct drm_device *dev, struct dw_dsi *dsi) +{ + struct drm_encoder *encoder = >encoder; + struct drm_bridge *bridge = dsi->bridge; + int ret; + + /* associate the bridge to dsi encoder */ + encoder->bridge = bridge; + bridge->encoder = encoder; + + ret = drm_bridge_attach(dev, bridge); + if (ret) { + DRM_ERROR("failed to attach external bridge\n"); + return ret; + } + + return 0; +} + static int dsi_bind(struct device *dev, struct device *master, void *data) { struct dsi_data *ddata = dev_get_drvdata(dev); @@ -703,6 +723,10 @@ static int dsi_bind(struct device *dev, struct device *master, void *data) if (ret) return ret; + ret = dsi_bridge_init(drm_dev, dsi); + if (ret) + return ret; + return 0; } @@ -719,8 +743,36 @@ static const struct component_ops dsi_ops = { static int dsi_parse_dt(struct platform_device *pdev, struct dw_dsi *dsi) { struct dsi_hw_ctx *ctx = dsi->ctx; + struct device_node *np = pdev->dev.of_node; + struct device_node *endpoint, *bridge_node; + struct drm_bridge *bridge; struct resource *res; + /* +* Get the endpoint node. In our case, dsi has one output port1 +* to which the external HDMI bridge is connected. +*/ + endpoint = of_graph_get_endpoint_by_regs(np, 1, -1); + if (!endpoint) { + DRM_ERROR("no valid endpoint node\n"); + return -ENODEV; + } + of_node_put(endpoint); + + bridge_node = of_graph_get_remote_port_parent(endpoint); + if (!bridge_node) { + DRM_ERROR("no valid bridge node\n"); + return -ENODEV; + } + of_node_put(bridge_node); + + bridge = of_drm_find_bridge(bridge_node); + if (!bridge) { + DRM_INFO("wait for external HDMI bridge driver.\n"); + return -EPROBE_DEFER; + } + dsi->bridge = bridge; + ctx->dsi_cfg_clk = devm_clk_get(>dev, "pclk_dsi"); if (IS_ERR(ctx->dsi_cfg_clk)) { DRM_ERROR("failed to get dsi plck clock\n"); -- 1.9.1
[PATCH v5 08/11] drm/hisilicon: Add designware dsi host driver
Add DesignWare dsi host driver for hi6220 SoC. v5: None. v4: None. v3: None. v2: - Remove abtraction layer. Signed-off-by: Xinliang Liu --- drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c | 50 1 file changed, 50 insertions(+) diff --git a/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c b/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c index 7c9423537b71..2837af01e935 100644 --- a/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c +++ b/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c @@ -79,6 +79,7 @@ struct dsi_hw_ctx { struct dw_dsi { struct drm_encoder encoder; + struct mipi_dsi_host host; struct drm_display_mode cur_mode; struct dsi_hw_ctx *ctx; struct mipi_phy_params phy; @@ -642,6 +643,51 @@ static int dw_drm_encoder_init(struct device *dev, return 0; } +static int dsi_host_attach(struct mipi_dsi_host *host, + struct mipi_dsi_device *mdsi) +{ + struct dw_dsi *dsi = host_to_dsi(host); + + if (mdsi->lanes < 1 || mdsi->lanes > 4) { + DRM_ERROR("dsi device params invalid\n"); + return -EINVAL; + } + + dsi->lanes = mdsi->lanes; + dsi->format = mdsi->format; + dsi->mode_flags = mdsi->mode_flags; + + return 0; +} + +static int dsi_host_detach(struct mipi_dsi_host *host, + struct mipi_dsi_device *mdsi) +{ + /* do nothing */ + return 0; +} + +static const struct mipi_dsi_host_ops dsi_host_ops = { + .attach = dsi_host_attach, + .detach = dsi_host_detach, +}; + +static int dsi_host_init(struct device *dev, struct dw_dsi *dsi) +{ + struct mipi_dsi_host *host = >host; + int ret; + + host->dev = dev; + host->ops = _host_ops; + ret = mipi_dsi_host_register(host); + if (ret) { + DRM_ERROR("failed to register dsi host\n"); + return ret; + } + + return 0; +} + static int dsi_bind(struct device *dev, struct device *master, void *data) { struct dsi_data *ddata = dev_get_drvdata(dev); @@ -653,6 +699,10 @@ static int dsi_bind(struct device *dev, struct device *master, void *data) if (ret) return ret; + ret = dsi_host_init(dev, dsi); + if (ret) + return ret; + return 0; } -- 1.9.1
[PATCH v5 07/11] drm/hisilicon: Add designware dsi encoder driver
Add DesignWare MIPI DSI Host Controller v1.02 encoder driver for hi6220 SoC. v5: None. v4: None. v3: - Rename file name to dw_drm_dsi.c - Make encoder type as DRM_MODE_ENCODER_DSI. - A few cleanup. v2: - Remove abtraction layer. Signed-off-by: Xinliang Liu Signed-off-by: Xinwei Kong Signed-off-by: Andy Green --- drivers/gpu/drm/hisilicon/kirin/Kconfig | 1 + drivers/gpu/drm/hisilicon/kirin/Makefile | 3 +- drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c | 743 +++ drivers/gpu/drm/hisilicon/kirin/dw_dsi_reg.h | 83 +++ 4 files changed, 829 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c create mode 100644 drivers/gpu/drm/hisilicon/kirin/dw_dsi_reg.h diff --git a/drivers/gpu/drm/hisilicon/kirin/Kconfig b/drivers/gpu/drm/hisilicon/kirin/Kconfig index 3ac4b8edeac1..de0d454c5c13 100644 --- a/drivers/gpu/drm/hisilicon/kirin/Kconfig +++ b/drivers/gpu/drm/hisilicon/kirin/Kconfig @@ -4,6 +4,7 @@ config DRM_HISI_KIRIN select DRM_KMS_HELPER select DRM_GEM_CMA_HELPER select DRM_KMS_CMA_HELPER + select DRM_MIPI_DSI help Choose this option if you have a hisilicon Kirin chipsets(hi6220). If M is selected the module will be called kirin-drm. diff --git a/drivers/gpu/drm/hisilicon/kirin/Makefile b/drivers/gpu/drm/hisilicon/kirin/Makefile index 2a61ab006ddb..5dcd0d4328b6 100644 --- a/drivers/gpu/drm/hisilicon/kirin/Makefile +++ b/drivers/gpu/drm/hisilicon/kirin/Makefile @@ -1,4 +1,5 @@ kirin-drm-y := kirin_drm_drv.o \ - kirin_drm_ade.o + kirin_drm_ade.o \ + dw_drm_dsi.o obj-$(CONFIG_DRM_HISI_KIRIN) += kirin-drm.o diff --git a/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c b/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c new file mode 100644 index ..7c9423537b71 --- /dev/null +++ b/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c @@ -0,0 +1,743 @@ +/* + * DesignWare MIPI DSI Host Controller v1.02 driver + * + * Copyright (c) 2016 Linaro Limited. + * Copyright (c) 2014-2016 Hisilicon Limited. + * + * Author: + * Xinliang Liu + * Xinliang Liu + * Xinwei Kong + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "dw_dsi_reg.h" + +#define MAX_TX_ESC_CLK(10) +#define ROUND(x, y) ((x) / (y) + ((x) % (y) * 10 / (y) >= 5 ? 1 : 0)) +#define PHY_REF_CLK_RATE 1920 +#define PHY_REF_CLK_PERIOD_PS (10 / (PHY_REF_CLK_RATE / 1000)) + +#define encoder_to_dsi(encoder) \ + container_of(encoder, struct dw_dsi, encoder) +#define host_to_dsi(host) \ + container_of(host, struct dw_dsi, host) + +struct mipi_phy_params { + u32 clk_t_lpx; + u32 clk_t_hs_prepare; + u32 clk_t_hs_zero; + u32 clk_t_hs_trial; + u32 clk_t_wakeup; + u32 data_t_lpx; + u32 data_t_hs_prepare; + u32 data_t_hs_zero; + u32 data_t_hs_trial; + u32 data_t_ta_go; + u32 data_t_ta_get; + u32 data_t_wakeup; + u32 hstx_ckg_sel; + u32 pll_fbd_div5f; + u32 pll_fbd_div1f; + u32 pll_fbd_2p; + u32 pll_enbwt; + u32 pll_fbd_p; + u32 pll_fbd_s; + u32 pll_pre_div1p; + u32 pll_pre_p; + u32 pll_vco_750M; + u32 pll_lpf_rs; + u32 pll_lpf_cs; + u32 clklp2hs_time; + u32 clkhs2lp_time; + u32 lp2hs_time; + u32 hs2lp_time; + u32 clk_to_data_delay; + u32 data_to_clk_delay; + u32 lane_byte_clk_kHz; + u32 clk_division; +}; + +struct dsi_hw_ctx { + void __iomem *base; + struct clk *dsi_cfg_clk; +}; + +struct dw_dsi { + struct drm_encoder encoder; + struct drm_display_mode cur_mode; + struct dsi_hw_ctx *ctx; + struct mipi_phy_params phy; + + u32 lanes; + enum mipi_dsi_pixel_format format; + unsigned long mode_flags; + bool enable; +}; + +struct dsi_data { + struct dw_dsi dsi; + struct dsi_hw_ctx ctx; +}; + +struct dsi_phy_range { + u32 min_range_kHz; + u32 max_range_kHz; + u32 pll_vco_750M; + u32 hstx_ckg_sel; +}; + +static const struct dsi_phy_range dphy_range_info[] = { + { 46875,62500, 1,7 }, + { 62500,93750, 0,7 }, + { 93750, 125000, 1,6 }, + { 125000, 187500, 0,6 }, + { 187500, 25, 1,5 }, + { 25, 375000, 0,5 }, + { 375000, 50, 1,4 }, + { 50, 75, 0,4 }, + { 75, 100, 1,0 }, + { 100, 150, 0,0 } +}; + +static void dsi_get_phy_params(u32 phy_freq_kHz, + struct mipi_phy_params *phy) +{ + u32 ui = 0; + u32
[PATCH v5 06/11] drm/hisilicon: Add cma fbdev and hotplug
Add cma Fbdev, Fbdev is legency and optional, you can enable/disable it by configuring DRM_FBDEV_EMULATION. Add hotplug. v5: None. v4: None. v3: None. v2: - Use CONFIG_DRM_FBDEV_EMULATION instead of CONFIG_DRM_HISI_FBDEV. Signed-off-by: Xinliang Liu --- drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c | 34 + drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.h | 3 +++ 2 files changed, 37 insertions(+) diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c index 723888feb760..d57b9fa0ce3e 100644 --- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c +++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "kirin_drm_drv.h" @@ -32,6 +33,13 @@ static int kirin_drm_kms_cleanup(struct drm_device *dev) { struct kirin_drm_private *priv = dev->dev_private; +#ifdef CONFIG_DRM_FBDEV_EMULATION + if (priv->fbdev) { + drm_fbdev_cma_fini(priv->fbdev); + priv->fbdev = NULL; + } +#endif + drm_kms_helper_poll_fini(dev); drm_vblank_cleanup(dev); dc_ops->cleanup(dev); drm_mode_config_cleanup(dev); @@ -41,8 +49,28 @@ static int kirin_drm_kms_cleanup(struct drm_device *dev) return 0; } +#ifdef CONFIG_DRM_FBDEV_EMULATION +static void kirin_fbdev_output_poll_changed(struct drm_device *dev) +{ + struct kirin_drm_private *priv = dev->dev_private; + + if (priv->fbdev) { + drm_fbdev_cma_hotplug_event(priv->fbdev); + } else { + priv->fbdev = drm_fbdev_cma_init(dev, 32, + dev->mode_config.num_crtc, + dev->mode_config.num_connector); + if (IS_ERR(priv->fbdev)) + priv->fbdev = NULL; + } +} +#endif + static const struct drm_mode_config_funcs kirin_drm_mode_config_funcs = { .fb_create = drm_fb_cma_create, +#ifdef CONFIG_DRM_FBDEV_EMULATION + .output_poll_changed = kirin_fbdev_output_poll_changed, +#endif .atomic_check = drm_atomic_helper_check, .atomic_commit = drm_atomic_helper_commit, }; @@ -98,6 +126,12 @@ static int kirin_drm_kms_init(struct drm_device *dev) /* reset all the states of crtc/plane/encoder/connector */ drm_mode_config_reset(dev); + /* init kms poll for handling hpd */ + drm_kms_helper_poll_init(dev); + + /* force detection after connectors init */ + (void)drm_helper_hpd_irq_event(dev); + return 0; err_unbind_all: diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.h b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.h index 5a05ad6a81db..1a07caf8e7f4 100644 --- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.h +++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.h @@ -21,6 +21,9 @@ struct kirin_dc_ops { struct kirin_drm_private { struct drm_crtc *crtc[MAX_CRTC]; +#ifdef CONFIG_DRM_FBDEV_EMULATION + struct drm_fbdev_cma *fbdev; +#endif }; extern const struct kirin_dc_ops ade_dc_ops; -- 1.9.1
[PATCH v5 05/11] drm/hisilicon: Add vblank driver for ADE
Add vblank irq handle. v5: None. v4: None. v3: - Remove hisi_get_crtc_from_index func. - A few cleanup. v2: - Remove abtraction layer. Signed-off-by: Xinliang Liu --- drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c | 62 + drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c | 14 +- 2 files changed, 75 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c index fae5f0afadb8..918897fa4e9e 100644 --- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c +++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c @@ -292,6 +292,59 @@ static void ade_set_medianoc_qos(struct ade_crtc *acrtc) SOCKET_QOS_EN, SOCKET_QOS_EN); } +static int ade_enable_vblank(struct drm_device *dev, unsigned int pipe) +{ + struct kirin_drm_private *priv = dev->dev_private; + struct ade_crtc *acrtc = to_ade_crtc(priv->crtc[pipe]); + struct ade_hw_ctx *ctx = acrtc->ctx; + void __iomem *base = ctx->base; + + if (!ctx->power_on) + (void)ade_power_up(ctx); + + ade_update_bits(base + LDI_INT_EN, FRAME_END_INT_EN_OFST, + MASK(1), 1); + + return 0; +} + +static void ade_disable_vblank(struct drm_device *dev, unsigned int pipe) +{ + struct kirin_drm_private *priv = dev->dev_private; + struct ade_crtc *acrtc = to_ade_crtc(priv->crtc[pipe]); + struct ade_hw_ctx *ctx = acrtc->ctx; + void __iomem *base = ctx->base; + + if (!ctx->power_on) { + DRM_ERROR("power is down! vblank disable fail\n"); + return; + } + + ade_update_bits(base + LDI_INT_EN, FRAME_END_INT_EN_OFST, + MASK(1), 0); +} + +static irqreturn_t ade_irq_handler(int irq, void *data) +{ + struct ade_crtc *acrtc = data; + struct ade_hw_ctx *ctx = acrtc->ctx; + struct drm_crtc *crtc = >base; + void __iomem *base = ctx->base; + u32 status; + + status = readl(base + LDI_MSK_INT); + DRM_DEBUG_VBL("LDI IRQ: status=0x%X\n", status); + + /* vblank irq */ + if (status & BIT(FRAME_END_INT_EN_OFST)) { + ade_update_bits(base + LDI_INT_CLR, FRAME_END_INT_EN_OFST, + MASK(1), 1); + drm_crtc_handle_vblank(crtc); + } + + return IRQ_HANDLED; +} + static void ade_display_enable(struct ade_crtc *acrtc) { struct ade_hw_ctx *ctx = acrtc->ctx; @@ -967,6 +1020,15 @@ int ade_drm_init(struct drm_device *dev) if (ret) return ret; + /* vblank irq init */ + ret = devm_request_irq(dev->dev, ctx->irq, ade_irq_handler, + DRIVER_IRQ_SHARED, dev->driver->name, acrtc); + if (ret) + return ret; + dev->driver->get_vblank_counter = drm_vblank_no_hw_counter; + dev->driver->enable_vblank = ade_enable_vblank; + dev->driver->disable_vblank = ade_disable_vblank; + return 0; } diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c index 055729c1889c..723888feb760 100644 --- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c +++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c @@ -32,6 +32,7 @@ static int kirin_drm_kms_cleanup(struct drm_device *dev) { struct kirin_drm_private *priv = dev->dev_private; + drm_vblank_cleanup(dev); dc_ops->cleanup(dev); drm_mode_config_cleanup(dev); devm_kfree(dev->dev, priv); @@ -85,11 +86,22 @@ static int kirin_drm_kms_init(struct drm_device *dev) goto err_dc_cleanup; } + /* vblank init */ + ret = drm_vblank_init(dev, dev->mode_config.num_crtc); + if (ret) { + DRM_ERROR("failed to initialize vblank.\n"); + goto err_unbind_all; + } + /* with irq_enabled = true, we can use the vblank feature. */ + dev->irq_enabled = true; + /* reset all the states of crtc/plane/encoder/connector */ drm_mode_config_reset(dev); return 0; +err_unbind_all: + component_unbind_all(dev->dev, dev); err_dc_cleanup: dc_ops->cleanup(dev); err_mode_config_cleanup: @@ -123,7 +135,7 @@ static int kirin_gem_cma_dumb_create(struct drm_file *file, static struct drm_driver kirin_drm_driver = { .driver_features= DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME | - DRIVER_ATOMIC, + DRIVER_ATOMIC | DRIVER_HAVE_IRQ, .fops = _drm_fops, .set_busid = drm_platform_set_busid, -- 1.9.1
[PATCH v5 04/11] drm/hisilicon: Add plane driver for ADE
Add plane funcs and helper funcs for ADE. v5: None. v4: None. v3: - A few cleanup. v2: - Remove abtraction layer. Signed-off-by: Xinliang Liu --- drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c | 535 +++- 1 file changed, 534 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c index dbdeb1fc33e3..fae5f0afadb8 100644 --- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c +++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c @@ -27,13 +27,23 @@ #include #include #include +#include +#include +#include #include "kirin_drm_drv.h" #include "kirin_ade_reg.h" +#define PRIMARY_CH ADE_CH1 /* primary plane */ +#define OUT_OVLY ADE_OVLY2 /* output overlay compositor */ +#define ADE_DEBUG 1 + #define to_ade_crtc(crtc) \ container_of(crtc, struct ade_crtc, base) +#define to_ade_plane(plane) \ + container_of(plane, struct ade_plane, base) + struct ade_hw_ctx { void __iomem *base; struct regmap *noc_regmap; @@ -52,11 +62,76 @@ struct ade_crtc { u32 out_format; }; +struct ade_plane { + struct drm_plane base; + void *ctx; + u8 ch; /* channel */ +}; + struct ade_data { struct ade_crtc acrtc; + struct ade_plane aplane[ADE_CH_NUM]; struct ade_hw_ctx ctx; }; +/* ade-format info: */ +struct ade_format { + u32 pixel_format; + enum ade_fb_format ade_format; +}; + +static const struct ade_format ade_formats[] = { + /* 16bpp RGB: */ + { DRM_FORMAT_RGB565, ADE_RGB_565 }, + { DRM_FORMAT_BGR565, ADE_BGR_565 }, + /* 24bpp RGB: */ + { DRM_FORMAT_RGB888, ADE_RGB_888 }, + { DRM_FORMAT_BGR888, ADE_BGR_888 }, + /* 32bpp [A]RGB: */ + { DRM_FORMAT_XRGB, ADE_XRGB_ }, + { DRM_FORMAT_XBGR, ADE_XBGR_ }, + { DRM_FORMAT_RGBA, ADE_RGBA_ }, + { DRM_FORMAT_BGRA, ADE_BGRA_ }, + { DRM_FORMAT_ARGB, ADE_ARGB_ }, + { DRM_FORMAT_ABGR, ADE_ABGR_ }, +}; + +static const u32 channel_formats1[] = { + /* channel 1,2,3,4 */ + DRM_FORMAT_RGB565, DRM_FORMAT_BGR565, DRM_FORMAT_RGB888, + DRM_FORMAT_BGR888, DRM_FORMAT_XRGB, DRM_FORMAT_XBGR, + DRM_FORMAT_RGBA, DRM_FORMAT_BGRA, DRM_FORMAT_ARGB, + DRM_FORMAT_ABGR +}; + +u32 ade_get_channel_formats(u8 ch, const u32 **formats) +{ + switch (ch) { + case ADE_CH1: + *formats = channel_formats1; + return ARRAY_SIZE(channel_formats1); + default: + DRM_ERROR("no this channel %d\n", ch); + *formats = NULL; + return 0; + } +} + +/* convert from fourcc format to ade format */ +static u32 ade_get_format(u32 pixel_format) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(ade_formats); i++) + if (ade_formats[i].pixel_format == pixel_format) + return ade_formats[i].ade_format; + + /* not found */ + DRM_ERROR("Not found pixel format!!fourcc_format= %d\n", + pixel_format); + return ADE_FORMAT_NOT_SUPPORT; +} + static void ade_update_reload_bit(void __iomem *base, u32 bit_num, u32 val) { u32 bit_ofst, reg_num; @@ -89,7 +164,7 @@ static void ade_init(struct ade_hw_ctx *ctx) /* clear overlay */ writel(0, base + ADE_OVLY1_TRANS_CFG); writel(0, base + ADE_OVLY_CTL); - writel(0, base + ADE_OVLYX_CTL(ADE_OVLY2)); + writel(0, base + ADE_OVLYX_CTL(OUT_OVLY)); /* clear reset and reload regs */ writel(MASK(32), base + ADE_SOFT_RST_SEL(0)); writel(MASK(32), base + ADE_SOFT_RST_SEL(1)); @@ -147,6 +222,10 @@ static void ade_ldi_set_mode(struct ade_crtc *acrtc, mode->clock * 1000, ret); adj_mode->clock = clk_get_rate(ctx->ade_pix_clk) / 1000; + /* set overlay compositor output size */ + writel(((width - 1) << OUTPUT_XSIZE_OFST) | (height - 1), + base + ADE_OVLY_OUTPUT_SIZE(OUT_OVLY)); + /* ctran6 setting */ writel(CTRAN_BYPASS_ON, base + ADE_CTRAN_DIS(ADE_CTRAN6)); /* the configured value is actual value - 1 */ @@ -219,6 +298,10 @@ static void ade_display_enable(struct ade_crtc *acrtc) void __iomem *base = ctx->base; u32 out_fmt = acrtc->out_format; + /* enable output overlay compositor */ + writel(ADE_ENABLE, base + ADE_OVLYX_CTL(OUT_OVLY)); + ade_update_reload_bit(base, OVLY_OFST + OUT_OVLY, 0); + /* display source setting */ writel(DISP_SRC_OVLY2, base + ADE_DISP_SRC_CFG); @@ -232,6 +315,97 @@ static void ade_display_enable(struct ade_crtc *acrtc) writel(DSI_PCLK_ON, base + LDI_HDMI_DSI_GT); } +#if ADE_DEBUG +static void ade_rdma_dump_regs(void __iomem *base, u32 ch) +{ + u32 reg_ctrl, reg_addr, reg_size, reg_stride, reg_space, reg_en; + u32 val; +
[PATCH v5 03/11] drm/hisilicon: Add crtc driver for ADE
Add crtc funcs and helper funcs for ADE. v5: - Use syscon to access ADE media NOC QoS registers instread of directly writing registers. - Use reset controller to reset ADE instead of directly writing registers. v4: None. v3: - Make ade as the master driver. - Use port to connect with encoder. - A few cleanup. v2: - Remove abtraction layer. Signed-off-by: Xinliang Liu --- drivers/gpu/drm/hisilicon/kirin/Makefile| 3 +- drivers/gpu/drm/hisilicon/kirin/kirin_ade_reg.h | 290 +++ drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c | 452 drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c | 15 + drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.h | 8 + 5 files changed, 767 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/hisilicon/kirin/kirin_ade_reg.h create mode 100644 drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c diff --git a/drivers/gpu/drm/hisilicon/kirin/Makefile b/drivers/gpu/drm/hisilicon/kirin/Makefile index cb346de47d48..2a61ab006ddb 100644 --- a/drivers/gpu/drm/hisilicon/kirin/Makefile +++ b/drivers/gpu/drm/hisilicon/kirin/Makefile @@ -1,3 +1,4 @@ -kirin-drm-y := kirin_drm_drv.o +kirin-drm-y := kirin_drm_drv.o \ + kirin_drm_ade.o obj-$(CONFIG_DRM_HISI_KIRIN) += kirin-drm.o diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_ade_reg.h b/drivers/gpu/drm/hisilicon/kirin/kirin_ade_reg.h new file mode 100644 index ..eb444b899c7b --- /dev/null +++ b/drivers/gpu/drm/hisilicon/kirin/kirin_ade_reg.h @@ -0,0 +1,290 @@ +/* + * Copyright (c) 2016 Linaro Limited. + * Copyright (c) 2014-2016 Hisilicon Limited. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#ifndef __KIRIN_ADE_REG_H__ +#define __KIRIN_ADE_REG_H__ + +/* + * ADE Registers + */ +#define MASK(x)(BIT(x) - 1) + +#define ADE_CTRL 0x0004 +#define FRM_END_START_OFST 0 +#define FRM_END_START_MASK MASK(2) +#define ADE_CTRL1 0x008C +#define AUTO_CLK_GATE_EN_OFST 0 +#define AUTO_CLK_GATE_EN BIT(0) +#define ADE_ROT_SRC_CFG0x0010 +#define ADE_DISP_SRC_CFG 0x0018 +#define ADE_WDMA2_SRC_CFG 0x001C +#define ADE_SEC_OVLY_SRC_CFG 0x0020 +#define ADE_WDMA3_SRC_CFG 0x0024 +#define ADE_OVLY1_TRANS_CFG0x002C +#define ADE_EN 0x0100 +#define ADE_DISABLE0 +#define ADE_ENABLE 1 +#define INTR_MASK_CPU(x) (0x0C10 + (x) * 0x4) +#define ADE_FRM_DISGARD_CTRL 0x00A4 +/* reset and reload regs */ +#define ADE_SOFT_RST_SEL(x)(0x0078 + (x) * 0x4) +#define ADE_RELOAD_DIS(x) (0x00AC + (x) * 0x4) +#define RDMA_OFST 0 +#define CLIP_OFST 15 +#define SCL_OFST 21 +#define CTRAN_OFST 24 +#define OVLY_OFST 37 /* 32+5 */ +/* channel regs */ +#define RD_CH_PE(x)(0x1000 + (x) * 0x80) +#define RD_CH_CTRL(x) (0x1004 + (x) * 0x80) +#define RD_CH_ADDR(x) (0x1008 + (x) * 0x80) +#define RD_CH_SIZE(x) (0x100C + (x) * 0x80) +#define RD_CH_STRIDE(x)(0x1010 + (x) * 0x80) +#define RD_CH_SPACE(x) (0x1014 + (x) * 0x80) +#define RD_CH_PARTIAL_SIZE(x) (0x1018 + (x) * 0x80) +#define RD_CH_PARTIAL_SPACE(x) (0x101C + (x) * 0x80) +#define RD_CH_EN(x)(0x1020 + (x) * 0x80) +#define RD_CH_STATUS(x)(0x1024 + (x) * 0x80) +#define RD_CH_DISP_CTRL0x1404 +#define RD_CH_DISP_ADDR0x1408 +#define RD_CH_DISP_SIZE0x140C +#define RD_CH_DISP_STRIDE 0x1410 +#define RD_CH_DISP_SPACE 0x1414 +#define RD_CH_DISP_EN 0x142C +/* clip regs */ +#define ADE_CLIP_DISABLE(x)(0x6800 + (x) * 0x100) +#define ADE_CLIP_SIZE0(x) (0x6804 + (x) * 0x100) +#define ADE_CLIP_SIZE1(x) (0x6808 + (x) * 0x100) +#define ADE_CLIP_SIZE2(x) (0x680C + (x) * 0x100) +#define ADE_CLIP_CFG_OK(x) (0x6810 + (x) * 0x100) +/* scale regs */ +#define ADE_SCL1_MUX_CFG 0x000C +#define ADE_SCL2_SRC_CFG 0x0014 +#define ADE_SCL3_MUX_CFG 0x0008 +#define ADE_SCL_CTRL(x)(0x3000 + (x) * 0x800) +#define ADE_SCL_HSP(x) (0x3004 + (x) * 0x800) +#define ADE_SCL_UV_HSP(x) (0x3008 + (x) * 0x800) +#define ADE_SCL_VSP(x) (0x300C + (x) * 0x800) +#define ADE_SCL_UV_VSP(x) (0x3010 + (x) * 0x800) +#define ADE_SCL_ORES(x)(0x3014 + (x) *
[PATCH v5 02/11] drm/hisilicon: Add hisilicon kirin drm master driver
Add kirin DRM master driver for hi6220 SoC which used in HiKey board. Add dumb buffer feature. Add prime dmabuf feature. v5: None. v4: None. v3: - Move and rename all the files to kirin sub-directory. So that we could separate different seires SoCs' driver. - Replace drm_platform_init, load, unload implementation. v2: - Remove abtraction layer. Signed-off-by: Xinliang Liu --- drivers/gpu/drm/Kconfig | 2 + drivers/gpu/drm/Makefile| 1 + drivers/gpu/drm/hisilicon/Kconfig | 5 + drivers/gpu/drm/hisilicon/Makefile | 5 + drivers/gpu/drm/hisilicon/kirin/Kconfig | 9 + drivers/gpu/drm/hisilicon/kirin/Makefile| 3 + drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c | 321 drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.h | 20 ++ 8 files changed, 366 insertions(+) create mode 100644 drivers/gpu/drm/hisilicon/Kconfig create mode 100644 drivers/gpu/drm/hisilicon/Makefile create mode 100644 drivers/gpu/drm/hisilicon/kirin/Kconfig create mode 100644 drivers/gpu/drm/hisilicon/kirin/Makefile create mode 100644 drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c create mode 100644 drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.h diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index b50ae60f5f50..f5c5656e2547 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -277,3 +277,5 @@ source "drivers/gpu/drm/imx/Kconfig" source "drivers/gpu/drm/vc4/Kconfig" source "drivers/gpu/drm/etnaviv/Kconfig" + +source "drivers/gpu/drm/hisilicon/Kconfig" diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 61766dec6a8d..60554832079c 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -74,3 +74,4 @@ obj-y += panel/ obj-y += bridge/ obj-$(CONFIG_DRM_FSL_DCU) += fsl-dcu/ obj-$(CONFIG_DRM_ETNAVIV) += etnaviv/ +obj-y += hisilicon/ diff --git a/drivers/gpu/drm/hisilicon/Kconfig b/drivers/gpu/drm/hisilicon/Kconfig new file mode 100644 index ..558c61b1b8e8 --- /dev/null +++ b/drivers/gpu/drm/hisilicon/Kconfig @@ -0,0 +1,5 @@ +# +# hisilicon drm device configuration. +# Please keep this list sorted alphabetically + +source "drivers/gpu/drm/hisilicon/kirin/Kconfig" diff --git a/drivers/gpu/drm/hisilicon/Makefile b/drivers/gpu/drm/hisilicon/Makefile new file mode 100644 index ..e3f6d493c996 --- /dev/null +++ b/drivers/gpu/drm/hisilicon/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for hisilicon drm drivers. +# Please keep this list sorted alphabetically + +obj-$(CONFIG_DRM_HISI_KIRIN) += kirin/ diff --git a/drivers/gpu/drm/hisilicon/kirin/Kconfig b/drivers/gpu/drm/hisilicon/kirin/Kconfig new file mode 100644 index ..3ac4b8edeac1 --- /dev/null +++ b/drivers/gpu/drm/hisilicon/kirin/Kconfig @@ -0,0 +1,9 @@ +config DRM_HISI_KIRIN + tristate "DRM Support for Hisilicon Kirin series SoCs Platform" + depends on DRM + select DRM_KMS_HELPER + select DRM_GEM_CMA_HELPER + select DRM_KMS_CMA_HELPER + help + Choose this option if you have a hisilicon Kirin chipsets(hi6220). + If M is selected the module will be called kirin-drm. diff --git a/drivers/gpu/drm/hisilicon/kirin/Makefile b/drivers/gpu/drm/hisilicon/kirin/Makefile new file mode 100644 index ..cb346de47d48 --- /dev/null +++ b/drivers/gpu/drm/hisilicon/kirin/Makefile @@ -0,0 +1,3 @@ +kirin-drm-y := kirin_drm_drv.o + +obj-$(CONFIG_DRM_HISI_KIRIN) += kirin-drm.o diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c new file mode 100644 index ..789ebd1f5922 --- /dev/null +++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c @@ -0,0 +1,321 @@ +/* + * Hisilicon Kirin SoCs drm master driver + * + * Copyright (c) 2016 Linaro Limited. + * Copyright (c) 2014-2016 Hisilicon Limited. + * + * Author: + * Xinliang Liu + * Xinliang Liu + * Xinwei Kong + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include "kirin_drm_drv.h" + +static struct kirin_dc_ops *dc_ops; + +static int kirin_drm_kms_cleanup(struct drm_device *dev) +{ + dc_ops->cleanup(dev); + drm_mode_config_cleanup(dev); + + return 0; +} + +static const struct drm_mode_config_funcs kirin_drm_mode_config_funcs = { + .fb_create = drm_fb_cma_create, + .atomic_check = drm_atomic_helper_check, + .atomic_commit = drm_atomic_helper_commit, +}; + +static void kirin_drm_mode_config_init(struct drm_device *dev) +{ + dev->mode_config.min_width = 0; + dev->mode_config.min_height = 0; + + dev->mode_config.max_width = 2048; +