[PATCH] drm: bridge: dw-hdmi: add ASoC dependency

2016-11-25 Thread Arnd Bergmann
The newly added sound driver depends on SND_SOC_HDMI_CODEC, which in
turn only makes sense when ASoC is enabled, as shown by this warning:

warning: (DRM_MSM && DRM_STI && DRM_MEDIATEK_HDMI && DRM_I2C_NXP_TDA998X && 
DRM_DW_HDMI_I2S_AUDIO) selects SND_SOC_HDMI_CODEC which has unmet direct 
dependencies (SOUND && !M68K && !UML && SND && SND_SOC)

Since the audio driver is probably useless without the audio subsystem,
adding a dependency here seems the right solution.

Fixes: 2761ba6c0925 ("drm: bridge: add DesignWare HDMI I2S audio support")
Signed-off-by: Arnd Bergmann 
---
 drivers/gpu/drm/bridge/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index 4980ecc55721..71db3e659be9 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -41,6 +41,7 @@ config DRM_DW_HDMI_AHB_AUDIO

 config DRM_DW_HDMI_I2S_AUDIO
tristate "Synopsis Designware I2S Audio interface"
+   depends on SND_SOC
depends on DRM_DW_HDMI
select SND_SOC_HDMI_CODEC
help
-- 
2.9.0



Enabling peer to peer device transactions for PCIe devices

2016-11-25 Thread Christian König
Am 25.11.2016 um 20:32 schrieb Jason Gunthorpe:
> On Fri, Nov 25, 2016 at 02:22:17PM +0100, Christian König wrote:
>
>>> Like you say below we have to handle short lived in the usual way, and
>>> that covers basically every device except IB MRs, including the
>>> command queue on a NVMe drive.
>> Well a problem which wasn't mentioned so far is that while GPUs do have a
>> page table to mirror the CPU page table, they usually can't recover from
>> page faults.
>> So what we do is making sure that all memory accessed by the GPU Jobs stays
>> in place while those jobs run (pretty much the same pinning you do for the
>> DMA).
> Yes, it is DMA, so this is a valid approach.
>
> But, you don't need page faults from the GPU to do proper coherent
> page table mirroring. Basically when the driver submits the work to
> the GPU it 'faults' the pages into the CPU and mirror translation
> table (instead of pinning).
>
> Like in ODP, MMU notifiers/HMM are used to monitor for translation
> changes. If a change comes in the GPU driver checks if an executing
> command is touching those pages and blocks the MMU notifier until the
> command flushes, then unfaults the page (blocking future commands) and
> unblocks the mmu notifier.

Yeah, we have a function to "import" anonymous pages from a CPU pointer 
which works exactly that way as well.

We call this "userptr" and it's just a combination of get_user_pages() 
on command submission and making sure the returned list of pages stays 
valid using a MMU notifier.

The "big" problem with this approach is that it is horrible slow. I mean 
seriously horrible slow so that we actually can't use it for some of the 
purposes we wanted to use it.

> The code moving the page will move it and the next GPU command that
> needs it will refault it in the usual way, just like the CPU would.

And here comes the problem. CPU do this on a page by page basis, so they 
fault only what needed and everything else gets filled in on demand. 
This results that faulting a page is relatively light weight operation.

But for GPU command submission we don't know which pages might be 
accessed beforehand, so what we do is walking all possible pages and 
make sure all of them are present.

Now as far as I understand it the I/O subsystem for example assumes that 
it can easily change the CPU page tables without much overhead. So for 
example when a page can't modified it is temporary marked as readonly 
AFAIK (you are probably way deeper into this than me, so please confirm).

That absolutely kills any performance for GPU command submissions. We 
have use cases where we practically ended up playing ping/pong between 
the GPU driver trying to grab the page with get_user_pages() and sombody 
else in the kernel marking it readonly.

> This might be much more efficient since it optimizes for the common
> case of unchanging translation tables.

Yeah, completely agree. It works perfectly fine as long as you don't 
have two drivers trying to mess with the same page.

> This assumes the commands are fairly short lived of course, the
> expectation of the mmu notifiers is that a flush is reasonably prompt

Correct, this is another problem. GFX command submissions usually don't 
take longer than a few milliseconds, but compute command submission can 
easily take multiple hours.

I can easily imagine what would happen when kswapd is blocked by a GPU 
command submission for an hour or so while the system is under memory 
pressure :)

I'm thinking on this problem for about a year now and going in circles 
for quite a while. So if you have ideas on this even if they sound 
totally crazy, feel free to come up.

Cheers,
Christian.



Question regarding clocks in the DW-HDMI DT bindings

2016-11-25 Thread Laurent Pinchart
Hi Philipp,

On Friday 25 Nov 2016 17:08:13 Philipp Zabel wrote:
> Am Freitag, den 25.11.2016, 17:45 +0200 schrieb Laurent Pinchart:
> > On Friday 25 Nov 2016 10:56:55 Philipp Zabel wrote:
> >> Am Donnerstag, den 24.11.2016, 23:16 +0200 schrieb Laurent Pinchart:
> >>> Hi Andy,
> >>> 
> >>> As the author of the DW-HDMI DT bindings this question is addressed to
> >>> you, but information from anyone is more than welcome.
> >>> 
> >>> The DT bindings specify two clocks named "iahb" and "isfr" but don't
> >>> describe them. While I assume that the "isfr" clock corresponds to the
> >>> "isfrclk" input signal of the DW HDMI, there is no "iahb" clock
> >>> described in the IP core datasheet.
> >> 
> >> The Table 33-1 "HDMI clocks" in the i.MX6DQ reference manual [1] lists
> >> iahbclk (AHB bus clock), icecclk (32 kHz CEC clock), ihclk (module
> >> clock) and isfrclk (27 MHz internal SFR clock).
> >> 
> >> [1]
> >> http://www.nxp.com/assets/documents/data/en/reference-manuals/IMX6DQRM.p
> >> df
> >> 
> >>> The DW HDMI IP exposes control registers through an APB, not an AHB.
> >>> There is a bus clock named "iapbclk", is "iahb" just an incorrect name
> >>> for that clock ?
> >> 
> >> According to figure 33-3 "HDMI TX Top Level Block Diagram" the control
> >> interface is AMBA AHB on i.MX6. Both iahbclk and ihclk are clocked by
> >> ahb_clk_root on i.MX6.
> >> 
> >> Register 5 (HDMI_CONFIG1_ID) contains a few bits (confsfrdir, confi2c,
> >> confocp, confapb, confahb) that indicate which control interface is
> >> used.
> > 
> > That's interesting. The DW HDMI TX documentation I found (1.40a-ea00,
> > Early Adopter Edition) only has the confahb bit in that register. Do you
> > know which version of the IP is used in iMX.6 ? I wonder whether the above
> > is a Freescale-specific modification to the IP core.
> 
> The driver reports:
> 
> dwhdmi-imx 12.hdmi: Detected HDMI controller 0x13:0xa:0xa0:0xc1
> 
> That is DESIGN_ID 0x13, REVISION_ID 0x0a.
> 
> > I'm also a bit puzzled by the differences in the HDMI PHY between
> > Freescale and Renesas. The Renesas datasheet documents three registers
> > only for the PHY (other might exist and be undocumented), and while they
> > contain fields similar to the ones documented in the Freescale datasheet,
> > the exact register layouts are different.
> 
> Do you mean the HDMI_PHY_* registers in the HDMI TX register space or
> the separate HDMI PHY i2c registers? The PHY may very well be completely
> different. I think OMAP5 HDMI driver uses the same DesignWare HDMI TX as
> i.MX6, but not the same PHY.

I meant the HDMI PHY I2C registers, yes. If the PHYs are really SoC-specific 
maybe we should move the supporting code to the platform glue driver.

Would anyone happen to have access to the Synopsys HDMI TX PHY documentation ?

-- 
Regards,

Laurent Pinchart



[Bug 98005] VCE dual instance encoding inconsistent since st/va: enable dual instances encode by sync surface

2016-11-25 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=98005

--- Comment #27 from Boyuan Zhang  ---
(In reply to Andy Furniss from comment #26)
> So far the patches seem good :-)
> 
> cbr and vbr are behaving as expected - including md5sums always being the
> same.

Sounds cool! =)

Sorry for taking a long time to fully solve these issues. The two/three
reported issues are caused by 2 root causes, however these 2 root causes can
actually affect each other in certain way. Thanks for catching all these
issues.

I will let you run more tests a bit. If everything seems fine, I will push the
patches to upstream.

Regards,
Boyuan

-- 
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/20161125/7f41b3dd/attachment.html>


[Bug 90202] Firefox nightly hangs with accelerated layers and latest r600 driver

2016-11-25 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=90202

Ernst Sjöstrand  changed:

   What|Removed |Added

 Resolution|--- |FIXED
 Status|NEW |RESOLVED

--- Comment #9 from Ernst Sjöstrand  ---
Fixed!

-- 
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/20161125/c576c659/attachment.html>


[Bug 92996] [Fiji/amdgpu/Powerplay] Problems with interactivity, performance, EQ overflow with Powerplay

2016-11-25 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=92996

Ernst Sjöstrand  changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution|--- |FIXED

--- Comment #18 from Ernst Sjöstrand  ---
Right, this was fixed! :-)

-- 
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/20161125/1212152b/attachment.html>


[Bug 98239] saints row 3: performance is limited by flushes

2016-11-25 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=98239

--- Comment #2 from almos  ---
(In reply to Marek Olšák from comment #1)
> What's your GPU and kernel driver?

I have an R9 270x (Curaçao XT), the kernel driver is radeon. BTW the game runs
noticeably smoother with Mesa 13 than with 12.

-- 
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/20161125/3c798609/attachment.html>


[PATCH V3 2/3] dt-bindings: mxsfb: Add new bindings for the MXSFB driver

2016-11-25 Thread Marek Vasut
On 11/16/2016 01:21 PM, Marek Vasut wrote:
> Add new DT bindings for new MXSFB driver that is using the
> OF graph to parse the video output structure instead of
> hard-coding the display properties into the MXSFB node.
> The old MXSFB fbdev driver bindings are preserved in the
> same file in the "Old bindings" section.
> 
> Signed-off-by: Marek Vasut 
> Cc: Rob Herring 
> Cc: Lucas Stach 
> Cc: Fabio Estevam 
> Cc: Shawn Guo 
> --
> V2: - Merge the new bindings into mxsfb.txt file instead of keeping
>   them in separate mxsfb-drm.txt file.
> - Add dedicated compatible for i.MX6SX
> - Drop all references to DRM/KMS
> - Repair the required bits in clock node
> V3: - Replace lcdif with LCDIF, lcdif at 0 with display-controller@,
>   Old with Deprecated to address V2 feedback

Bump ?

> ---
>  .../devicetree/bindings/display/mxsfb.txt  | 41 
> --
>  1 file changed, 39 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/display/mxsfb.txt 
> b/Documentation/devicetree/bindings/display/mxsfb.txt
> index a4431f2..472e1ea 100644
> --- a/Documentation/devicetree/bindings/display/mxsfb.txt
> +++ b/Documentation/devicetree/bindings/display/mxsfb.txt
> @@ -1,10 +1,47 @@
>  * Freescale MXS LCD Interface (LCDIF)
>  
> +New bindings:
> +=
>  Required properties:
>  - compatible:Should be "fsl,imx23-lcdif" for i.MX23.
>   Should be "fsl,imx28-lcdif" for i.MX28.
> -- reg:   Address and length of the register set for lcdif
> -- interrupts:Should contain lcdif interrupts
> + Should be "fsl,imx6sx-lcdif" for i.MX6SX.
> +- reg:   Address and length of the register set for LCDIF
> +- interrupts:Should contain LCDIF interrupt
> +- clocks:A list of phandle + clock-specifier pairs, one for each
> + entry in 'clock-names'.
> +- clock-names:   A list of clock names. For MXSFB it should contain:
> +- "pix" for the LCDIF block clock
> +- (MX6SX-only) "axi", "disp_axi" for the bus interface clock
> +
> +Required sub-nodes:
> +  - port: The connection to an encoder chip.
> +
> +Example:
> +
> + lcdif1: display-controller at 222 {
> + compatible = "fsl,imx6sx-lcdif", "fsl,imx28-lcdif";
> + reg = <0x0222 0x4000>;
> + interrupts = ;
> + clocks = < IMX6SX_CLK_LCDIF1_PIX>,
> +  < IMX6SX_CLK_LCDIF_APB>,
> +  < IMX6SX_CLK_DISPLAY_AXI>;
> + clock-names = "pix", "axi", "disp_axi";
> +
> + port {
> + parallel_out: endpoint {
> + remote-endpoint = <_in_parallel>;
> + };
> + };
> + };
> +
> +Deprecated bindings:
> +
> +Required properties:
> +- compatible:Should be "fsl,imx23-lcdif" for i.MX23.
> + Should be "fsl,imx28-lcdif" for i.MX28.
> +- reg:   Address and length of the register set for LCDIF
> +- interrupts:Should contain LCDIF interrupts
>  - display:   phandle to display node (see below for details)
>  
>  * display node
> 


-- 
Best regards,
Marek Vasut


Enabling peer to peer device transactions for PCIe devices

2016-11-25 Thread Alex Deucher
On Fri, Nov 25, 2016 at 2:34 PM, Jason Gunthorpe
 wrote:
> On Fri, Nov 25, 2016 at 12:16:30PM -0500, Serguei Sagalovitch wrote:
>
>> b) Allocation may not  have CPU address  at all - only GPU one.
>
> But you don't expect RDMA to work in the case, right?
>
> GPU people need to stop doing this windowed memory stuff :)
>

Blame 32 bit systems and GPUs with tons of vram :)

I think resizable bars are finally coming in a useful way so this
should go away soon.

Alex


[PATCH v10 13/13] drm/mediatek: add support for Mediatek SoC MT2701

2016-11-25 Thread YT Shen
This patch add support for the Mediatek MT2701 DISP subsystem.
There is only one OVL engine in MT2701.

Signed-off-by: YT Shen 
---
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c |  8 
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c|  6 ++
 drivers/gpu/drm/mediatek/mtk_drm_ddp.c  | 17 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  7 +++
 drivers/gpu/drm/mediatek/mtk_drm_drv.c  | 29 +
 drivers/gpu/drm/mediatek/mtk_dsi.c  |  1 +
 drivers/gpu/drm/mediatek/mtk_mipi_tx.c  |  6 ++
 7 files changed, 74 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 678595c..0adb0e4 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -35,6 +35,7 @@
 #define DISP_REG_OVL_PITCH(n)  (0x0044 + 0x20 * (n))
 #define DISP_REG_OVL_RDMA_CTRL(n)  (0x00c0 + 0x20 * (n))
 #define DISP_REG_OVL_RDMA_GMC(n)   (0x00c8 + 0x20 * (n))
+#define DISP_REG_OVL_ADDR_MT2701   0x0040
 #define DISP_REG_OVL_ADDR_MT8173   0x0f40
 #define DISP_REG_OVL_ADDR(ovl, n)  ((ovl)->data->addr + 0x20 * (n))

@@ -302,12 +303,19 @@ static int mtk_disp_ovl_remove(struct platform_device 
*pdev)
return 0;
 }

+static const struct mtk_disp_ovl_data mt2701_ovl_driver_data = {
+   .addr = DISP_REG_OVL_ADDR_MT2701,
+   .fmt_rgb565_is_0 = false,
+};
+
 static const struct mtk_disp_ovl_data mt8173_ovl_driver_data = {
.addr = DISP_REG_OVL_ADDR_MT8173,
.fmt_rgb565_is_0 = true,
 };

 static const struct of_device_id mtk_disp_ovl_driver_dt_match[] = {
+   { .compatible = "mediatek,mt2701-disp-ovl",
+ .data = _ovl_driver_data},
{ .compatible = "mediatek,mt8173-disp-ovl",
  .data = _ovl_driver_data},
{},
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c 
b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
index e5e5318..b68a513 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
@@ -236,11 +236,17 @@ static int mtk_disp_rdma_remove(struct platform_device 
*pdev)
return 0;
 }

+static const struct mtk_disp_rdma_data mt2701_rdma_driver_data = {
+   .fifo_size = SZ_4K,
+};
+
 static const struct mtk_disp_rdma_data mt8173_rdma_driver_data = {
.fifo_size = SZ_8K,
 };

 static const struct of_device_id mtk_disp_rdma_driver_dt_match[] = {
+   { .compatible = "mediatek,mt2701-disp-rdma",
+ .data = _rdma_driver_data},
{ .compatible = "mediatek,mt8173-disp-rdma",
  .data = _rdma_driver_data},
{},
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c 
b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
index a9b209c..8130f3d 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
@@ -60,6 +60,13 @@
 #define MT8173_MUTEX_MOD_DISP_PWM1 BIT(24)
 #define MT8173_MUTEX_MOD_DISP_OD   BIT(25)

+#define MT2701_MUTEX_MOD_DISP_OVL  BIT(3)
+#define MT2701_MUTEX_MOD_DISP_WDMA BIT(6)
+#define MT2701_MUTEX_MOD_DISP_COLORBIT(7)
+#define MT2701_MUTEX_MOD_DISP_BLS  BIT(9)
+#define MT2701_MUTEX_MOD_DISP_RDMA0BIT(10)
+#define MT2701_MUTEX_MOD_DISP_RDMA1BIT(12)
+
 #define MUTEX_SOF_SINGLE_MODE  0
 #define MUTEX_SOF_DSI0 1
 #define MUTEX_SOF_DSI1 2
@@ -92,6 +99,15 @@ struct mtk_ddp {
const unsigned int  *mutex_mod;
 };

+static const unsigned int mt2701_mutex_mod[DDP_COMPONENT_ID_MAX] = {
+   [DDP_COMPONENT_BLS] = MT2701_MUTEX_MOD_DISP_BLS,
+   [DDP_COMPONENT_COLOR0] = MT2701_MUTEX_MOD_DISP_COLOR,
+   [DDP_COMPONENT_OVL0] = MT2701_MUTEX_MOD_DISP_OVL,
+   [DDP_COMPONENT_RDMA0] = MT2701_MUTEX_MOD_DISP_RDMA0,
+   [DDP_COMPONENT_RDMA1] = MT2701_MUTEX_MOD_DISP_RDMA1,
+   [DDP_COMPONENT_WDMA0] = MT2701_MUTEX_MOD_DISP_WDMA,
+};
+
 static const unsigned int mt8173_mutex_mod[DDP_COMPONENT_ID_MAX] = {
[DDP_COMPONENT_AAL] = MT8173_MUTEX_MOD_DISP_AAL,
[DDP_COMPONENT_COLOR0] = MT8173_MUTEX_MOD_DISP_COLOR0,
@@ -390,6 +406,7 @@ static int mtk_ddp_remove(struct platform_device *pdev)
 }

 static const struct of_device_id ddp_driver_dt_match[] = {
+   { .compatible = "mediatek,mt2701-disp-mutex", .data = mt2701_mutex_mod},
{ .compatible = "mediatek,mt8173-disp-mutex", .data = mt8173_mutex_mod},
{},
 };
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c 
b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 7fb32d8..b10b3f2 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -39,6 +39,7 @@
 #define DISP_REG_UFO_START 0x

 #define DISP_COLOR_CFG_MAIN0x0400
+#define DISP_COLOR_START_MT27010x0f00
 #define DISP_COLOR_START_MT8173   

[PATCH v10 12/13] drm/mediatek: update DSI sub driver flow for sending commands to panel

2016-11-25 Thread YT Shen
This patch update enable/disable flow of DSI module.
Original flow works on there is a bridge chip: DSI -> bridge -> panel.
In this case: DSI -> panel, the DSI sub driver flow should be updated.
We need to initialize DSI first so that we can send commands to panel.

Signed-off-by: shaoming chen 
Signed-off-by: YT Shen 
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 101 +
 1 file changed, 80 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
b/drivers/gpu/drm/mediatek/mtk_dsi.c
index ded4202..0569f2e 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -126,6 +126,10 @@
 #define CLK_HS_POST(0xff << 8)
 #define CLK_HS_EXIT(0xff << 16)

+#define DSI_VM_CMD_CON 0x130
+#define VM_CMD_EN  BIT(0)
+#define TS_VFP_EN  BIT(5)
+
 #define DSI_CMDQ0  0x180
 #define CONFIG (0xff << 0)
 #define SHORT_PACKET   0
@@ -249,7 +253,9 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
 * mipi_ratio is mipi clk coefficient for balance the pixel clk in mipi.
 * we set mipi_ratio is 1.05.
 */
-   dsi->data_rate = dsi->vm.pixelclock * 3 * 21 / (1 * 1000 * 10);
+   dsi->data_rate = dsi->vm.pixelclock * 12 * 21;
+   dsi->data_rate /= (dsi->lanes * 1000 * 10);
+   DRM_DEBUG_DRIVER("set mipitx's data rate: %dMHz\n", dsi->data_rate);

ret = clk_set_rate(dsi->hs_clk, dsi->data_rate * 100);
if (ret < 0) {
@@ -333,16 +339,23 @@ static void mtk_dsi_set_mode(struct mtk_dsi *dsi)
u32 vid_mode = CMD_MODE;

if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) {
-   vid_mode = SYNC_PULSE_MODE;
-
-   if ((dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) &&
-   !(dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE))
+   if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
vid_mode = BURST_MODE;
+   else if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
+   vid_mode = SYNC_PULSE_MODE;
+   else
+   vid_mode = SYNC_EVENT_MODE;
}

writel(vid_mode, dsi->regs + DSI_MODE_CTRL);
 }

+static void mtk_dsi_set_vm_cmd(struct mtk_dsi *dsi)
+{
+   mtk_dsi_mask(dsi, DSI_VM_CMD_CON, VM_CMD_EN, VM_CMD_EN);
+   mtk_dsi_mask(dsi, DSI_VM_CMD_CON, TS_VFP_EN, TS_VFP_EN);
+}
+
 static void mtk_dsi_ps_control_vact(struct mtk_dsi *dsi)
 {
struct videomode *vm = >vm;
@@ -480,6 +493,16 @@ static void mtk_dsi_start(struct mtk_dsi *dsi)
writel(1, dsi->regs + DSI_START);
 }

+static void mtk_dsi_stop(struct mtk_dsi *dsi)
+{
+   writel(0, dsi->regs + DSI_START);
+}
+
+static void mtk_dsi_set_cmd_mode(struct mtk_dsi *dsi)
+{
+   writel(CMD_MODE, dsi->regs + DSI_MODE_CTRL);
+}
+
 static void mtk_dsi_set_interrupt_enable(struct mtk_dsi *dsi)
 {
u32 inten = LPRX_RD_RDY_INT_FLAG | CMD_DONE_INT_FLAG | VM_DONE_INT_FLAG;
@@ -538,6 +561,19 @@ static irqreturn_t mtk_dsi_irq(int irq, void *dev_id)
return IRQ_HANDLED;
 }

+static s32 mtk_dsi_switch_to_cmd_mode(struct mtk_dsi *dsi, u8 irq_flag, u32 t)
+{
+   mtk_dsi_irq_data_clear(dsi, irq_flag);
+   mtk_dsi_set_cmd_mode(dsi);
+
+   if (!mtk_dsi_wait_for_irq_done(dsi, irq_flag, t)) {
+   DRM_ERROR("failed to switch cmd mode\n");
+   return -ETIME;
+   } else {
+   return 0;
+   }
+}
+
 static void mtk_dsi_poweroff(struct mtk_dsi *dsi)
 {
if (WARN_ON(dsi->refcount == 0))
@@ -546,11 +582,6 @@ static void mtk_dsi_poweroff(struct mtk_dsi *dsi)
if (--dsi->refcount != 0)
return;

-   mtk_dsi_lane0_ulp_mode_enter(dsi);
-   mtk_dsi_clk_ulp_mode_enter(dsi);
-
-   mtk_dsi_disable(dsi);
-
clk_disable_unprepare(dsi->engine_clk);
clk_disable_unprepare(dsi->digital_clk);

@@ -564,13 +595,6 @@ static void mtk_output_dsi_enable(struct mtk_dsi *dsi)
if (dsi->enabled)
return;

-   if (dsi->panel) {
-   if (drm_panel_prepare(dsi->panel)) {
-   DRM_ERROR("failed to setup the panel\n");
-   return;
-   }
-   }
-
ret = mtk_dsi_poweron(dsi);
if (ret < 0) {
DRM_ERROR("failed to power on dsi\n");
@@ -578,21 +602,43 @@ static void mtk_output_dsi_enable(struct mtk_dsi *dsi)
}

mtk_dsi_rxtx_control(dsi);
+   mtk_dsi_ps_control_vact(dsi);
+   mtk_dsi_set_vm_cmd(dsi);
+   mtk_dsi_config_vdo_timing(dsi);
+   mtk_dsi_set_interrupt_enable(dsi);

mtk_dsi_clk_ulp_mode_leave(dsi);
mtk_dsi_lane0_ulp_mode_leave(dsi);
mtk_dsi_clk_hs_mode(dsi, 0);
-   mtk_dsi_set_mode(dsi);

-   mtk_dsi_ps_control_vact(dsi);
-   mtk_dsi_config_vdo_timing(dsi);
-   

[PATCH v10 11/13] drm/mediatek: add dsi rxtx control

2016-11-25 Thread YT Shen
add non-continuous clock mode and EOT packet control for dsi

Signed-off-by: shaoming chen 
Signed-off-by: YT Shen 
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 01df829..ded4202 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -399,6 +399,9 @@ static void mtk_dsi_rxtx_control(struct mtk_dsi *dsi)
break;
}

+   tmp_reg |= (dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) << 6;
+   tmp_reg |= (dsi->mode_flags & MIPI_DSI_MODE_EOT_PACKET) >> 3;
+
writel(tmp_reg, dsi->regs + DSI_TXRX_CTRL);
 }

-- 
1.9.1



[PATCH v10 10/13] drm/mediatek: add dsi ulp mode control

2016-11-25 Thread YT Shen
modify dsi enter ultra low power mode method

Signed-off-by: shaoming chen 
Signed-off-by: YT Shen 
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
b/drivers/gpu/drm/mediatek/mtk_dsi.c
index d03a0f1..01df829 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -289,7 +289,7 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
 static void mtk_dsi_clk_ulp_mode_enter(struct mtk_dsi *dsi)
 {
mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_HS_TX_EN, 0);
-   mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_ULPM_EN, 0);
+   mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_ULPM_EN, LC_ULPM_EN);
 }

 static void mtk_dsi_clk_ulp_mode_leave(struct mtk_dsi *dsi)
@@ -302,7 +302,7 @@ static void mtk_dsi_clk_ulp_mode_leave(struct mtk_dsi *dsi)
 static void mtk_dsi_lane0_ulp_mode_enter(struct mtk_dsi *dsi)
 {
mtk_dsi_mask(dsi, DSI_PHY_LD0CON, LD0_HS_TX_EN, 0);
-   mtk_dsi_mask(dsi, DSI_PHY_LD0CON, LD0_ULPM_EN, 0);
+   mtk_dsi_mask(dsi, DSI_PHY_LD0CON, LD0_ULPM_EN, LD0_ULPM_EN);
 }

 static void mtk_dsi_lane0_ulp_mode_leave(struct mtk_dsi *dsi)
-- 
1.9.1



[PATCH v10 09/13] drm/mediatek: add mipi_tx data rate check

2016-11-25 Thread YT Shen
modify data rate limitation (>lGbps/lane) for mipitx

Signed-off-by: shaoming chen 
Signed-off-by: YT Shen 
---
 drivers/gpu/drm/mediatek/mtk_mipi_tx.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_mipi_tx.c 
b/drivers/gpu/drm/mediatek/mtk_mipi_tx.c
index fd84914..1ef00ac 100644
--- a/drivers/gpu/drm/mediatek/mtk_mipi_tx.c
+++ b/drivers/gpu/drm/mediatek/mtk_mipi_tx.c
@@ -177,7 +177,9 @@ static int mtk_mipi_tx_pll_prepare(struct clk_hw *hw)

dev_dbg(mipi_tx->dev, "prepare: %u Hz\n", mipi_tx->data_rate);

