Skip to content

Commit

Permalink
Merge tag 'imx-drm-next-2018-12-03' of git://git.pengutronix.de/git/p…
Browse files Browse the repository at this point in the history
…za/linux into drm-next

drm/imx: update image-convert with fixes for multi-tiled scaling

Update the ipu-v3 mem2mem image-convert code, with some fixes for race
conditions, alignment issues, and visual artifacts due to tile alignment
and scaling factor issues when scaling images larger than hardware
limitations in multiple tiles. This will allow the V4L2 mem2mem scaler
driver to write output images larger than 1024x1024 pixels.

Also switch drm/imx source files to SPDX license identifiers, constify
struct clk_ops in imx-tve, and add a timeout warning to the busy wait in
ipu_plane_disable().

Signed-off-by: Dave Airlie <airlied@redhat.com>

From: Philipp Zabel <p.zabel@pengutronix.de>
Link: https://patchwork.freedesktop.org/patch/msgid/1543835266.5647.1.camel@pengutronix.de
  • Loading branch information
Dave Airlie committed Dec 5, 2018
2 parents 167bfe5 + 97c78f4 commit 818182d
Show file tree
Hide file tree
Showing 11 changed files with 940 additions and 268 deletions.
5 changes: 1 addition & 4 deletions drivers/gpu/drm/imx/dw_hdmi-imx.c
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
*
* derived from imx-hdmi.c(renamed to bridge/dw_hdmi.c now)
*
* 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 <linux/module.h>
#include <linux/platform_device.h>
Expand Down
11 changes: 1 addition & 10 deletions drivers/gpu/drm/imx/imx-drm-core.c
Original file line number Diff line number Diff line change
@@ -1,17 +1,8 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Freescale i.MX drm driver
*
* Copyright (C) 2011 Sascha Hauer, Pengutronix
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/component.h>
#include <linux/device.h>
Expand Down
10 changes: 1 addition & 9 deletions drivers/gpu/drm/imx/imx-ldb.c
Original file line number Diff line number Diff line change
@@ -1,16 +1,8 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* i.MX drm driver - LVDS display bridge
*
* Copyright (C) 2012 Sascha Hauer, Pengutronix
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/

#include <linux/module.h>
Expand Down
12 changes: 2 additions & 10 deletions drivers/gpu/drm/imx/imx-tve.c
Original file line number Diff line number Diff line change
@@ -1,16 +1,8 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* i.MX drm driver - Television Encoder (TVEv2)
*
* Copyright (C) 2013 Philipp Zabel, Pengutronix
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/

#include <linux/clk.h>
Expand Down Expand Up @@ -442,7 +434,7 @@ static int clk_tve_di_set_rate(struct clk_hw *hw, unsigned long rate,
return 0;
}