-   if (mipi_tx->data_rate >= 5) {
+   if (mipi_tx->data_rate > 125000) {
+   return -EINVAL;
+   } else if (mipi_tx->data_rate >= 5) {
txdiv = 1;
txdiv0 = 0;
txdiv1 = 0;
-- 
1.9.1



[PATCH v10 08/13] drm/mediatek: add dsi transfer function

2016-11-25 Thread YT Shen
From: shaoming chen 

add dsi read/write commands for transfer function

Signed-off-by: shaoming chen 
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 168 -
 1 file changed, 166 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
b/drivers/gpu/drm/mediatek/mtk_dsi.c
index d236e2d..d03a0f1 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -24,6 +24,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 

 #include "mtk_drm_ddp_comp.h"
@@ -80,8 +81,16 @@
 #define DSI_HBP_WC 0x54
 #define DSI_HFP_WC 0x58

+#define DSI_CMDQ_SIZE  0x60
+#define CMDQ_SIZE  0x3f
+
 #define DSI_HSTX_CKL_WC0x64

+#define DSI_RX_DATA0   0x74
+#define DSI_RX_DATA1   0x78
+#define DSI_RX_DATA2   0x7c
+#define DSI_RX_DATA3   0x80
+
 #define DSI_RACK   0x84
 #define RACK   BIT(0)

@@ -117,8 +126,23 @@
 #define CLK_HS_POST(0xff << 8)
 #define CLK_HS_EXIT(0xff << 16)

+#define DSI_CMDQ0  0x180
+#define CONFIG (0xff << 0)
+#define SHORT_PACKET   0
+#define LONG_PACKET2
+#define BTABIT(2)
+#define DATA_ID(0xff << 8)
+#define DATA_0 (0xff << 16)
+#define DATA_1 (0xff << 24)
+
 #define NS_TO_CYCLE(n, c)((n) / (c) + (((n) % (c)) ? 1 : 0))

+#define MTK_DSI_HOST_IS_READ(type) \
+   ((type == MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM) || \
+   (type == MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM) || \
+   (type == MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM) || \
+   (type == MIPI_DSI_DCS_READ))
+
 struct phy;

 struct mtk_dsi {
@@ -465,12 +489,12 @@ static void mtk_dsi_irq_data_set(struct mtk_dsi *dsi, u32 
irq_bit)
dsi->irq_data |= irq_bit;
 }

-static __maybe_unused void mtk_dsi_irq_data_clear(struct mtk_dsi *dsi, u32 
irq_bit)
+static void mtk_dsi_irq_data_clear(struct mtk_dsi *dsi, u32 irq_bit)
 {
dsi->irq_data &= ~irq_bit;
 }

-static __maybe_unused s32 mtk_dsi_wait_for_irq_done(struct mtk_dsi *dsi, u32 
irq_flag,
+static s32 mtk_dsi_wait_for_irq_done(struct mtk_dsi *dsi, u32 irq_flag,
 unsigned int timeout)
 {
s32 ret = 0;
@@ -807,9 +831,149 @@ static int mtk_dsi_host_detach(struct mipi_dsi_host *host,
return 0;
 }

+static void mtk_dsi_wait_for_idle(struct mtk_dsi *dsi)
+{
+   u32 timeout_ms = 50; /* total 1s ~ 2s timeout */
+
+   while (timeout_ms--) {
+   if (!(readl(dsi->regs + DSI_INTSTA) & DSI_BUSY))
+   break;
+
+   usleep_range(2, 4);
+   }
+
+   if (timeout_ms == 0) {
+   DRM_WARN("polling dsi wait not busy timeout!\n");
+
+   mtk_dsi_enable(dsi);
+   mtk_dsi_reset_engine(dsi);
+   }
+}
+
+static u32 mtk_dsi_recv_cnt(u8 type, u8 *read_data)
+{
+   switch (type) {
+   case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_1BYTE:
+   case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE:
+   return 1;
+   case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_2BYTE:
+   case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE:
+   return 2;
+   case MIPI_DSI_RX_GENERIC_LONG_READ_RESPONSE:
+   case MIPI_DSI_RX_DCS_LONG_READ_RESPONSE:
+   return read_data[1] + read_data[2] * 16;
+   case MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT:
+   DRM_INFO("type is 0x02, try again\n");
+   break;
+   default:
+   DRM_INFO("type(0x%x) cannot be non-recognite\n", type);
+   break;
+   }
+
+   return 0;
+}
+
+static void mtk_dsi_cmdq(struct mtk_dsi *dsi, const struct mipi_dsi_msg *msg)
+{
+   const char *tx_buf = msg->tx_buf;
+   u8 config, cmdq_size, cmdq_off, type = msg->type;
+   u32 reg_val, cmdq_mask, i;
+
+   if (MTK_DSI_HOST_IS_READ(type))
+   config = BTA;
+   else
+   config = (msg->tx_len > 2) ? LONG_PACKET : SHORT_PACKET;
+
+   if (msg->tx_len > 2) {
+   cmdq_size = 1 + (msg->tx_len + 3) / 4;
+   cmdq_off = 4;
+   cmdq_mask = CONFIG | DATA_ID | DATA_0 | DATA_1;
+   reg_val = (msg->tx_len << 16) | (type << 8) | config;
+   } else {
+   cmdq_size = 1;
+   cmdq_off = 2;
+   cmdq_mask = CONFIG | DATA_ID;
+   reg_val = (type << 8) | config;
+   }
+
+   for (i = 0; i < msg->tx_len; i++)
+   writeb(tx_buf[i], dsi->regs + DSI_CMDQ0 + cmdq_off + i);
+
+   mtk_dsi_mask(dsi, DSI_CMDQ0, cmdq_mask, reg_val);
+   mtk_dsi_mask(dsi, DSI_CMDQ_SIZE, CMDQ_SIZE, cmdq_size);
+}
+
+static ssize_t mtk_dsi_host_send_cmd(struct mtk_dsi *dsi,
+ 

[PATCH v10 07/13] drm/mediatek: add dsi interrupt control

2016-11-25 Thread YT Shen
From: shaoming chen 

add dsi interrupt control

Signed-off-by: shaoming chen 
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 92 ++
 1 file changed, 92 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 4efeb38..d236e2d 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -29,6 +30,16 @@

 #define DSI_START  0x00

+#define DSI_INTEN  0x08
+
+#define DSI_INTSTA 0x0c
+#define LPRX_RD_RDY_INT_FLAG   BIT(0)
+#define CMD_DONE_INT_FLAG  BIT(1)
+#define TE_RDY_INT_FLAGBIT(2)
+#define VM_DONE_INT_FLAG   BIT(3)
+#define EXT_TE_RDY_INT_FLAGBIT(4)
+#define DSI_BUSY   BIT(31)
+
 #define DSI_CON_CTRL   0x10
 #define DSI_RESET  BIT(0)
 #define DSI_EN BIT(1)
@@ -71,6 +82,9 @@

 #define DSI_HSTX_CKL_WC0x64

+#define DSI_RACK   0x84
+#define RACK   BIT(0)
+
 #define DSI_PHY_LCCON  0x104
 #define LC_HS_TX_ENBIT(0)
 #define LC_ULPM_EN BIT(1)
@@ -131,6 +145,8 @@ struct mtk_dsi {
struct videomode vm;
int refcount;
bool enabled;
+   u32 irq_data;
+   wait_queue_head_t irq_wait_queue;
 };

 static inline struct mtk_dsi *encoder_to_dsi(struct drm_encoder *e)
@@ -437,6 +453,64 @@ static void mtk_dsi_start(struct mtk_dsi *dsi)
writel(1, dsi->regs + DSI_START);
 }

+static void mtk_dsi_set_interrupt_enable(struct mtk_dsi *dsi)
+{
+   u32 inten = LPRX_RD_RDY_INT_FLAG | CMD_DONE_INT_FLAG | VM_DONE_INT_FLAG;
+
+   writel(inten, dsi->regs + DSI_INTEN);
+}
+
+static void mtk_dsi_irq_data_set(struct mtk_dsi *dsi, u32 irq_bit)
+{
+   dsi->irq_data |= irq_bit;
+}
+
+static __maybe_unused void mtk_dsi_irq_data_clear(struct mtk_dsi *dsi, u32 
irq_bit)
+{
+   dsi->irq_data &= ~irq_bit;
+}
+
+static __maybe_unused s32 mtk_dsi_wait_for_irq_done(struct mtk_dsi *dsi, u32 
irq_flag,
+unsigned int timeout)
+{
+   s32 ret = 0;
+   unsigned long jiffies = msecs_to_jiffies(timeout);
+
+   ret = wait_event_interruptible_timeout(dsi->irq_wait_queue,
+  dsi->irq_data & irq_flag,
+  jiffies);
+   if (ret == 0) {
+   DRM_WARN("Wait DSI IRQ(0x%08x) Timeout\n", irq_flag);
+
+   mtk_dsi_enable(dsi);
+   mtk_dsi_reset_engine(dsi);
+   }
+
+   return ret;
+}
+
+static irqreturn_t mtk_dsi_irq(int irq, void *dev_id)
+{
+   struct mtk_dsi *dsi = dev_id;
+   u32 status, tmp;
+   u32 flag = LPRX_RD_RDY_INT_FLAG | CMD_DONE_INT_FLAG | VM_DONE_INT_FLAG;
+
+   status = readl(dsi->regs + DSI_INTSTA) & flag;
+
+   if (status) {
+   do {
+   mtk_dsi_mask(dsi, DSI_RACK, RACK, RACK);
+   tmp = readl(dsi->regs + DSI_INTSTA);
+   } while (tmp & DSI_BUSY);
+
+   mtk_dsi_mask(dsi, DSI_INTSTA, status, 0);
+   mtk_dsi_irq_data_set(dsi, status);
+   wake_up_interruptible(>irq_wait_queue);
+   }
+
+   return IRQ_HANDLED;
+}
+
 static void mtk_dsi_poweroff(struct mtk_dsi *dsi)
 {
if (WARN_ON(dsi->refcount == 0))
@@ -485,6 +559,7 @@ static void mtk_output_dsi_enable(struct mtk_dsi *dsi)

mtk_dsi_ps_control_vact(dsi);
mtk_dsi_config_vdo_timing(dsi);
+   mtk_dsi_set_interrupt_enable(dsi);

mtk_dsi_set_mode(dsi);
mtk_dsi_clk_hs_mode(dsi, 1);
@@ -793,6 +868,7 @@ static int mtk_dsi_probe(struct platform_device *pdev)
struct device *dev = >dev;
struct device_node *remote_node, *endpoint;
struct resource *regs;
+   int irq_num;
int comp_id;
int ret;

@@ -869,6 +945,22 @@ static int mtk_dsi_probe(struct platform_device *pdev)
return ret;
}

+   irq_num = platform_get_irq(pdev, 0);
+   if (irq_num < 0) {
+   dev_err(>dev, "failed to request dsi irq resource\n");
+   return -EPROBE_DEFER;
+   }
+
+   irq_set_status_flags(irq_num, IRQ_TYPE_LEVEL_LOW);
+   ret = devm_request_irq(>dev, irq_num, mtk_dsi_irq,
+  IRQF_TRIGGER_LOW, dev_name(>dev), dsi);
+   if (ret) {
+   dev_err(>dev, "failed to request mediatek dsi irq\n");
+   return -EPROBE_DEFER;
+   }
+
+   init_waitqueue_head(>irq_wait_queue);
+
platform_set_drvdata(pdev, dsi);

return component_add(>dev, _dsi_component_ops);
-- 
1.9.1



[PATCH v10 06/13] drm/mediatek: cleaning up and refine

2016-11-25 Thread YT Shen
cleaning up unused define and refine function name and variable

Signed-off-by: shaoming chen 
Signed-off-by: YT Shen 
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 77 --
 drivers/gpu/drm/mediatek/mtk_mipi_tx.c |  8 ++--
 2 files changed, 41 insertions(+), 44 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 28b2044..4efeb38 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -27,9 +27,6 @@

 #include "mtk_drm_ddp_comp.h"

-#define DSI_VIDEO_FIFO_DEPTH   (1920 / 4)
-#define DSI_HOST_FIFO_DEPTH64
-
 #define DSI_START  0x00

 #define DSI_CON_CTRL   0x10
@@ -46,7 +43,7 @@
 #define MIX_MODE   BIT(17)

 #define DSI_TXRX_CTRL  0x18
-#define VC_NUM (2 << 0)
+#define VC_NUM BIT(1)
 #define LANE_NUM   (0xf << 2)
 #define DIS_EOTBIT(6)
 #define NULL_ENBIT(7)
@@ -158,11 +155,11 @@ static void mtk_dsi_mask(struct mtk_dsi *dsi, u32 offset, 
u32 mask, u32 data)
writel((temp & ~mask) | (data & mask), dsi->regs + offset);
 }

-static void dsi_phy_timconfig(struct mtk_dsi *dsi)
+static void mtk_dsi_phy_timconfig(struct mtk_dsi *dsi)
 {
u32 timcon0, timcon1, timcon2, timcon3;
-   unsigned int ui, cycle_time;
-   unsigned int lpx;
+   u32 ui, cycle_time;
+   u32 lpx;

ui = 1000 / dsi->data_rate + 0x01;
cycle_time = 8000 / dsi->data_rate + 0x01;
@@ -192,7 +189,7 @@ static void mtk_dsi_disable(struct mtk_dsi *dsi)
mtk_dsi_mask(dsi, DSI_CON_CTRL, DSI_EN, 0);
 }

-static void mtk_dsi_reset(struct mtk_dsi *dsi)
+static void mtk_dsi_reset_engine(struct mtk_dsi *dsi)
 {
mtk_dsi_mask(dsi, DSI_CON_CTRL, DSI_RESET, DSI_RESET);
mtk_dsi_mask(dsi, DSI_CON_CTRL, DSI_RESET, 0);
@@ -235,8 +232,8 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
}

mtk_dsi_enable(dsi);
-   mtk_dsi_reset(dsi);
-   dsi_phy_timconfig(dsi);
+   mtk_dsi_reset_engine(dsi);
+   mtk_dsi_phy_timconfig(dsi);

return 0;

@@ -249,33 +246,33 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
return ret;
 }

-static void dsi_clk_ulp_mode_enter(struct mtk_dsi *dsi)
+static void mtk_dsi_clk_ulp_mode_enter(struct mtk_dsi *dsi)
 {
mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_HS_TX_EN, 0);
mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_ULPM_EN, 0);
 }

-static void dsi_clk_ulp_mode_leave(struct mtk_dsi *dsi)
+static void mtk_dsi_clk_ulp_mode_leave(struct mtk_dsi *dsi)
 {
mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_ULPM_EN, 0);
mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_WAKEUP_EN, LC_WAKEUP_EN);
mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_WAKEUP_EN, 0);
 }

-static void dsi_lane0_ulp_mode_enter(struct mtk_dsi *dsi)
+static void mtk_dsi_lane0_ulp_mode_enter(struct mtk_dsi *dsi)
 {
mtk_dsi_mask(dsi, DSI_PHY_LD0CON, LD0_HS_TX_EN, 0);
mtk_dsi_mask(dsi, DSI_PHY_LD0CON, LD0_ULPM_EN, 0);
 }

-static void dsi_lane0_ulp_mode_leave(struct mtk_dsi *dsi)
+static void mtk_dsi_lane0_ulp_mode_leave(struct mtk_dsi *dsi)
 {
mtk_dsi_mask(dsi, DSI_PHY_LD0CON, LD0_ULPM_EN, 0);
mtk_dsi_mask(dsi, DSI_PHY_LD0CON, LD0_WAKEUP_EN, LD0_WAKEUP_EN);
mtk_dsi_mask(dsi, DSI_PHY_LD0CON, LD0_WAKEUP_EN, 0);
 }

-static bool dsi_clk_hs_state(struct mtk_dsi *dsi)
+static bool mtk_dsi_clk_hs_state(struct mtk_dsi *dsi)
 {
u32 tmp_reg1;

@@ -283,15 +280,15 @@ static bool dsi_clk_hs_state(struct mtk_dsi *dsi)
return ((tmp_reg1 & LC_HS_TX_EN) == 1) ? true : false;
 }

-static void dsi_clk_hs_mode(struct mtk_dsi *dsi, bool enter)
+static void mtk_dsi_clk_hs_mode(struct mtk_dsi *dsi, bool enter)
 {
-   if (enter && !dsi_clk_hs_state(dsi))
+   if (enter && !mtk_dsi_clk_hs_state(dsi))
mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_HS_TX_EN, LC_HS_TX_EN);
-   else if (!enter && dsi_clk_hs_state(dsi))
+   else if (!enter && mtk_dsi_clk_hs_state(dsi))
mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_HS_TX_EN, 0);
 }

-static void dsi_set_mode(struct mtk_dsi *dsi)
+static void mtk_dsi_set_mode(struct mtk_dsi *dsi)
 {
u32 vid_mode = CMD_MODE;

@@ -306,7 +303,7 @@ static void dsi_set_mode(struct mtk_dsi *dsi)
writel(vid_mode, dsi->regs + DSI_MODE_CTRL);
 }

-static void dsi_ps_control_vact(struct mtk_dsi *dsi)
+static void mtk_dsi_ps_control_vact(struct mtk_dsi *dsi)
 {
struct videomode *vm = >vm;
u32 dsi_buf_bpp, ps_wc;
@@ -340,7 +337,7 @@ static void dsi_ps_control_vact(struct mtk_dsi *dsi)
writel(ps_wc, dsi->regs + DSI_HSTX_CKL_WC);
 }

-static void dsi_rxtx_control(struct mtk_dsi *dsi)
+static void mtk_dsi_rxtx_control(struct mtk_dsi *dsi)
 {
u32 tmp_reg;

@@ -365,9 +362,9 @@ static void dsi_rxtx_control(struct mtk_dsi *dsi)
writel(tmp_reg, dsi->regs + DSI_TXRX_CTRL);
 

[PATCH v10 05/13] drm/mediatek: update display module connections

2016-11-25 Thread YT Shen
update connections for OVL, RDMA, BLS, DSI

Signed-off-by: YT Shen 
---
 drivers/gpu/drm/mediatek/mtk_drm_ddp.c | 25 +
 1 file changed, 25 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c 
b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
index b77d456..a9b209c 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
@@ -32,6 +32,10 @@
 #define DISP_REG_CONFIG_DISP_RDMA1_MOUT_EN 0x0c8
 #define DISP_REG_CONFIG_MMSYS_CG_CON0  0x100

+#define DISP_REG_CONFIG_DISP_OVL_MOUT_EN   0x030
+#define DISP_REG_CONFIG_OUT_SEL0x04c
+#define DISP_REG_CONFIG_DSI_SEL0x050
+
 #define DISP_REG_MUTEX_EN(n)   (0x20 + 0x20 * (n))
 #define DISP_REG_MUTEX(n)  (0x24 + 0x20 * (n))
 #define DISP_REG_MUTEX_RST(n)  (0x28 + 0x20 * (n))
@@ -71,6 +75,10 @@
 #define DPI0_SEL_IN_RDMA1  0x1
 #define COLOR1_SEL_IN_OVL1 0x1

+#define OVL_MOUT_EN_RDMA   0x1
+#define BLS_TO_DSI_RDMA1_TO_DPI1   0x8
+#define DSI_SEL_IN_BLS 0x0
+
 struct mtk_disp_mutex {
int id;
bool claimed;
@@ -111,6 +119,9 @@ static unsigned int mtk_ddp_mout_en(enum mtk_ddp_comp_id 
cur,
if (cur == DDP_COMPONENT_OVL0 && next == DDP_COMPONENT_COLOR0) {
*addr = DISP_REG_CONFIG_DISP_OVL0_MOUT_EN;
value = OVL0_MOUT_EN_COLOR0;
+   } else if (cur == DDP_COMPONENT_OVL0 && next == DDP_COMPONENT_RDMA0) {
+   *addr = DISP_REG_CONFIG_DISP_OVL_MOUT_EN;
+   value = OVL_MOUT_EN_RDMA;
} else if (cur == DDP_COMPONENT_OD && next == DDP_COMPONENT_RDMA0) {
*addr = DISP_REG_CONFIG_DISP_OD_MOUT_EN;
value = OD_MOUT_EN_RDMA0;
@@ -148,6 +159,9 @@ static unsigned int mtk_ddp_sel_in(enum mtk_ddp_comp_id cur,
} else if (cur == DDP_COMPONENT_OVL1 && next == DDP_COMPONENT_COLOR1) {
*addr = DISP_REG_CONFIG_DISP_COLOR1_SEL_IN;
value = COLOR1_SEL_IN_OVL1;
+   } else if (cur == DDP_COMPONENT_BLS && next == DDP_COMPONENT_DSI0) {
+   *addr = DISP_REG_CONFIG_DSI_SEL;
+   value = DSI_SEL_IN_BLS;
} else {
value = 0;
}
@@ -155,6 +169,15 @@ static unsigned int mtk_ddp_sel_in(enum mtk_ddp_comp_id 
cur,
return value;
 }

+static void mtk_ddp_sout_sel(void __iomem *config_regs,
+enum mtk_ddp_comp_id cur,
+enum mtk_ddp_comp_id next)
+{
+   if (cur == DDP_COMPONENT_BLS && next == DDP_COMPONENT_DSI0)
+   writel_relaxed(BLS_TO_DSI_RDMA1_TO_DPI1,
+  config_regs + DISP_REG_CONFIG_OUT_SEL);
+}
+
 void mtk_ddp_add_comp_to_path(void __iomem *config_regs,
  enum mtk_ddp_comp_id cur,
  enum mtk_ddp_comp_id next)
@@ -167,6 +190,8 @@ void mtk_ddp_add_comp_to_path(void __iomem *config_regs,
writel_relaxed(reg, config_regs + addr);
}

+   mtk_ddp_sout_sel(config_regs, cur, next);
+
value = mtk_ddp_sel_in(cur, next, );
if (value) {
reg = readl_relaxed(config_regs + addr) | value;
-- 
1.9.1



[PATCH v10 04/13] drm/mediatek: add BLS component

2016-11-25 Thread YT Shen
Add BLS component for PWM + GAMMA function

Signed-off-by: YT Shen 
---
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 5 -
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 2 ++
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c 
b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index d20f6cb..7fb32d8 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -237,6 +237,7 @@ static void mtk_gamma_set(struct mtk_ddp_comp *comp,
[MTK_DISP_PWM] = "pwm",
[MTK_DISP_MUTEX] = "mutex",
[MTK_DISP_OD] = "od",
+   [MTK_DISP_BLS] = "bls",
 };

 struct mtk_ddp_comp_match {
@@ -247,6 +248,7 @@ struct mtk_ddp_comp_match {

 static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = 
{
[DDP_COMPONENT_AAL] = { MTK_DISP_AAL,   0, _aal },
+   [DDP_COMPONENT_BLS] = { MTK_DISP_BLS,   0, NULL },
[DDP_COMPONENT_COLOR0]  = { MTK_DISP_COLOR, 0, _color },
[DDP_COMPONENT_COLOR1]  = { MTK_DISP_COLOR, 1, _color },
[DDP_COMPONENT_DPI0]= { MTK_DPI,0, NULL },
@@ -305,7 +307,8 @@ int mtk_ddp_comp_init(struct device *dev, struct 
device_node *node,
comp->id = comp_id;
comp->funcs = funcs ?: mtk_ddp_matches[comp_id].funcs;

-   if (comp_id == DDP_COMPONENT_DPI0 ||
+   if (comp_id == DDP_COMPONENT_BLS ||
+   comp_id == DDP_COMPONENT_DPI0 ||
comp_id == DDP_COMPONENT_DSI0 ||
comp_id == DDP_COMPONENT_PWM0) {
comp->regs = NULL;
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h 
b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index cfaa760..4bf68ae 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -36,11 +36,13 @@ enum mtk_ddp_comp_type {
MTK_DISP_PWM,
MTK_DISP_MUTEX,
MTK_DISP_OD,
+   MTK_DISP_BLS,
MTK_DDP_COMP_TYPE_MAX,
 };

 enum mtk_ddp_comp_id {
DDP_COMPONENT_AAL,
+   DDP_COMPONENT_BLS,
DDP_COMPONENT_COLOR0,
DDP_COMPONENT_COLOR1,
DDP_COMPONENT_DPI0,
-- 
1.9.1



[PATCH v10 03/13] drm/mediatek: add shadow register support

2016-11-25 Thread YT Shen
We need to acquire mutex before using the resources,
and need to release it after finished.
So we don't need to write registers in the blanking period.

Signed-off-by: YT Shen 
---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 76 -
 drivers/gpu/drm/mediatek/mtk_drm_ddp.c  | 25 +++
 drivers/gpu/drm/mediatek/mtk_drm_ddp.h  |  2 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.h  |  1 +
 4 files changed, 75 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index 01a21dd..a4f2b3a 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -329,6 +329,42 @@ static void mtk_crtc_ddp_hw_fini(struct mtk_drm_crtc 
*mtk_crtc)
pm_runtime_put(drm->dev);
 }

+static void mtk_crtc_ddp_config(struct drm_crtc *crtc)
+{
+   struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
+   struct mtk_crtc_state *state = to_mtk_crtc_state(mtk_crtc->base.state);
+   struct mtk_ddp_comp *ovl = mtk_crtc->ddp_comp[0];
+   unsigned int i;
+
+   /*
+* TODO: instead of updating the registers here, we should prepare
+* working registers in atomic_commit and let the hardware command
+* queue update module registers on vblank.
+*/
+   if (state->pending_config) {
+   mtk_ddp_comp_config(ovl, state->pending_width,
+   state->pending_height,
+   state->pending_vrefresh, 0);
+
+   state->pending_config = false;
+   }
+
+   if (mtk_crtc->pending_planes) {
+   for (i = 0; i < OVL_LAYER_NR; i++) {
+   struct drm_plane *plane = _crtc->planes[i];
+   struct mtk_plane_state *plane_state;
+
+   plane_state = to_mtk_plane_state(plane->state);
+
+   if (plane_state->pending.config) {
+   mtk_ddp_comp_layer_config(ovl, i, plane_state);
+   plane_state->pending.config = false;
+   }
+   }
+   mtk_crtc->pending_planes = false;
+   }
+}
+
 static void mtk_drm_crtc_enable(struct drm_crtc *crtc)
 {
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
@@ -405,6 +441,7 @@ static void mtk_drm_crtc_atomic_flush(struct drm_crtc *crtc,
  struct drm_crtc_state *old_crtc_state)
 {
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
+   struct mtk_drm_private *priv = crtc->dev->dev_private;
unsigned int pending_planes = 0;
int i;

@@ -423,6 +460,13 @@ static void mtk_drm_crtc_atomic_flush(struct drm_crtc 
*crtc,
}
if (pending_planes)
mtk_crtc->pending_planes = true;
+
+   if (priv->data->shadow_register) {
+   mtk_disp_mutex_acquire(mtk_crtc->mutex);
+   mtk_crtc_ddp_config(crtc);
+   mtk_disp_mutex_release(mtk_crtc->mutex);
+   }
+
if (crtc->state->color_mgmt_changed)
for (i = 0; i < mtk_crtc->ddp_comp_nr; i++)
mtk_ddp_gamma_set(mtk_crtc->ddp_comp[i], crtc->state);
@@ -471,36 +515,10 @@ static int mtk_drm_crtc_init(struct drm_device *drm,
 void mtk_crtc_ddp_irq(struct drm_crtc *crtc, struct mtk_ddp_comp *ovl)
 {
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
-   struct mtk_crtc_state *state = to_mtk_crtc_state(mtk_crtc->base.state);
-   unsigned int i;
+   struct mtk_drm_private *priv = crtc->dev->dev_private;

-   /*
-* TODO: instead of updating the registers here, we should prepare
-* working registers in atomic_commit and let the hardware command
-* queue update module registers on vblank.
-*/
-   if (state->pending_config) {
-   mtk_ddp_comp_config(ovl, state->pending_width,
-   state->pending_height,
-   state->pending_vrefresh, 0);
-
-   state->pending_config = false;
-   }
-
-   if (mtk_crtc->pending_planes) {
-   for (i = 0; i < OVL_LAYER_NR; i++) {
-   struct drm_plane *plane = _crtc->planes[i];
-   struct mtk_plane_state *plane_state;
-
-   plane_state = to_mtk_plane_state(plane->state);
-
-   if (plane_state->pending.config) {
-   mtk_ddp_comp_layer_config(ovl, i, plane_state);
-   plane_state->pending.config = false;
-   }
-   }
-   mtk_crtc->pending_planes = false;
-   }
+   if (!priv->data->shadow_register)
+   mtk_crtc_ddp_config(crtc);

mtk_drm_finish_page_flip(mtk_crtc);
 }
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c 
b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c
index 8030769..b77d456 100644

[PATCH v10 02/13] drm/mediatek: add *driver_data for different hardware settings

2016-11-25 Thread YT Shen
There are some hardware settings changed, between MT8173 & MT2701:
DISP_OVL address offset changed, color format definition changed.
DISP_RDMA fifo size changed.
DISP_COLOR offset changed.
MIPI_TX pll setting changed.
And add prefix for mtk_ddp_main & mtk_ddp_ext & mutex_mod.

Signed-off-by: YT Shen 
---
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 41 -
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c| 18 +++-
 drivers/gpu/drm/mediatek/mtk_drm_ddp.c  | 71 +++--
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 29 +---
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |  5 ++
 drivers/gpu/drm/mediatek/mtk_drm_drv.c  | 25 +++---
 drivers/gpu/drm/mediatek/mtk_drm_drv.h  |  8 
 drivers/gpu/drm/mediatek/mtk_mipi_tx.c  | 24 +-
 8 files changed, 160 insertions(+), 61 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 17971e4..678595c 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -35,18 +35,27 @@
 #define DISP_REG_OVL_PITCH(n)  (0x0044 + 0x20 * (n))
 #define DISP_REG_OVL_RDMA_CTRL(n)  (0x00c0 + 0x20 * (n))
 #define DISP_REG_OVL_RDMA_GMC(n)   (0x00c8 + 0x20 * (n))
-#define DISP_REG_OVL_ADDR(n)   (0x0f40 + 0x20 * (n))
+#define DISP_REG_OVL_ADDR_MT8173   0x0f40
+#define DISP_REG_OVL_ADDR(ovl, n)  ((ovl)->data->addr + 0x20 * (n))

 #defineOVL_RDMA_MEM_GMC0x40402020

 #define OVL_CON_BYTE_SWAP  BIT(24)
-#define OVL_CON_CLRFMT_RGB565  (0 << 12)
-#define OVL_CON_CLRFMT_RGB888  (1 << 12)
+#define OVL_CON_CLRFMT_RGB (1 << 12)
 #define OVL_CON_CLRFMT_RGBA(2 << 12)
 #define OVL_CON_CLRFMT_ARGB(3 << 12)
+#define OVL_CON_CLRFMT_RGB565(ovl) ((ovl)->data->fmt_rgb565_is_0 ? \
+   0 : OVL_CON_CLRFMT_RGB)
+#define OVL_CON_CLRFMT_RGB888(ovl) ((ovl)->data->fmt_rgb565_is_0 ? \
+   OVL_CON_CLRFMT_RGB : 0)
 #defineOVL_CON_AEN BIT(8)
 #defineOVL_CON_ALPHA   0xff

+struct mtk_disp_ovl_data {
+   unsigned int addr;
+   bool fmt_rgb565_is_0;
+};
+
 /**
  * struct mtk_disp_ovl - DISP_OVL driver structure
  * @ddp_comp - structure containing type enum and hardware resources
@@ -55,6 +64,7 @@
 struct mtk_disp_ovl {
struct mtk_ddp_comp ddp_comp;
struct drm_crtc *crtc;
+   const struct mtk_disp_ovl_data  *data;
 };

 static inline struct mtk_disp_ovl *comp_to_ovl(struct mtk_ddp_comp *comp)
@@ -140,18 +150,18 @@ static void mtk_ovl_layer_off(struct mtk_ddp_comp *comp, 
unsigned int idx)
writel(0x0, comp->regs + DISP_REG_OVL_RDMA_CTRL(idx));
 }

-static unsigned int ovl_fmt_convert(unsigned int fmt)
+static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt)
 {
switch (fmt) {
default:
case DRM_FORMAT_RGB565:
-   return OVL_CON_CLRFMT_RGB565;
+   return OVL_CON_CLRFMT_RGB565(ovl);
case DRM_FORMAT_BGR565:
-   return OVL_CON_CLRFMT_RGB565 | OVL_CON_BYTE_SWAP;
+   return OVL_CON_CLRFMT_RGB565(ovl) | OVL_CON_BYTE_SWAP;
case DRM_FORMAT_RGB888:
-   return OVL_CON_CLRFMT_RGB888;
+   return OVL_CON_CLRFMT_RGB888(ovl);
case DRM_FORMAT_BGR888:
-   return OVL_CON_CLRFMT_RGB888 | OVL_CON_BYTE_SWAP;
+   return OVL_CON_CLRFMT_RGB888(ovl) | OVL_CON_BYTE_SWAP;
case DRM_FORMAT_RGBX:
case DRM_FORMAT_RGBA:
return OVL_CON_CLRFMT_ARGB;
@@ -170,6 +180,7 @@ static unsigned int ovl_fmt_convert(unsigned int fmt)
 static void mtk_ovl_layer_config(struct mtk_ddp_comp *comp, unsigned int idx,
 struct mtk_plane_state *state)
 {
+   struct mtk_disp_ovl *ovl = comp_to_ovl(comp);
struct mtk_plane_pending_state *pending = >pending;
unsigned int addr = pending->addr;
unsigned int pitch = pending->pitch & 0x;
@@ -181,7 +192,7 @@ static void mtk_ovl_layer_config(struct mtk_ddp_comp *comp, 
unsigned int idx,
if (!pending->enable)
mtk_ovl_layer_off(comp, idx);

-   con = ovl_fmt_convert(fmt);
+   con = ovl_fmt_convert(ovl, fmt);
if (idx != 0)
con |= OVL_CON_AEN | OVL_CON_ALPHA;

@@ -189,7 +200,7 @@ static void mtk_ovl_layer_config(struct mtk_ddp_comp *comp, 
unsigned int idx,
writel_relaxed(pitch, comp->regs + DISP_REG_OVL_PITCH(idx));
writel_relaxed(src_size, comp->regs + DISP_REG_OVL_SRC_SIZE(idx));
writel_relaxed(offset, comp->regs + DISP_REG_OVL_OFFSET(idx));
-   writel_relaxed(addr, comp->regs + DISP_REG_OVL_ADDR(idx));
+   writel_relaxed(addr, comp->regs + DISP_REG_OVL_ADDR(ovl, idx));

if (pending->enable)

[PATCH v10 01/13] drm/mediatek: add helpers for coverting from the generic components

2016-11-25 Thread YT Shen
define helpers for converting from 'mtk_ddp_comp' to 'mtk_disp_ovl'
define helpers for converting from 'mtk_ddp_comp' to 'mtk_disp_rdma'

Signed-off-by: YT Shen 
---
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c  | 15 +--
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c | 15 +--
 2 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 019b7ca..17971e4 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -57,6 +57,11 @@ struct mtk_disp_ovl {
struct drm_crtc *crtc;
 };

+static inline struct mtk_disp_ovl *comp_to_ovl(struct mtk_ddp_comp *comp)
+{
+   return container_of(comp, struct mtk_disp_ovl, ddp_comp);
+}
+
 static irqreturn_t mtk_disp_ovl_irq_handler(int irq, void *dev_id)
 {
struct mtk_disp_ovl *priv = dev_id;
@@ -76,19 +81,17 @@ static irqreturn_t mtk_disp_ovl_irq_handler(int irq, void 
*dev_id)
 static void mtk_ovl_enable_vblank(struct mtk_ddp_comp *comp,
  struct drm_crtc *crtc)
 {
-   struct mtk_disp_ovl *priv = container_of(comp, struct mtk_disp_ovl,
-ddp_comp);
+   struct mtk_disp_ovl *ovl = comp_to_ovl(comp);

-   priv->crtc = crtc;
+   ovl->crtc = crtc;
writel_relaxed(OVL_FME_CPL_INT, comp->regs + DISP_REG_OVL_INTEN);
 }

 static void mtk_ovl_disable_vblank(struct mtk_ddp_comp *comp)
 {
-   struct mtk_disp_ovl *priv = container_of(comp, struct mtk_disp_ovl,
-ddp_comp);
+   struct mtk_disp_ovl *ovl = comp_to_ovl(comp);

-   priv->crtc = NULL;
+   ovl->crtc = NULL;
writel_relaxed(0x0, comp->regs + DISP_REG_OVL_INTEN);
 }

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c 
b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
index 0df05f9..21eff6f 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
@@ -49,6 +49,11 @@ struct mtk_disp_rdma {
struct drm_crtc *crtc;
 };

+static inline struct mtk_disp_rdma *comp_to_rdma(struct mtk_ddp_comp *comp)
+{
+   return container_of(comp, struct mtk_disp_rdma, ddp_comp);
+}
+
 static irqreturn_t mtk_disp_rdma_irq_handler(int irq, void *dev_id)
 {
struct mtk_disp_rdma *priv = dev_id;
@@ -77,20 +82,18 @@ static void rdma_update_bits(struct mtk_ddp_comp *comp, 
unsigned int reg,
 static void mtk_rdma_enable_vblank(struct mtk_ddp_comp *comp,
   struct drm_crtc *crtc)
 {
-   struct mtk_disp_rdma *priv = container_of(comp, struct mtk_disp_rdma,
- ddp_comp);
+   struct mtk_disp_rdma *rdma = comp_to_rdma(comp);

-   priv->crtc = crtc;
+   rdma->crtc = crtc;
rdma_update_bits(comp, DISP_REG_RDMA_INT_ENABLE, RDMA_FRAME_END_INT,
 RDMA_FRAME_END_INT);
 }

 static void mtk_rdma_disable_vblank(struct mtk_ddp_comp *comp)
 {
-   struct mtk_disp_rdma *priv = container_of(comp, struct mtk_disp_rdma,
- ddp_comp);
+   struct mtk_disp_rdma *rdma = comp_to_rdma(comp);

-   priv->crtc = NULL;
+   rdma->crtc = NULL;
rdma_update_bits(comp, DISP_REG_RDMA_INT_ENABLE, RDMA_FRAME_END_INT, 0);
 }

-- 
1.9.1



[PATCH v10 00/13] MT2701 DRM support

2016-11-25 Thread YT Shen
This is MT2701 DRM support PATCH v10, based on 4.9-rc1.
We add DSI interrupt control, transfer function for MIPI DSI panel support.
Most codes are the same, except some register changed.

For example:
 - DISP_OVL address offset changed, color format definition changed.
 - DISP_RDMA fifo size changed.
 - DISP_COLOR offset changed.
 - MIPI_TX setting changed.

We add a new component DDP_COMPONENT_BLS, and the connections are updated.
OVL -> RDMA -> COLOR -> BLS -> DSI
RDMA -> DPI
And we have shadow register support in MT2701.

We remove dts patch from the patch series, which depends on MT2701 CCF and 
scpsys.

Changes since v9:
- Split DSI patches into smaller parts
- Use a real linux errno for return value
- Add error handling in mtk_output_dsi_enable()
- Remove unused changes and redundant delays
- Add helpers and macros for configuration
- Combine "drm/mediatek: rename macros, add chip prefix" and "drm/mediatek: add 
*driver_data for different hardware setting"

Changes since v8:
- enable 3 DSI interrupts only
- move mtk_dsi_wait_for_irq_done() to the patch of irq control
- use the name BLS in DRM driver part
- move BLS declaration to a separate patch
- update mtk_dsi_switch_to_cmd_mode()
- update mtk_output_dsi_enable() and mtk_output_dsi_disable()

Changes since v7:
- Remove redundant codes
- Move the definition of DDP_COMPONENT_BLS to patch of "drm/mediatek: update 
display module connections"
- Move _dsi_irq_wait_queue into platform driver data
- Move mtk_dsi_irq_data_clear() to patch of "drm/mediatek: add dsi interrupt 
control"
- Add more descriptions in the commit messages

Changes since v6:
- Change data type of irq_data to u32
- Rewrite mtk_dsi_host_transfer() for simplify
- Move some MIPI_TX config to patch of "drm/mediatek: add *driver_data for 
different hardware settings".
- Remove device tree from this patch series

Changes since v5:
- Remove DPI device tree and compatible string
- Use one wait queue to handle interrupt status
- Update the interrupt check flow and DSI_INT_ALL_BITS
- Use same function for host read/write command
- various fixes

Changes since v4:
- Add messages when timeout in mtk_disp_mutex_acquire()
- Add descriptions for DISP_REG_MUTEX registers
- Move connection settings for display modules to a separate patch
- Remove 'mt2701-disp-wdma' because it is unused
- Move cleaning up and renaming to a separate patch
- Use wait_event_interruptible_timeout() to replace polling
- Remove irq_num from mtk_dsi structure
- Remove redundant and debug codes

Changes since v3:
- Add DSI support for MIPI DSI panels
- Update BLS binding to PWM nodes
- Remove ufoe device nodes
- Remove redundant parentheses
- Remove global variable initialization

Changes since v2:
- Rename mtk_ddp_mux_sel to mtk_ddp_sout_sel
- Update mt2701_mtk_ddp_ext components
- Changed to prefix naming
- Reorder the patch series
- Use of_device_get_match_data() to get driver private data
- Use iopoll macros to implement mtk_disp_mutex_acquire()
- Removed empty device tree nodes

Changes since v1:
- Removed BLS bindings and codes, which belong to pwm driver
- Moved mtk_disp_mutex_acquire() just before mtk_crtc_ddp_config()
- Split patch into smaller parts
- Added const keyword to constant structure
- Removed codes for special memory align

Thanks,
yt.shen

YT Shen (11):
  drm/mediatek: add helpers for coverting from the generic components
  drm/mediatek: add *driver_data for different hardware settings
  drm/mediatek: add shadow register support
  drm/mediatek: add BLS component
  drm/mediatek: update display module connections
  drm/mediatek: cleaning up and refine
  drm/mediatek: add mipi_tx data rate check
  drm/mediatek: add dsi ulp mode control
  drm/mediatek: add dsi rxtx control
  drm/mediatek: update DSI sub driver flow for sending commands to panel
  drm/mediatek: add support for Mediatek SoC MT2701

shaoming chen (2):
  drm/mediatek: add dsi interrupt control
  drm/mediatek: add dsi transfer function

 drivers/gpu/drm/mediatek/mtk_disp_ovl.c |  64 +++--
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c|  39 ++-
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c |  76 +++--
 drivers/gpu/drm/mediatek/mtk_drm_ddp.c  | 138 ++---
 drivers/gpu/drm/mediatek/mtk_drm_ddp.h  |   2 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  41 ++-
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |   7 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c  |  54 +++-
 drivers/gpu/drm/mediatek/mtk_drm_drv.h  |   9 +
 drivers/gpu/drm/mediatek/mtk_dsi.c  | 430 
 drivers/gpu/drm/mediatek/mtk_mipi_tx.c  |  42 ++-
 11 files changed, 737 insertions(+), 165 deletions(-)

-- 
1.9.1



[PATCH v6 3/5] ARM: dts: sun8i-h3: add HDMI video nodes

2016-11-25 Thread Icenowy Zheng


25.11.2016, 18:22, "Jean-Francois Moine" :
> On Fri, 25 Nov 2016 17:41:51 +0800
> Icenowy Zheng  wrote:
>
>>  After removing CLK_PLL_DE's assigned-clock, the kernel passes compilation.
>
> The 'pll-de' and 'de' must have a fixed rate. Otherwise, if you do not
> use the legacy u-boot, I don't know which can be the rate of the DE.

Can't CCU deal with this?

I still kept the CLK_DE's assigned-clock...

>
>>  However, it cannot recognize any HDMI screen...
>>
>>  (My board is Orange Pi One, and I manually added status="okay"; to , 
>> , )
>>
>>  [ 16.507802] sun8i-de2 100.de-controller: bound 1c0c000.lcd-controller 
>> (ops de2_lcd_ops [sun8i_de2_drm])
>>  [ 16.675948] sun8i-de2 100.de-controller: bound 1ee.hdmi (ops 
>> de2_hdmi_fini [sun8i_de2_hdmi])
>>  [ 16.685120] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
>>  [ 16.695876] [drm] No driver support for vblank timestamp query.
>>  [ 16.701862] sun8i-de2 100.de-controller: No connectors reported 
>> connected with modes
>>  [ 16.713061] [drm] Cannot find any crtc or sizes - going 1024x768
>>  [ 16.734214] Console: switching to colour frame buffer device 128x48
>>  [ 16.751022] sun8i-de2 100.de-controller: fb0: frame buffer device
>
> I put a 'pr_warn' message is case the EDID cannot be read.
> Have you this message?

Seems no...

>
> Anyway, there is a problem with the EDID:
> - my Orange Pi 2 (H3) randomly fails to read it. But this succeeds after
>   rebooting once or twice.
> - my Banana Pi M2+ (H3) reads it correctly each time.
> - my Banana Pi M3 (A83T) can never read it.
>
> BTW, on first tries, I was forcing a CEA mode thru the kernel command
> line. This was working with the OPi2 and BPiM3, but there was no sound.
> In the last version, I use a EDID in edid_firmware for having sound
> with the BPiM3. This works fine.
> But, forcing a CEA mode is no more possible, so, when the OPi2 cannot
> read the EDID, the system switches to a VGA mode (default 1024x768)
> which is not supported. It seems that this is your case.
>
> So, in brief, if your board cannot read the EDID, put a EDID somewhere
> and its path in /sys/module/drm_kms_helper/parameters/edid_firmware.
> There will be no console, but X11 will work correctly.

The problem seems to be that the CRTC is not properly initialized...

>
> --
> Ken ar c'hentañ | ** Breizh ha Linux atav! **
> Jef | http://moinejf.free.fr/


Question regarding clocks in the DW-HDMI DT bindings

2016-11-25 Thread Laurent Pinchart
Hi Fabio,

On Friday 25 Nov 2016 13:29:37 Fabio Estevam wrote:
> On Fri, Nov 25, 2016 at 1:22 PM, Laurent Pinchart wrote:
> >> I got the clock name from I.MX6Q TRM, I also checked the name again
> >> with Rockchip IC design team now, hope to get some new information soon.
> > 
> > Thank you. While at it, could you ask them which version of the DW HDMI IP
> > used in the SoC ?
> 
> DW HDMI IP used in Rockchip is:
> dwhdmi-rockchip ff98.hdmi: Detected HDMI controller 0x20:0xa:0xa0:0xc1
> 
> as shown at
> https://storage.kernelci.org/mainline/v4.9-rc6-157-g16ae16c6e561/arm-multi_
> v7_defconfig/lab-collabora/boot-rk3288-rock2-square_rootfs:nfs.html
> 
> DW HDMI IP used  on mx6q is:
> dwhdmi-imx 12.hdmi: Detected HDMI controller 0x13:0xa:0xa0:0xc1

Thank you for the information. This is what I get on the Renesas R-Car H3.

rcar-dw-hdmi fead.hdmi0: Detected HDMI controller 0x20:0x1a:0xa0:0xc1
rcar-dw-hdmi feae.hdmi1: Detected HDMI controller 0x20:0x1a:0xa0:0xc1

-- 
Regards,

Laurent Pinchart



Question regarding clocks in the DW-HDMI DT bindings

2016-11-25 Thread Laurent Pinchart
Hi Philipp,

On Friday 25 Nov 2016 10:56:55 Philipp Zabel wrote:
> Am Donnerstag, den 24.11.2016, 23:16 +0200 schrieb Laurent Pinchart:
> > Hi Andy,
> > 
> > As the author of the DW-HDMI DT bindings this question is addressed to
> > you, but information from anyone is more than welcome.
> > 
> > The DT bindings specify two clocks named "iahb" and "isfr" but don't
> > describe them. While I assume that the "isfr" clock corresponds to the
> > "isfrclk" input signal of the DW HDMI, there is no "iahb" clock described
> > in the IP core datasheet.
> 
> The Table 33-1 "HDMI clocks" in the i.MX6DQ reference manual [1] lists
> iahbclk (AHB bus clock), icecclk (32 kHz CEC clock), ihclk (module
> clock) and isfrclk (27 MHz internal SFR clock).
> 
> [1]
> http://www.nxp.com/assets/documents/data/en/reference-manuals/IMX6DQRM.pdf
>
> > The DW HDMI IP exposes control registers through an APB, not an AHB. There
> > is a bus clock named "iapbclk", is "iahb" just an incorrect name for that
> > clock ?
>
> According to figure 33-3 "HDMI TX Top Level Block Diagram" the control
> interface is AMBA AHB on i.MX6. Both iahbclk and ihclk are clocked by
> ahb_clk_root on i.MX6.
>
> Register 5 (HDMI_CONFIG1_ID) contains a few bits (confsfrdir, confi2c,
> confocp, confapb, confahb) that indicate which control interface is
> used.

That's interesting. The DW HDMI TX documentation I found (1.40a-ea00, Early 
Adopter Edition) only has the confahb bit in that register. Do you know which 
version of the IP is used in iMX.6 ? I wonder whether the above is a 
Freescale-specific modification to the IP core.

I'm also a bit puzzled by the differences in the HDMI PHY between Freescale 
and Renesas. The Renesas datasheet documents three registers only for the PHY 
(other might exist and be undocumented), and while they contain fields similar 
to the ones documented in the Freescale datasheet, the exact register layouts 
are different.

-- 
Regards,

Laurent Pinchart



[PATCH v6 3/5] ARM: dts: sun8i-h3: add HDMI video nodes

2016-11-25 Thread Icenowy Zheng


20.11.2016, 20:12, "Jean-Francois Moine" :
> Signed-off-by: Jean-Francois Moine 
> ---
>  arch/arm/boot/dts/sun8i-h3.dtsi | 51 
> +
>  1 file changed, 51 insertions(+)
>
> diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi
> index 416b825..7c6b1d5 100644
> --- a/arch/arm/boot/dts/sun8i-h3.dtsi
> +++ b/arch/arm/boot/dts/sun8i-h3.dtsi
> @@ -140,6 +140,16 @@
>                  #size-cells = <1>;
>                  ranges;
>
> + de: de-controller at 0100 {
> + compatible = "allwinner,sun8i-h3-display-engine";
> + reg = <0x0100 0x40>;
> + clocks = < CLK_BUS_DE>, < CLK_DE>;
> + clock-names = "bus", "clock";
> + resets = < RST_BUS_DE>;
> + ports = <_p>;
> + status = "disabled";
> + };
> +
>                  dma: dma-controller at 01c02000 {
>                          compatible = 
> "allwinner,sun8i-h3-dma";
>                          reg = <0x01c02000 0x1000>;
> @@ -149,6 +159,23 @@
>                          #dma-cells = <1>;
>                  };
>
> + lcd0: lcd-controller at 01c0c000 {
> + compatible = "allwinner,sun8i-a83t-tcon";
> + reg = <0x01c0c000 0x400>;
> + clocks = < CLK_BUS_TCON0>, < CLK_TCON0>;
> + clock-names = "bus", "clock";
> + resets = < RST_BUS_TCON0>;
> + interrupts = ;
> + status = "disabled";
> + #address-cells = <1>;
> + #size-cells = <0>;
> + lcd0_p: port {
> + lcd0_hdmi: endpoint {
> + remote-endpoint = <_lcd0>;
> + };
> + };
> + };
> +
>                  mmc0: mmc at 01c0f000 {
>                          compatible = 
> "allwinner,sun7i-a20-mmc";
>                          reg = <0x01c0f000 0x1000>;
> @@ -314,6 +341,11 @@
>                          clock-names = "hosc", 
> "losc";
>                          #clock-cells = <1>;
>                          #reset-cells = <1>;
> +
> + assigned-clocks = < CLK_PLL_DE>,
> + < CLK_DE>;
> + assigned-clock-rates = <86400>,
> + <43200>;
>                  };
>
>                  pio: pinctrl at 01c20800 {
> @@ -564,6 +596,25 @@
>                          interrupts =  (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
>                  };
>
> + hdmi: hdmi at 01ee {
> + compatible = "allwinner,sun8i-h3-hdmi";
> + reg = <0x01ee 0x2>;
> + clocks = < CLK_BUS_HDMI>, < CLK_HDMI>,
> + < CLK_HDMI_DDC>;
> + clock-names = "bus", "clock", "ddc-clock";
> + resets = < RST_BUS_HDMI0>, < RST_BUS_HDMI1>;
> + reset-names = "hdmi0", "hdmi1";
> + status = "disabled";
> + #address-cells = <1>;
> + #size-cells = <0>;
> + port at 0 { /* video */
> + reg = <0>;
> + hdmi_lcd0: endpoint {
> + remote-endpoint = <_hdmi>;
> + };
> + };
> + };
> +
>                  rtc: rtc at 01f0 {
>                          compatible = 
> "allwinner,sun6i-a31-rtc";
>                          reg = <0x01f0 0x54>;

After removing CLK_PLL_DE's assigned-clock, the kernel passes compilation.

However, it cannot recognize any HDMI screen...

(My board is Orange Pi One, and I manually added status="okay"; to , , 
)

[   16.507802] sun8i-de2 100.de-controller: bound 1c0c000.lcd-controller 
(ops de2_lcd_ops [sun8i_de2_drm])
[   16.675948] sun8i-de2 100.de-controller: bound 1ee.hdmi (ops 
de2_hdmi_fini [sun8i_de2_hdmi])
[   16.685120] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
[   16.695876] [drm] No driver support for vblank timestamp query.
[   16.701862] sun8i-de2 100.de-controller: No connectors reported 
connected with modes
[   16.713061] [drm] Cannot find any crtc or sizes - going 1024x768
[   16.734214] Console: switching to colour frame buffer device 128x48
[   16.751022] sun8i-de2 100.de-controller: fb0:  frame buffer device

> --
> 2.10.2
>
> ___
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


Question regarding clocks in the DW-HDMI DT bindings

2016-11-25 Thread Laurent Pinchart
Hi Andy,

On Friday 25 Nov 2016 10:56:53 Andy Yan wrote:
> On 2016年11月25日 07:26, Laurent Pinchart wrote:
> > On Friday 25 Nov 2016 00:16:00 Vladimir Zapolskiy wrote:
> >> On 11/25/2016 12:07 AM, Fabio Estevam wrote:
> >>> On Thu, Nov 24, 2016 at 7:16 PM, Laurent Pinchart wrote:
>  Hi Andy,
>  
>  As the author of the DW-HDMI DT bindings this question is addressed to
>  you, but information from anyone is more than welcome.
>  
>  The DT bindings specify two clocks named "iahb" and "isfr" but don't
>  describe them. While I assume that the "isfr" clock corresponds to the
>  "isfrclk" input signal of the DW HDMI, there is no "iahb" clock
>  described in the IP core datasheet.
> >>> 
> >>> i.MX6Q has a DW-HDMI IP block.
> >>> 
> >>> The names in the devicetree binding matches the ones listed at the
> >>> i.MX6Q Reference Manual - Table 33-1. HDMI Clocks
> >> 
> >> correct, for your convenience the table is copied below:
> >> 
> >> Clock name | Clock Root | Description
> >> ---++---
> >>   iahbclk  | ahb_clk_root   | Bus clock
> >>   icecclk  | ckil_sync_clk_root | CEC low-frequency clock (32kHZ)
> >>   ihclk| ahb_clk_root   | Module clock
> >>   isfrclk  | video_27m_clk_root | Internal SFR clock (video clock
> >>   27MHz)
> >> 
> >> Here AHB stands for ARM Advanced High-performance Bus.
> > 
> > That's what I suspected. I believe the "iahb" name is wrong, as the DW
> > HDMI TX IP core clearly documents the bus clock as being called
> > "iapbclk". We could rename that in the DT bindings (with compatibility
> > code in the driver to keep supporting the old name) but it might not be
> > worth it. The bindings should however document that the "iahb" clock is
> > the IP core's "iapbclk" bus clock.
>
> I got the clock name from I.MX6Q TRM, I also checked the name again
> with Rockchip IC design team now, hope to get some new information soon.

Thank you. While at it, could you ask them which version of the DW HDMI IP 
used in the SoC ?

> > Another question I have about the bus clock (CC'ing the devicetree mailing
> > list as well as the clock maintainers) is whether it should be made
> > optional. The clock is obviously mandatory from a hardware point of view
> > (given that APB is a synchronous bus and thus requires a clock), but in
> > some SoCs (specifically for the Renesas SoCs) that clock is always on and
> > can't be controlled. We already omit bus clocks in DT for most IP cores
> > when the clock can never be controlled (and we also omit a bunch of other
> > clocks that we don't even know exist), so it could make sense to make the
> > clock optional. Otherwise there would be runtime overhead trying to handle
> > a clock that can't be controlled.
> 
> If this is the case on Renesas SOCs, we can consider make the clock as
> optional. Or move all the clock operations to platform specific
> code(dw_hdmi-rockchip.c/dw_hdmi-imx.c)?

I'd prefer keeping the code generic, otherwise we'd end up with platform-
specific code that would perform the same operations on most platforms. I'll 
submit a patch soon to make the clock optional, we can discuss it then.

> >> By the way while we're discussing DW HDMI bindings specific to iMX,
> >> I would recommend to remove utterly hackish and iMX only "gpr"
> >> property from the example in bindings/display/bridge/dw_hdmi.txt

-- 
Regards,

Laurent Pinchart



[Bug 98856] Dirt: Showdown broken graphics

2016-11-25 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=98856

Bug ID: 98856
   Summary: Dirt: Showdown broken graphics
   Product: Mesa
   Version: git
  Hardware: x86-64 (AMD64)
OS: Linux (All)
Status: NEW
  Severity: normal
  Priority: medium
 Component: Drivers/Gallium/radeonsi
  Assignee: dri-devel at lists.freedesktop.org
  Reporter: gr.muench at gmail.com
QA Contact: dri-devel at lists.freedesktop.org

For about 4 weeks the game has polygon distortion especially on the Nevada map.
Its not on every map but it can be seen with the ingame benchmark.


Im on:
Radeon HD 7970
OpenGL renderer string: Gallium 0.4 on AMD TAHITI (DRM 2.48.0 /
4.9.0-rc4-gbc33b0c, LLVM 4.0.0)
OpenGL core profile version string: 4.5 (Core Profile) Mesa 13.1.0-devel
(git-b27be18)

-- 
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/20161125/3e2cbfce/attachment-0001.html>


Question regarding clocks in the DW-HDMI DT bindings

2016-11-25 Thread Philipp Zabel
Am Freitag, den 25.11.2016, 17:45 +0200 schrieb Laurent Pinchart:
> Hi Philipp,
> 
> On Friday 25 Nov 2016 10:56:55 Philipp Zabel wrote:
> > Am Donnerstag, den 24.11.2016, 23:16 +0200 schrieb Laurent Pinchart:
> > > Hi Andy,
> > > 
> > > As the author of the DW-HDMI DT bindings this question is addressed to
> > > you, but information from anyone is more than welcome.
> > > 
> > > The DT bindings specify two clocks named "iahb" and "isfr" but don't
> > > describe them. While I assume that the "isfr" clock corresponds to the
> > > "isfrclk" input signal of the DW HDMI, there is no "iahb" clock described
> > > in the IP core datasheet.
> > 
> > The Table 33-1 "HDMI clocks" in the i.MX6DQ reference manual [1] lists
> > iahbclk (AHB bus clock), icecclk (32 kHz CEC clock), ihclk (module
> > clock) and isfrclk (27 MHz internal SFR clock).
> > 
> > [1]
> > http://www.nxp.com/assets/documents/data/en/reference-manuals/IMX6DQRM.pdf
> >
> > > The DW HDMI IP exposes control registers through an APB, not an AHB. There
> > > is a bus clock named "iapbclk", is "iahb" just an incorrect name for that
> > > clock ?
> >
> > According to figure 33-3 "HDMI TX Top Level Block Diagram" the control
> > interface is AMBA AHB on i.MX6. Both iahbclk and ihclk are clocked by
> > ahb_clk_root on i.MX6.
> >
> > Register 5 (HDMI_CONFIG1_ID) contains a few bits (confsfrdir, confi2c,
> > confocp, confapb, confahb) that indicate which control interface is
> > used.
> 
> That's interesting. The DW HDMI TX documentation I found (1.40a-ea00, Early 
> Adopter Edition) only has the confahb bit in that register. Do you know which 
> version of the IP is used in iMX.6 ? I wonder whether the above is a 
> Freescale-specific modification to the IP core.

The driver reports:

dwhdmi-imx 12.hdmi: Detected HDMI controller 0x13:0xa:0xa0:0xc1

That is DESIGN_ID 0x13, REVISION_ID 0x0a.

> I'm also a bit puzzled by the differences in the HDMI PHY between Freescale 
> and Renesas. The Renesas datasheet documents three registers only for the PHY 
> (other might exist and be undocumented), and while they contain fields 
> similar 
> to the ones documented in the Freescale datasheet, the exact register layouts 
> are different.

Do you mean the HDMI_PHY_* registers in the HDMI TX register space or
the separate HDMI PHY i2c registers? The PHY may very well be completely
different. I think OMAP5 HDMI driver uses the same DesignWare HDMI TX as
i.MX6, but not the same PHY.

regards
Philipp



[PATCH 3/3] ARM: dts: da850: enable the memctrl and mstpri nodes per board

2016-11-25 Thread Bartosz Golaszewski
Currently the memory controller and master priorities drivers are
enabled in da850.dtsi. For boards for which there are no settings
defined, this makes these drivers emit error messages.

Disable the nodes in da850.dtsi and only enable them for da850-lcdk -
the only board that currently needs them.

Signed-off-by: Bartosz Golaszewski 
---
 arch/arm/boot/dts/da850-lcdk.dts | 8 
 arch/arm/boot/dts/da850.dtsi | 2 ++
 2 files changed, 10 insertions(+)

diff --git a/arch/arm/boot/dts/da850-lcdk.dts b/arch/arm/boot/dts/da850-lcdk.dts
index 6952c68..d0f7680 100644
--- a/arch/arm/boot/dts/da850-lcdk.dts
+++ b/arch/arm/boot/dts/da850-lcdk.dts
@@ -285,3 +285,11 @@
remote-endpoint = <_bridge_in>;
};
 };
+
+ {
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi
index 9b7c444..2ea0e06 100644
--- a/arch/arm/boot/dts/da850.dtsi
+++ b/arch/arm/boot/dts/da850.dtsi
@@ -213,6 +213,7 @@
prictrl: priority-controller at 14110 {
compatible = "ti,da850-mstpri";
reg = <0x14110 0x0c>;
+   status = "disabled";
};
cfgchip: chip-controller at 1417c {
compatible = "ti,da830-cfgchip", "syscon", "simple-mfd";
@@ -486,5 +487,6 @@
memctrl: memory-controller at b000 {
compatible = "ti,da850-ddr-controller";
reg = <0xb000 0xe8>;
+   status = "disabled";
};
 };
-- 
2.9.3



[PATCH 2/3] ARM: dts: da850: specify the maximum bandwidth for tilcdc

2016-11-25 Thread Bartosz Golaszewski
It has been determined that the maximum resolution supported correctly
by tilcdc rev1 on da850 SoCs is 800x600 at 60. Due to memory throughput
constraints we must filter out higher modes.

Specify the max-bandwidth property for the display node for
da850-based boards.

Signed-off-by: Bartosz Golaszewski 
---
 arch/arm/boot/dts/da850.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi
index 8e30d9b..9b7c444 100644
--- a/arch/arm/boot/dts/da850.dtsi
+++ b/arch/arm/boot/dts/da850.dtsi
@@ -452,6 +452,7 @@
compatible = "ti,da850-tilcdc";
reg = <0x213000 0x1000>;
interrupts = <52>;
+   max-bandwidth = <2880>;
status = "disabled";

ports {
-- 
2.9.3



[PATCH 1/3] ARM: da850-lcdk: add the dumb-vga-dac node

2016-11-25 Thread Bartosz Golaszewski
Add the dumb-vga-dac node to the board DT together with corresponding
ports and vga connector. This allows to retrieve the edid info from
the display automatically.

Signed-off-by: Bartosz Golaszewski 
---
 arch/arm/boot/dts/da850-lcdk.dts | 58 
 arch/arm/boot/dts/da850.dtsi | 17 
 2 files changed, 75 insertions(+)

diff --git a/arch/arm/boot/dts/da850-lcdk.dts b/arch/arm/boot/dts/da850-lcdk.dts
index 8411a91..6952c68 100644
--- a/arch/arm/boot/dts/da850-lcdk.dts
+++ b/arch/arm/boot/dts/da850-lcdk.dts
@@ -50,6 +50,53 @@
system-clock-frequency = <24576000>;
};
};
+
+   vga_bridge {
+   compatible = "dumb-vga-dac";
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins>;
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   port at 0 {
+   #address-cells = <1>;
+   #size-cells = <0>;
+   reg = <0>;
+
+   vga_bridge_in: endpoint at 0 {
+   reg = <0>;
+   remote-endpoint = <_out_vga>;
+   };
+   };
+
+   port at 1 {
+   #address-cells = <1>;
+   #size-cells = <0>;
+   reg = <1>;
+
+   vga_bridge_out: endpoint at 0 {
+   reg = <0>;
+   remote-endpoint = <_con_in>;
+   };
+   };
+   };
+   };
+
+   vga {
+   compatible = "vga-connector";
+
+   ddc-i2c-bus = <>;
+
+   port {
+   vga_con_in: endpoint {
+   remote-endpoint = <_bridge_out>;
+   };
+   };
+   };
 };

 _core {
@@ -227,3 +274,14 @@
};
};
 };
+
+ {
+   status = "okay";
+};
+
+_out {
+   display_out_vga: endpoint at 0 {
+   reg = <0>;
+   remote-endpoint = <_bridge_in>;
+   };
+};
diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi
index ff13e95..8e30d9b 100644
--- a/arch/arm/boot/dts/da850.dtsi
+++ b/arch/arm/boot/dts/da850.dtsi
@@ -453,6 +453,23 @@
reg = <0x213000 0x1000>;
interrupts = <52>;
status = "disabled";
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   display_in: port at 0 {
+   #address-cells = <1>;
+   #size-cells = <0>;
+   reg = <0>;
+   };
+
+   display_out: port at 1 {
+   #address-cells = <1>;
+   #size-cells = <0>;
+   reg = <1>;
+   };
+   };
};
};
aemif: aemif at 6800 {
-- 
2.9.3



[PATCH 0/3] ARM: dts: da850: tilcdc related DT changes

2016-11-25 Thread Bartosz Golaszewski
I previously sent these patches separately, but since they're touching
the same files while coming from different trees, I decided to post
it again in a series to make applying them easier.

Bartosz Golaszewski (3):
  ARM: da850-lcdk: add the dumb-vga-dac node
  ARM: dts: da850: specify the maximum bandwidth for tilcdc
  ARM: dts: da850: enable the memctrl and mstpri nodes per board

 arch/arm/boot/dts/da850-lcdk.dts | 66 
 arch/arm/boot/dts/da850.dtsi | 20 
 2 files changed, 86 insertions(+)

-- 
2.9.3



[RFC PATCH 3/3] dt-bindings: display: add Amlogic Meson DRM Bindings

2016-11-25 Thread Neil Armstrong
Signed-off-by: Neil Armstrong 
---
 .../bindings/display/meson/meson-drm.txt   | 134 +
 1 file changed, 134 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/meson/meson-drm.txt

diff --git a/Documentation/devicetree/bindings/display/meson/meson-drm.txt 
b/Documentation/devicetree/bindings/display/meson/meson-drm.txt
new file mode 100644
index 000..89c1b5f
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/meson/meson-drm.txt
@@ -0,0 +1,134 @@
+Amlogic Meson Display Controller
+
+
+The Amlogic Meson Display controller is composed of several components
+that are going to be documented below:
+
+DMC|---VPU (Video Processing Unit)|--HHI--|
+   | vd1   ___ __ |   |
+D  |---|  |||   |||   HDMI PLL|
+D  | vd2   | VIU  || Video Post |   | Video Encoders |<---|-VCLK  |
+R  |---|  || Processing |   |||   |
+   | osd2  |  |||---| Enci --||-VDAC--|
+R  |---| CSC  || Scalers|   | Encp --||HDMI-TX|
+A  | osd1  |  || Blenders   |   | Encl --||---|
+M  |---|__|||   |||   |
+___|__|___|
+
+
+VIU: Video Input Unit
+-
+
+The Video Input Unit is in charge of the pixel scanout from the DDR memory.
+It fetches the frames addresses, stride and parameters from the "Canvas" 
memory.
+This part is also in charge of the CSC (Colorspace Conversion).
+It can handle 2 OSD Planes and 2 Video Planes.
+
+VPP: Video Processing Unit
+--
+
+The Video Processing Unit is in charge if the scaling and blending of the
+various planes into a single pixel stream.
+There is a special "pre-blending" used by the video planes with a dedicated
+scaler and a "post-blending" to merge with the OSD Planes.
+The OSD planes also have a dedicated scaler for one of the OSD.
+
+VENC: Video Encoders
+
+
+The VENC is composed of the multiple pixel encoders :
+ - ENCI : Interlace Video encoder for CVBS and Interlace HDMI
+ - ENCP : Progressive Video Encoder for HDMI
+ - ENCL : LCD LVDS Encoder
+The VENC Unit gets a Pixel Clocks (VCLK) from a dedicated HDMI PLL and clock
+tree and provides the scanout clock to the VPP and VIU.
+The ENCI is connected to a single VDAC for Composite Output.
+The ENCI and ENCP are connected to an on-chip HDMI Transceiver.
+
+Device Tree Bindings:
+-
+
+VPU: Video Processing Unit
+--
+
+Required properties:
+ - compatible: value should be different for each SoC family as :
+   - GXBB (S905) : "amlogic,meson-gxbb-vpu"
+   - GXL (S905X, S905D) : "amlogic,meson-gxl-vpu"
+   - GXM (S912) : "amlogic,meson-gxm-vpu"
+   followed by the common "amlogic,meson-gx-vpu"
+ - reg: base address and size of he following memory-mapped regions :
+   - vpu
+   - hhi
+   - dmc
+ - reg-names: should contain the names of the previous memory regions
+ - interrupts: should contain the VENC Vsync interrupt number
+
+- ports: A ports node with endpoint definitions as defined in
+  Documentation/devicetree/bindings/media/video-interfaces.txt. The
+  second port should be the output endpoints for VENC connectors.
+
+VENC CBVS Output
+--
+
+The VENC can output Composite/CVBS output via a decicated VDAC.
+
+Required properties:
+  - compatible: value must be one of:
+ - compatible: value should be different for each SoC family as :
+   - GXBB (S905) : "amlogic,meson-gxbb-venc-cvbs"
+   - GXL (S905X, S905D) : "amlogic,meson-gxl-venc-cvbs"
+   - GXM (S912) : "amlogic,meson-gxm-venc-cvbs"
+   followed by the common "amlogic,meson-gx-venc-cvbs"
+
+- ports: A ports node with endpoint definitions as defined in
+  Documentation/devicetree/bindings/media/video-interfaces.txt. The
+  first port should be the input endpoints, connected ot the VPU node.
+
+Example:
+
+venc_cvbs: venc-cvbs {
+   compatible = "amlogic,meson-gxbb-venc-cvbs";
+   status = "okay";
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   enc_cvbs_in: port at 0 {
+#address-cells = <1>;
+#size-cells = <0>;
+reg = <0>;
+
+venc_cvbs_in_vpu: endpoint at 0 {
+reg = <0>;
+remote-endpoint = <_out_venc_cvbs>;
+   };
+   };
+   };
+};
+
+vpu: vpu at d010 {
+   compatible = "amlogic,meson-gxbb-vpu";
+   reg = <0x0 0xd010 0x0 0x10>,
+ <0x0 

[RFC PATCH 2/3] ARM64: dts: meson-gx: Add Graphic Controller nodes

2016-11-25 Thread Neil Armstrong
Add Video Processing Unit and CVBS Output nodes, and enable CVBS on selected
boards.

Signed-off-by: Neil Armstrong 
---
 arch/arm64/boot/dts/amlogic/meson-gx.dtsi  | 46 ++
 .../boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts|  4 ++
 arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi   |  4 ++
 arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi| 12 ++
 .../boot/dts/amlogic/meson-gxl-nexbox-a95x.dts |  4 ++
 arch/arm64/boot/dts/amlogic/meson-gxl.dtsi |  8 
 .../arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts |  4 ++
 arch/arm64/boot/dts/amlogic/meson-gxm.dtsi |  9 +
 8 files changed, 91 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi 
b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
index fc033c0..bcc1d1f 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
@@ -153,6 +153,27 @@
};
};

+   venc_cvbs: venc-cvbs {
+   compatible = "amlogic,meson-gx-venc-cvbs";
+   status = "disabled";
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   enc_cvbs_in: port at 0 {
+#address-cells = <1>;
+#size-cells = <0>;
+reg = <0>;
+
+venc_cvbs_in_vpu: endpoint at 0 {
+reg = <0>;
+remote-endpoint = <_out_venc_cvbs>;
+   };
+   };
+   };
+   };
+
soc {
compatible = "simple-bus";
#address-cells = <2>;
@@ -356,5 +377,30 @@
status = "disabled";
};
};
+
+   vpu: vpu at d010 {
+   compatible = "amlogic,meson-gx-vpu";
+   reg = <0x0 0xd010 0x0 0x10>,
+ <0x0 0xc883c000 0x0 0x1000>,
+ <0x0 0xc8838000 0x0 0x1000>;
+   reg-names = "base", "hhi", "dmc";
+   interrupts = ;
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   vpu_out: port at 1 {
+   #address-cells = <1>;
+   #size-cells = <0>;
+   reg = <1>;
+
+   vpu_out_venc_cvbs: endpoint at 0 {
+   reg = <0>;
+   remote-endpoint = 
<_cvbs_in_vpu>;
+   };
+   };
+   };
+   };
};
 };
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts 
b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts
index 9696820..a55d1cf 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts
@@ -229,3 +229,7 @@
clocks = < CLKID_FCLK_DIV4>;
clock-names = "clkin0";
 };