static struct clk_ops clk_tve_di_ops = {
static const struct clk_ops clk_tve_di_ops = {
.round_rate = clk_tve_di_round_rate,
.set_rate = clk_tve_di_set_rate,
.recalc_rate = clk_tve_di_recalc_rate,
Expand Down
10 changes: 1 addition & 9 deletions drivers/gpu/drm/imx/ipuv3-crtc.c
Original file line number Diff line number Diff line change
@@ -1,16 +1,8 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* i.MX IPUv3 Graphics driver
*
* Copyright (C) 2011 Sascha Hauer, Pengutronix
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/component.h>
#include <linux/module.h>
Expand Down
18 changes: 8 additions & 10 deletions drivers/gpu/drm/imx/ipuv3-plane.c
Original file line number Diff line number Diff line change
@@ -1,16 +1,8 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* i.MX IPUv3 DP Overlay Planes
*
* Copyright (C) 2013 Philipp Zabel, Pengutronix
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/

#include <drm/drmP.h>
Expand Down Expand Up @@ -236,9 +228,15 @@ static void ipu_plane_enable(struct ipu_plane *ipu_plane)

void ipu_plane_disable(struct ipu_plane *ipu_plane, bool disable_dp_channel)
{
int ret;

DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);

ipu_idmac_wait_busy(ipu_plane->ipu_ch, 50);
ret = ipu_idmac_wait_busy(ipu_plane->ipu_ch, 50);
if (ret == -ETIMEDOUT) {
DRM_ERROR("[PLANE:%d] IDMAC timeout\n",
ipu_plane->base.base.id);
}

if (ipu_plane->dp && disable_dp_channel)
ipu_dp_disable_channel(ipu_plane->dp, false);
Expand Down
10 changes: 1 addition & 9 deletions drivers/gpu/drm/imx/parallel-display.c
Original file line number Diff line number Diff line change
@@ -1,16 +1,8 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* i.MX drm driver - parallel display implementation
*
* Copyright (C) 2012 Sascha Hauer, Pengutronix
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/

#include <linux/component.h>
Expand Down
52 changes: 33 additions & 19 deletions drivers/gpu/ipu-v3/ipu-cpmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,8 @@ EXPORT_SYMBOL_GPL(ipu_cpmem_set_high_priority);

void ipu_cpmem_set_buffer(struct ipuv3_channel *ch, int bufnum, dma_addr_t buf)
{
WARN_ON_ONCE(buf & 0x7);

if (bufnum)
ipu_ch_param_write_field(ch, IPU_FIELD_EBA1, buf >> 3);
else
Expand All @@ -268,6 +270,8 @@ EXPORT_SYMBOL_GPL(ipu_cpmem_set_buffer);

void ipu_cpmem_set_uv_offset(struct ipuv3_channel *ch, u32 u_off, u32 v_off)
{
WARN_ON_ONCE((u_off & 0x7) || (v_off & 0x7));

ipu_ch_param_write_field(ch, IPU_FIELD_UBO, u_off / 8);
ipu_ch_param_write_field(ch, IPU_FIELD_VBO, v_off / 8);
}
Expand Down Expand Up @@ -435,6 +439,8 @@ void ipu_cpmem_set_yuv_planar_full(struct ipuv3_channel *ch,
unsigned int uv_stride,
unsigned int u_offset, unsigned int v_offset)
{
WARN_ON_ONCE((u_offset & 0x7) || (v_offset & 0x7));

ipu_ch_param_write_field(ch, IPU_FIELD_SLUV, uv_stride - 1);
ipu_ch_param_write_field(ch, IPU_FIELD_UBO, u_offset / 8);
ipu_ch_param_write_field(ch, IPU_FIELD_VBO, v_offset / 8);
Expand Down Expand Up @@ -739,48 +745,56 @@ int ipu_cpmem_set_image(struct ipuv3_channel *ch, struct ipu_image *image)
switch (pix->pixelformat) {
case V4L2_PIX_FMT_YUV420:
offset = Y_OFFSET(pix, image->rect.left, image->rect.top);
u_offset = U_OFFSET(pix, image->rect.left,
image->rect.top) - offset;
v_offset = V_OFFSET(pix, image->rect.left,
image->rect.top) - offset;
u_offset = image->u_offset ?
image->u_offset : U_OFFSET(pix, image->rect.left,
image->rect.top) - offset;
v_offset = image->v_offset ?
image->v_offset : V_OFFSET(pix, image->rect.left,
image->rect.top) - offset;

ipu_cpmem_set_yuv_planar_full(ch, pix->bytesperline / 2,
u_offset, v_offset);
break;
case V4L2_PIX_FMT_YVU420:
offset = Y_OFFSET(pix, image->rect.left, image->rect.top);
u_offset = U_OFFSET(pix, image->rect.left,
image->rect.top) - offset;
v_offset = V_OFFSET(pix, image->rect.left,
image->rect.top) - offset;
u_offset = image->u_offset ?
image->u_offset : V_OFFSET(pix, image->rect.left,
image->rect.top) - offset;
v_offset = image->v_offset ?
image->v_offset : U_OFFSET(pix, image->rect.left,
image->rect.top) - offset;

ipu_cpmem_set_yuv_planar_full(ch, pix->bytesperline / 2,
v_offset, u_offset);
u_offset, v_offset);
break;
case V4L2_PIX_FMT_YUV422P:
offset = Y_OFFSET(pix, image->rect.left, image->rect.top);
u_offset = U2_OFFSET(pix, image->rect.left,
image->rect.top) - offset;
v_offset = V2_OFFSET(pix, image->rect.left,
image->rect.top) - offset;
u_offset = image->u_offset ?
image->u_offset : U2_OFFSET(pix, image->rect.left,
image->rect.top) - offset;
v_offset = image->v_offset ?
image->v_offset : V2_OFFSET(pix, image->rect.left,
image->rect.top) - offset;

ipu_cpmem_set_yuv_planar_full(ch, pix->bytesperline / 2,
u_offset, v_offset);
break;
case V4L2_PIX_FMT_NV12:
offset = Y_OFFSET(pix, image->rect.left, image->rect.top);
u_offset = UV_OFFSET(pix, image->rect.left,
image->rect.top) - offset;
v_offset = 0;
u_offset = image->u_offset ?
image->u_offset : UV_OFFSET(pix, image->rect.left,
image->rect.top) - offset;
v_offset = image->v_offset ? image->v_offset : 0;

ipu_cpmem_set_yuv_planar_full(ch, pix->bytesperline,
u_offset, v_offset);
break;
case V4L2_PIX_FMT_NV16:
offset = Y_OFFSET(pix, image->rect.left, image->rect.top);
u_offset = UV2_OFFSET(pix, image->rect.left,
image->rect.top) - offset;
v_offset = 0;
u_offset = image->u_offset ?
image->u_offset : UV2_OFFSET(pix, image->rect.left,
image->rect.top) - offset;
v_offset = image->v_offset ? image->v_offset : 0;

ipu_cpmem_set_yuv_planar_full(ch, pix->bytesperline,
u_offset, v_offset);
Expand Down
52 changes: 33 additions & 19 deletions drivers/gpu/ipu-v3/ipu-ic.c
Original file line number Diff line number Diff line change
Expand Up @@ -442,36 +442,40 @@ int ipu_ic_task_graphics_init(struct ipu_ic *ic,
}
EXPORT_SYMBOL_GPL(ipu_ic_task_graphics_init);

int ipu_ic_task_init(struct ipu_ic *ic,
int in_width, int in_height,
int out_width, int out_height,
enum ipu_color_space in_cs,
enum ipu_color_space out_cs)
int ipu_ic_task_init_rsc(struct ipu_ic *ic,
int in_width, int in_height,
int out_width, int out_height,
enum ipu_color_space in_cs,
enum ipu_color_space out_cs,
u32 rsc)
{
struct ipu_ic_priv *priv = ic->priv;
u32 reg, downsize_coeff, resize_coeff;
u32 downsize_coeff, resize_coeff;
unsigned long flags;
int ret = 0;

/* Setup vertical resizing */
ret = calc_resize_coeffs(ic, in_height, out_height,
&resize_coeff, &downsize_coeff);
if (ret)
return ret;
if (!rsc) {
/* Setup vertical resizing */

reg = (downsize_coeff << 30) | (resize_coeff << 16);
ret = calc_resize_coeffs(ic, in_height, out_height,
&resize_coeff, &downsize_coeff);
if (ret)
return ret;

rsc = (downsize_coeff << 30) | (resize_coeff << 16);

/* Setup horizontal resizing */
ret = calc_resize_coeffs(ic, in_width, out_width,
&resize_coeff, &downsize_coeff);
if (ret)
return ret;
/* Setup horizontal resizing */
ret = calc_resize_coeffs(ic, in_width, out_width,
&resize_coeff, &downsize_coeff);
if (ret)
return ret;

reg |= (downsize_coeff << 14) | resize_coeff;
rsc |= (downsize_coeff << 14) | resize_coeff;
}

spin_lock_irqsave(&priv->lock, flags);

ipu_ic_write(ic, reg, ic->reg->rsc);
ipu_ic_write(ic, rsc, ic->reg->rsc);

/* Setup color space conversion */
ic->in_cs = in_cs;
Expand All @@ -487,6 +491,16 @@ int ipu_ic_task_init(struct ipu_ic *ic,
spin_unlock_irqrestore(&priv->lock, flags);
return ret;
}

int ipu_ic_task_init(struct ipu_ic *ic,
int in_width, int in_height,
int out_width, int out_height,
enum ipu_color_space in_cs,
enum ipu_color_space out_cs)
{
return ipu_ic_task_init_rsc(ic, in_width, in_height, out_width,
out_height, in_cs, out_cs, 0);
}
EXPORT_SYMBOL_GPL(ipu_ic_task_init);

int ipu_ic_task_idma_init(struct ipu_ic *ic, struct ipuv3_channel *channel,
Expand Down
Loading

0 comments on commit 818182d

Please sign in to comment.