+
+_cvbs {
+   status = "okay";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi 
b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi
index 5e5e2de..3c09bd1 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi
@@ -266,3 +266,7 @@
clocks = < CLKID_FCLK_DIV4>;
clock-names = "clkin0";
 };
+
+_cvbs {
+   status = "okay";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi 
b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
index ac5ad3b..99ff37c 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
@@ -506,3 +506,15 @@
 < CLKID_FCLK_DIV2>;
clock-names = "core", "clkin0", "clkin1";
 };
+
+_cvbs {
+   status = "okay";
+};
+
+_cvbs {
+   compatible = "amlogic,meson-gxbb-venc-cvbs", 
"amlogic,meson-gx-venc-cvbs";
+};
+
+ {
+   compatible = "amlogic,meson-gxbb-vpu", "amlogic,meson-gx-vpu";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-nexbox-a95x.dts 
b/arch/arm64/boot/dts/amlogic/meson-gxl-nexbox-a95x.dts
index e99101a..2a9b46f 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-nexbox-a95x.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-nexbox-a95x.dts
@@ -203,3 +203,7 @@
clocks = < CLKID_FCLK_DIV4>;
clock-names = "clkin0";
 };
+
+_cvbs {
+   status = "okay";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi 
b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
index 3af54dc..98b8118 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi

[RFC PATCH 1/3] drm: Add support for Amlogic Meson Graphic Controller

2016-11-25 Thread Neil Armstrong
The Amlogic Meson Display controller is composed of several components :

DMC|---VPU (Video Processing Unit)|--HHI--|
   | vd1   ___ __ |   |
D  |---|  |||   |||   HDMI PLL|
D  | vd2   | VIU  || Video Post |   | Video Encoders |<---|-VCLK  |
R  |---|  || Processing |   |||   |
   | osd2  |  |||---| Enci --||-VDAC--|
R  |---| CSC  || Scalers|   | Encp --||HDMI-TX|
A  | osd1  |  || Blenders   |   | Encl --||---|
M  |---|__|||   |||   |
___|__|___|


VIU: Video Input Unit
-

The Video Input Unit is in charge of the pixel scanout from the DDR memory.
It fetches the frames addresses, stride and parameters from the "Canvas" memory.
This part is also in charge of the CSC (Colorspace Conversion).
It can handle 2 OSD Planes and 2 Video Planes.

VPP: Video Processing Unit
--

The Video Processing Unit is in charge if the scaling and blending of the
various planes into a single pixel stream.
There is a special "pre-blending" used by the video planes with a dedicated
scaler and a "post-blending" to merge with the OSD Planes.
The OSD planes also have a dedicated scaler for one of the OSD.

VENC: Video Encoders


The VENC is composed of the multiple pixel encoders :
 - ENCI : Interlace Video encoder for CVBS and Interlace HDMI
 - ENCP : Progressive Video Encoder for HDMI
 - ENCL : LCD LVDS Encoder
The VENC Unit gets a Pixel Clocks (VCLK) from a dedicated HDMI PLL and clock
tree and provides the scanout clock to the VPP and VIU.
The ENCI is connected to a single VDAC for Composite Output.
The ENCI and ENCP are connected to an on-chip HDMI Transceiver.

This driver is a DRM/KMS driver using the following DRM components :
 - GEM-CMA
 - PRIME-CMA
 - Atomic Modesetting
 - FBDev-CMA

For the following SoCs :
 - GXBB Family (S905)
 - GXL Family (S905X, S905D)
 - GXM Family (S912)

The current driver only supports the CVBS PAL/NTSC output modes, but the
CRTC/Planes management should support bigger modes.
But Advanced Colorspace Conversion, Scaling and HDMI Modes will be added in
a second time.

The Device Tree bindings makes use of the endpoints video interface definitions
to connect to the optional CVBS and in the future the HDMI Connector nodes.

HDMI Support is planned for a next release.

Signed-off-by: Neil Armstrong 
---
 drivers/gpu/drm/Kconfig |2 +
 drivers/gpu/drm/Makefile|1 +
 drivers/gpu/drm/meson/Kconfig   |8 +
 drivers/gpu/drm/meson/Makefile  |5 +
 drivers/gpu/drm/meson/meson_canvas.c|   96 +++
 drivers/gpu/drm/meson/meson_canvas.h|   31 +
 drivers/gpu/drm/meson/meson_crtc.c  |  176 
 drivers/gpu/drm/meson/meson_crtc.h  |   34 +
 drivers/gpu/drm/meson/meson_cvbs.c  |  293 +++
 drivers/gpu/drm/meson/meson_cvbs.h  |   32 +
 drivers/gpu/drm/meson/meson_drv.c   |  383 +
 drivers/gpu/drm/meson/meson_drv.h   |   68 ++
 drivers/gpu/drm/meson/meson_plane.c |  150 
 drivers/gpu/drm/meson/meson_plane.h |   32 +
 drivers/gpu/drm/meson/meson_registers.h | 1395 +++
 drivers/gpu/drm/meson/meson_vclk.c  |  169 
 drivers/gpu/drm/meson/meson_vclk.h  |   36 +
 drivers/gpu/drm/meson/meson_venc.c  |  286 +++
 drivers/gpu/drm/meson/meson_venc.h  |   77 ++
 drivers/gpu/drm/meson/meson_viu.c   |  497 +++
 drivers/gpu/drm/meson/meson_viu.h   |   37 +
 drivers/gpu/drm/meson/meson_vpp.c   |  189 +
 drivers/gpu/drm/meson/meson_vpp.h   |   43 +
 23 files changed, 4040 insertions(+)
 create mode 100644 drivers/gpu/drm/meson/Kconfig
 create mode 100644 drivers/gpu/drm/meson/Makefile
 create mode 100644 drivers/gpu/drm/meson/meson_canvas.c
 create mode 100644 drivers/gpu/drm/meson/meson_canvas.h
 create mode 100644 drivers/gpu/drm/meson/meson_crtc.c
 create mode 100644 drivers/gpu/drm/meson/meson_crtc.h
 create mode 100644 drivers/gpu/drm/meson/meson_cvbs.c
 create mode 100644 drivers/gpu/drm/meson/meson_cvbs.h
 create mode 100644 drivers/gpu/drm/meson/meson_drv.c
 create mode 100644 drivers/gpu/drm/meson/meson_drv.h
 create mode 100644 drivers/gpu/drm/meson/meson_plane.c
 create mode 100644 drivers/gpu/drm/meson/meson_plane.h
 create mode 100644 drivers/gpu/drm/meson/meson_registers.h
 create mode 100644 drivers/gpu/drm/meson/meson_vclk.c
 create mode 100644 drivers/gpu/drm/meson/meson_vclk.h
 create mode 100644 drivers/gpu/drm/meson/meson_venc.c
 create mode 100644 drivers/gpu/drm/meson/meson_venc.h
 create mode 100644 drivers/gpu/drm/meson/meson_viu.c
 create 

[RFC PATCH 0/3] drm: Add support for the Amlogic Video Processing Unit

2016-11-25 Thread Neil Armstrong
The Amlogic Meson SoCs embeds a Video Processing Unit able to output at least
a Composite/CVBS Video with embedded VDAC and an HDMI Link with Embedded HDMI
Transceiver.

Thus, the current driver does not support HDMI yet.

The Video Processig Unit is composed of multiple modules like the Video
Input Unit and the Video Post Processing that can be associated to a
CRTC with Planes management.
The last Unit is the Venc that embeds at least 3 Encoders, ENCI for Interlace
Video used by CVBS or HDMI, ENCP for Progressive Video used by the HDMI
Transceiver and ENCL for LCD Display.

The LCD Display is not planned to be supported on the Meson GX Family.

This driver is a DRM/KMS driver using the following DRM components :
 - GEM-CMA
 - PRIME-CMA
 - Atomic Modesetting
 - FBDev-CMA

For the following SoCs :
 - GXBB Family (S905)
 - GXL Family (S905X, S905D)
 - GXM Family (S912)

The current driver only supports the CVBS PAL/NTSC output modes, but the
CRTC/Planes management should support bigger modes.
But Advanced Colorspace Conversion, Scaling and HDMI Modes will be added in
a second time.

The Device Tree bindings makes use of the endpoints video interface definitions
to connect to the optional CVBS and in the future the HDMI Connector nodes.

The driver has been tested with Xorg modesetting driver and Weston DRM backend.

Neil Armstrong (3):
  drm: Add support for Amlogic Meson Graphic Controller
  ARM64: dts: meson-gx: Add Graphic Controller nodes
  dt-bindings: display: add Amlogic Meson DRM Bindings

 .../bindings/display/meson/meson-drm.txt   |  134 ++
 arch/arm64/boot/dts/amlogic/meson-gx.dtsi  |   46 +
 .../boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts|4 +
 arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi   |4 +
 arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi|   12 +
 .../boot/dts/amlogic/meson-gxl-nexbox-a95x.dts |4 +
 arch/arm64/boot/dts/amlogic/meson-gxl.dtsi |8 +
 .../arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts |4 +
 arch/arm64/boot/dts/amlogic/meson-gxm.dtsi |9 +
 drivers/gpu/drm/Kconfig|2 +
 drivers/gpu/drm/Makefile   |1 +
 drivers/gpu/drm/meson/Kconfig  |8 +
 drivers/gpu/drm/meson/Makefile |5 +
 drivers/gpu/drm/meson/meson_canvas.c   |   96 ++
 drivers/gpu/drm/meson/meson_canvas.h   |   31 +
 drivers/gpu/drm/meson/meson_crtc.c |  176 +++
 drivers/gpu/drm/meson/meson_crtc.h |   34 +
 drivers/gpu/drm/meson/meson_cvbs.c |  293 
 drivers/gpu/drm/meson/meson_cvbs.h |   32 +
 drivers/gpu/drm/meson/meson_drv.c  |  383 ++
 drivers/gpu/drm/meson/meson_drv.h  |   68 +
 drivers/gpu/drm/meson/meson_plane.c|  150 +++
 drivers/gpu/drm/meson/meson_plane.h|   32 +
 drivers/gpu/drm/meson/meson_registers.h| 1395 
 drivers/gpu/drm/meson/meson_vclk.c |  169 +++
 drivers/gpu/drm/meson/meson_vclk.h |   36 +
 drivers/gpu/drm/meson/meson_venc.c |  286 
 drivers/gpu/drm/meson/meson_venc.h |   77 ++
 drivers/gpu/drm/meson/meson_viu.c  |  497 +++
 drivers/gpu/drm/meson/meson_viu.h  |   37 +
 drivers/gpu/drm/meson/meson_vpp.c  |  189 +++
 drivers/gpu/drm/meson/meson_vpp.h  |   43 +
 32 files changed, 4265 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/meson/meson-drm.txt
 create mode 100644 drivers/gpu/drm/meson/Kconfig
 create mode 100644 drivers/gpu/drm/meson/Makefile
 create mode 100644 drivers/gpu/drm/meson/meson_canvas.c
 create mode 100644 drivers/gpu/drm/meson/meson_canvas.h
 create mode 100644 drivers/gpu/drm/meson/meson_crtc.c
 create mode 100644 drivers/gpu/drm/meson/meson_crtc.h
 create mode 100644 drivers/gpu/drm/meson/meson_cvbs.c
 create mode 100644 drivers/gpu/drm/meson/meson_cvbs.h
 create mode 100644 drivers/gpu/drm/meson/meson_drv.c
 create mode 100644 drivers/gpu/drm/meson/meson_drv.h
 create mode 100644 drivers/gpu/drm/meson/meson_plane.c
 create mode 100644 drivers/gpu/drm/meson/meson_plane.h
 create mode 100644 drivers/gpu/drm/meson/meson_registers.h
 create mode 100644 drivers/gpu/drm/meson/meson_vclk.c
 create mode 100644 drivers/gpu/drm/meson/meson_vclk.h
 create mode 100644 drivers/gpu/drm/meson/meson_venc.c
 create mode 100644 drivers/gpu/drm/meson/meson_venc.h
 create mode 100644 drivers/gpu/drm/meson/meson_viu.c
 create mode 100644 drivers/gpu/drm/meson/meson_viu.h
 create mode 100644 drivers/gpu/drm/meson/meson_vpp.c
 create mode 100644 drivers/gpu/drm/meson/meson_vpp.h

-- 
1.9.1



[PATCH 6/6] drm: mali-dp: Add writeback connector

2016-11-25 Thread Brian Starkey
Mali-DP has a memory writeback engine which can be used to write the
composition result to a memory buffer. Expose this functionality as a
DRM writeback connector on supported hardware.

Changes since v1:
 Daniel Vetter:
 - Don't require a modeset when writeback routing changes
 - Make writeback connector always disconnected

Changes since v2:
 - Rebase onto new drm_writeback_connector
 - Add reset callback, allocating subclassed state
 Daniel Vetter:
 - Squash out-fence support into this commit
 Gustavo Padovan:
 - Don't signal fence directly from driver (and drop malidp_mw_job)

Signed-off-by: Brian Starkey 
---
 drivers/gpu/drm/arm/Makefile  |1 +
 drivers/gpu/drm/arm/malidp_crtc.c |   21 +++
 drivers/gpu/drm/arm/malidp_drv.c  |   25 +++-
 drivers/gpu/drm/arm/malidp_drv.h  |3 +
 drivers/gpu/drm/arm/malidp_hw.c   |7 +-
 drivers/gpu/drm/arm/malidp_mw.c   |  278 +
 drivers/gpu/drm/arm/malidp_mw.h   |   18 +++
 7 files changed, 348 insertions(+), 5 deletions(-)
 create mode 100644 drivers/gpu/drm/arm/malidp_mw.c
 create mode 100644 drivers/gpu/drm/arm/malidp_mw.h

diff --git a/drivers/gpu/drm/arm/Makefile b/drivers/gpu/drm/arm/Makefile
index bb8b158..3bf31d1 100644
--- a/drivers/gpu/drm/arm/Makefile
+++ b/drivers/gpu/drm/arm/Makefile
@@ -1,4 +1,5 @@
 hdlcd-y := hdlcd_drv.o hdlcd_crtc.o
 obj-$(CONFIG_DRM_HDLCD)+= hdlcd.o
 mali-dp-y := malidp_drv.o malidp_hw.o malidp_planes.o malidp_crtc.o
+mali-dp-y += malidp_mw.o
 obj-$(CONFIG_DRM_MALI_DISPLAY) += mali-dp.o
diff --git a/drivers/gpu/drm/arm/malidp_crtc.c 
b/drivers/gpu/drm/arm/malidp_crtc.c
index 08e6a71..5413a5a 100644
--- a/drivers/gpu/drm/arm/malidp_crtc.c
+++ b/drivers/gpu/drm/arm/malidp_crtc.c
@@ -68,6 +68,18 @@ static void malidp_crtc_enable(struct drm_crtc *crtc)
clk_set_rate(hwdev->pxlclk, crtc->state->adjusted_mode.crtc_clock * 
1000);

hwdev->modeset(hwdev, );
+   /*
+* We should always disable the memory write when leaving config mode,
+* otherwise the hardware will start writing right away - possibly with
+* a stale config, and definitely before we've had a chance to configure
+* the planes.
+* If the memory write needs to be enabled, that will get taken care
+* of later during the atomic commit
+*/
+   if (hwdev->disable_memwrite) {
+   DRM_DEV_DEBUG_DRIVER(crtc->dev->dev, "Disable memwrite\n");
+   hwdev->disable_memwrite(hwdev);
+   }
hwdev->leave_config_mode(hwdev);
drm_crtc_vblank_on(crtc);
 }
@@ -157,6 +169,15 @@ static int malidp_crtc_atomic_check(struct drm_crtc *crtc,
}
}

+   /* If only the writeback routing has changed, we don't need a modeset */
+   if (state->connectors_changed) {
+   u32 old_mask = crtc->state->connector_mask;
+   u32 new_mask = state->connector_mask;
+   if ((old_mask ^ new_mask) ==
+   (1 << drm_connector_index(>mw_connector.base)))
+   state->connectors_changed = false;
+   }
+
return 0;
 }

diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c
index 32f746e..2d0465b 100644
--- a/drivers/gpu/drm/arm/malidp_drv.c
+++ b/drivers/gpu/drm/arm/malidp_drv.c
@@ -28,6 +28,7 @@
 #include 

 #include "malidp_drv.h"
+#include "malidp_mw.h"
 #include "malidp_regs.h"
 #include "malidp_hw.h"

@@ -92,6 +93,14 @@ static void malidp_atomic_commit_tail(struct 
drm_atomic_state *state)

drm_atomic_helper_commit_modeset_disables(drm, state);
drm_atomic_helper_commit_modeset_enables(drm, state);
+
+   /*
+* The order here is important. We must configure memory-write after
+* the CRTC is already enabled, so that its configuration update is
+* gated on the next CVAL.
+*/
+   malidp_mw_atomic_commit(drm, state);
+
drm_atomic_helper_commit_planes(drm, state, 0);

malidp_atomic_commit_hw_done(state);
@@ -147,12 +156,20 @@ static int malidp_init(struct drm_device *drm)
drm->mode_config.helper_private = _mode_config_helpers;

ret = malidp_crtc_init(drm);
-   if (ret) {
-   drm_mode_config_cleanup(drm);
-   return ret;
-   }
+   if (ret)
+   goto crtc_fail;
+
+   ret = malidp_mw_connector_init(drm);
+   if (ret)
+   goto mw_fail;

return 0;
+
+mw_fail:
+   malidp_de_planes_destroy(drm);
+crtc_fail:
+   drm_mode_config_cleanup(drm);
+   return ret;
 }

 static void malidp_fini(struct drm_device *drm)
diff --git a/drivers/gpu/drm/arm/malidp_drv.h b/drivers/gpu/drm/arm/malidp_drv.h
index 9fc8a2e..8abfa8a 100644
--- a/drivers/gpu/drm/arm/malidp_drv.h
+++ b/drivers/gpu/drm/arm/malidp_drv.h
@@ -13,6 +13,7 @@
 #ifndef __MALIDP_DRV_H__
 #define __MALIDP_DRV_H__

+#include 
 #include 
 #include 
 #include "malidp_hw.h"
@@ -22,6 +23,8 @@ struct malidp_drm {
  

[PATCH 5/6] drm: mali-dp: Add RGB writeback formats for DP550/DP650

2016-11-25 Thread Brian Starkey
Add a layer bit for the SE memory-write, and add it to the pixel format
matrix for DP550/DP650.

Signed-off-by: Brian Starkey 
---
 drivers/gpu/drm/arm/malidp_hw.c |   28 ++--
 drivers/gpu/drm/arm/malidp_hw.h |1 +
 2 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/arm/malidp_hw.c b/drivers/gpu/drm/arm/malidp_hw.c
index c696e67..be17631 100644
--- a/drivers/gpu/drm/arm/malidp_hw.c
+++ b/drivers/gpu/drm/arm/malidp_hw.c
@@ -46,20 +46,20 @@

 #define MALIDP_COMMON_FORMATS \
/*fourcc,   layers supporting the format,  internal id   */ \
-   { DRM_FORMAT_ARGB2101010, DE_VIDEO1 | DE_GRAPHICS1 | DE_VIDEO2, 
MALIDP_ID(0, 0) }, \
-   { DRM_FORMAT_ABGR2101010, DE_VIDEO1 | DE_GRAPHICS1 | DE_VIDEO2, 
MALIDP_ID(0, 1) }, \
-   { DRM_FORMAT_RGBA1010102, DE_VIDEO1 | DE_GRAPHICS1 | DE_VIDEO2, 
MALIDP_ID(0, 2) }, \
-   { DRM_FORMAT_BGRA1010102, DE_VIDEO1 | DE_GRAPHICS1 | DE_VIDEO2, 
MALIDP_ID(0, 3) }, \
-   { DRM_FORMAT_ARGB, DE_VIDEO1 | DE_GRAPHICS1 | DE_VIDEO2 | DE_SMART, 
MALIDP_ID(1, 0) }, \
-   { DRM_FORMAT_ABGR, DE_VIDEO1 | DE_GRAPHICS1 | DE_VIDEO2 | DE_SMART, 
MALIDP_ID(1, 1) }, \
-   { DRM_FORMAT_RGBA, DE_VIDEO1 | DE_GRAPHICS1 | DE_VIDEO2 | DE_SMART, 
MALIDP_ID(1, 2) }, \
-   { DRM_FORMAT_BGRA, DE_VIDEO1 | DE_GRAPHICS1 | DE_VIDEO2 | DE_SMART, 
MALIDP_ID(1, 3) }, \
-   { DRM_FORMAT_XRGB, DE_VIDEO1 | DE_GRAPHICS1 | DE_VIDEO2 | DE_SMART, 
MALIDP_ID(2, 0) }, \
-   { DRM_FORMAT_XBGR, DE_VIDEO1 | DE_GRAPHICS1 | DE_VIDEO2 | DE_SMART, 
MALIDP_ID(2, 1) }, \
-   { DRM_FORMAT_RGBX, DE_VIDEO1 | DE_GRAPHICS1 | DE_VIDEO2 | DE_SMART, 
MALIDP_ID(2, 2) }, \
-   { DRM_FORMAT_BGRX, DE_VIDEO1 | DE_GRAPHICS1 | DE_VIDEO2 | DE_SMART, 
MALIDP_ID(2, 3) }, \
-   { DRM_FORMAT_RGB888, DE_VIDEO1 | DE_GRAPHICS1 | DE_VIDEO2, MALIDP_ID(3, 
0) }, \
-   { DRM_FORMAT_BGR888, DE_VIDEO1 | DE_GRAPHICS1 | DE_VIDEO2, MALIDP_ID(3, 
1) }, \
+   { DRM_FORMAT_ARGB2101010, DE_VIDEO1 | DE_GRAPHICS1 | DE_VIDEO2 | 
SE_MEMWRITE, MALIDP_ID(0, 0) }, \
+   { DRM_FORMAT_ABGR2101010, DE_VIDEO1 | DE_GRAPHICS1 | DE_VIDEO2 | 
SE_MEMWRITE, MALIDP_ID(0, 1) }, \
+   { DRM_FORMAT_RGBA1010102, DE_VIDEO1 | DE_GRAPHICS1 | DE_VIDEO2 | 
SE_MEMWRITE, MALIDP_ID(0, 2) }, \
+   { DRM_FORMAT_BGRA1010102, DE_VIDEO1 | DE_GRAPHICS1 | DE_VIDEO2 | 
SE_MEMWRITE, MALIDP_ID(0, 3) }, \
+   { DRM_FORMAT_ARGB, DE_VIDEO1 | DE_GRAPHICS1 | DE_VIDEO2 | DE_SMART 
| SE_MEMWRITE, MALIDP_ID(1, 0) }, \
+   { DRM_FORMAT_ABGR, DE_VIDEO1 | DE_GRAPHICS1 | DE_VIDEO2 | DE_SMART 
| SE_MEMWRITE, MALIDP_ID(1, 1) }, \
+   { DRM_FORMAT_RGBA, DE_VIDEO1 | DE_GRAPHICS1 | DE_VIDEO2 | DE_SMART 
| SE_MEMWRITE, MALIDP_ID(1, 2) }, \
+   { DRM_FORMAT_BGRA, DE_VIDEO1 | DE_GRAPHICS1 | DE_VIDEO2 | DE_SMART 
| SE_MEMWRITE, MALIDP_ID(1, 3) }, \
+   { DRM_FORMAT_XRGB, DE_VIDEO1 | DE_GRAPHICS1 | DE_VIDEO2 | DE_SMART 
| SE_MEMWRITE, MALIDP_ID(2, 0) }, \
+   { DRM_FORMAT_XBGR, DE_VIDEO1 | DE_GRAPHICS1 | DE_VIDEO2 | DE_SMART 
| SE_MEMWRITE, MALIDP_ID(2, 1) }, \
+   { DRM_FORMAT_RGBX, DE_VIDEO1 | DE_GRAPHICS1 | DE_VIDEO2 | DE_SMART 
| SE_MEMWRITE, MALIDP_ID(2, 2) }, \
+   { DRM_FORMAT_BGRX, DE_VIDEO1 | DE_GRAPHICS1 | DE_VIDEO2 | DE_SMART 
| SE_MEMWRITE, MALIDP_ID(2, 3) }, \
+   { DRM_FORMAT_RGB888, DE_VIDEO1 | DE_GRAPHICS1 | DE_VIDEO2 | 
SE_MEMWRITE, MALIDP_ID(3, 0) }, \
+   { DRM_FORMAT_BGR888, DE_VIDEO1 | DE_GRAPHICS1 | DE_VIDEO2 | 
SE_MEMWRITE, MALIDP_ID(3, 1) }, \
{ DRM_FORMAT_RGBA5551, DE_VIDEO1 | DE_GRAPHICS1 | DE_VIDEO2, 
MALIDP_ID(4, 0) }, \
{ DRM_FORMAT_ABGR1555, DE_VIDEO1 | DE_GRAPHICS1 | DE_VIDEO2, 
MALIDP_ID(4, 1) }, \
{ DRM_FORMAT_RGB565, DE_VIDEO1 | DE_GRAPHICS1 | DE_VIDEO2, MALIDP_ID(4, 
2) }, \
diff --git a/drivers/gpu/drm/arm/malidp_hw.h b/drivers/gpu/drm/arm/malidp_hw.h
index 091171d..8056efa 100644
--- a/drivers/gpu/drm/arm/malidp_hw.h
+++ b/drivers/gpu/drm/arm/malidp_hw.h
@@ -33,6 +33,7 @@ enum {
DE_GRAPHICS2 = BIT(2), /* used only in DP500 */
DE_VIDEO2 = BIT(3),
DE_SMART = BIT(4),
+   SE_MEMWRITE = BIT(5),
 };

 struct malidp_format_id {
-- 
1.7.9.5



[PATCH 4/6] drm: mali-dp: Add support for writeback on DP550/DP650

2016-11-25 Thread Brian Starkey
From: Liviu Dudau 

Mali-DP display processors are able to write the composition result to a
memory buffer via the SE.

Add entry points in the HAL for enabling/disabling this feature, and
implement support for it on DP650 and DP550. DP500 acts differently and
so is omitted from this change.

Signed-off-by: Liviu Dudau 
Signed-off-by: Brian Starkey 
---
 drivers/gpu/drm/arm/malidp_hw.c   |   52 +++--
 drivers/gpu/drm/arm/malidp_hw.h   |   18 +
 drivers/gpu/drm/arm/malidp_regs.h |   15 +++
 3 files changed, 83 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/arm/malidp_hw.c b/drivers/gpu/drm/arm/malidp_hw.c
index 9ec6d69..c696e67 100644
--- a/drivers/gpu/drm/arm/malidp_hw.c
+++ b/drivers/gpu/drm/arm/malidp_hw.c
@@ -384,6 +384,48 @@ static int malidp550_rotmem_required(struct 
malidp_hw_device *hwdev, u16 w, u16
return w * bytes_per_col;
 }

+static int malidp550_enable_memwrite(struct malidp_hw_device *hwdev,
+dma_addr_t *addrs, s32 *pitches,
+int num_planes, u16 w, u16 h, u32 fmt_id)
+{
+   u32 base = MALIDP550_SE_MEMWRITE_BASE;
+   u32 de_base = malidp_get_block_base(hwdev, MALIDP_DE_BLOCK);
+
+   /* enable the scaling engine block */
+   malidp_hw_setbits(hwdev, MALIDP_SCALE_ENGINE_EN, de_base + 
MALIDP_DE_DISPLAY_FUNC);
+
+   malidp_hw_write(hwdev, fmt_id, base + MALIDP_MW_FORMAT);
+   switch (num_planes) {
+   case 2:
+   malidp_hw_write(hwdev, lower_32_bits(addrs[1]), base + 
MALIDP_MW_P2_PTR_LOW);
+   malidp_hw_write(hwdev, upper_32_bits(addrs[1]), base + 
MALIDP_MW_P2_PTR_HIGH);
+   malidp_hw_write(hwdev, pitches[1], base + MALIDP_MW_P2_STRIDE);
+   /* fall through */
+   case 1:
+   malidp_hw_write(hwdev, lower_32_bits(addrs[0]), base + 
MALIDP_MW_P1_PTR_LOW);
+   malidp_hw_write(hwdev, upper_32_bits(addrs[0]), base + 
MALIDP_MW_P1_PTR_HIGH);
+   malidp_hw_write(hwdev, pitches[0], base + MALIDP_MW_P1_STRIDE);
+   break;
+   default:
+   WARN(1, "Invalid number of planes");
+   }
+
+   malidp_hw_write(hwdev, MALIDP_DE_H_ACTIVE(w) | MALIDP_DE_V_ACTIVE(h),
+   MALIDP550_SE_MEMWRITE_OUT_SIZE);
+   malidp_hw_setbits(hwdev, MALIDP550_SE_MEMWRITE_ONESHOT | 
MALIDP_SE_MEMWRITE_EN,
+ MALIDP550_SE_CONTROL);
+
+   return 0;
+}
+
+static void malidp550_disable_memwrite(struct malidp_hw_device *hwdev)
+{
+   u32 base = malidp_get_block_base(hwdev, MALIDP_DE_BLOCK);
+   malidp_hw_clearbits(hwdev, MALIDP550_SE_MEMWRITE_ONESHOT | 
MALIDP_SE_MEMWRITE_EN,
+   MALIDP550_SE_CONTROL);
+   malidp_hw_clearbits(hwdev, MALIDP_SCALE_ENGINE_EN, base + 
MALIDP_DE_DISPLAY_FUNC);
+}
+
 static int malidp650_query_hw(struct malidp_hw_device *hwdev)
 {
u32 conf = malidp_hw_read(hwdev, MALIDP550_CONFIG_ID);
@@ -466,7 +508,8 @@ static int malidp650_query_hw(struct malidp_hw_device 
*hwdev)
MALIDP550_SE_IRQ_AXI_ERR,
},
.dc_irq_map = {
-   .irq_mask = MALIDP550_DC_IRQ_CONF_VALID,
+   .irq_mask = MALIDP550_DC_IRQ_CONF_VALID |
+   MALIDP550_DC_IRQ_SE,
.vsync_irq = MALIDP550_DC_IRQ_CONF_VALID,
},
.pixel_formats = malidp550_de_formats,
@@ -480,6 +523,8 @@ static int malidp650_query_hw(struct malidp_hw_device 
*hwdev)
.set_config_valid = malidp550_set_config_valid,
.modeset = malidp550_modeset,
.rotmem_required = malidp550_rotmem_required,
+   .enable_memwrite = malidp550_enable_memwrite,
+   .disable_memwrite = malidp550_disable_memwrite,
},
[MALIDP_650] = {
.map = {
@@ -500,7 +545,8 @@ static int malidp650_query_hw(struct malidp_hw_device 
*hwdev)
MALIDP550_SE_IRQ_AXI_ERR,
},
.dc_irq_map = {
-   .irq_mask = MALIDP550_DC_IRQ_CONF_VALID,
+   .irq_mask = MALIDP550_DC_IRQ_CONF_VALID |
+   MALIDP550_DC_IRQ_SE,
.vsync_irq = MALIDP550_DC_IRQ_CONF_VALID,
},
.pixel_formats = malidp550_de_formats,
@@ -514,6 +560,8 @@ static int malidp650_query_hw(struct malidp_hw_device 
*hwdev)
.set_config_valid = malidp550_set_config_valid,
.modeset = malidp550_modeset,
.rotmem_required = malidp550_rotmem_required,
+   .enable_memwrite = malidp550_enable_memwrite,
+  

[PATCH 3/6] drm: mali-dp: Rename malidp_input_format

2016-11-25 Thread Brian Starkey
We're going to use the same format list for output formats, so rename
everything related to input formats to avoid confusion.

Signed-off-by: Brian Starkey 
Reviewed-by: Liviu Dudau 
---
 drivers/gpu/drm/arm/malidp_hw.c |   24 
 drivers/gpu/drm/arm/malidp_hw.h |8 
 drivers/gpu/drm/arm/malidp_planes.c |8 
 3 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/arm/malidp_hw.c b/drivers/gpu/drm/arm/malidp_hw.c
index 4bdf531..9ec6d69 100644
--- a/drivers/gpu/drm/arm/malidp_hw.c
+++ b/drivers/gpu/drm/arm/malidp_hw.c
@@ -21,7 +21,7 @@
 #include "malidp_drv.h"
 #include "malidp_hw.h"

-static const struct malidp_input_format malidp500_de_formats[] = {
+static const struct malidp_format_id malidp500_de_formats[] = {
/*fourcc,   layers supporting the format, internal id  */
{ DRM_FORMAT_ARGB2101010, DE_VIDEO1 | DE_GRAPHICS1 | DE_GRAPHICS2,  0 },
{ DRM_FORMAT_ABGR2101010, DE_VIDEO1 | DE_GRAPHICS1 | DE_GRAPHICS2,  1 },
@@ -69,7 +69,7 @@
{ DRM_FORMAT_NV12, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 6) },\
{ DRM_FORMAT_YUV420, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 7) }

-static const struct malidp_input_format malidp550_de_formats[] = {
+static const struct malidp_format_id malidp550_de_formats[] = {
MALIDP_COMMON_FORMATS,
 };

@@ -436,8 +436,8 @@ static int malidp650_query_hw(struct malidp_hw_device 
*hwdev)
.irq_mask = MALIDP500_DE_IRQ_CONF_VALID,
.vsync_irq = MALIDP500_DE_IRQ_CONF_VALID,
},
-   .input_formats = malidp500_de_formats,
-   .n_input_formats = ARRAY_SIZE(malidp500_de_formats),
+   .pixel_formats = malidp500_de_formats,
+   .n_pixel_formats = ARRAY_SIZE(malidp500_de_formats),
.bus_align_bytes = 8,
},
.query_hw = malidp500_query_hw,
@@ -469,8 +469,8 @@ static int malidp650_query_hw(struct malidp_hw_device 
*hwdev)
.irq_mask = MALIDP550_DC_IRQ_CONF_VALID,
.vsync_irq = MALIDP550_DC_IRQ_CONF_VALID,
},
-   .input_formats = malidp550_de_formats,
-   .n_input_formats = ARRAY_SIZE(malidp550_de_formats),
+   .pixel_formats = malidp550_de_formats,
+   .n_pixel_formats = ARRAY_SIZE(malidp550_de_formats),
.bus_align_bytes = 8,
},
.query_hw = malidp550_query_hw,
@@ -503,8 +503,8 @@ static int malidp650_query_hw(struct malidp_hw_device 
*hwdev)
.irq_mask = MALIDP550_DC_IRQ_CONF_VALID,
.vsync_irq = MALIDP550_DC_IRQ_CONF_VALID,
},
-   .input_formats = malidp550_de_formats,
-   .n_input_formats = ARRAY_SIZE(malidp550_de_formats),
+   .pixel_formats = malidp550_de_formats,
+   .n_pixel_formats = ARRAY_SIZE(malidp550_de_formats),
.bus_align_bytes = 16,
},
.query_hw = malidp650_query_hw,
@@ -522,10 +522,10 @@ u8 malidp_hw_get_format_id(const struct malidp_hw_regmap 
*map,
 {
unsigned int i;

-   for (i = 0; i < map->n_input_formats; i++) {
-   if (((map->input_formats[i].layer & layer_id) == layer_id) &&
-   (map->input_formats[i].format == format))
-   return map->input_formats[i].id;
+   for (i = 0; i < map->n_pixel_formats; i++) {
+   if (((map->pixel_formats[i].layer & layer_id) == layer_id) &&
+   (map->pixel_formats[i].format == format))
+   return map->pixel_formats[i].id;
}

return MALIDP_INVALID_FORMAT_ID;
diff --git a/drivers/gpu/drm/arm/malidp_hw.h b/drivers/gpu/drm/arm/malidp_hw.h
index 087e1202..4f8c884 100644
--- a/drivers/gpu/drm/arm/malidp_hw.h
+++ b/drivers/gpu/drm/arm/malidp_hw.h
@@ -35,7 +35,7 @@ enum {
DE_SMART = BIT(4),
 };

-struct malidp_input_format {
+struct malidp_format_id {
u32 format; /* DRM fourcc */
u8 layer;   /* bitmask of layers supporting it */
u8 id;  /* used internally */
@@ -85,9 +85,9 @@ struct malidp_hw_regmap {
const struct malidp_irq_map se_irq_map;
const struct malidp_irq_map dc_irq_map;

-   /* list of supported input formats for each layer */
-   const struct malidp_input_format *input_formats;
-   const u8 n_input_formats;
+   /* list of supported pixel formats for each layer */
+   const struct malidp_format_id *pixel_formats;
+   const u8 n_pixel_formats;

/* pitch alignment requirement in bytes */
const u8 bus_align_bytes;
diff --git 

[PATCH 2/6] drm: writeback: Add out-fences for writeback connectors

2016-11-25 Thread Brian Starkey
Add the OUT_FENCE_PTR property to writeback connectors, to enable
userspace to get a fence which will signal once the writeback is
complete. It is not allowed to request an out-fence without a
framebuffer attached to the connector.

A timeline is added to drm_writeback_connector for use by the writeback
out-fences.

In the case of a commit failure or DRM_MODE_ATOMIC_TEST_ONLY, the fence
is set to -1.

Changes from v2:
 - Rebase onto Gustavo Padovan's v9 explicit sync series
 - Change out_fence_ptr type to s32 __user *
 - Set *out_fence_ptr to -1 in drm_atomic_connector_set_property
 - Store fence in drm_writeback_job
 Gustavo Padovan:
 - Move out_fence_ptr out of connector_state
 - Signal fence from drm_writeback_signal_completion instead of
   in driver directly

Signed-off-by: Brian Starkey 
---
 drivers/gpu/drm/drm_atomic.c|   96 +
 drivers/gpu/drm/drm_writeback.c |   99 ++-
 include/drm/drm_atomic.h|8 
 include/drm/drm_connector.h |8 ++--
 include/drm/drm_writeback.h |   39 ++-
 5 files changed, 234 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 343e2b7..0e3c900 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -308,6 +308,32 @@ static s64 __user *get_out_fence_for_crtc(struct 
drm_atomic_state *state,
return fence_ptr;
 }

+static int set_out_fence_for_connector(struct drm_atomic_state *state,
+   struct drm_connector *connector,
+   s64 __user *fence_ptr)
+{
+   unsigned int index = drm_connector_index(connector);
+
+   if (fence_ptr && put_user(-1, fence_ptr))
+   return -EFAULT;
+
+   state->connectors[index].out_fence_ptr = fence_ptr;
+
+   return 0;
+}
+
+static s64 __user *get_out_fence_for_connector(struct drm_atomic_state *state,
+  struct drm_connector *connector)
+{
+   unsigned int index = drm_connector_index(connector);
+   s64 __user *fence_ptr;
+
+   fence_ptr = state->connectors[index].out_fence_ptr;
+   state->connectors[index].out_fence_ptr = NULL;
+
+   return fence_ptr;
+}
+
 /**
  * drm_atomic_set_mode_for_crtc - set mode for CRTC
  * @state: the CRTC whose incoming state to update
@@ -696,6 +722,12 @@ static int drm_atomic_connector_check(struct drm_connector 
*connector,
return -EINVAL;
}

+   if (writeback_job->out_fence && !writeback_job->fb) {
+   DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] requesting out-fence 
without framebuffer\n",
+connector->base.id, connector->name);
+   return -EINVAL;
+   }
+
return 0;
 }

@@ -1134,6 +1166,11 @@ int drm_atomic_connector_set_property(struct 
drm_connector *connector,
if (fb)
drm_framebuffer_unreference(fb);
return ret;
+   } else if (property == config->prop_out_fence_ptr) {
+   s64 __user *fence_ptr = u64_to_user_ptr(val);
+
+   return set_out_fence_for_connector(state->state, connector,
+  fence_ptr);
} else if (connector->funcs->atomic_set_property) {
return connector->funcs->atomic_set_property(connector,
state, property, val);
@@ -1185,6 +1222,8 @@ static void drm_atomic_connector_print_state(struct 
drm_printer *p,
} else if (property == config->writeback_fb_id_property) {
/* Writeback framebuffer is one-shot, write and forget */
*val = 0;
+   } else if (property == config->prop_out_fence_ptr) {
+   *val = 0;
} else if (connector->funcs->atomic_get_property) {
return connector->funcs->atomic_get_property(connector,
state, property, val);
@@ -1976,7 +2015,7 @@ static int setup_out_fence(struct drm_out_fence_state 
*fence_state,
return 0;
 }

-static int prepare_crtc_signaling(struct drm_device *dev,
+static int prepare_signaling(struct drm_device *dev,
  struct drm_atomic_state *state,
  struct drm_mode_atomic *arg,
  struct drm_file *file_priv,
@@ -1985,6 +2024,8 @@ static int prepare_crtc_signaling(struct drm_device *dev,
 {
struct drm_crtc *crtc;
struct drm_crtc_state *crtc_state;
+   struct drm_connector *conn;
+   struct drm_connector_state *conn_state;
int i, ret;

if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY)
@@ -2048,14 +2089,51 @@ static int prepare_crtc_signaling(struct drm_device 
*dev,
}
}

+   for_each_connector_in_state(state, conn, conn_state, i) {
+   struct drm_writeback_job 

[PATCH 1/6] drm: Add writeback connector type

2016-11-25 Thread Brian Starkey
Writeback connectors represent writeback engines which can write the
CRTC output to a memory framebuffer. Add a writeback connector type and
related support functions.

Drivers should initialize a writeback connector with
drm_writeback_connector_init() which takes care of setting up all the
writeback-specific details on top of the normal functionality of
drm_connector_init().

Writeback connectors have a WRITEBACK_FB_ID property, used to set the
output framebuffer, and a PIXEL_FORMATS blob used to expose the
supported writeback formats to userspace.

When a framebuffer is attached to a writeback connector with the
WRITEBACK_FB_ID property, it is used only once (for the commit in which
it was included), and userspace can never read back the value of
WRITEBACK_FB_ID. WRITEBACK_FB_ID can only be set if the connector is
attached to a CRTC.

Changes since v1:
 - Added drm_writeback.c + documentation
 - Added helper to initialize writeback connector in one go
 - Added core checks
 - Squashed into a single commit
 - Dropped the client cap
 - Writeback framebuffers are no longer persistent

Changes since v2:
 Daniel Vetter:
 - Subclass drm_connector to drm_writeback_connector
 - Relax check to allow CRTC to be set without an FB
 - Add some writeback_ prefixes
 - Drop PIXEL_FORMATS_SIZE property, as it was unnecessary
 Gustavo Padovan:
 - Add drm_writeback_job to handle writeback signalling centrally

Signed-off-by: Brian Starkey 
---
 Documentation/gpu/drm-kms.rst   |9 ++
 drivers/gpu/drm/Makefile|2 +-
 drivers/gpu/drm/drm_atomic.c|  130 
 drivers/gpu/drm/drm_atomic_helper.c |6 +
 drivers/gpu/drm/drm_connector.c |4 +-
 drivers/gpu/drm/drm_writeback.c |  230 +++
 include/drm/drm_atomic.h|3 +
 include/drm/drm_connector.h |   13 ++
 include/drm/drm_mode_config.h   |   14 +++
 include/drm/drm_writeback.h |   78 
 include/uapi/drm/drm_mode.h |1 +
 11 files changed, 488 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/drm_writeback.c
 create mode 100644 include/drm/drm_writeback.h

diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst
index 568f3c2..3a4f35b 100644
--- a/Documentation/gpu/drm-kms.rst
+++ b/Documentation/gpu/drm-kms.rst
@@ -122,6 +122,15 @@ Connector Functions Reference
 .. kernel-doc:: drivers/gpu/drm/drm_connector.c
:export:

+Writeback Connectors
+
+
+.. kernel-doc:: drivers/gpu/drm/drm_writeback.c
+  :doc: overview
+
+.. kernel-doc:: drivers/gpu/drm/drm_writeback.c
+  :export:
+
 Encoder Abstraction
 ===

diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 883f3e7..3209aa4 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -16,7 +16,7 @@ drm-y   :=drm_auth.o drm_bufs.o drm_cache.o \
drm_framebuffer.o drm_connector.o drm_blend.o \
drm_encoder.o drm_mode_object.o drm_property.o \
drm_plane.o drm_color_mgmt.o drm_print.o \
-   drm_dumb_buffers.o drm_mode_config.o
+   drm_dumb_buffers.o drm_mode_config.o drm_writeback.o

 drm-$(CONFIG_COMPAT) += drm_ioc32.o
 drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index b476ec5..343e2b7 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -31,6 +31,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 

 #include "drm_crtc_internal.h"
@@ -659,6 +660,46 @@ static void drm_atomic_crtc_print_state(struct drm_printer 
*p,
 }

 /**
+ * drm_atomic_connector_check - check connector state
+ * @connector: connector to check
+ * @state: connector state to check
+ *
+ * Provides core sanity checks for connector state.
+ *
+ * RETURNS:
+ * Zero on success, error code on failure
+ */
+static int drm_atomic_connector_check(struct drm_connector *connector,
+   struct drm_connector_state *state)
+{
+   struct drm_crtc_state *crtc_state;
+   struct drm_writeback_job *writeback_job = state->writeback_job;
+
+   if ((connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK) ||
+   !writeback_job)
+   return 0;
+
+   if (writeback_job->fb && !state->crtc) {
+   DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] framebuffer without CRTC\n",
+connector->base.id, connector->name);
+   return -EINVAL;
+   }
+
+   if (state->crtc)
+   crtc_state = drm_atomic_get_existing_crtc_state(state->state,
+   state->crtc);
+
+   if (writeback_job->fb && !crtc_state->active) {
+   DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] has framebuffer, but 
[CRTC:%d] is off\n",
+connector->base.id, connector->name,
+  

[RFC PATCH v3 0/6] Introduce writeback connectors

2016-11-25 Thread Brian Starkey
Hi,

This is v3 of my series introducing a new connector type:
 DRM_MODE_CONNECTOR_WRITEBACK
See v1 and v2 here: [1] [2]

Writeback connectors are used to expose the memory writeback engines
found in some display controllers, which can write a CRTC's
composition result to a memory buffer.
This is useful e.g. for testing, screen-recording, screenshots,
wireless display, display cloning, memory-to-memory composition.

Writeback connectors are given a WRITEBACK_FB_ID property (which acts
slightly differently to FB_ID, so gets a new name), as well as
a PIXEL_FORMATS blob to list the supported writeback formats, and
OUT_FENCE_PTR to be used for out-fences.

The changes since v2 are in the commit messages of each commit.

The main differences are:
 - Subclass drm_connector as drm_writeback_connector
 - Slight relaxation of core checks, to allow
   (connector->crtc && !connector->fb)
 - Dropped PIXEL_FORMATS_SIZE, which was redundant
 - Reworked the event interface, drivers don't need to deal with the
   fence directly
 - Re-ordered the commits to introduce writeback out-fences up-front.

I've kept RFC on this series because the event reporting (introduction
of drm_writeback_job) is probably up for debate.

v4 will be accompanied by igt tests.

As always, I look forward to any comments.

Thanks,
Brian

[1] http://www.mail-archive.com/linux-kernel at vger.kernel.org/msg1247574.html
[2] http://www.mail-archive.com/linux-kernel at vger.kernel.org/msg1258017.html

---

Brian Starkey (5):
  drm: Add writeback connector type
  drm: writeback: Add out-fences for writeback connectors
  drm: mali-dp: Rename malidp_input_format
  drm: mali-dp: Add RGB writeback formats for DP550/DP650
  drm: mali-dp: Add writeback connector

Liviu Dudau (1):
  drm: mali-dp: Add support for writeback on DP550/DP650

 Documentation/gpu/drm-kms.rst   |9 +
 drivers/gpu/drm/Makefile|2 +-
 drivers/gpu/drm/arm/Makefile|1 +
 drivers/gpu/drm/arm/malidp_crtc.c   |   21 +++
 drivers/gpu/drm/arm/malidp_drv.c|   25 ++-
 drivers/gpu/drm/arm/malidp_drv.h|3 +
 drivers/gpu/drm/arm/malidp_hw.c |  111 
 drivers/gpu/drm/arm/malidp_hw.h |   27 ++-
 drivers/gpu/drm/arm/malidp_mw.c |  278 ++
 drivers/gpu/drm/arm/malidp_mw.h |   18 ++
 drivers/gpu/drm/arm/malidp_planes.c |8 +-
 drivers/gpu/drm/arm/malidp_regs.h   |   15 ++
 drivers/gpu/drm/drm_atomic.c|  226 +++-
 drivers/gpu/drm/drm_atomic_helper.c |6 +
 drivers/gpu/drm/drm_connector.c |4 +-
 drivers/gpu/drm/drm_writeback.c |  325 +++
 include/drm/drm_atomic.h|   11 ++
 include/drm/drm_connector.h |   13 ++
 include/drm/drm_mode_config.h   |   14 ++
 include/drm/drm_writeback.h |  115 +
 include/uapi/drm/drm_mode.h |1 +
 21 files changed, 1181 insertions(+), 52 deletions(-)
 create mode 100644 drivers/gpu/drm/arm/malidp_mw.c
 create mode 100644 drivers/gpu/drm/arm/malidp_mw.h
 create mode 100644 drivers/gpu/drm/drm_writeback.c
 create mode 100644 include/drm/drm_writeback.h

-- 
1.7.9.5



[PATCH] ARM: dts: da850: specify the maximum bandwidth for tilcdc

2016-11-25 Thread Bartosz Golaszewski
It has been determined that the maximum resolution supported correctly
by tilcdc rev1 on da850 SoCs is 800x600 at 60. Due to memory throughput
constraints we must filter out higher modes.

Specify the max-bandwidth property for the display node for
da850-based boards.

Signed-off-by: Bartosz Golaszewski 
---
 arch/arm/boot/dts/da850.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi
index 8e30d9b..9b7c444 100644
--- a/arch/arm/boot/dts/da850.dtsi
+++ b/arch/arm/boot/dts/da850.dtsi
@@ -452,6 +452,7 @@
compatible = "ti,da850-tilcdc";
reg = <0x213000 0x1000>;
interrupts = <52>;
+   max-bandwidth = <2880>;
status = "disabled";

ports {
-- 
2.9.3



[GIT PULL] Another HDLCD fix

2016-11-25 Thread Liviu Dudau
Hi Dave,

Thanks for pulling the previous patch for HDLCD. Unfortunately,
yesterday Robin Murphy discovered another issue while playing with
CMA allocation sizes, which he has submitted a fix for. If you
think it is too late for this to go into v4.9, please let me know.

Many thanks,
Liviu

The following changes since commit 7a79279e7186c4ac8b753cbd335ecc4ba81b5970:

  drm/arm: hdlcd: fix plane base address update (2016-11-22 14:09:06 +)

are available in the git repository at:

  git://linux-arm.org/linux-ld.git for-upstream/hdlcd

for you to fetch changes up to 747e5a5ff2a2ae84715c33d6679ac3c5220a3aec:

  drm: hdlcd: Fix cleanup order (2016-11-25 15:51:57 +)


Robin Murphy (1):
  drm: hdlcd: Fix cleanup order

 drivers/gpu/drm/arm/hdlcd_drv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

-- 

| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---
¯\_(ツ)_/¯


Enabling peer to peer device transactions for PCIe devices

2016-11-25 Thread Felix Kuehling

On 16-11-25 03:40 PM, Christian König wrote:
> Am 25.11.2016 um 20:32 schrieb Jason Gunthorpe:
>> This assumes the commands are fairly short lived of course, the
>> expectation of the mmu notifiers is that a flush is reasonably prompt
>
> Correct, this is another problem. GFX command submissions usually
> don't take longer than a few milliseconds, but compute command
> submission can easily take multiple hours.
>
> I can easily imagine what would happen when kswapd is blocked by a GPU
> command submission for an hour or so while the system is under memory
> pressure :)
>
> I'm thinking on this problem for about a year now and going in circles
> for quite a while. So if you have ideas on this even if they sound
> totally crazy, feel free to come up.

Our GPUs (at least starting with VI) support compute-wave-save-restore
and can swap out compute queues with fairly low latency. Yes, there is
some overhead (both memory usage and time), but it's a fairly regular
thing with our hardware scheduler (firmware, actually) when we need to
preempt running compute queues to update runlists or we overcommit the
hardware queue resources.

Regards,
  Felix



Enabling peer to peer device transactions for PCIe devices

2016-11-25 Thread Serguei Sagalovitch

On 2016-11-25 03:26 PM, Felix Kuehling wrote:
> On 16-11-25 12:20 PM, Serguei Sagalovitch wrote:
>>> A white list may end up being rather complicated if it has to cover
>>> different CPU generations and system architectures. I feel this is a
>>> decision user space could easily make.
>>>
>>> Logan
>> I agreed that it is better to leave up to user space to check what is
>> working
>> and what is not. I found that write is practically always working but
>> read very
>> often not. Also sometimes system BIOS update could fix the issue.
>>
> But is user mode always aware that P2P is going on or even possible? For
> example you may have a library reading a buffer from a file, but it
> doesn't necessarily know where that buffer is located (system memory,
> VRAM, ...) and it may not know what kind of the device the file is on
> (SATA drive, NVMe SSD, ...). The library will never know if all it gets
> is a pointer and a file descriptor.
>
> The library ends up calling a read system call. Then it would be up to
> the kernel to figure out the most efficient way to read the buffer from
> the file. If supported, it could use P2P between a GPU and NVMe where
> the NVMe device performs a DMA write to VRAM.
>
> If you put the burden of figuring out the P2P details on user mode code,
> I think it will severely limit the use cases that actually take
> advantage of it. You also risk a bunch of different implementations that
> get it wrong half the time on half the systems out there.
>
> Regards,
>Felix
>
>
I agreed in theory with you but  I must admit that I do not know how
kernel could effectively collect all informations without running
pretty complicated tests each time on boot-up (if any configuration
changed including BIOS settings)  and on pnp events. Also for efficient
way kernel needs to know performance results (and it could also
depends on clock / power mode) for read/write of each pair devices, for
double-buffering it needs to know / detect on which NUMA node
to allocate, etc. etc.  Also  device could be fully configured only
on the first request for access so it may be needed to change initialization
sequences.



Question regarding clocks in the DW-HDMI DT bindings

2016-11-25 Thread Vladimir Zapolskiy
On 11/25/2016 03:06 PM, Fabio Estevam wrote:
> Hi Vladimir,
>
> On Fri, Nov 25, 2016 at 11:00 AM, Vladimir Zapolskiy
>  wrote:
>
>> according to the DTSI files in the vanilla kernel DW HDMI IP is found
>> only on iMX6Q/D and iMX6DL/iMX6S SoCs (but please double check it),
>> so this approach should work ideally.
>
> After thinking more about this I think we can not get rid of "gpr". If
> we have a new i.MX SoC that is not compatible with
> "fsl,imx6q-iomuxc-gpr" then the lookup will fail.
>

Practically and when it becomes needed it should be possible to add SoC
specific hooks related to IOMUX_GPRx controls on basis of device
compatibles bound to the SoC variant.

Hypothetically if in future there is one more iMX SoC with a similar PCIe
or SATA controller but different GPR controls, to preserve backward
compatibility with old iMX6* DTB firmware the same handling of device
compatibles must be done in the drivers.

>> I see that the same has already been done in PCIe and SATA drivers,
>> but please consider to send a similar change against iMX LDB driver
>
> The i.MX LDB driver is also used on imx53, so we cannot search for
> "fsl,imx6q-iomuxc-gpr" compatible, as it will fail on imx53.
>
> So it seems we need to keep the "gpr" property in this case.
>

Right, I missed it. By chance GPR controls of LDB/LVDS are the same
on iMX53 and iMX6*, otherwise the driver shall care about GPR controls
differently, for example get a SoC specific GPR device compatible.

Nevertheless it is just a suggestion and it may remain just a mental
exercise of how to beautify/standardize iMX device binding descriptions.

--
With best wishes,
Vladimir


[PATCH 3/3] drm: Track framebuffer references at the point of assignment

2016-11-25 Thread Chris Wilson
We can simplify the code greatly if both legacy and atomic paths updated
the references as they assigned the framebuffer to the planes. Long
before framebuffer reference counting was added, the code had to keep
the old_fb around until after the operation was completed - but now we
can simply leave it to the reference handling to prevent invalid use.

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c |  2 +-
 drivers/gpu/drm/armada/armada_crtc.c|  9 +
 drivers/gpu/drm/bochs/bochs_kms.c   |  2 +-
 drivers/gpu/drm/drm_atomic.c| 44 +---
 drivers/gpu/drm/drm_atomic_helper.c | 35 ++--
 drivers/gpu/drm/drm_crtc.c  | 18 +
 drivers/gpu/drm/drm_crtc_helper.c   | 18 +
 drivers/gpu/drm/drm_fb_helper.c | 23 +--
 drivers/gpu/drm/drm_plane.c | 62 ++---
 drivers/gpu/drm/i915/intel_display.c| 17 
 drivers/gpu/drm/mgag200/mgag200_mode.c  |  2 +-
 drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c   |  2 +-
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c   |  2 +-
 drivers/gpu/drm/nouveau/nouveau_display.c   |  2 +-
 drivers/gpu/drm/nouveau/nv50_display.c  |  7 
 drivers/gpu/drm/qxl/qxl_display.c   |  4 +-
 drivers/gpu/drm/radeon/radeon_display.c |  3 +-
 drivers/gpu/drm/shmobile/shmob_drm_crtc.c   |  2 +-
 drivers/gpu/drm/tilcdc/tilcdc_crtc.c|  4 +-
 drivers/gpu/drm/udl/udl_modeset.c   |  2 +-
 drivers/gpu/drm/vc4/vc4_crtc.c  |  2 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c |  4 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c| 10 ++---
 drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c|  4 +-
 include/drm/drm_atomic.h|  3 --
 include/drm/drm_plane.h | 27 ++---
 26 files changed, 100 insertions(+), 210 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 741144fcc7bc..2aa4e707be1b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -225,7 +225,7 @@ int amdgpu_crtc_page_flip_target(struct drm_crtc *crtc,
DRM_DEBUG_DRIVER("crtc:%d[%p], pflip_stat:AMDGPU_FLIP_PENDING, work: 
%p,\n",
 amdgpu_crtc->crtc_id, amdgpu_crtc, 
work);
/* update crtc fb */
-   crtc->primary->fb = fb;
+   drm_plane_set_fb(crtc->primary, fb);
spin_unlock_irqrestore(>dev->event_lock, flags);
amdgpu_flip_work_func(>flip_work.work);
return 0;
diff --git a/drivers/gpu/drm/armada/armada_crtc.c 
b/drivers/gpu/drm/armada/armada_crtc.c
index 95cb3966b2ca..1b8cc4dbe5a5 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -1065,13 +1065,7 @@ static int armada_drm_crtc_page_flip(struct drm_crtc 
*crtc,
return ret;
}

-   /*
-* Don't take a reference on the new framebuffer;
-* drm_mode_page_flip_ioctl() has already grabbed a reference and
-* will _not_ drop that reference on successful return from this
-* function.  Simply mark this new framebuffer as the current one.
-*/
-   dcrtc->crtc.primary->fb = fb;
+   drm_plane_set_fb(dcrtc->crtc.primary, fb);

/*
 * Finally, if the display is blanked, we won't receive an
@@ -1080,6 +1074,7 @@ static int armada_drm_crtc_page_flip(struct drm_crtc 
*crtc,
if (dpms_blanked(dcrtc->dpms))
armada_drm_plane_work_run(dcrtc, dcrtc->crtc.primary);

+   drm_framebuffer_unreference(fb);
return 0;
 }

diff --git a/drivers/gpu/drm/bochs/bochs_kms.c 
b/drivers/gpu/drm/bochs/bochs_kms.c
index 0b4e5d117043..afe3bd2cd79e 100644
--- a/drivers/gpu/drm/bochs/bochs_kms.c
+++ b/drivers/gpu/drm/bochs/bochs_kms.c
@@ -103,7 +103,7 @@ static int bochs_crtc_page_flip(struct drm_crtc *crtc,
struct drm_framebuffer *old_fb = crtc->primary->fb;
unsigned long irqflags;

-   crtc->primary->fb = fb;
+   drm_plane_set_fb(crtc->primary, fb);
bochs_crtc_mode_set_base(crtc, 0, 0, old_fb);
if (event) {
spin_lock_irqsave(>dev->event_lock, irqflags);
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 19d7bcb88217..63dd5d5becdf 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1253,7 +1253,7 @@ drm_atomic_set_fb_for_plane(struct drm_plane_state 
*plane_state,
DRM_DEBUG_ATOMIC("Set [NOFB] for plane state %p\n",
 plane_state);

-   drm_framebuffer_assign(_state->fb, fb);
+   drm_framebuffer_assign(__mkwrite_drm_framebuffer(_state->fb), fb);
 }
 EXPORT_SYMBOL(drm_atomic_set_fb_for_plane);

@@ -1774,45 +1774,6 @@ static int atomic_set_prop(struct drm_atomic_state 
*state,
 }

 /**
- * drm_atomic_clean_old_fb -- Unset old_fb 

[PATCH 2/3] drm: Introduce drm_framebuffer_assign()

2016-11-25 Thread Chris Wilson
In a couple of places currently, and with the intent to add more, we
update a pointer to a framebuffer to hold a new fb reference (evicting
the old).

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/drm_atomic.c  |  8 ++--
 include/drm/drm_framebuffer.h | 18 ++
 2 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 89737e42fa83..19d7bcb88217 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1246,18 +1246,14 @@ void
 drm_atomic_set_fb_for_plane(struct drm_plane_state *plane_state,
struct drm_framebuffer *fb)
 {
-   if (plane_state->fb)
-   drm_framebuffer_unreference(plane_state->fb);
-   if (fb)
-   drm_framebuffer_reference(fb);
-   plane_state->fb = fb;
-
if (fb)
DRM_DEBUG_ATOMIC("Set [FB:%d] for plane state %p\n",
 fb->base.id, plane_state);
else
DRM_DEBUG_ATOMIC("Set [NOFB] for plane state %p\n",
 plane_state);
+
+   drm_framebuffer_assign(_state->fb, fb);
 }
 EXPORT_SYMBOL(drm_atomic_set_fb_for_plane);

diff --git a/include/drm/drm_framebuffer.h b/include/drm/drm_framebuffer.h
index b3141a0e609b..1ddfa2928802 100644
--- a/include/drm/drm_framebuffer.h
+++ b/include/drm/drm_framebuffer.h
@@ -251,6 +251,24 @@ static inline uint32_t 
drm_framebuffer_read_refcount(struct drm_framebuffer *fb)
 }

 /**
+ * drm_framebuffer_assign - store a reference to the fb
+ * @p: location to store framebuffer
+ * @fb: new framebuffer (maybe NULL)
+ *
+ * This functions sets the location to store a reference to the framebuffer,
+ * unreferencing the framebuffer that was previously stored in that location.
+ */
+static inline void drm_framebuffer_assign(struct drm_framebuffer **p,
+ struct drm_framebuffer *fb)
+{
+   if (fb)
+   drm_framebuffer_reference(fb);
+   if (*p)
+   drm_framebuffer_unreference(*p);
+   *p = fb;
+}
+
+/*
  * drm_for_each_fb - iterate over all framebuffers
  * @fb: the loop cursor
  * @dev: the DRM device
-- 
2.10.2



[PATCH 1/3] drm/i915: Use helper for setting plane->state->fb

2016-11-25 Thread Chris Wilson
We are told not to set plane_state->fb directly, but use
drm_atomic_set_fb_for_plane() instead. Using the helper, means one less
piece of code that needs fixing should the interface change...

Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/i915/intel_display.c | 6 +-
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 77c4ff9efbe3..8630de472f9a 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2732,11 +2732,7 @@ update_state_fb(struct drm_plane *plane)
if (plane->fb == plane->state->fb)
return;

-   if (plane->state->fb)
-   drm_framebuffer_unreference(plane->state->fb);
-   plane->state->fb = plane->fb;
-   if (plane->state->fb)
-   drm_framebuffer_reference(plane->state->fb);
+   drm_atomic_set_fb_for_plane(plane->state, plane->fb);
 }

 static void
-- 
2.10.2



Enabling peer to peer device transactions for PCIe devices

2016-11-25 Thread Felix Kuehling
On 16-11-25 12:20 PM, Serguei Sagalovitch wrote:
>
>> A white list may end up being rather complicated if it has to cover
>> different CPU generations and system architectures. I feel this is a
>> decision user space could easily make.
>>
>> Logan
> I agreed that it is better to leave up to user space to check what is
> working
> and what is not. I found that write is practically always working but
> read very
> often not. Also sometimes system BIOS update could fix the issue.
>
But is user mode always aware that P2P is going on or even possible? For
example you may have a library reading a buffer from a file, but it
doesn't necessarily know where that buffer is located (system memory,
VRAM, ...) and it may not know what kind of the device the file is on
(SATA drive, NVMe SSD, ...). The library will never know if all it gets
is a pointer and a file descriptor.

The library ends up calling a read system call. Then it would be up to
the kernel to figure out the most efficient way to read the buffer from
the file. If supported, it could use P2P between a GPU and NVMe where
the NVMe device performs a DMA write to VRAM.

If you put the burden of figuring out the P2P details on user mode code,
I think it will severely limit the use cases that actually take
advantage of it. You also risk a bunch of different implementations that
get it wrong half the time on half the systems out there.

Regards,
  Felix




Question regarding clocks in the DW-HDMI DT bindings

2016-11-25 Thread Laurent Pinchart
Hi Fabio,

On Friday 25 Nov 2016 10:43:04 Fabio Estevam wrote:
> On Thu, Nov 24, 2016 at 9:26 PM, Laurent Pinchart wrote:
> > Another question I have about the bus clock (CC'ing the devicetree mailing
> > list as well as the clock maintainers) is whether it should be made
> > optional. The clock is obviously mandatory from a hardware point of view
> > (given that APB is a synchronous bus and thus requires a clock), but in
> > some SoCs (specifically for the Renesas SoCs) that clock is always on and
> > can't be controlled. We already omit bus clocks in DT for most IP cores
> > when the clock can never be controlled (and we also omit a bunch of other
> > clocks that we don't even know exist), so it could make sense to make the
> > clock optional. Otherwise there would be runtime overhead trying to handle
> > a clock that can't be controlled.
> 
> What if you register the clock as a "dummy" clock instead?

In that case I can as well specify the correct clock. My point was that, for 
clocks that we know are always on, specifying them in DT will lead to runtime 
overhead (registration of the clock, lookup, runtime handling, ...) that we 
could as well avoid. I think the question has a broader scope than just the 
dw-hdmi driver, hence the widened audience in CC.

-- 
Regards,

Laurent Pinchart



Question regarding clocks in the DW-HDMI DT bindings

2016-11-25 Thread Vladimir Zapolskiy
Hi Fabio,

On 11/25/2016 02:29 PM, Fabio Estevam wrote:
> Hi Vladimir,
>
> On Thu, Nov 24, 2016 at 8:16 PM, Vladimir Zapolskiy
>  wrote:
>
>> By the way while we're discussing DW HDMI bindings specific to iMX,
>> I would recommend to remove utterly hackish and iMX only "gpr"
>> property from the example in bindings/display/bridge/dw_hdmi.txt
>
> What if we get rid of the "gpr" property completely?
>
> --- a/drivers/gpu/drm/imx/dw_hdmi-imx.c
> +++ b/drivers/gpu/drm/imx/dw_hdmi-imx.c
> @@ -99,9 +99,8 @@ static const struct dw_hdmi_phy_config imx_phy_config[] = {
>
>  static int dw_hdmi_imx_parse_dt(struct imx_hdmi *hdmi)
>  {
> -   struct device_node *np = hdmi->dev->of_node;
> +   hdmi->regmap =
> syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
>
> -   hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "gpr");
> if (IS_ERR(hdmi->regmap)) {
> dev_err(hdmi->dev, "Unable to get gpr\n");
> return PTR_ERR(hdmi->regmap);
>
> Then we can remove the gpr from the device tree files.
>

according to the DTSI files in the vanilla kernel DW HDMI IP is found
only on iMX6Q/D and iMX6DL/iMX6S SoCs (but please double check it),
so this approach should work ideally.

I see that the same has already been done in PCIe and SATA drivers,
but please consider to send a similar change against iMX LDB driver
including removal of the property from imx6qdl.dtsi and
Documentation/devicetree/bindings/display/imx/ldb.txt.

And back to DW HDMI IP it seems that after removing "gpr" property
Documentation/devicetree/bindings/display/imx/hdmi.txt can be removed,
because bindings/display/bridge/dw_hdmi.txt replaces it.

--
With best wishes,
Vladimir


[PATCH] drm: Fixup kernel doc for driver->gem_create_object

2016-11-25 Thread Daniel Vetter
On Fri, Nov 25, 2016 at 12:34:27PM +, Chris Wilson wrote:
> Silences
> 
> ./include/drm/drm_drv.h:295: warning: Incorrect use of kernel-doc format
> 
> Signed-off-by: Chris Wilson 

Applied to drm-misc, thanks.
-Daniel

> ---
>  include/drm/drm_drv.h | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
> index aad8bbacd1f0..52bf44e2b5cc 100644
> --- a/include/drm/drm_drv.h
> +++ b/include/drm/drm_drv.h
> @@ -291,6 +291,8 @@ struct drm_driver {
>   void (*gem_close_object) (struct drm_gem_object *, struct drm_file *);
>  
>   /**
> +  * @gem_create_object: constructor for gem objects
> +  *
>* Hook for allocating the GEM object struct, for use by core
>* helpers.
>*/
> -- 
> 2.10.2
> 
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


Enabling peer to peer device transactions for PCIe devices

2016-11-25 Thread Serguei Sagalovitch
On 2016-11-25 02:34 PM, Jason Gunthorpe wrote:
> On Fri, Nov 25, 2016 at 12:16:30PM -0500, Serguei Sagalovitch wrote:
>
>> b) Allocation may not  have CPU address  at all - only GPU one.
> But you don't expect RDMA to work in the case, right?
>
> GPU people need to stop doing this windowed memory stuff :)
GPU could perfectly access all VRAM.  It is only issue for p2p without
special interconnect and CPU access. Strictly speaking as long as we
have "bus address"  we could have RDMA but  I agreed that for
RDMA we could/should(?) always "request"  CPU address (I hope that we
could forget about 32-bit application :-)).

BTW/FYI: About CPU access: Some user-level API is mainly handle based
so there is no need for CPU access by default.

About "visible" / non-visible VRAM parts: I assume  that going
forward we will be able to get rid from it completely as soon as support
for resizable PCI BAR will be implemented and/or old/current h/w
will become obsolete.


[git pull] drm fixes for v4.9-rc7

2016-11-25 Thread Dave Airlie
Hi Linus,

Seems to be quietening down nicely, a few mediatek, one exynos and one
hdlcd fix,
along with 2 amd fixes.

Dave.

The following changes since commit 9c763584b7c8911106bb77af7e648bef09af9d80:

  Linux 4.9-rc6 (2016-11-20 13:52:19 -0800)

are available in the git repository at:

  git://people.freedesktop.org/~airlied/linux tags/drm-fixes-for-v4.9-rc7

for you to fetch changes up to 9704668e4b7105ede483f38da7f29d71b5bc0165:

  Merge branch 'mediatek-drm-fixes-2016-11-24' of
https://github.com/ckhu-mediatek/linux.git-tags into drm-fixes
(2016-11-25 14:21:26 +1000)


amd, mediatek, exynos and hdlcd fixes.


Arvind Yadav (1):
  gpu/drm/exynos/exynos_hdmi - Unmap region obtained by of_iomap

Bibby Hsieh (1):
  drm/mediatek: fix a typo of DISP_OD_CFG to OD_RELAYMODE

Dave Airlie (3):
  Merge branch 'drm-fixes-4.9' of
git://people.freedesktop.org/~agd5f/linux into drm-fixes
  Merge branch 'for-upstream/hdlcd' of
git://linux-arm.org/linux-ld into drm-fixes
  Merge branch 'mediatek-drm-fixes-2016-11-24' of
https://github.com/ckhu-mediatek/linux.git-tags into drm-fixes

Jitao Shi (1):
  drm/mediatek: fixed the calc method of data rate per lane

Matthias Brugger (1):
  drm/mediatek: fix null pointer dereference

Peter Wu (2):
  drm/amdgpu: fix power state when port pm is unavailable
  drm/radeon: fix power state when port pm is unavailable (v2)

Rex Zhu (1):
  drm/amd/powerplay: avoid out of bounds access on array ps.

Russell King (1):
  drm/arm: hdlcd: fix plane base address update

 drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c |  9 +++-
 drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c | 12 ++---
 drivers/gpu/drm/arm/hdlcd_crtc.c |  5 +-
 drivers/gpu/drm/exynos/exynos_hdmi.c |  5 ++
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c  | 14 +++---
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c  |  2 +-
 drivers/gpu/drm/mediatek/mtk_dsi.c   | 64 ++--
 drivers/gpu/drm/radeon/radeon_atpx_handler.c |  9 +++-
 8 files changed, 85 insertions(+), 35 deletions(-)


Enabling peer to peer device transactions for PCIe devices

2016-11-25 Thread Christian König
Am 24.11.2016 um 17:42 schrieb Jason Gunthorpe:
> On Wed, Nov 23, 2016 at 06:25:21PM -0700, Logan Gunthorpe wrote:
>>
>> On 23/11/16 02:55 PM, Jason Gunthorpe wrote:
> Only ODP hardware allows changing the DMA address on the fly, and it
> works at the page table level. We do not need special handling for
> RDMA.
 I am aware of ODP but, noted by others, it doesn't provide a general
 solution to the points above.
>>> How do you mean?
>> I was only saying it wasn't general in that it wouldn't work for IB
>> hardware that doesn't support ODP or other hardware  that doesn't do
>> similar things (like an NVMe drive).
> There are three cases to worry about:
>   - Coherent long lived page table mirroring (RDMA ODP MR)
>   - Non-coherent long lived page table mirroring (RDMA MR)
>   - Short lived DMA mapping (everything else)
>
> Like you say below we have to handle short lived in the usual way, and
> that covers basically every device except IB MRs, including the
> command queue on a NVMe drive.

Well a problem which wasn't mentioned so far is that while GPUs do have 
a page table to mirror the CPU page table, they usually can't recover 
from page faults.

So what we do is making sure that all memory accessed by the GPU Jobs 
stays in place while those jobs run (pretty much the same pinning you do 
for the DMA).

But since this can lock down huge amounts of memory the whole command 
submission to GPUs is bound to the memory management. So when to much 
memory would get blocked by the GPU we block further command submissions 
until the situation resolves.

>> any complex allocators (GPU or otherwise) should respect that. And that
>> seems like it should be the default way most of this works -- and I
>> think it wouldn't actually take too much effort to make it all work now
>> as is. (Our iopmem work is actually quite small and simple.)
> Yes, absolutely, some kind of page pinning like locking is a hard
> requirement.
>
>> Yeah, we've had RDMA and O_DIRECT transfers to PCIe backed ZONE_DEVICE
>> memory working for some time. I'd say it's a good fit. The main question
>> we've had is how to expose PCIe bars to userspace to be used as MRs and
>> such.
> Is there any progress on that?
>
> I still don't quite get what iopmem was about.. I thought the
> objection to uncachable ZONE_DEVICE & DAX made sense, so running DAX
> over iopmem and still ending up with uncacheable mmaps still seems
> like a non-starter to me...
>
> Serguei, what is your plan in GPU land for migration? Ie if I have a
> CPU mapped page and the GPU moves it to VRAM, it becomes non-cachable
> - do you still allow the CPU to access it? Or do you swap it back to
> cachable memory if the CPU touches it?

Depends on the policy in command, but currently it's the other way 
around most of the time.

E.g. we allocate memory in VRAM, the CPU writes to it WC and avoids 
reading because that is slow, the GPU in turn can access it with full speed.

When we run out of VRAM we move those allocations to system memory and 
update both the CPU as well as the GPU page tables.

So that move is transparent for both userspace as well as shaders 
running on the GPU.

> One approach might be to mmap the uncachable ZONE_DEVICE memory and
> mark it inaccessible to the CPU - DMA could still translate. If the
> CPU needs it then the kernel migrates it to system memory so it
> becomes cachable. ??

The whole purpose of this effort is that we can do I/O on VRAM directly 
without migrating everything back to system memory.

Allowing this, but then doing the migration by the first touch of the 
CPU is clearly not a good idea.

Regards,
Christian.

>
> Jason




Enabling peer to peer device transactions for PCIe devices

2016-11-25 Thread Jason Gunthorpe
On Fri, Nov 25, 2016 at 09:40:10PM +0100, Christian König wrote:

> We call this "userptr" and it's just a combination of get_user_pages() on
> command submission and making sure the returned list of pages stays valid
> using a MMU notifier.

Doesn't that still pin the page?

> The "big" problem with this approach is that it is horrible slow. I mean
> seriously horrible slow so that we actually can't use it for some of the
> purposes we wanted to use it.
> 
> >The code moving the page will move it and the next GPU command that
> >needs it will refault it in the usual way, just like the CPU would.
> 
> And here comes the problem. CPU do this on a page by page basis, so they
> fault only what needed and everything else gets filled in on demand. This
> results that faulting a page is relatively light weight operation.
>
> But for GPU command submission we don't know which pages might be accessed
> beforehand, so what we do is walking all possible pages and make sure all of
> them are present.

Little confused why this is slow? So you fault the entire user MM into
your page tables at start of day and keep track of it with mmu
notifiers?

> >This might be much more efficient since it optimizes for the common
> >case of unchanging translation tables.
> 
> Yeah, completely agree. It works perfectly fine as long as you don't have
> two drivers trying to mess with the same page.

Well, the idea would be to not have the GPU block the other driver
beyond hinting that the page shouldn't be swapped out.

> >This assumes the commands are fairly short lived of course, the
> >expectation of the mmu notifiers is that a flush is reasonably prompt
> 
> Correct, this is another problem. GFX command submissions usually don't take
> longer than a few milliseconds, but compute command submission can easily
> take multiple hours.

So, that won't work - you have the same issue as RDMA with work loads
like that.

If you can't somehow fence the hardware then pinning is the only
solution. Felix has the right kind of suggestion for what is needed -
globally stop the GPU, fence the DMA, fix the page tables, and start
it up again. :\

> I can easily imagine what would happen when kswapd is blocked by a GPU
> command submission for an hour or so while the system is under memory
> pressure :)

Right. The advantage of pinning is it tells the other stuff not to
touch the page and doesn't block it, MMU notifiers have to be able to
block quickly.

> I'm thinking on this problem for about a year now and going in circles for
> quite a while. So if you have ideas on this even if they sound totally
> crazy, feel free to come up.

Well, it isn't a software problem. From what I've seen in this thread
the GPU application requires coherent page table mirroring, so the
only full & complete solution is going to be to actually implement
that somehow in GPU hardware.

Everything else is going to be deeply flawed somehow. Linux just
doesn't have the support for this kind of stuff - and I'm honestly not
sure something better is even possible considering the hardware
constraints

This doesn't have to be faulting, but really anything that lets you
pause the GPU DMA and reload the page tables.

You might look at trying to use the IOMMU and/or PCI ATS in very new
hardware. IIRC the physical IOMMU hardware can do the fault and fence
and block stuff, but I'm not sure about software support for using the
IOMMU to create coherent user page table mirrors - that is something
Linux doesn't do today. But there is demand for this kind of capability..

Jason


Enabling peer to peer device transactions for PCIe devices

2016-11-25 Thread Christian König
Am 24.11.2016 um 18:55 schrieb Logan Gunthorpe:
> Hey,
>
> On 24/11/16 02:45 AM, Christian König wrote:
>> E.g. it can happen that PCI device A exports it's BAR using ZONE_DEVICE.
>> Not PCI device B (a SATA device) can directly read/write to it because
>> it is on the same bus segment, but PCI device C (a network card for
>> example) can't because it is on a different bus segment and the bridge
>> can't handle P2P transactions.
> Yeah, that could be an issue but in our experience we have yet to see
> it. We've tested with two separate PCI buses on different CPUs connected
> through QPI links and it works fine. (It is rather slow but I understand
> Intel has improved the bottleneck in newer CPUs than the ones we tested.)

Well Serguei send me a couple of documents about QPI when we started to 
discuss this internally as well and that's exactly one of the cases I 
had in mind when writing this.

If I understood it correctly for such systems P2P is technical possible, 
but not necessary a good idea. Usually it is faster to just use a 
bouncing buffer when the peers are a bit "father" apart.

That this problem is solved on newer hardware is good, but doesn't helps 
us at all if we at want to support at least systems from the last five 
years or so.

> It may just be older hardware that has this issue. I expect that as long
> as a failed transfer can be handled gracefully by the initiator I don't
> see a need to predetermine whether a device can see another devices memory.

I don't want to predetermine whether a device can see another devices 
memory at get_user_pages() time.

My thinking was more going into the direction of a whitelist to figure 
out during dma_map_single()/dma_map_sg() time if we should use a 
bouncing buffer or not.

Christian.

>
>
> Logan




[Bug 97403] AMDGPU/Iceland Strange warnings on drm-next-4.9-wip

2016-11-25 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=97403

--- Comment #11 from Armin K  ---
Forgot to add: Information from previous comment appears every time the GPU
powers back up at runtime, as well as at boot before it powers down.

-- 
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/20161125/c263f791/attachment.html>


[Bug 97403] AMDGPU/Iceland Strange warnings on drm-next-4.9-wip

2016-11-25 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=97403

--- Comment #10 from Armin K  ---
[  139.811192] cant't get the mac of 5 
[  139.819526] [drm] ring test on 0 succeeded in 10 usecs
[  139.819729] [drm] ring test on 1 succeeded in 13 usecs
[  139.819749] [drm] ring test on 2 succeeded in 10 usecs
[  139.819757] [drm] ring test on 3 succeeded in 3 usecs
[  139.819760] [drm] ring test on 4 succeeded in 1 usecs
[  139.819765] [drm] ring test on 5 succeeded in 2 usecs
[  139.819769] [drm] ring test on 6 succeeded in 1 usecs
[  139.819774] [drm] ring test on 7 succeeded in 2 usecs
[  139.819779] [drm] ring test on 8 succeeded in 2 usecs
[  139.819812] [drm] ring test on 9 succeeded in 4 usecs
[  139.819816] [drm] ring test on 10 succeeded in 3 usecs
[  146.992737] VI should always have 2 performance levels
[  147.448605] amdgpu :01:00.0: GPU pci config reset
[  151.265505] [drm] PCIE GART of 3931M enabled (table at 0x0004).

In addition to original report, two more "strange" warnings now appear:

[  139.811192] cant't get the mac of 5 
[  147.448605] amdgpu :01:00.0: GPU pci config reset

Not sure if second one is a warning or just information (intended).

I have gotten amdgpu to work on 4.9 by building it into kernel, along with all
the firmware. atiflash still doesn't work. glxgears with vblank_mode=0 has
broken rendering and hangs the system, requiring hard reboot. When synced to
vblank, it doesn't hang anything.

-- 
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/20161125/68e7a2bb/attachment.html>


[Bug 98238] witcher 2: objects are black when changing lod

2016-11-25 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=98238

--- Comment #9 from Arek Ruśniak  ---
I've  forgot to mention, in both case I've build mesa against LLVM 3.9.0
(official arch packages)
I cannot simply revert ab29788250a705eb0dd517cb3d38f37f944eb8ad
I had compile errors with LLVM 4.0, didn't try 3.8.x.

-- 
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/20161125/4b936e6d/attachment.html>


Question regarding clocks in the DW-HDMI DT bindings

2016-11-25 Thread Fabio Estevam
On Fri, Nov 25, 2016 at 1:22 PM, Laurent Pinchart
 wrote:

>> I got the clock name from I.MX6Q TRM, I also checked the name again
>> with Rockchip IC design team now, hope to get some new information soon.
>
> Thank you. While at it, could you ask them which version of the DW HDMI IP
> used in the SoC ?

DW HDMI IP used in Rockchip is:
dwhdmi-rockchip ff98.hdmi: Detected HDMI controller 0x20:0xa:0xa0:0xc1

as shown at 
https://storage.kernelci.org/mainline/v4.9-rc6-157-g16ae16c6e561/arm-multi_v7_defconfig/lab-collabora/boot-rk3288-rock2-square_rootfs:nfs.html

DW HDMI IP used  on mx6q is:
dwhdmi-imx 12.hdmi: Detected HDMI controller 0x13:0xa:0xa0:0xc1


[linux-sunxi] [PATCH v6 3/5] ARM: dts: sun8i-h3: add HDMI video nodes

2016-11-25 Thread Icenowy Zheng


20.11.2016, 20:07, "Jean-Francois Moine" :
> Signed-off-by: Jean-Francois Moine 
> ---
>  arch/arm/boot/dts/sun8i-h3.dtsi | 51 
> +
>  1 file changed, 51 insertions(+)
>
> diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi
> index 416b825..7c6b1d5 100644
> --- a/arch/arm/boot/dts/sun8i-h3.dtsi
> +++ b/arch/arm/boot/dts/sun8i-h3.dtsi
> @@ -140,6 +140,16 @@
>                  #size-cells = <1>;
>                  ranges;
>
> + de: de-controller at 0100 {
> + compatible = "allwinner,sun8i-h3-display-engine";
> + reg = <0x0100 0x40>;
> + clocks = < CLK_BUS_DE>, < CLK_DE>;
> + clock-names = "bus", "clock";
> + resets = < RST_BUS_DE>;
> + ports = <_p>;
> + status = "disabled";
> + };
> +
>                  dma: dma-controller at 01c02000 {
>                          compatible = 
> "allwinner,sun8i-h3-dma";
>                          reg = <0x01c02000 0x1000>;
> @@ -149,6 +159,23 @@
>                          #dma-cells = <1>;
>                  };
>
> + lcd0: lcd-controller at 01c0c000 {
> + compatible = "allwinner,sun8i-a83t-tcon";
> + reg = <0x01c0c000 0x400>;
> + clocks = < CLK_BUS_TCON0>, < CLK_TCON0>;
> + clock-names = "bus", "clock";
> + resets = < RST_BUS_TCON0>;
> + interrupts = ;
> + status = "disabled";
> + #address-cells = <1>;
> + #size-cells = <0>;
> + lcd0_p: port {
> + lcd0_hdmi: endpoint {
> + remote-endpoint = <_lcd0>;
> + };
> + };
> + };
> +
>                  mmc0: mmc at 01c0f000 {
>                          compatible = 
> "allwinner,sun7i-a20-mmc";
>                          reg = <0x01c0f000 0x1000>;
> @@ -314,6 +341,11 @@
>                          clock-names = "hosc", 
> "losc";
>                          #clock-cells = <1>;
>                          #reset-cells = <1>;
> +
> + assigned-clocks = < CLK_PLL_DE>,

Cannot get the patch built on 4.9-rc, as CLK_PLL_DE is not an exported clock.

Only CLK_DE is exported.

> + < CLK_DE>;
> + assigned-clock-rates = <86400>,
> + <43200>;
>                  };
>
>                  pio: pinctrl at 01c20800 {
> @@ -564,6 +596,25 @@
>                          interrupts =  (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
>                  };
>
> + hdmi: hdmi at 01ee {
> + compatible = "allwinner,sun8i-h3-hdmi";
> + reg = <0x01ee 0x2>;
> + clocks = < CLK_BUS_HDMI>, < CLK_HDMI>,
> + < CLK_HDMI_DDC>;
> + clock-names = "bus", "clock", "ddc-clock";
> + resets = < RST_BUS_HDMI0>, < RST_BUS_HDMI1>;
> + reset-names = "hdmi0", "hdmi1";
> + status = "disabled";
> + #address-cells = <1>;
> + #size-cells = <0>;
> + port at 0 { /* video */
> + reg = <0>;
> + hdmi_lcd0: endpoint {
> + remote-endpoint = <_hdmi>;
> + };
> + };
> + };
> +
>                  rtc: rtc at 01f0 {
>                          compatible = 
> "allwinner,sun6i-a31-rtc";
>                          reg = <0x01f0 0x54>;
> --
> 2.10.2
>
> --
> You received this message because you are subscribed to the Google Groups 
> "linux-sunxi" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to linux-sunxi+unsubscribe at googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.


Enabling peer to peer device transactions for PCIe devices

2016-11-25 Thread Jason Gunthorpe
On Fri, Nov 25, 2016 at 02:49:50PM -0500, Serguei Sagalovitch wrote:

> GPU could perfectly access all VRAM.  It is only issue for p2p without
> special interconnect and CPU access. Strictly speaking as long as we
> have "bus address"  we could have RDMA but  I agreed that for
> RDMA we could/should(?) always "request"  CPU address (I hope that we
> could forget about 32-bit application :-)).

At least on x86 if you have a bus address you have a CPU address. All
RDMAable VRAM has to be visible in the BAR.

> BTW/FYI: About CPU access: Some user-level API is mainly handle based
> so there is no need for CPU access by default.

You mean no need for the memory to be virtually mapped into the
process?

Do you expect to RDMA from this kind of API? How will that work?

Jason


[Intel-gfx] v4.9-rc3: graphical artefacts in X

2016-11-25 Thread Pavel Machek
On Fri 2016-11-18 11:14:16, Chris Wilson wrote:
> On Fri, Nov 18, 2016 at 12:02:56PM +0100, Pavel Machek wrote:
> > Hi!
> > 
> > With v4.9, if I maximize "nowcast -x" application, I get broken
> > display (as if someone split the window into rectangles and shuffled
> > them a bit). Switching virtual desktops either fixes it or breaks it,
> > depending in how fast I switch. (Yes, strange).
> 
> The fix should have landed in v4.9-rc5

Yep, I just tested -rc5, and problem seems gone. Thanks!
Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) 
http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
-- next part --
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: 
<https://lists.freedesktop.org/archives/dri-devel/attachments/20161125/6b145771/attachment.sig>


[Bug 98238] witcher 2: objects are black when changing lod

2016-11-25 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=98238

--- Comment #8 from Arek Ruśniak  ---
I can't provide apitrace or any kind of usefull things for witcher but I've
found regression in unigine-valley for the same commit
If you think it can help I can provide apirace form valley.

-- 
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/20161125/6e8d0861/attachment.html>


Enabling peer to peer device transactions for PCIe devices

2016-11-25 Thread Serguei Sagalovitch

> Well, I guess there's some consensus building to do. The existing
> options are:
>
> * Device DAX: which could work but the problem I see with it is that it
> only allows one application to do these transfers. Or there would have
> to be some user-space coordination to figure which application gets what
> memeroy.
About one application restriction: so it is per memory mapping? I assume 
that
it should not be problem for one application to do transfer to the 
several devices
simultaneously? Am I right?

May be we should follow RDMA MR design and register memory for p2p 
transfer from user
space?

What about the following:

a)  Device DAX is created
b) "Normal" (movable, etc.) allocation will be done for PCIe memory and 
CPU pointer/access will
be requested.
c)  p2p_mr_register() will be called and CPU pointer (mmap( on DAX 
Device)) will be returned.
Accordingly such memory will be marked as "unmovable" by e.g. graphics 
driver.
d) When p2p is not needed then p2p_mr_unregister() will be called.

What do you think? Will it work?




[Bug 98238] witcher 2: objects are black when changing lod

2016-11-25 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=98238

--- Comment #7 from Arek Ruśniak  ---
Ok, I think I've found big part of this problem:

author  Marek Olšák2016-09-13 15:33:23 (GMT)
committer   Marek Olšák2016-09-14 10:33:00
(GMT)
commit  ab29788250a705eb0dd517cb3d38f37f944eb8ad (patch)

radeonsi: reload PS inputs with direct indexing at each use (v2)
The LLVM compiler can CSE interp intrinsics thanks to
LLVMReadNoneAttribute.

26011 shaders in 14651 tests
Totals:
SGPRS: 1146340 -> 1132676 (-1.19 %)
VGPRS: 727371 -> 711730 (-2.15 %)
Spilled SGPRs: 2218 -> 2078 (-6.31 %)
Spilled VGPRs: 369 -> 369 (0.00 %)
Scratch VGPRs: 1344 -> 1344 (0.00 %) dwords per thread
Code Size: 35841268 -> 36009732 (0.47 %) bytes
LDS: 767 -> 767 (0.00 %) blocks
Max Waves: 222559 -> 224779 (1.00 %)
Wait states: 0 -> 0 (0.00 %)

v2: don't call load_input for fragment shaders in emit_declaration


videos from "last good" and "first bad":
https://youtu.be/X3Zqb-cYssg
https://youtu.be/73X9SVf6_1g

-- 
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/20161125/153d3f94/attachment.html>


Enabling peer to peer device transactions for PCIe devices

2016-11-25 Thread Jason Gunthorpe
On Thu, Nov 24, 2016 at 11:58:17PM -0800, Christoph Hellwig wrote:
> On Thu, Nov 24, 2016 at 11:11:34AM -0700, Logan Gunthorpe wrote:
> > * Regular DAX in the FS doesn't work at this time because the FS can
> > move the file you think your transfer to out from under you. Though I
> > understand there's been some work with XFS to solve that issue.
> 
> The file system will never move anything under locked down pages,
> locking down pages is used exactly to protect against that.

.. And ODP style mmu notifiers work correctly as well, I'd assume.

So this should work with ZONE_DEVICE, if it doesn't it is a filesystem
bug?

> really want a notification to the consumer if the file systems wants
> to remove the mapping.  We have implemented that using FL_LAYOUTS locks
> for NFSD, but only XFS supports it so far.  Without that a long term
> locked down region of memory (e.g. a kernel MR) would prevent various
> file operations that would simply hang.

So you imagine a signal back to user space asking user space to drop
any RDMA MRS so the FS can relocate things?

Do we need that, or should we encourage people to use either short
lived MRs or ODP MRs when working with scenarios that need FS
relocation?

Jason


[PATCH] drm: Fixup kernel doc for driver->gem_create_object

2016-11-25 Thread Chris Wilson
Silences

./include/drm/drm_drv.h:295: warning: Incorrect use of kernel-doc format

Signed-off-by: Chris Wilson 
---
 include/drm/drm_drv.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
index aad8bbacd1f0..52bf44e2b5cc 100644
--- a/include/drm/drm_drv.h
+++ b/include/drm/drm_drv.h
@@ -291,6 +291,8 @@ struct drm_driver {
void (*gem_close_object) (struct drm_gem_object *, struct drm_file *);

/**
+* @gem_create_object: constructor for gem objects
+*
 * Hook for allocating the GEM object struct, for use by core
 * helpers.
 */
-- 
2.10.2



Enabling peer to peer device transactions for PCIe devices

2016-11-25 Thread Jason Gunthorpe
On Fri, Nov 25, 2016 at 12:16:30PM -0500, Serguei Sagalovitch wrote:

> b) Allocation may not  have CPU address  at all - only GPU one.

But you don't expect RDMA to work in the case, right?

GPU people need to stop doing this windowed memory stuff :)

Jason


Enabling peer to peer device transactions for PCIe devices

2016-11-25 Thread Jason Gunthorpe
On Fri, Nov 25, 2016 at 02:22:17PM +0100, Christian König wrote:

> >Like you say below we have to handle short lived in the usual way, and
> >that covers basically every device except IB MRs, including the
> >command queue on a NVMe drive.
> 
> Well a problem which wasn't mentioned so far is that while GPUs do have a
> page table to mirror the CPU page table, they usually can't recover from
> page faults.

> So what we do is making sure that all memory accessed by the GPU Jobs stays
> in place while those jobs run (pretty much the same pinning you do for the
> DMA).

Yes, it is DMA, so this is a valid approach.

But, you don't need page faults from the GPU to do proper coherent
page table mirroring. Basically when the driver submits the work to
the GPU it 'faults' the pages into the CPU and mirror translation
table (instead of pinning).

Like in ODP, MMU notifiers/HMM are used to monitor for translation
changes. If a change comes in the GPU driver checks if an executing
command is touching those pages and blocks the MMU notifier until the
command flushes, then unfaults the page (blocking future commands) and
unblocks the mmu notifier.

The code moving the page will move it and the next GPU command that
needs it will refault it in the usual way, just like the CPU would.

This might be much more efficient since it optimizes for the common
case of unchanging translation tables.

This assumes the commands are fairly short lived of course, the
expectation of the mmu notifiers is that a flush is reasonably prompt
..

> >Serguei, what is your plan in GPU land for migration? Ie if I have a
> >CPU mapped page and the GPU moves it to VRAM, it becomes non-cachable
> >- do you still allow the CPU to access it? Or do you swap it back to
> >cachable memory if the CPU touches it?
> 
> Depends on the policy in command, but currently it's the other way around
> most of the time.
> 
> E.g. we allocate memory in VRAM, the CPU writes to it WC and avoids reading
> because that is slow, the GPU in turn can access it with full speed.
> 
> When we run out of VRAM we move those allocations to system memory and
> update both the CPU as well as the GPU page tables.
> 
> So that move is transparent for both userspace as well as shaders running on
> the GPU.

That makes sense to me, but the objection that came back for
non-cachable CPU mappings is that it basically breaks too much stuff
subtly, eg atomics, unaligned accesses, the CPU threading memory
model, all change on various architectures and break when caching is
disabled.

IMHO that is OK for specialty things like the GPU where the mmap comes
in via drm or something and apps know to handle that buffer specially.

But it is certainly not OK for DAX where the application is coded for
normal file open()/mmap() is not prepared for a mmap where (eg)
unaligned read accesses or atomics don't work depending on how the
filesystem is setup.

Which is why I think iopmem is still problematic..

At the very least I think a mmap flag or open flag should be needed to
opt into this behavior and by default non-cachebale DAX mmaps should
be paged into system ram when the CPU accesses them.

I'm hearing most people say ZONE_DEVICE is the way to handle this,
which means the missing remaing piece for RDMA is some kind of DMA
core support for p2p address translation..

Jason


Enabling peer to peer device transactions for PCIe devices

2016-11-25 Thread Serguei Sagalovitch

> A white list may end up being rather complicated if it has to cover
> different CPU generations and system architectures. I feel this is a
> decision user space could easily make.
>
> Logan
I agreed that it is better to leave up to user space to check what is 
working
and what is not. I found that write is practically always working but 
read very
often not. Also sometimes system BIOS update could fix the issue.



Enabling peer to peer device transactions for PCIe devices

2016-11-25 Thread Serguei Sagalovitch
On 2016-11-25 08:22 AM, Christian König wrote:
>
>> Serguei, what is your plan in GPU land for migration? Ie if I have a
>> CPU mapped page and the GPU moves it to VRAM, it becomes non-cachable
>> - do you still allow the CPU to access it? Or do you swap it back to
>> cachable memory if the CPU touches it?
>
> Depends on the policy in command, but currently it's the other way 
> around most of the time.
>
> E.g. we allocate memory in VRAM, the CPU writes to it WC and avoids 
> reading because that is slow, the GPU in turn can access it with full 
> speed.
>
> When we run out of VRAM we move those allocations to system memory and 
> update both the CPU as well as the GPU page tables.
>
> So that move is transparent for both userspace as well as shaders 
> running on the GPU.
I would like to add more in relation to  CPU access :

a) we could have CPU-accessible part of VRAM ("inside" of PCIe BAR register)
and non-CPU  accessible part.  As the result if user needs to have
CPU access than memory should be located in CPU-accessible part
of VRAM or in system memory.

Application/user mode driver could specify preference/hints of
locations based on their assumption / knowledge about access
patterns requirements, game resolution,  knowledge
about size of VRAM memory, etc.  So if CPU access performance
is critical then such memory should be allocated in system memory
as  the first (and may be only) choice.

b) Allocation may not  have CPU address  at all - only GPU one.
Also we may not be able to have CPU address/accesses for all VRAM
memory but memory may still  be migrated in any case unrelated
if we have CPU address or not.

c) " VRAM, it becomes non-cachable "
Strictly speaking VRAM is configured as WC (write-combined memory) to
provide fast CPU write access. Also it was found that sometimes if CPU
access is not critical from performance perspective it may be useful
to allocate/program system memory also as WC to  avoid needs for
extra "snooping" to synchronize with CPU caches during GPU access.
So potentially system memory could be WC too.




[PATCH v4 00/10] drm/tilcdc: LCDC Revision 1 related fixes

2016-11-25 Thread Bartosz Golaszewski
2016-11-25 10:09 GMT+01:00 Jyri Sarha :
> The git branch bellow is updated.
>
> Changes since v3:
> - "drm/tilcdc: Enable sync lost error and recovery handling for rev 1 LCDC"
>   - disable sync-lost irq also for rev1 LCDC
>   - LCDC_V1_SYNC_LOST_ENA to LCDC_V1_SYNC_LOST_INT_ENA
> - "drm/tilcdc: Enable palette loading for revision 2 LCDC too"
>   - disable palette loaded interrupt after receiving it
> - "drm/tilcdc: Enable frame done irq and functionality for LCDC rev 1"
>   - disable FRAME_DONE interrupt for rev 1 lcdc in interrupt routine
>   - LCDC_V1_FRAME_DONE_ENA to LCDC_V1_FRAME_DONE_INT_ENA
> - Add: "drm/tilcdc: Configure video mode to HW in enable() not in 
> mode_set_nofb()"
> - Drop "drm/tilcdc: Use complete_all() to indicate completed palette loading"
> - Drop "drm/tilcdc: Call reset() before loading the palette"
> - "drm/tilcdc: Load palette at the end of mode_set_nofb()"
>   - Just load the palette every time, no runtime_resume hook
>
> Changes since v2:
> - Add: "drm/tilcdc: Fix load mode bit-field setting in tilcdc_crtc_enable()"
> - Drop: "drm/tilcdc: Free palette dma memory in tilcdc_crtc_destroy()"
> - Add: "drm/tilcdc: Add timeout wait for palette loading to complete"
> - Add: "drm/tilcdc: Call reset() before loading the palette"
> - Add: "drm/tilcdc: Use complete_all() to indicate completed palette loading"
> - Add "drm/tilcdc: Enable frame done irq and functionality for LCDC rev 1"
>   - Bartosz: Please test if this works! The symptom for not working is
> "timeout waiting for framedone" message when screen is blanked.
>
> Changes since first version of the series:
>
> - Move tilcdc_regs.h changes from "drm/tilcdc: Enable palette loading
>   for revision 2 LCDC too" to "drm/tilcdc: Add tilcdc_write_mask() to
>   tilcdc_regs.h"
>
> These patches are inspired by this series form Bartosz Golaszewski:
> https://www.spinics.net/lists/arm-kernel/msg539629.html
>
> The patches are based on drm-next plus the earlier patches that I plan
> to send in a pull request for 4.10. The base + these patches are
> pushed here:
>
> https://github.com/jsarha/linux drm-next-tilcdc-for-4.10-wip
>
> Bartosz, please test if this branch works for rev1 LCDC, with your dts
> file!
>
> Bartosz Golaszewski (1):
>   drm/tilcdc: implement palette loading for rev1
>
> Jyri Sarha (9):
>   drm/tilcdc: Enable sync lost error and recovery handling for rev 1
> LCDC
>   drm/tilcdc: Fix tilcdc_crtc_create() return value handling
>   drm/tilcdc: Add tilcdc_write_mask() to tilcdc_regs.h
>   drm/tilcdc: Fix load mode bit-field setting in tilcdc_crtc_enable()
>   drm/tilcdc: Enable palette loading for revision 2 LCDC too
>   drm/tilcdc: Add timeout wait for palette loading to complete
>   drm/tilcdc: Load palette at the end of mode_set_nofb()
>   drm/tilcdc: Configure video mode to HW in enable() not in
> mode_set_nofb()
>   drm/tilcdc: Enable frame done irq and functionality for LCDC rev 1
>
>  drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 558 
> ---
>  drivers/gpu/drm/tilcdc/tilcdc_drv.c  |  17 +-
>  drivers/gpu/drm/tilcdc/tilcdc_drv.h  |   2 +-
>  drivers/gpu/drm/tilcdc/tilcdc_regs.h |  15 +
>  4 files changed, 344 insertions(+), 248 deletions(-)
>
> --
> 1.9.1
>

Tested-by: Bartosz Golaszewski 


[PATCH v5 0/4] drm/tilcdc: Add bridge support and sync-lost flood recovery

2016-11-25 Thread Bartosz Golaszewski
2016-11-25 10:02 GMT+01:00 Jyri Sarha :
> Changes since v4:
> - "drm/bridge: Add ti-tfp410 DVI transmitter driver"
>   - Put i2c behind #if IS_ENABLED(CONFIG_I2C)
> - "drm/tilcdc: Add drm bridge support for attaching drm bridge drivers"
>   - Use exsisting infrastructure to hookup crtc mode validation code
> to newly connected connector, whether that came from componentized
> driver or trough an attached bridge
>
> Changes since v3:
> - "drm/tilcdc: Enable sync lost error and recovery handling for rev 1 LCDC"
>   - Fix broken irq enable/disble code for LCDC rev 1
> - Add: "dt-bindings: Move "ti,tfp410.txt" from display/ti to display/bridge"
> - "drm/bridge: Add ti-tfp410 DVI transmitter driver"
>   - Don't fail if either i2c or platform driver register succeeds
>   - ftp410 -> tfp410
>   - Merge the old display/ti,tfp410.txt document with my addition
>
> Changes since v2:
> - "drm/tilcdc: Recover from sync lost error flood by resetting the LCDC"
>   - no change
> - "drm/bridge: Add ti-tfp410 DVI transmitter driver"
>   - Fix deveice-tree document
> - "driver node" -> "device node"
> - remove "(the current implementation does not yet support this)"
>   - Add dummy i2c support. The driver probe works also if placed under
> i2c controller node, but there is no actual i2c probing.
> - "drm/tilcdc: Add drm bridge support for attaching drm bridge drivers"
>   - no change
>
> Changes since first version of the series:
> - "drm/tilcdc: Recover from sync lost error flood by resetting the LCDC"
>   - no change
> - "drm/bridge: Add ti-tfp410 DVI transmitter driver"
>   - HDMI -> DVI
>   - DT Binding document
> - Prepare for tfp410 connected trough i2c by optional reg property
> - Require two port nodes
>   - Implementation
> - Implement connector node functionality with in tfp410 bridge
>   drive, but follow generic connector binding by pulling the
>   ddc-i2c-bus property from the connector node.
> - "drm/tilcdc: Add drm bridge support for attaching drm bridge drivers"
>   - Remove earlier change in TD binding document. There is no need to
> mention DRM implementation details, like bridge support, in DT
> binding.
>
> The first patch is an independent on and I've been testing it for
> quite a while now.
>
> The tfp410 bridge driver and the tilcdc bridge support are tested with
> BeagleBone DVI-D Cape Rev A3. The tfp410 bridge driver is missing a
> lot of features, because the DVI-D cape does not have too many wires
> connected. The missing features can be added later when they are
> needed.
>
> Jyri Sarha (4):
>   drm/tilcdc: Recover from sync lost error flood by resetting the LCDC
>   dt-bindings: Move "ti,tfp410.txt" from display/ti to display/bridge
>   drm/bridge: Add ti-tfp410 DVI transmitter driver
>   drm/tilcdc: Add drm bridge support for attaching drm bridge drivers
>
>  .../bindings/display/{ti => bridge}/ti,tfp410.txt  |   9 +-
>  drivers/gpu/drm/bridge/Kconfig |   7 +
>  drivers/gpu/drm/bridge/Makefile|   1 +
>  drivers/gpu/drm/bridge/ti-tfp410.c | 317 
> +
>  drivers/gpu/drm/tilcdc/tilcdc_crtc.c   |  26 +-
>  drivers/gpu/drm/tilcdc/tilcdc_drv.c|  11 +-
>  drivers/gpu/drm/tilcdc/tilcdc_drv.h|   5 +-
>  drivers/gpu/drm/tilcdc/tilcdc_external.c   | 260 -
>  drivers/gpu/drm/tilcdc/tilcdc_external.h   |   5 +-
>  9 files changed, 564 insertions(+), 77 deletions(-)
>  rename Documentation/devicetree/bindings/display/{ti => 
> bridge}/ti,tfp410.txt (65%)
>  create mode 100644 drivers/gpu/drm/bridge/ti-tfp410.c
>
> --
> 1.9.1
>

For 1/4 and 4/4:

Tested-by: Bartosz Golaszewski 


[Bug 188621] Function kfd_wait_on_events() does not set error code when the call to copy_from_user() fails

2016-11-25 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=188621

--- Comment #1 from Oded Gabbay  ---
I'll look into it.
Thanks for the bug.
Oded

-- 
You are receiving this mail because:
You are watching the assignee of the bug.


[PATCH v6 3/5] ARM: dts: sun8i-h3: add HDMI video nodes

2016-11-25 Thread Jean-Francois Moine
On Fri, 25 Nov 2016 17:41:51 +0800
Icenowy Zheng  wrote:

> After removing CLK_PLL_DE's assigned-clock, the kernel passes compilation.

The 'pll-de' and 'de' must have a fixed rate. Otherwise, if you do not
use the legacy u-boot, I don't know which can be the rate of the DE.

> However, it cannot recognize any HDMI screen...
> 
> (My board is Orange Pi One, and I manually added status="okay"; to , 
> , )
> 
> [   16.507802] sun8i-de2 100.de-controller: bound 1c0c000.lcd-controller 
> (ops de2_lcd_ops [sun8i_de2_drm])
> [   16.675948] sun8i-de2 100.de-controller: bound 1ee.hdmi (ops 
> de2_hdmi_fini [sun8i_de2_hdmi])
> [   16.685120] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
> [   16.695876] [drm] No driver support for vblank timestamp query.
> [   16.701862] sun8i-de2 100.de-controller: No connectors reported 
> connected with modes
> [   16.713061] [drm] Cannot find any crtc or sizes - going 1024x768
> [   16.734214] Console: switching to colour frame buffer device 128x48
> [   16.751022] sun8i-de2 100.de-controller: fb0:  frame buffer device

I put a 'pr_warn' message is case the EDID cannot be read.
Have you this message?

Anyway, there is a problem with the EDID:
- my Orange Pi 2 (H3) randomly fails to read it. But this succeeds after
  rebooting once or twice.
- my Banana Pi M2+ (H3) reads it correctly each time.
- my Banana Pi M3 (A83T) can never read it.

BTW, on first tries, I was forcing a CEA mode thru the kernel command
line. This was working with the OPi2 and BPiM3, but there was no sound.
In the last version, I use a EDID in edid_firmware for having sound
with the BPiM3. This works fine.
But, forcing a CEA mode is no more possible, so, when the OPi2 cannot
read the EDID, the system switches to a VGA mode (default 1024x768)
which is not supported. It seems that this is your case.

So, in brief, if your board cannot read the EDID, put a EDID somewhere
and its path in /sys/module/drm_kms_helper/parameters/edid_firmware.
There will be no console, but X11 will work correctly.

-- 
Ken ar c'hentañ| ** Breizh ha Linux atav! **
Jef |   http://moinejf.free.fr/


[Bug 98239] saints row 3: performance is limited by flushes

2016-11-25 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=98239

--- Comment #1 from Marek Olšák  ---
What's your GPU and kernel driver?

-- 
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/20161125/258169b4/attachment.html>


[PATCH v4 10/10] drm/tilcdc: Enable frame done irq and functionality for LCDC rev 1

2016-11-25 Thread Jyri Sarha
We should wait for the last frame to complete before shutting things
down also on LCDC rev 1.

Signed-off-by: Jyri Sarha 
---
 drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 18 +++---
 drivers/gpu/drm/tilcdc/tilcdc_regs.h |  1 +
 2 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c 
b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
index fb24422..9942b05 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
@@ -171,7 +171,7 @@ static void tilcdc_crtc_enable_irqs(struct drm_device *dev)

if (priv->rev == 1) {
tilcdc_set(dev, LCDC_RASTER_CTRL_REG,
-   LCDC_V1_SYNC_LOST_INT_ENA |
+   LCDC_V1_SYNC_LOST_INT_ENA | LCDC_V1_FRAME_DONE_INT_ENA |
LCDC_V1_UNDERFLOW_INT_ENA);
tilcdc_set(dev, LCDC_DMA_CTRL_REG,
LCDC_V1_END_OF_FRAME_INT_ENA);
@@ -190,7 +190,7 @@ static void tilcdc_crtc_disable_irqs(struct drm_device *dev)
/* disable irqs that we might have enabled: */
if (priv->rev == 1) {
tilcdc_clear(dev, LCDC_RASTER_CTRL_REG,
-   LCDC_V1_SYNC_LOST_INT_ENA |
+   LCDC_V1_SYNC_LOST_INT_ENA | LCDC_V1_FRAME_DONE_INT_ENA |
LCDC_V1_UNDERFLOW_INT_ENA | LCDC_V1_PL_INT_ENA);
tilcdc_clear(dev, LCDC_DMA_CTRL_REG,
LCDC_V1_END_OF_FRAME_INT_ENA);
@@ -935,13 +935,17 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc)
}
}

+   if (stat & LCDC_FRAME_DONE) {
+   tilcdc_crtc->frame_done = true;
+   wake_up(_crtc->frame_done_wq);
+   /* rev 1 lcdc appears to hang if irq is not disbaled here */
+   if (priv->rev == 1)
+   tilcdc_clear(dev, LCDC_RASTER_CTRL_REG,
+LCDC_V1_FRAME_DONE_INT_ENA);
+   }
+
/* For revision 2 only */
if (priv->rev == 2) {
-   if (stat & LCDC_FRAME_DONE) {
-   tilcdc_crtc->frame_done = true;
-   wake_up(_crtc->frame_done_wq);
-   }
-
/* Indicate to LCDC that the interrupt service routine has
 * completed, see 13.3.6.1.6 in AM335x TRM.
 */
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_regs.h 
b/drivers/gpu/drm/tilcdc/tilcdc_regs.h
index d69a940..9d528c0 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_regs.h
+++ b/drivers/gpu/drm/tilcdc/tilcdc_regs.h
@@ -67,6 +67,7 @@
 #define LCDC_V1_PL_INT_ENA   BIT(4)
 #define LCDC_V2_PL_INT_ENA   BIT(6)
 #define LCDC_V1_SYNC_LOST_INT_ENABIT(5)
+#define LCDC_V1_FRAME_DONE_INT_ENA   BIT(3)
 #define LCDC_MONOCHROME_MODE BIT(1)
 #define LCDC_RASTER_ENABLE   BIT(0)
 #define LCDC_TFT_ALT_ENABLE  BIT(23)
-- 
1.9.1



[PATCH v4 09/10] drm/tilcdc: Configure video mode to HW in enable() not in mode_set_nofb()

2016-11-25 Thread Jyri Sarha
Configure video mode to HW in enable() call back. There is no reason
to do it before that. This makes PM functions way easier because there
is no HW context to save when screen is for instance blanked. This
patch removes mode_set_nofb() call back from tilcdc.

Signed-off-by: Jyri Sarha 
---
 drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 426 +--
 drivers/gpu/drm/tilcdc/tilcdc_drv.c  |   6 -
 2 files changed, 212 insertions(+), 220 deletions(-)

diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c 
b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
index 4472540..fb24422 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
@@ -215,214 +215,6 @@ static void reset(struct drm_crtc *crtc)
tilcdc_clear(dev, LCDC_CLK_RESET_REG, LCDC_CLK_MAIN_RESET);
 }

-static void tilcdc_crtc_enable(struct drm_crtc *crtc)
-{
-   struct drm_device *dev = crtc->dev;
-   struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
-
-   WARN_ON(!drm_modeset_is_locked(>mutex));
-   mutex_lock(_crtc->enable_lock);
-   if (tilcdc_crtc->enabled || tilcdc_crtc->shutdown) {
-   mutex_unlock(_crtc->enable_lock);
-   return;
-   }
-
-   pm_runtime_get_sync(dev->dev);
-
-   reset(crtc);
-
-   tilcdc_crtc_enable_irqs(dev);
-
-   tilcdc_clear(dev, LCDC_DMA_CTRL_REG, LCDC_DUAL_FRAME_BUFFER_ENABLE);
-   tilcdc_write_mask(dev, LCDC_RASTER_CTRL_REG,
- LCDC_PALETTE_LOAD_MODE(DATA_ONLY),
- LCDC_PALETTE_LOAD_MODE_MASK);
-   tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE);
-
-   drm_crtc_vblank_on(crtc);
-
-   tilcdc_crtc->enabled = true;
-   mutex_unlock(_crtc->enable_lock);
-}
-
-static void tilcdc_crtc_off(struct drm_crtc *crtc, bool shutdown)
-{
-   struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
-   struct drm_device *dev = crtc->dev;
-   struct tilcdc_drm_private *priv = dev->dev_private;
-
-   mutex_lock(_crtc->enable_lock);
-   if (shutdown)
-   tilcdc_crtc->shutdown = true;
-   if (!tilcdc_crtc->enabled) {
-   mutex_unlock(_crtc->enable_lock);
-   return;
-   }
-   tilcdc_crtc->frame_done = false;
-   tilcdc_clear(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE);
-
-   /*
-* if necessary wait for framedone irq which will still come
-* before putting things to sleep..
-*/
-   if (priv->rev == 2) {
-   int ret = wait_event_timeout(tilcdc_crtc->frame_done_wq,
-tilcdc_crtc->frame_done,
-msecs_to_jiffies(500));
-   if (ret == 0)
-   dev_err(dev->dev, "%s: timeout waiting for framedone\n",
-   __func__);
-   }
-
-   drm_crtc_vblank_off(crtc);
-
-   tilcdc_crtc_disable_irqs(dev);
-
-   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);
-   tilcdc_crtc->curr_fb = NULL;
-   }
-
-   drm_flip_work_commit(_crtc->unref_work, priv->wq);
-   tilcdc_crtc->last_vblank = ktime_set(0, 0);
-
-   tilcdc_crtc->enabled = false;
-   mutex_unlock(_crtc->enable_lock);
-}
-
-static void tilcdc_crtc_disable(struct drm_crtc *crtc)
-{
-   WARN_ON(!drm_modeset_is_locked(>mutex));
-   tilcdc_crtc_off(crtc, false);
-}
-
-void tilcdc_crtc_shutdown(struct drm_crtc *crtc)
-{
-   tilcdc_crtc_off(crtc, true);
-}
-
-static bool tilcdc_crtc_is_on(struct drm_crtc *crtc)
-{
-   return crtc->state && crtc->state->enable && crtc->state->active;
-}
-
-static void tilcdc_crtc_recover_work(struct work_struct *work)
-{
-   struct tilcdc_crtc *tilcdc_crtc =
-   container_of(work, struct tilcdc_crtc, recover_work);
-   struct drm_crtc *crtc = _crtc->base;
-
-   dev_info(crtc->dev->dev, "%s: Reset CRTC", __func__);
-
-   drm_modeset_lock_crtc(crtc, NULL);
-
-   if (!tilcdc_crtc_is_on(crtc))
-   goto out;
-
-   tilcdc_crtc_disable(crtc);
-   tilcdc_crtc_enable(crtc);
-out:
-   drm_modeset_unlock_crtc(crtc);
-}
-
-static void tilcdc_crtc_destroy(struct drm_crtc *crtc)
-{
-   struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
-   struct tilcdc_drm_private *priv = crtc->dev->dev_private;
-
-   drm_modeset_lock_crtc(crtc, NULL);
-   tilcdc_crtc_disable(crtc);
-   drm_modeset_unlock_crtc(crtc);
-
-   flush_workqueue(priv->wq);
-
-   of_node_put(crtc->port);
-   drm_crtc_cleanup(crtc);
-   drm_flip_work_cleanup(_crtc->unref_work);
-}
-
-int 

[PATCH v4 08/10] drm/tilcdc: Load palette at the end of mode_set_nofb()

2016-11-25 Thread Jyri Sarha
Load palette at the end of mode_set_nofb(). Moving the palette loading
to mode_set_nofb() saves us from storing and restoring of framebuffer
addresses in dma registers that were just recently written there.

Signed-off-by: Jyri Sarha 
---
 drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 25 +
 1 file changed, 5 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c 
b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
index f736a89..4472540 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
@@ -121,15 +121,12 @@ static void set_scanout(struct drm_crtc *crtc, struct 
drm_framebuffer *fb)
  */
 static void tilcdc_crtc_load_palette(struct drm_crtc *crtc)
 {
-   u32 dma_fb_base, dma_fb_ceiling, raster_ctl;
struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
struct drm_device *dev = crtc->dev;
struct tilcdc_drm_private *priv = dev->dev_private;
int ret;

-   dma_fb_base = tilcdc_read(dev, LCDC_DMA_FB_BASE_ADDR_0_REG);
-   dma_fb_ceiling = tilcdc_read(dev, LCDC_DMA_FB_CEILING_ADDR_0_REG);
-   raster_ctl = tilcdc_read(dev, LCDC_RASTER_CTRL_REG);
+   reinit_completion(_crtc->palette_loaded);

/* Tell the LCDC where the palette is located. */
tilcdc_write(dev, LCDC_DMA_FB_BASE_ADDR_0_REG,
@@ -164,11 +161,6 @@ static void tilcdc_crtc_load_palette(struct drm_crtc *crtc)
tilcdc_clear(dev, LCDC_RASTER_CTRL_REG, LCDC_V1_PL_INT_ENA);
else
tilcdc_write(dev, LCDC_INT_ENABLE_CLR_REG, LCDC_V2_PL_INT_ENA);
-
-   /* Restore the registers. */
-   tilcdc_write(dev, LCDC_DMA_FB_BASE_ADDR_0_REG, dma_fb_base);
-   tilcdc_write(dev, LCDC_DMA_FB_CEILING_ADDR_0_REG, dma_fb_ceiling);
-   tilcdc_write(dev, LCDC_RASTER_CTRL_REG, raster_ctl);
 }

 static void tilcdc_crtc_enable_irqs(struct drm_device *dev)
@@ -239,9 +231,6 @@ static void tilcdc_crtc_enable(struct drm_crtc *crtc)

reset(crtc);

-   if (!completion_done(_crtc->palette_loaded))
-   tilcdc_crtc_load_palette(crtc);
-
tilcdc_crtc_enable_irqs(dev);

tilcdc_clear(dev, LCDC_DMA_CTRL_REG, LCDC_DUAL_FRAME_BUFFER_ENABLE);
@@ -285,12 +274,6 @@ static void tilcdc_crtc_off(struct drm_crtc *crtc, bool 
shutdown)
__func__);
}

-   /*
-* LCDC will not retain the palette when reset. Make sure it gets
-* reloaded on tilcdc_crtc_enable().
-*/
-   reinit_completion(_crtc->palette_loaded);
-
drm_crtc_vblank_off(crtc);

tilcdc_crtc_disable_irqs(dev);
@@ -678,10 +661,12 @@ static void tilcdc_crtc_mode_set_nofb(struct drm_crtc 
*crtc)

drm_framebuffer_reference(fb);

-   set_scanout(crtc, fb);
-
tilcdc_crtc_set_clk(crtc);

+   tilcdc_crtc_load_palette(crtc);
+
+   set_scanout(crtc, fb);
+
crtc->hwmode = crtc->state->adjusted_mode;
 }

-- 
1.9.1



[PATCH v4 07/10] drm/tilcdc: Add timeout wait for palette loading to complete

2016-11-25 Thread Jyri Sarha
Add timeout wait for palette loadind to complete. We do not want to
hang forever if palette loaded interrupt does not arrive for some
reason.

Signed-off-by: Jyri Sarha 
---
 drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c 
b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
index b3edc6d..f736a89 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
@@ -125,6 +125,7 @@ static void tilcdc_crtc_load_palette(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;
+   int ret;

dma_fb_base = tilcdc_read(dev, LCDC_DMA_FB_BASE_ADDR_0_REG);
dma_fb_ceiling = tilcdc_read(dev, LCDC_DMA_FB_CEILING_ADDR_0_REG);
@@ -152,7 +153,10 @@ static void tilcdc_crtc_load_palette(struct drm_crtc *crtc)
tilcdc_clear_irqstatus(dev, 0x);
tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE);

-   wait_for_completion(_crtc->palette_loaded);
+   ret = wait_for_completion_timeout(_crtc->palette_loaded,
+ msecs_to_jiffies(50));
+   if (ret == 0)
+   dev_err(dev->dev, "%s: Palette loading timeout", __func__);

/* Disable LCDC DMA and DMA Palette Loaded Interrupt. */
tilcdc_clear(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE);
-- 
1.9.1



[PATCH v4 06/10] drm/tilcdc: Enable palette loading for revision 2 LCDC too

2016-11-25 Thread Jyri Sarha
The LCDC revision 2 documentation also mentions the mandatory palette
for true color modes. Even if the rev 2 LCDC appears to work just fine
without the palette being loaded loading it helps in testing the
feature.

Signed-off-by: Jyri Sarha 
---
 drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 90 +++-
 1 file changed, 47 insertions(+), 43 deletions(-)

diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c 
b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
index 1ed65dd..b3edc6d 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
@@ -28,8 +28,8 @@
 #include "tilcdc_regs.h"

 #define TILCDC_VBLANK_SAFETY_THRESHOLD_US  1000
-#define TILCDC_REV1_PALETTE_SIZE   32
-#define TILCDC_REV1_PALETTE_FIRST_ENTRY0x4000
+#define TILCDC_PALETTE_SIZE32
+#define TILCDC_PALETTE_FIRST_ENTRY 0x4000

 struct tilcdc_crtc {
struct drm_crtc base;
@@ -62,7 +62,7 @@ struct tilcdc_crtc {
struct work_struct recover_work;

dma_addr_t palette_dma_handle;
-   void *palette_base;
+   u16 *palette_base;
struct completion palette_loaded;
 };
 #define to_tilcdc_crtc(x) container_of(x, struct tilcdc_crtc, base)
@@ -114,23 +114,17 @@ static void set_scanout(struct drm_crtc *crtc, struct 
drm_framebuffer *fb)
 }

 /*
- * The driver currently only supports the RGB565 format for revision 1. For
- * 16 bits-per-pixel the palette block is bypassed, but the first 32 bytes of
- * the framebuffer are still considered palette. The first 16-bit entry must
- * be 0x4000 while all other entries must be zeroed.
+ * The driver currently only supports only true color formats. For
+ * true color the palette block is bypassed, but a 32 byte palette
+ * should still be loaded. The first 16-bit entry must be 0x4000 while
+ * all other entries must be zeroed.
  */
 static void tilcdc_crtc_load_palette(struct drm_crtc *crtc)
 {
u32 dma_fb_base, dma_fb_ceiling, raster_ctl;
-   struct tilcdc_crtc *tilcdc_crtc;
-   struct drm_device *dev;
-   u16 *first_entry;
-
-   dev = crtc->dev;
-   tilcdc_crtc = to_tilcdc_crtc(crtc);
-   first_entry = tilcdc_crtc->palette_base;
-
-   *first_entry = TILCDC_REV1_PALETTE_FIRST_ENTRY;
+   struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
+   struct drm_device *dev = crtc->dev;
+   struct tilcdc_drm_private *priv = dev->dev_private;

dma_fb_base = tilcdc_read(dev, LCDC_DMA_FB_BASE_ADDR_0_REG);
dma_fb_ceiling = tilcdc_read(dev, LCDC_DMA_FB_CEILING_ADDR_0_REG);
@@ -140,23 +134,34 @@ static void tilcdc_crtc_load_palette(struct drm_crtc 
*crtc)
tilcdc_write(dev, LCDC_DMA_FB_BASE_ADDR_0_REG,
 tilcdc_crtc->palette_dma_handle);
tilcdc_write(dev, LCDC_DMA_FB_CEILING_ADDR_0_REG,
-(u32)tilcdc_crtc->palette_dma_handle
-   + TILCDC_REV1_PALETTE_SIZE - 1);
+(u32) tilcdc_crtc->palette_dma_handle +
+TILCDC_PALETTE_SIZE - 1);

-   /* Load it. */
-   tilcdc_clear(dev, LCDC_RASTER_CTRL_REG,
-LCDC_PALETTE_LOAD_MODE(DATA_ONLY));
-   tilcdc_set(dev, LCDC_RASTER_CTRL_REG,
-  LCDC_PALETTE_LOAD_MODE(PALETTE_ONLY));
+   /* Set dma load mode for palette loading only. */
+   tilcdc_write_mask(dev, LCDC_RASTER_CTRL_REG,
+ LCDC_PALETTE_LOAD_MODE(PALETTE_ONLY),
+ LCDC_PALETTE_LOAD_MODE_MASK);
+
+   /* Enable DMA Palette Loaded Interrupt */
+   if (priv->rev == 1)
+   tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_V1_PL_INT_ENA);
+   else
+   tilcdc_write(dev, LCDC_INT_ENABLE_SET_REG, LCDC_V2_PL_INT_ENA);

-   /* Enable the LCDC and wait for palette to be loaded. */
-   tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_V1_PL_INT_ENA);
+   /* Enable LCDC DMA and wait for palette to be loaded. */
+   tilcdc_clear_irqstatus(dev, 0x);
tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE);

wait_for_completion(_crtc->palette_loaded);

-   /* Restore the registers. */
+   /* Disable LCDC DMA and DMA Palette Loaded Interrupt. */
tilcdc_clear(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE);
+   if (priv->rev == 1)
+   tilcdc_clear(dev, LCDC_RASTER_CTRL_REG, LCDC_V1_PL_INT_ENA);
+   else
+   tilcdc_write(dev, LCDC_INT_ENABLE_CLR_REG, LCDC_V2_PL_INT_ENA);
+
+   /* Restore the registers. */
tilcdc_write(dev, LCDC_DMA_FB_BASE_ADDR_0_REG, dma_fb_base);
tilcdc_write(dev, LCDC_DMA_FB_CEILING_ADDR_0_REG, dma_fb_ceiling);
tilcdc_write(dev, LCDC_RASTER_CTRL_REG, raster_ctl);
@@ -218,7 +223,6 @@ static void tilcdc_crtc_enable(struct drm_crtc *crtc)
 {
struct drm_device *dev = crtc->dev;
struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
-   struct tilcdc_drm_private *priv 

[PATCH v4 05/10] drm/tilcdc: Fix load mode bit-field setting in tilcdc_crtc_enable()

2016-11-25 Thread Jyri Sarha
Set LCDC_PALETTE_LOAD_MODE bit-field with new tilcdc_write_mask()
instead of tilcdc_set(). Setting a bit-fields with tilcdc_set() is
fundamentally broken.

Signed-off-by: Jyri Sarha 
---
 drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c 
b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
index 4605942..1ed65dd 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
@@ -237,7 +237,9 @@ static void tilcdc_crtc_enable(struct drm_crtc *crtc)
tilcdc_crtc_enable_irqs(dev);

tilcdc_clear(dev, LCDC_DMA_CTRL_REG, LCDC_DUAL_FRAME_BUFFER_ENABLE);
-   tilcdc_set(dev, LCDC_RASTER_CTRL_REG, 
LCDC_PALETTE_LOAD_MODE(DATA_ONLY));
+   tilcdc_write_mask(dev, LCDC_RASTER_CTRL_REG,
+ LCDC_PALETTE_LOAD_MODE(DATA_ONLY),
+ LCDC_PALETTE_LOAD_MODE_MASK);
tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE);

drm_crtc_vblank_on(crtc);
-- 
1.9.1



[PATCH v4 04/10] drm/tilcdc: Add tilcdc_write_mask() to tilcdc_regs.h

2016-11-25 Thread Jyri Sarha
Add tilcdc_write_mask() for handling register field wider than one bit
and mask values for those fields.

Signed-off-by: Jyri Sarha 
---
 drivers/gpu/drm/tilcdc/tilcdc_regs.h | 13 +
 1 file changed, 13 insertions(+)

diff --git a/drivers/gpu/drm/tilcdc/tilcdc_regs.h 
b/drivers/gpu/drm/tilcdc/tilcdc_regs.h
index d195b65..d69a940 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_regs.h
+++ b/drivers/gpu/drm/tilcdc/tilcdc_regs.h
@@ -34,11 +34,14 @@

 /* LCDC DMA Control Register */
 #define LCDC_DMA_BURST_SIZE(x)   ((x) << 4)
+#define LCDC_DMA_BURST_SIZE_MASK ((0x7) << 4)
 #define LCDC_DMA_BURST_1 0x0
 #define LCDC_DMA_BURST_2 0x1
 #define LCDC_DMA_BURST_4 0x2
 #define LCDC_DMA_BURST_8 0x3
 #define LCDC_DMA_BURST_160x4
+#define LCDC_DMA_FIFO_THRESHOLD(x)   ((x) << 8)
+#define LCDC_DMA_FIFO_THRESHOLD_MASK ((0x3) << 8)
 #define LCDC_V1_END_OF_FRAME_INT_ENA BIT(2)
 #define LCDC_V2_END_OF_FRAME0_INT_ENABIT(8)
 #define LCDC_V2_END_OF_FRAME1_INT_ENABIT(9)
@@ -46,10 +49,12 @@

 /* LCDC Control Register */
 #define LCDC_CLK_DIVISOR(x)  ((x) << 8)
+#define LCDC_CLK_DIVISOR_MASK((0xFF) << 8)
 #define LCDC_RASTER_MODE 0x01

 /* LCDC Raster Control Register */
 #define LCDC_PALETTE_LOAD_MODE(x)((x) << 20)
+#define LCDC_PALETTE_LOAD_MODE_MASK  ((0x3) << 20)
 #define PALETTE_AND_DATA 0x00
 #define PALETTE_ONLY 0x01
 #define DATA_ONLY0x02
@@ -75,7 +80,9 @@

 /* LCDC Raster Timing 2 Register */
 #define LCDC_AC_BIAS_TRANSITIONS_PER_INT(x)  ((x) << 16)
+#define LCDC_AC_BIAS_TRANSITIONS_PER_INT_MASK((0xF) << 16)
 #define LCDC_AC_BIAS_FREQUENCY(x)((x) << 8)
+#define LCDC_AC_BIAS_FREQUENCY_MASK  ((0xFF) << 8)
 #define LCDC_SYNC_CTRL   BIT(25)
 #define LCDC_SYNC_EDGE   BIT(24)
 #define LCDC_INVERT_PIXEL_CLOCK  BIT(22)
@@ -140,6 +147,12 @@ static inline u32 tilcdc_read(struct drm_device *dev, u32 
reg)
return ioread32(priv->mmio + reg);
 }

+static inline void tilcdc_write_mask(struct drm_device *dev, u32 reg,
+u32 val, u32 mask)
+{
+   tilcdc_write(dev, reg, (tilcdc_read(dev, reg) & ~mask) | (val & mask));
+}
+
 static inline void tilcdc_set(struct drm_device *dev, u32 reg, u32 mask)
 {
tilcdc_write(dev, reg, tilcdc_read(dev, reg) | mask);
-- 
1.9.1



[PATCH v4 03/10] drm/tilcdc: Fix tilcdc_crtc_create() return value handling

2016-11-25 Thread Jyri Sarha
Failed tilcdc_crtc_create() error handling was broken, this patch
should fix it.

Signed-off-by: Jyri Sarha 
---
 drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 12 +++-
 drivers/gpu/drm/tilcdc/tilcdc_drv.c  | 11 ---
 drivers/gpu/drm/tilcdc/tilcdc_drv.h  |  2 +-
 3 files changed, 12 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c 
b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
index 7ea34c2..4605942 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
@@ -957,7 +957,7 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc)
return IRQ_HANDLED;
 }

-struct drm_crtc *tilcdc_crtc_create(struct drm_device *dev)
+int tilcdc_crtc_create(struct drm_device *dev)
 {
struct tilcdc_drm_private *priv = dev->dev_private;
struct tilcdc_crtc *tilcdc_crtc;
@@ -967,7 +967,7 @@ struct drm_crtc *tilcdc_crtc_create(struct drm_device *dev)
tilcdc_crtc = devm_kzalloc(dev->dev, sizeof(*tilcdc_crtc), GFP_KERNEL);
if (!tilcdc_crtc) {
dev_err(dev->dev, "allocation failed\n");
-   return NULL;
+   return -ENOMEM;
}

if (priv->rev == 1) {
@@ -977,7 +977,7 @@ struct drm_crtc *tilcdc_crtc_create(struct drm_device *dev)
_crtc->palette_dma_handle,
GFP_KERNEL | __GFP_ZERO);
if (!tilcdc_crtc->palette_base)
-   return ERR_PTR(-ENOMEM);
+   return -ENOMEM;
}

crtc = _crtc->base;
@@ -1020,13 +1020,15 @@ struct drm_crtc *tilcdc_crtc_create(struct drm_device 
*dev)
if (!crtc->port) { /* This should never happen */
dev_err(dev->dev, "Port node not found in %s\n",
dev->dev->of_node->full_name);
+   ret = -EINVAL;
goto fail;
}
}

-   return crtc;
+   priv->crtc = crtc;
+   return 0;

 fail:
tilcdc_crtc_destroy(crtc);
-   return NULL;
+   return -ENOMEM;
 }
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c 
b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
index 7f4d3bc..b1bbbfe 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
@@ -153,13 +153,11 @@ static int tilcdc_commit(struct drm_device *dev,
.atomic_commit = tilcdc_commit,
 };

-static int modeset_init(struct drm_device *dev)
+static void modeset_init(struct drm_device *dev)
 {
struct tilcdc_drm_private *priv = dev->dev_private;
struct tilcdc_module *mod;

-   priv->crtc = tilcdc_crtc_create(dev);
-
list_for_each_entry(mod, _list, list) {
DBG("loading module: %s", mod->name);
mod->funcs->modeset_init(mod, dev);
@@ -170,8 +168,6 @@ static int modeset_init(struct drm_device *dev)
dev->mode_config.max_width = tilcdc_crtc_max_width(priv->crtc);
dev->mode_config.max_height = 2048;
dev->mode_config.funcs = _config_funcs;
-
-   return 0;
 }

 #ifdef CONFIG_CPU_FREQ
@@ -370,11 +366,12 @@ static int tilcdc_init(struct drm_driver *ddrv, struct 
device *dev)
}
}

-   ret = modeset_init(ddev);
+   ret = tilcdc_crtc_create(ddev);
if (ret < 0) {
-   dev_err(dev, "failed to initialize mode setting\n");
+   dev_err(dev, "failed to create crtc\n");
goto init_failed;
}
+   modeset_init(ddev);

if (priv->is_componentized) {
ret = component_bind_all(dev, ddev);
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.h 
b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
index 411f8a8..0e71daf 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
@@ -168,7 +168,7 @@ struct tilcdc_panel_info {

 #define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__)

-struct drm_crtc *tilcdc_crtc_create(struct drm_device *dev);
+int tilcdc_crtc_create(struct drm_device *dev);
 irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc);
 void tilcdc_crtc_update_clk(struct drm_crtc *crtc);
 void tilcdc_crtc_set_panel_info(struct drm_crtc *crtc,
-- 
1.9.1



[PATCH v4 02/10] drm/tilcdc: implement palette loading for rev1

2016-11-25 Thread Jyri Sarha
From: Bartosz Golaszewski 

Revision 1 of the IP doesn't work if we don't load the palette (even
if it's not used, which is the case for the RGB565 format).

Add a function called from tilcdc_crtc_enable() which performs all
required actions if we're dealing with a rev1 chip.

Signed-off-by: Bartosz Golaszewski 
Signed-off-by: Jyri Sarha 
---
 drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 88 +++-
 1 file changed, 87 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c 
b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
index 0169240..7ea34c2 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
@@ -21,11 +21,15 @@
 #include 
 #include 
 #include 
+#include 
+#include 

 #include "tilcdc_drv.h"
 #include "tilcdc_regs.h"

-#define TILCDC_VBLANK_SAFETY_THRESHOLD_US 1000
+#define TILCDC_VBLANK_SAFETY_THRESHOLD_US  1000
+#define TILCDC_REV1_PALETTE_SIZE   32
+#define TILCDC_REV1_PALETTE_FIRST_ENTRY0x4000

 struct tilcdc_crtc {
struct drm_crtc base;
@@ -56,6 +60,10 @@ struct tilcdc_crtc {
int sync_lost_count;
bool frame_intact;
struct work_struct recover_work;
+
+   dma_addr_t palette_dma_handle;
+   void *palette_base;
+   struct completion palette_loaded;
 };
 #define to_tilcdc_crtc(x) container_of(x, struct tilcdc_crtc, base)

@@ -105,6 +113,55 @@ static void set_scanout(struct drm_crtc *crtc, struct 
drm_framebuffer *fb)
tilcdc_crtc->curr_fb = fb;
 }

+/*
+ * The driver currently only supports the RGB565 format for revision 1. For
+ * 16 bits-per-pixel the palette block is bypassed, but the first 32 bytes of
+ * the framebuffer are still considered palette. The first 16-bit entry must
+ * be 0x4000 while all other entries must be zeroed.
+ */
+static void tilcdc_crtc_load_palette(struct drm_crtc *crtc)
+{
+   u32 dma_fb_base, dma_fb_ceiling, raster_ctl;
+   struct tilcdc_crtc *tilcdc_crtc;
+   struct drm_device *dev;
+   u16 *first_entry;
+
+   dev = crtc->dev;
+   tilcdc_crtc = to_tilcdc_crtc(crtc);
+   first_entry = tilcdc_crtc->palette_base;
+
+   *first_entry = TILCDC_REV1_PALETTE_FIRST_ENTRY;
+
+   dma_fb_base = tilcdc_read(dev, LCDC_DMA_FB_BASE_ADDR_0_REG);
+   dma_fb_ceiling = tilcdc_read(dev, LCDC_DMA_FB_CEILING_ADDR_0_REG);
+   raster_ctl = tilcdc_read(dev, LCDC_RASTER_CTRL_REG);
+
+   /* Tell the LCDC where the palette is located. */
+   tilcdc_write(dev, LCDC_DMA_FB_BASE_ADDR_0_REG,
+tilcdc_crtc->palette_dma_handle);
+   tilcdc_write(dev, LCDC_DMA_FB_CEILING_ADDR_0_REG,
+(u32)tilcdc_crtc->palette_dma_handle
+   + TILCDC_REV1_PALETTE_SIZE - 1);
+
+   /* Load it. */
+   tilcdc_clear(dev, LCDC_RASTER_CTRL_REG,
+LCDC_PALETTE_LOAD_MODE(DATA_ONLY));
+   tilcdc_set(dev, LCDC_RASTER_CTRL_REG,
+  LCDC_PALETTE_LOAD_MODE(PALETTE_ONLY));
+
+   /* Enable the LCDC and wait for palette to be loaded. */
+   tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_V1_PL_INT_ENA);
+   tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE);
+
+   wait_for_completion(_crtc->palette_loaded);
+
+   /* Restore the registers. */
+   tilcdc_clear(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE);
+   tilcdc_write(dev, LCDC_DMA_FB_BASE_ADDR_0_REG, dma_fb_base);
+   tilcdc_write(dev, LCDC_DMA_FB_CEILING_ADDR_0_REG, dma_fb_ceiling);
+   tilcdc_write(dev, LCDC_RASTER_CTRL_REG, raster_ctl);
+}
+
 static void tilcdc_crtc_enable_irqs(struct drm_device *dev)
 {
struct tilcdc_drm_private *priv = dev->dev_private;
@@ -161,6 +218,7 @@ static void tilcdc_crtc_enable(struct drm_crtc *crtc)
 {
struct drm_device *dev = crtc->dev;
struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
+   struct tilcdc_drm_private *priv = dev->dev_private;

WARN_ON(!drm_modeset_is_locked(>mutex));
mutex_lock(_crtc->enable_lock);
@@ -173,6 +231,9 @@ static void tilcdc_crtc_enable(struct drm_crtc *crtc)

reset(crtc);

+   if (priv->rev == 1 && !completion_done(_crtc->palette_loaded))
+   tilcdc_crtc_load_palette(crtc);
+
tilcdc_crtc_enable_irqs(dev);

tilcdc_clear(dev, LCDC_DMA_CTRL_REG, LCDC_DUAL_FRAME_BUFFER_ENABLE);
@@ -214,6 +275,13 @@ static void tilcdc_crtc_off(struct drm_crtc *crtc, bool 
shutdown)
__func__);
}

+   /*
+* LCDC will not retain the palette when reset. Make sure it gets
+* reloaded on tilcdc_crtc_enable().
+*/
+   if (priv->rev == 1)
+   reinit_completion(_crtc->palette_loaded);
+
drm_crtc_vblank_off(crtc);

tilcdc_crtc_disable_irqs(dev);
@@ -847,6 +915,14 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc)
dev_err_ratelimited(dev->dev, "%s(0x%08x): FIFO 

[PATCH v4 01/10] drm/tilcdc: Enable sync lost error and recovery handling for rev 1 LCDC

2016-11-25 Thread Jyri Sarha
Revision 1 LCDC support also sync lost errors and can benefit from
sync lost recovery routine.

Signed-off-by: Jyri Sarha 
---
 drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 35 ---
 drivers/gpu/drm/tilcdc/tilcdc_regs.h |  1 +
 2 files changed, 21 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c 
b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
index c787349..0169240 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
@@ -113,6 +113,7 @@ static void tilcdc_crtc_enable_irqs(struct drm_device *dev)

if (priv->rev == 1) {
tilcdc_set(dev, LCDC_RASTER_CTRL_REG,
+   LCDC_V1_SYNC_LOST_INT_ENA |
LCDC_V1_UNDERFLOW_INT_ENA);
tilcdc_set(dev, LCDC_DMA_CTRL_REG,
LCDC_V1_END_OF_FRAME_INT_ENA);
@@ -131,6 +132,7 @@ static void tilcdc_crtc_disable_irqs(struct drm_device *dev)
/* disable irqs that we might have enabled: */
if (priv->rev == 1) {
tilcdc_clear(dev, LCDC_RASTER_CTRL_REG,
+   LCDC_V1_SYNC_LOST_INT_ENA |
LCDC_V1_UNDERFLOW_INT_ENA | LCDC_V1_PL_INT_ENA);
tilcdc_clear(dev, LCDC_DMA_CTRL_REG,
LCDC_V1_END_OF_FRAME_INT_ENA);
@@ -845,6 +847,24 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc)
dev_err_ratelimited(dev->dev, "%s(0x%08x): FIFO underflow",
__func__, stat);

+   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, recovering", __func__, stat);
+   queue_work(system_wq, _crtc->recover_work);
+   if (priv->rev == 1)
+   tilcdc_clear(dev, LCDC_RASTER_CTRL_REG,
+LCDC_V1_SYNC_LOST_INT_ENA);
+   else
+   tilcdc_write(dev, LCDC_INT_ENABLE_CLR_REG,
+LCDC_SYNC_LOST);
+   tilcdc_crtc->sync_lost_count = 0;
+   }
+   }
+
/* For revision 2 only */
if (priv->rev == 2) {
if (stat & LCDC_FRAME_DONE) {
@@ -852,21 +872,6 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc)
wake_up(_crtc->frame_done_wq);
}

-   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, recovering", __func__, stat);
-   queue_work(system_wq,
-  _crtc->recover_work);
-   tilcdc_write(dev, LCDC_INT_ENABLE_CLR_REG,
-LCDC_SYNC_LOST);
-   tilcdc_crtc->sync_lost_count = 0;
-   }
-   }
-
/* Indicate to LCDC that the interrupt service routine has
 * completed, see 13.3.6.1.6 in AM335x TRM.
 */
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_regs.h 
b/drivers/gpu/drm/tilcdc/tilcdc_regs.h
index f57c0d6..d195b65 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_regs.h
+++ b/drivers/gpu/drm/tilcdc/tilcdc_regs.h
@@ -61,6 +61,7 @@
 #define LCDC_V2_UNDERFLOW_INT_ENABIT(5)
 #define LCDC_V1_PL_INT_ENA   BIT(4)
 #define LCDC_V2_PL_INT_ENA   BIT(6)
+#define LCDC_V1_SYNC_LOST_INT_ENABIT(5)
 #define LCDC_MONOCHROME_MODE BIT(1)
 #define LCDC_RASTER_ENABLE   BIT(0)
 #define LCDC_TFT_ALT_ENABLE  BIT(23)
-- 
1.9.1



[PATCH v4 00/10] drm/tilcdc: LCDC Revision 1 related fixes

2016-11-25 Thread Jyri Sarha
The git branch bellow is updated.

Changes since v3:
- "drm/tilcdc: Enable sync lost error and recovery handling for rev 1 LCDC"
  - disable sync-lost irq also for rev1 LCDC
  - LCDC_V1_SYNC_LOST_ENA to LCDC_V1_SYNC_LOST_INT_ENA
- "drm/tilcdc: Enable palette loading for revision 2 LCDC too"
  - disable palette loaded interrupt after receiving it
- "drm/tilcdc: Enable frame done irq and functionality for LCDC rev 1"
  - disable FRAME_DONE interrupt for rev 1 lcdc in interrupt routine
  - LCDC_V1_FRAME_DONE_ENA to LCDC_V1_FRAME_DONE_INT_ENA
- Add: "drm/tilcdc: Configure video mode to HW in enable() not in 
mode_set_nofb()"
- Drop "drm/tilcdc: Use complete_all() to indicate completed palette loading"
- Drop "drm/tilcdc: Call reset() before loading the palette"
- "drm/tilcdc: Load palette at the end of mode_set_nofb()"
  - Just load the palette every time, no runtime_resume hook

Changes since v2:
- Add: "drm/tilcdc: Fix load mode bit-field setting in tilcdc_crtc_enable()"
- Drop: "drm/tilcdc: Free palette dma memory in tilcdc_crtc_destroy()"
- Add: "drm/tilcdc: Add timeout wait for palette loading to complete"
- Add: "drm/tilcdc: Call reset() before loading the palette"
- Add: "drm/tilcdc: Use complete_all() to indicate completed palette loading"
- Add "drm/tilcdc: Enable frame done irq and functionality for LCDC rev 1"
  - Bartosz: Please test if this works! The symptom for not working is
"timeout waiting for framedone" message when screen is blanked.

Changes since first version of the series:

- Move tilcdc_regs.h changes from "drm/tilcdc: Enable palette loading
  for revision 2 LCDC too" to "drm/tilcdc: Add tilcdc_write_mask() to
  tilcdc_regs.h"

These patches are inspired by this series form Bartosz Golaszewski:
https://www.spinics.net/lists/arm-kernel/msg539629.html

The patches are based on drm-next plus the earlier patches that I plan
to send in a pull request for 4.10. The base + these patches are
pushed here:

https://github.com/jsarha/linux drm-next-tilcdc-for-4.10-wip

Bartosz, please test if this branch works for rev1 LCDC, with your dts
file!

Bartosz Golaszewski (1):
  drm/tilcdc: implement palette loading for rev1

Jyri Sarha (9):
  drm/tilcdc: Enable sync lost error and recovery handling for rev 1
LCDC
  drm/tilcdc: Fix tilcdc_crtc_create() return value handling
  drm/tilcdc: Add tilcdc_write_mask() to tilcdc_regs.h
  drm/tilcdc: Fix load mode bit-field setting in tilcdc_crtc_enable()
  drm/tilcdc: Enable palette loading for revision 2 LCDC too
  drm/tilcdc: Add timeout wait for palette loading to complete
  drm/tilcdc: Load palette at the end of mode_set_nofb()
  drm/tilcdc: Configure video mode to HW in enable() not in
mode_set_nofb()
  drm/tilcdc: Enable frame done irq and functionality for LCDC rev 1

 drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 558 ---
 drivers/gpu/drm/tilcdc/tilcdc_drv.c  |  17 +-
 drivers/gpu/drm/tilcdc/tilcdc_drv.h  |   2 +-
 drivers/gpu/drm/tilcdc/tilcdc_regs.h |  15 +
 4 files changed, 344 insertions(+), 248 deletions(-)

-- 
1.9.1



[Bug 188911] New: Function qxl_release_alloc() returns an improper value when the call to kmalloc() fails, resulting in bad memory access

2016-11-25 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=188911

Bug ID: 188911
   Summary: Function qxl_release_alloc() returns an improper value
when the call to kmalloc() fails, resulting in bad
memory access
   Product: Drivers
   Version: 2.5
Kernel Version: linux-4.9-rc6
  Hardware: All
OS: Linux
  Tree: Mainline
Status: NEW
  Severity: normal
  Priority: P1
 Component: Video(DRI - non Intel)
  Assignee: drivers_video-dri at kernel-bugs.osdl.org
  Reporter: bianpan2010 at ruc.edu.cn
Regression: No

(1) Function kmalloc() return a NULL pointer if there is no enough memory. The
function qxl_release_alloc() defined in file drivers/gpu/drm/qxl/qxl_release.c
tries to allocate memory and stores in its third parameter @@ret. Parameter
@@ret keeps unmodified if the call to kmalloc() (at line 133) fails. In this
case, it returns 0.
(2) Function qxl_alloc_release_reserved() calls qxl_release_alloc() to allocate
memory for its parameter @@release. By reviewing the source code of the callers
of function qxl_alloc_release_reserved() (e.g. qxl_process_single_command()
defined in file drivers/gpu/drm/qxl/qxl_ioctl.c), we find that parameter
@@release is uninitialized. The return value of qxl_release_alloc() is checked,
if the return value is 0, the execution flow will continue, and the memory
pointed by @@release will be accessed (at line 368). Recall that function
qxl_release_alloc() returns 0 when kmalloc() fails. In this case, the
uninitialized memory will be accessed, causing bad memory access.
(3) To avoid bad memory access, it's better to return "-ENOMEM" when the call
to kmalloc() fails in function qxl_release_alloc().

Codes related to this bug are summarised as follows.
(1) qxl_release_alloc @@ drivers/gpu/drm/qxl/qxl_release.c
125 static int
126 qxl_release_alloc(struct qxl_device *qdev, int type,
127   struct qxl_release **ret)
128 {
129 struct qxl_release *release;
130 int handle;
131 size_t size = sizeof(*release);
132 
133 release = kmalloc(size, GFP_KERNEL);
134 if (!release) {
135 DRM_ERROR("Out of memory\n");
136 return 0;  // "return -ENOMEM;"?
137 }
...
155 *ret = release;
156 QXL_INFO(qdev, "allocated release %d\n", handle);
157 release->id = handle;
158 return handle;
159 }

(2) qxl_alloc_release_reserved @@ drivers/gpu/drm/qxl/qxl_release.c
323 int qxl_alloc_release_reserved(struct qxl_device *qdev, unsigned long size,
324int type, struct qxl_release **release,
325struct qxl_bo **rbo)
326 {
327 struct qxl_bo *bo;
328 int idr_ret;
...
344 idr_ret = qxl_release_alloc(qdev, type, release);
345 if (idr_ret < 0) {
346 if (rbo)
347 *rbo = NULL;
348 return idr_ret;
349 }
...
366 bo = qxl_bo_ref(qdev->current_release_bo[cur_idx]);
367 
// bad memory access when kmalloc() fails?
368 (*release)->release_offset = qdev->current_release_bo_offset[cur_idx] *
release_size_per_bo[cur_idx];
369 qdev->current_release_bo_offset[cur_idx]++;
...
388 }

(3) qxl_process_single_command @@ drivers/gpu/drm/qxl/qxl_ioctl.c
138 static int qxl_process_single_command(struct qxl_device *qdev,
139   struct drm_qxl_command *cmd,
140   struct drm_file *file_priv)
141 {
142 struct qxl_reloc_info *reloc_info;
143 int release_type;
144 struct qxl_release *release; // release is not initialized
...
175 ret = qxl_alloc_release_reserved(qdev,
176  sizeof(union qxl_release_info) +
177  cmd->command_size,
178  release_type,
179  ,
180  _bo);
181 if (ret)
182 goto out_free_reloc;
...
269 out_free_reloc:
270 kfree(reloc_info);
271 return ret;
272 }

Thanks very much!

-- 
You are receiving this mail because:
You are watching the assignee of the bug.


Question regarding clocks in the DW-HDMI DT bindings

2016-11-25 Thread Fabio Estevam
Hi Vladimir,

On Fri, Nov 25, 2016 at 11:00 AM, Vladimir Zapolskiy
 wrote:

> according to the DTSI files in the vanilla kernel DW HDMI IP is found
> only on iMX6Q/D and iMX6DL/iMX6S SoCs (but please double check it),
> so this approach should work ideally.

After thinking more about this I think we can not get rid of "gpr". If
we have a new i.MX SoC that is not compatible with
"fsl,imx6q-iomuxc-gpr" then the lookup will fail.

> I see that the same has already been done in PCIe and SATA drivers,
> but please consider to send a similar change against iMX LDB driver

The i.MX LDB driver is also used on imx53, so we cannot search for
"fsl,imx6q-iomuxc-gpr" compatible, as it will fail on imx53.

So it seems we need to keep the "gpr" property in this case.


[PATCH v5 4/4] drm/tilcdc: Add drm bridge support for attaching drm bridge drivers

2016-11-25 Thread Jyri Sarha
Adds drm bride support for attaching drm bridge drivers to tilcdc. The
decision whether a video port leads to an external encoder or bridge
is made simply based on remote device's compatible string. The code
has been tested with BeagleBone-Black with and without BeagleBone
DVI-D Cape Rev A3 using ti-tfp410 driver.

Signed-off-by: Jyri Sarha 
---
 drivers/gpu/drm/tilcdc/tilcdc_drv.c  |  11 +-
 drivers/gpu/drm/tilcdc/tilcdc_drv.h  |   5 +-
 drivers/gpu/drm/tilcdc/tilcdc_external.c | 260 +++
 drivers/gpu/drm/tilcdc/tilcdc_external.h |   5 +-
 4 files changed, 207 insertions(+), 74 deletions(-)

diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c 
b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
index 3d2cea0..7f4d3bc 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
@@ -209,7 +209,7 @@ static void tilcdc_fini(struct drm_device *dev)

drm_irq_uninstall(dev);
drm_mode_config_cleanup(dev);
-   tilcdc_remove_external_encoders(dev);
+   tilcdc_remove_external_device(dev);

 #ifdef CONFIG_CPU_FREQ
if (priv->freq_transition.notifier_call)
@@ -381,12 +381,17 @@ static int tilcdc_init(struct drm_driver *ddrv, struct 
device *dev)
if (ret < 0)
goto init_failed;

-   ret = tilcdc_add_external_encoders(ddev);
+   ret = tilcdc_add_component_encoder(ddev);
if (ret < 0)
goto init_failed;
+   } else {
+   ret = tilcdc_attach_external_device(ddev);
+   if (ret)
+   goto init_failed;
}

-   if ((priv->num_encoders == 0) || (priv->num_connectors == 0)) {
+   if (!priv->external_connector &&
+   ((priv->num_encoders == 0) || (priv->num_connectors == 0))) {
dev_err(dev, "no encoders/connectors found\n");
ret = -ENXIO;
goto init_failed;
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.h 
b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
index d31fe5d..411f8a8 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
@@ -88,7 +88,10 @@ struct tilcdc_drm_private {

unsigned int num_connectors;
struct drm_connector *connectors[8];
-   const struct drm_connector_helper_funcs *connector_funcs[8];
+
+   struct drm_encoder *external_encoder;
+   struct drm_connector *external_connector;
+   const struct drm_connector_helper_funcs *connector_funcs;

bool is_registered;
bool is_componentized;
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_external.c 
b/drivers/gpu/drm/tilcdc/tilcdc_external.c
index 06a4c58..c67d7cd 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_external.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_external.c
@@ -28,44 +28,50 @@
.raster_order   = 0,
 };

+static const struct tilcdc_panel_info panel_info_default = {
+   .ac_bias= 255,
+   .ac_bias_intrpt = 0,
+   .dma_burst_sz   = 16,
+   .bpp= 16,
+   .fdd= 0x80,
+   .tft_alt_mode   = 0,
+   .sync_edge  = 0,
+   .sync_ctrl  = 1,
+   .raster_order   = 0,
+};
+
 static int tilcdc_external_mode_valid(struct drm_connector *connector,
  struct drm_display_mode *mode)
 {
struct tilcdc_drm_private *priv = connector->dev->dev_private;
-   int ret, i;
+   int ret;

ret = tilcdc_crtc_mode_valid(priv->crtc, mode);
if (ret != MODE_OK)
return ret;

-   for (i = 0; i < priv->num_connectors &&
-priv->connectors[i] != connector; i++)
-   ;
-
-   BUG_ON(priv->connectors[i] != connector);
-   BUG_ON(!priv->connector_funcs[i]);
+   BUG_ON(priv->external_connector != connector);
+   BUG_ON(!priv->connector_funcs);

/* If the connector has its own mode_valid call it. */
-   if (!IS_ERR(priv->connector_funcs[i]) &&
-   priv->connector_funcs[i]->mode_valid)
-   return priv->connector_funcs[i]->mode_valid(connector, mode);
+   if (!IS_ERR(priv->connector_funcs) &&
+   priv->connector_funcs->mode_valid)
+   return priv->connector_funcs->mode_valid(connector, mode);

return MODE_OK;
 }

-static int tilcdc_add_external_encoder(struct drm_device *dev,
-  struct drm_connector *connector)
+static int tilcdc_add_external_connector(struct drm_device *dev,
+struct drm_connector *connector)
 {
struct tilcdc_drm_private *priv = dev->dev_private;
struct drm_connector_helper_funcs *connector_funcs;

-   priv->connectors[priv->num_connectors] = connector;
-   priv->encoders[priv->num_encoders++] = 

[PATCH v5 3/4] drm/bridge: Add ti-tfp410 DVI transmitter driver

2016-11-25 Thread Jyri Sarha
Add very basic ti-tfp410 DVI transmitter driver. The only feature
separating this from a completely dummy bridge is the EDID read
support trough DDC I2C. Even that functionality should be in a
separate generic connector driver. However, because of missing DRM
infrastructure support the connector is implemented within the bridge
driver. Some tfp410 HW specific features may be added later if needed,
because there is a set of registers behind i2c if it is connected.

This implementation is tested against my new tilcdc bridge support
and it works with BeagleBone DVI-D Cape Rev A3. A DT binding document
is also updated.

Signed-off-by: Jyri Sarha 
---
 .../bindings/display/bridge/ti,tfp410.txt  |   9 +-
 drivers/gpu/drm/bridge/Kconfig |   7 +
 drivers/gpu/drm/bridge/Makefile|   1 +
 drivers/gpu/drm/bridge/ti-tfp410.c | 317 +
 4 files changed, 332 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/bridge/ti-tfp410.c

diff --git a/Documentation/devicetree/bindings/display/bridge/ti,tfp410.txt 
b/Documentation/devicetree/bindings/display/bridge/ti,tfp410.txt
index 2cbe32a..54d7e31 100644
--- a/Documentation/devicetree/bindings/display/bridge/ti,tfp410.txt
+++ b/Documentation/devicetree/bindings/display/bridge/ti,tfp410.txt
@@ -6,10 +6,15 @@ Required properties:

 Optional properties:
 - powerdown-gpios: power-down gpio
+- reg: I2C address. If and only if present the device node
+   should be placed into the i2c controller node where the
+   tfp410 i2c is connected to.

 Required nodes:
-- Video port 0 for DPI input
-- Video port 1 for DVI output
+- Video port 0 for DPI input [1].
+- Video port 1 for DVI output [1].
+
+[1]: Documentation/devicetree/bindings/media/video-interfaces.txt

 Example
 ---
diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index bd6acc8..a424e03 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -81,6 +81,13 @@ config DRM_TOSHIBA_TC358767
---help---
  Toshiba TC358767 eDP bridge chip driver.

+config DRM_TI_TFP410
+   tristate "TI TFP410 DVI/HDMI bridge"
+   depends on OF
+   select DRM_KMS_HELPER
+   ---help---
+ Texas Instruments TFP410 DVI/HDMI Transmitter driver
+
 source "drivers/gpu/drm/bridge/analogix/Kconfig"

 source "drivers/gpu/drm/bridge/adv7511/Kconfig"
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index 97ed1a5..8b065d9 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -11,3 +11,4 @@ obj-$(CONFIG_DRM_SII902X) += sii902x.o
 obj-$(CONFIG_DRM_TOSHIBA_TC358767) += tc358767.o
 obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix/
 obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511/
+obj-$(CONFIG_DRM_TI_TFP410) += ti-tfp410.o
diff --git a/drivers/gpu/drm/bridge/ti-tfp410.c 
b/drivers/gpu/drm/bridge/ti-tfp410.c
new file mode 100644
index 000..b054ea3
--- /dev/null
+++ b/drivers/gpu/drm/bridge/ti-tfp410.c
@@ -0,0 +1,317 @@
+/*
+ * Copyright (C) 2016 Texas Instruments
+ * Author: Jyri Sarha 
+ *
+ * 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 
+
+struct tfp410 {
+   struct drm_bridge   bridge;
+   struct drm_connectorconnector;
+
+   struct i2c_adapter  *ddc;
+
+   struct device *dev;
+};
+
+static inline struct tfp410 *
+drm_bridge_to_tfp410(struct drm_bridge *bridge)
+{
+   return container_of(bridge, struct tfp410, bridge);
+}
+
+static inline struct tfp410 *
+drm_connector_to_tfp410(struct drm_connector *connector)
+{
+   return container_of(connector, struct tfp410, connector);
+}
+
+static int tfp410_get_modes(struct drm_connector *connector)
+{
+   struct tfp410 *dvi = drm_connector_to_tfp410(connector);
+   struct edid *edid;
+   int ret;
+
+   if (!dvi->ddc)
+   goto fallback;
+
+   edid = drm_get_edid(connector, dvi->ddc);
+   if (!edid) {
+   DRM_INFO("EDID read failed. Fallback to standard modes\n");
+   goto fallback;
+   }
+
+   drm_mode_connector_update_edid_property(connector, edid);
+
+   return drm_add_edid_modes(connector, edid);
+fallback:
+   /* No EDID, fallback on the XGA standard modes */
+   ret = drm_add_modes_noedid(connector, 1920, 1200);
+
+   /* And prefer a mode pretty much anything can handle */
+   drm_set_preferred_mode(connector, 1024, 768);
+
+   return ret;
+}
+
+static const struct drm_connector_helper_funcs tfp410_con_helper_funcs = {
+   .get_modes  = tfp410_get_modes,
+};
+
+static enum drm_connector_status
+tfp410_connector_detect(struct drm_connector *connector, bool force)
+{
+   struct tfp410 *dvi = 

[PATCH v5 2/4] dt-bindings: Move "ti, tfp410.txt" from display/ti to display/bridge

2016-11-25 Thread Jyri Sarha
Move "ti,tfp410.txt" from display/ti to display/bridge before adding
generic (non omapdrm/dss specific) implementation and new features.

Signed-off-by: Jyri Sarha 
---
 Documentation/devicetree/bindings/display/{ti => bridge}/ti,tfp410.txt | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename Documentation/devicetree/bindings/display/{ti => bridge}/ti,tfp410.txt 
(100%)

diff --git a/Documentation/devicetree/bindings/display/ti/ti,tfp410.txt 
b/Documentation/devicetree/bindings/display/bridge/ti,tfp410.txt
similarity index 100%
rename from Documentation/devicetree/bindings/display/ti/ti,tfp410.txt
rename to Documentation/devicetree/bindings/display/bridge/ti,tfp410.txt
-- 
1.9.1



[PATCH v5 1/4] drm/tilcdc: Recover from sync lost error flood by resetting the LCDC

2016-11-25 Thread Jyri Sarha
Recover from sync lost error flood by resetting the LCDC instead of
turning off the SYNC_LOST error IRQ. When LCDC starves on limited
memory bandwidth it may sometimes result an error situation when the
picture may have shifted couple of pixels to right and SYNC_LOST
interrupt is generated on every frame. LCDC main reset recovers from
this situation and causes a brief blanking on the screen.

Signed-off-by: Jyri Sarha 
---
 drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 26 +-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c 
b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
index 0d09acc..c787349 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
@@ -55,6 +55,7 @@ struct tilcdc_crtc {

int sync_lost_count;
bool frame_intact;
+   struct work_struct recover_work;
 };
 #define to_tilcdc_crtc(x) container_of(x, struct tilcdc_crtc, base)

@@ -252,6 +253,25 @@ static bool tilcdc_crtc_is_on(struct drm_crtc *crtc)
return crtc->state && crtc->state->enable && crtc->state->active;
 }

+static void tilcdc_crtc_recover_work(struct work_struct *work)
+{
+   struct tilcdc_crtc *tilcdc_crtc =
+   container_of(work, struct tilcdc_crtc, recover_work);
+   struct drm_crtc *crtc = _crtc->base;
+
+   dev_info(crtc->dev->dev, "%s: Reset CRTC", __func__);
+
+   drm_modeset_lock_crtc(crtc, NULL);
+
+   if (!tilcdc_crtc_is_on(crtc))
+   goto out;
+
+   tilcdc_crtc_disable(crtc);
+   tilcdc_crtc_enable(crtc);
+out:
+   drm_modeset_unlock_crtc(crtc);
+}
+
 static void tilcdc_crtc_destroy(struct drm_crtc *crtc)
 {
struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
@@ -838,9 +858,12 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc)
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);
+   dev_err(dev->dev, "%s(0x%08x): Sync lost flood 
detected, recovering", __func__, stat);
+   queue_work(system_wq,
+  _crtc->recover_work);
tilcdc_write(dev, LCDC_INT_ENABLE_CLR_REG,
 LCDC_SYNC_LOST);
+   tilcdc_crtc->sync_lost_count = 0;
}
}

@@ -880,6 +903,7 @@ struct drm_crtc *tilcdc_crtc_create(struct drm_device *dev)
"unref", unref_worker);

spin_lock_init(_crtc->irq_lock);
+   INIT_WORK(_crtc->recover_work, tilcdc_crtc_recover_work);

ret = drm_crtc_init_with_planes(dev, crtc,
_crtc->primary,
-- 
1.9.1



  1   2   >