mirror of
https://github.com/torvalds/linux.git
synced 2026-05-30 10:04:04 +02:00
drm/tegra: Changes for v5.18-rc1
This contains a couple more minor fixes that didn't seem urgent enough for v5.17. On top of that this improves YUV format support on older chips. -----BEGIN PGP SIGNATURE----- iQJHBAABCAAxFiEEiOrDCAFJzPfAjcif3SOs138+s6EFAmId87ITHHRyZWRpbmdA bnZpZGlhLmNvbQAKCRDdI6zXfz6zoeljEAC/615cS3PhFJVxC4A5J22r5eMZlLF8 x3GHUtXrHKzIeeyK2LwSLGiivs8cm0zweDrDMb8lVYLA0l/XGHplXS5u6DuE5jBh K3KeIMx6ADJtVmraXUsIKRMRaxUtHcCPrkQ0qQjPADe/2T3Avm1Yr1PRh30jFX4i rZf6P0F6vSKo3mdrrC3Uk53gWvkbGOTRktDwhoZBDurPUxbovBIqyMLvoO3jEKCp 2JkEC1pBuWg7t1Gg+JIzOOVg8tUyPBmv0MsCy2pKhXJlCCGmnskhfnYdsLlBNb4F 2phwi/FbuV3rGQgXfoZJy9uMqnmenpb2hOzYiqZvj8FisuozUpKc7A/Ut6I9Pdym 2L/MaYnpvsMtKYGPInljC9gfDCHoXvXy9/WHI525r394+tQ0hZGfQ76GNu9JeLRV fnwdej5aIJFHJwmvyeb03CwDBVSOFz77XqWr8CKqZsdfwVTr1L8et815CIsWlpnI fizER4Dr1bvkDyjXkCyOCl90mK9doY4GRxSP7/QOcQv1hJjMP79iriy644SfA4IA 7MSXNoQyDK2bzs05CyOW43m4DRfl3hzoasrWfjqC/TCzH07IKRK45kO5XCOSqPbf wuAogI31HwdTScSR/nXbpk1+2svlavSWfjGg7Oz9AWUkq5fNDbEKdNP+QnbWeCds 1LCZGOjJHOyKAA== =gvtK -----END PGP SIGNATURE----- Merge tag 'drm/tegra/for-5.18-rc1' of https://gitlab.freedesktop.org/drm/tegra into drm-next drm/tegra: Changes for v5.18-rc1 This contains a couple more minor fixes that didn't seem urgent enough for v5.17. On top of that this improves YUV format support on older chips. Signed-off-by: Dave Airlie <airlied@redhat.com> From: Thierry Reding <thierry.reding@gmail.com> Link: https://patchwork.freedesktop.org/patch/msgid/20220301124426.1207653-1-thierry.reding@gmail.com
This commit is contained in:
commit
66a8af1f6e
|
|
@ -345,18 +345,19 @@ static void tegra_dc_setup_window(struct tegra_plane *plane,
|
|||
{
|
||||
unsigned h_offset, v_offset, h_size, v_size, h_dda, v_dda, bpp;
|
||||
struct tegra_dc *dc = plane->dc;
|
||||
bool yuv, planar;
|
||||
unsigned int planes;
|
||||
u32 value;
|
||||
bool yuv;
|
||||
|
||||
/*
|
||||
* For YUV planar modes, the number of bytes per pixel takes into
|
||||
* account only the luma component and therefore is 1.
|
||||
*/
|
||||
yuv = tegra_plane_format_is_yuv(window->format, &planar, NULL);
|
||||
yuv = tegra_plane_format_is_yuv(window->format, &planes, NULL);
|
||||
if (!yuv)
|
||||
bpp = window->bits_per_pixel / 8;
|
||||
else
|
||||
bpp = planar ? 1 : 2;
|
||||
bpp = (planes > 1) ? 1 : 2;
|
||||
|
||||
tegra_plane_writel(plane, window->format, DC_WIN_COLOR_DEPTH);
|
||||
tegra_plane_writel(plane, window->swap, DC_WIN_BYTE_SWAP);
|
||||
|
|
@ -385,7 +386,7 @@ static void tegra_dc_setup_window(struct tegra_plane *plane,
|
|||
* For DDA computations the number of bytes per pixel for YUV planar
|
||||
* modes needs to take into account all Y, U and V components.
|
||||
*/
|
||||
if (yuv && planar)
|
||||
if (yuv && planes > 1)
|
||||
bpp = 2;
|
||||
|
||||
h_dda = compute_dda_inc(window->src.w, window->dst.w, false, bpp);
|
||||
|
|
@ -405,9 +406,12 @@ static void tegra_dc_setup_window(struct tegra_plane *plane,
|
|||
|
||||
tegra_plane_writel(plane, window->base[0], DC_WINBUF_START_ADDR);
|
||||
|
||||
if (yuv && planar) {
|
||||
if (yuv && planes > 1) {
|
||||
tegra_plane_writel(plane, window->base[1], DC_WINBUF_START_ADDR_U);
|
||||
tegra_plane_writel(plane, window->base[2], DC_WINBUF_START_ADDR_V);
|
||||
|
||||
if (planes > 2)
|
||||
tegra_plane_writel(plane, window->base[2], DC_WINBUF_START_ADDR_V);
|
||||
|
||||
value = window->stride[1] << 16 | window->stride[0];
|
||||
tegra_plane_writel(plane, value, DC_WIN_LINE_STRIDE);
|
||||
} else {
|
||||
|
|
@ -1193,6 +1197,13 @@ static const u32 tegra114_overlay_formats[] = {
|
|||
DRM_FORMAT_YUYV,
|
||||
DRM_FORMAT_YUV420,
|
||||
DRM_FORMAT_YUV422,
|
||||
/* semi-planar formats */
|
||||
DRM_FORMAT_NV12,
|
||||
DRM_FORMAT_NV21,
|
||||
DRM_FORMAT_NV16,
|
||||
DRM_FORMAT_NV61,
|
||||
DRM_FORMAT_NV24,
|
||||
DRM_FORMAT_NV42,
|
||||
};
|
||||
|
||||
static const u32 tegra124_overlay_formats[] = {
|
||||
|
|
@ -1221,8 +1232,18 @@ static const u32 tegra124_overlay_formats[] = {
|
|||
/* planar formats */
|
||||
DRM_FORMAT_UYVY,
|
||||
DRM_FORMAT_YUYV,
|
||||
DRM_FORMAT_YUV420,
|
||||
DRM_FORMAT_YUV422,
|
||||
DRM_FORMAT_YVYU,
|
||||
DRM_FORMAT_VYUY,
|
||||
DRM_FORMAT_YUV420, /* YU12 */
|
||||
DRM_FORMAT_YUV422, /* YU16 */
|
||||
DRM_FORMAT_YUV444, /* YU24 */
|
||||
/* semi-planar formats */
|
||||
DRM_FORMAT_NV12,
|
||||
DRM_FORMAT_NV21,
|
||||
DRM_FORMAT_NV16,
|
||||
DRM_FORMAT_NV61,
|
||||
DRM_FORMAT_NV24,
|
||||
DRM_FORMAT_NV42,
|
||||
};
|
||||
|
||||
static struct drm_plane *tegra_dc_overlay_plane_create(struct drm_device *drm,
|
||||
|
|
@ -3211,16 +3232,9 @@ static int tegra_dc_probe(struct platform_device *pdev)
|
|||
return -ENXIO;
|
||||
|
||||
err = tegra_dc_rgb_probe(dc);
|
||||
if (err < 0 && err != -ENODEV) {
|
||||
const char *level = KERN_ERR;
|
||||
|
||||
if (err == -EPROBE_DEFER)
|
||||
level = KERN_DEBUG;
|
||||
|
||||
dev_printk(level, dc->dev, "failed to probe RGB output: %d\n",
|
||||
err);
|
||||
return err;
|
||||
}
|
||||
if (err < 0 && err != -ENODEV)
|
||||
return dev_err_probe(&pdev->dev, err,
|
||||
"failed to probe RGB output\n");
|
||||
|
||||
platform_set_drvdata(pdev, dc);
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
|
|
|
|||
|
|
@ -637,6 +637,13 @@ int tegra_dc_rgb_exit(struct tegra_dc *dc);
|
|||
#define WIN_COLOR_DEPTH_A8B8G8R8 36
|
||||
#define WIN_COLOR_DEPTH_B8G8R8X8 37
|
||||
#define WIN_COLOR_DEPTH_R8G8B8X8 38
|
||||
#define WIN_COLOR_DEPTH_YCbCr444P 41
|
||||
#define WIN_COLOR_DEPTH_YCrCb420SP 42
|
||||
#define WIN_COLOR_DEPTH_YCbCr420SP 43
|
||||
#define WIN_COLOR_DEPTH_YCrCb422SP 44
|
||||
#define WIN_COLOR_DEPTH_YCbCr422SP 45
|
||||
#define WIN_COLOR_DEPTH_YCrCb444SP 48
|
||||
#define WIN_COLOR_DEPTH_YCbCr444SP 49
|
||||
#define WIN_COLOR_DEPTH_X8B8G8R8 65
|
||||
#define WIN_COLOR_DEPTH_X8R8G8B8 66
|
||||
|
||||
|
|
|
|||
|
|
@ -280,7 +280,6 @@ static void tegra_dpaux_hotplug(struct work_struct *work)
|
|||
static irqreturn_t tegra_dpaux_irq(int irq, void *data)
|
||||
{
|
||||
struct tegra_dpaux *dpaux = data;
|
||||
irqreturn_t ret = IRQ_HANDLED;
|
||||
u32 value;
|
||||
|
||||
/* clear interrupts */
|
||||
|
|
@ -297,7 +296,7 @@ static irqreturn_t tegra_dpaux_irq(int irq, void *data)
|
|||
if (value & DPAUX_INTR_AUX_DONE)
|
||||
complete(&dpaux->complete);
|
||||
|
||||
return ret;
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
enum tegra_dpaux_functions {
|
||||
|
|
|
|||
|
|
@ -1538,8 +1538,10 @@ static int tegra_dsi_ganged_probe(struct tegra_dsi *dsi)
|
|||
dsi->slave = platform_get_drvdata(gangster);
|
||||
of_node_put(np);
|
||||
|
||||
if (!dsi->slave)
|
||||
if (!dsi->slave) {
|
||||
put_device(&gangster->dev);
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
|
||||
dsi->slave->master = dsi;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1775,7 +1775,6 @@ static irqreturn_t tegra_hdmi_irq(int irq, void *data)
|
|||
|
||||
static int tegra_hdmi_probe(struct platform_device *pdev)
|
||||
{
|
||||
const char *level = KERN_ERR;
|
||||
struct tegra_hdmi *hdmi;
|
||||
struct resource *regs;
|
||||
int err;
|
||||
|
|
@ -1817,36 +1816,21 @@ static int tegra_hdmi_probe(struct platform_device *pdev)
|
|||
|
||||
hdmi->hdmi = devm_regulator_get(&pdev->dev, "hdmi");
|
||||
err = PTR_ERR_OR_ZERO(hdmi->hdmi);
|
||||
if (err) {
|
||||
if (err == -EPROBE_DEFER)
|
||||
level = KERN_DEBUG;
|
||||
|
||||
dev_printk(level, &pdev->dev,
|
||||
"failed to get HDMI regulator: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
if (err)
|
||||
return dev_err_probe(&pdev->dev, err,
|
||||
"failed to get HDMI regulator\n");
|
||||
|
||||
hdmi->pll = devm_regulator_get(&pdev->dev, "pll");
|
||||
err = PTR_ERR_OR_ZERO(hdmi->pll);
|
||||
if (err) {
|
||||
if (err == -EPROBE_DEFER)
|
||||
level = KERN_DEBUG;
|
||||
|
||||
dev_printk(level, &pdev->dev,
|
||||
"failed to get PLL regulator: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
if (err)
|
||||
return dev_err_probe(&pdev->dev, err,
|
||||
"failed to get PLL regulator\n");
|
||||
|
||||
hdmi->vdd = devm_regulator_get(&pdev->dev, "vdd");
|
||||
err = PTR_ERR_OR_ZERO(hdmi->vdd);
|
||||
if (err) {
|
||||
if (err == -EPROBE_DEFER)
|
||||
level = KERN_DEBUG;
|
||||
|
||||
dev_printk(level, &pdev->dev,
|
||||
"failed to get VDD regulator: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
if (err)
|
||||
return dev_err_probe(&pdev->dev, err,
|
||||
"failed to get VDD regulator\n");
|
||||
|
||||
hdmi->output.dev = &pdev->dev;
|
||||
|
||||
|
|
|
|||
|
|
@ -540,8 +540,8 @@ static void tegra_shared_plane_atomic_update(struct drm_plane *plane,
|
|||
struct tegra_plane *p = to_tegra_plane(plane);
|
||||
u32 value, min_width, bypass = 0;
|
||||
dma_addr_t base, addr_flag = 0;
|
||||
unsigned int bpc;
|
||||
bool yuv, planar;
|
||||
unsigned int bpc, planes;
|
||||
bool yuv;
|
||||
int err;
|
||||
|
||||
/* rien ne va plus */
|
||||
|
|
@ -559,7 +559,7 @@ static void tegra_shared_plane_atomic_update(struct drm_plane *plane,
|
|||
return;
|
||||
}
|
||||
|
||||
yuv = tegra_plane_format_is_yuv(tegra_plane_state->format, &planar, &bpc);
|
||||
yuv = tegra_plane_format_is_yuv(tegra_plane_state->format, &planes, &bpc);
|
||||
|
||||
tegra_dc_assign_shared_plane(dc, p);
|
||||
|
||||
|
|
@ -660,20 +660,26 @@ static void tegra_shared_plane_atomic_update(struct drm_plane *plane,
|
|||
value = PITCH(fb->pitches[0]);
|
||||
tegra_plane_writel(p, value, DC_WIN_PLANAR_STORAGE);
|
||||
|
||||
if (yuv && planar) {
|
||||
if (yuv && planes > 1) {
|
||||
base = tegra_plane_state->iova[1] + fb->offsets[1];
|
||||
base |= addr_flag;
|
||||
|
||||
tegra_plane_writel(p, upper_32_bits(base), DC_WINBUF_START_ADDR_HI_U);
|
||||
tegra_plane_writel(p, lower_32_bits(base), DC_WINBUF_START_ADDR_U);
|
||||
|
||||
base = tegra_plane_state->iova[2] + fb->offsets[2];
|
||||
base |= addr_flag;
|
||||
if (planes > 2) {
|
||||
base = tegra_plane_state->iova[2] + fb->offsets[2];
|
||||
base |= addr_flag;
|
||||
|
||||
tegra_plane_writel(p, upper_32_bits(base), DC_WINBUF_START_ADDR_HI_V);
|
||||
tegra_plane_writel(p, lower_32_bits(base), DC_WINBUF_START_ADDR_V);
|
||||
tegra_plane_writel(p, upper_32_bits(base), DC_WINBUF_START_ADDR_HI_V);
|
||||
tegra_plane_writel(p, lower_32_bits(base), DC_WINBUF_START_ADDR_V);
|
||||
}
|
||||
|
||||
value = PITCH_U(fb->pitches[1]);
|
||||
|
||||
if (planes > 2)
|
||||
value |= PITCH_V(fb->pitches[2]);
|
||||
|
||||
value = PITCH_U(fb->pitches[2]) | PITCH_V(fb->pitches[2]);
|
||||
tegra_plane_writel(p, value, DC_WIN_PLANAR_STORAGE_UV);
|
||||
} else {
|
||||
tegra_plane_writel(p, 0, DC_WINBUF_START_ADDR_U);
|
||||
|
|
|
|||
|
|
@ -413,6 +413,22 @@ int tegra_plane_format(u32 fourcc, u32 *format, u32 *swap)
|
|||
*swap = BYTE_SWAP_SWAP2;
|
||||
break;
|
||||
|
||||
case DRM_FORMAT_YVYU:
|
||||
if (!swap)
|
||||
return -EINVAL;
|
||||
|
||||
*format = WIN_COLOR_DEPTH_YCbCr422;
|
||||
*swap = BYTE_SWAP_SWAP4;
|
||||
break;
|
||||
|
||||
case DRM_FORMAT_VYUY:
|
||||
if (!swap)
|
||||
return -EINVAL;
|
||||
|
||||
*format = WIN_COLOR_DEPTH_YCbCr422;
|
||||
*swap = BYTE_SWAP_SWAP4HW;
|
||||
break;
|
||||
|
||||
case DRM_FORMAT_YUV420:
|
||||
*format = WIN_COLOR_DEPTH_YCbCr420P;
|
||||
break;
|
||||
|
|
@ -421,6 +437,34 @@ int tegra_plane_format(u32 fourcc, u32 *format, u32 *swap)
|
|||
*format = WIN_COLOR_DEPTH_YCbCr422P;
|
||||
break;
|
||||
|
||||
case DRM_FORMAT_YUV444:
|
||||
*format = WIN_COLOR_DEPTH_YCbCr444P;
|
||||
break;
|
||||
|
||||
case DRM_FORMAT_NV12:
|
||||
*format = WIN_COLOR_DEPTH_YCbCr420SP;
|
||||
break;
|
||||
|
||||
case DRM_FORMAT_NV21:
|
||||
*format = WIN_COLOR_DEPTH_YCrCb420SP;
|
||||
break;
|
||||
|
||||
case DRM_FORMAT_NV16:
|
||||
*format = WIN_COLOR_DEPTH_YCbCr422SP;
|
||||
break;
|
||||
|
||||
case DRM_FORMAT_NV61:
|
||||
*format = WIN_COLOR_DEPTH_YCrCb422SP;
|
||||
break;
|
||||
|
||||
case DRM_FORMAT_NV24:
|
||||
*format = WIN_COLOR_DEPTH_YCbCr444SP;
|
||||
break;
|
||||
|
||||
case DRM_FORMAT_NV42:
|
||||
*format = WIN_COLOR_DEPTH_YCrCb444SP;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -441,13 +485,13 @@ bool tegra_plane_format_is_indexed(unsigned int format)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool tegra_plane_format_is_yuv(unsigned int format, bool *planar, unsigned int *bpc)
|
||||
bool tegra_plane_format_is_yuv(unsigned int format, unsigned int *planes, unsigned int *bpc)
|
||||
{
|
||||
switch (format) {
|
||||
case WIN_COLOR_DEPTH_YCbCr422:
|
||||
case WIN_COLOR_DEPTH_YUV422:
|
||||
if (planar)
|
||||
*planar = false;
|
||||
if (planes)
|
||||
*planes = 1;
|
||||
|
||||
if (bpc)
|
||||
*bpc = 8;
|
||||
|
|
@ -462,8 +506,23 @@ bool tegra_plane_format_is_yuv(unsigned int format, bool *planar, unsigned int *
|
|||
case WIN_COLOR_DEPTH_YUV422R:
|
||||
case WIN_COLOR_DEPTH_YCbCr422RA:
|
||||
case WIN_COLOR_DEPTH_YUV422RA:
|
||||
if (planar)
|
||||
*planar = true;
|
||||
case WIN_COLOR_DEPTH_YCbCr444P:
|
||||
if (planes)
|
||||
*planes = 3;
|
||||
|
||||
if (bpc)
|
||||
*bpc = 8;
|
||||
|
||||
return true;
|
||||
|
||||
case WIN_COLOR_DEPTH_YCrCb420SP:
|
||||
case WIN_COLOR_DEPTH_YCbCr420SP:
|
||||
case WIN_COLOR_DEPTH_YCrCb422SP:
|
||||
case WIN_COLOR_DEPTH_YCbCr422SP:
|
||||
case WIN_COLOR_DEPTH_YCrCb444SP:
|
||||
case WIN_COLOR_DEPTH_YCbCr444SP:
|
||||
if (planes)
|
||||
*planes = 2;
|
||||
|
||||
if (bpc)
|
||||
*bpc = 8;
|
||||
|
|
@ -471,8 +530,8 @@ bool tegra_plane_format_is_yuv(unsigned int format, bool *planar, unsigned int *
|
|||
return true;
|
||||
}
|
||||
|
||||
if (planar)
|
||||
*planar = false;
|
||||
if (planes)
|
||||
*planes = 1;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ int tegra_plane_state_add(struct tegra_plane *plane,
|
|||
|
||||
int tegra_plane_format(u32 fourcc, u32 *format, u32 *swap);
|
||||
bool tegra_plane_format_is_indexed(unsigned int format);
|
||||
bool tegra_plane_format_is_yuv(unsigned int format, bool *planar, unsigned int *bpc);
|
||||
bool tegra_plane_format_is_yuv(unsigned int format, unsigned int *planes, unsigned int *bpc);
|
||||
int tegra_plane_setup_legacy_state(struct tegra_plane *tegra,
|
||||
struct tegra_plane_state *state);
|
||||
int tegra_plane_interconnect_init(struct tegra_plane *plane);
|
||||
|
|
|
|||
|
|
@ -447,7 +447,6 @@ static int host1x_probe(struct platform_device *pdev)
|
|||
if (syncpt_irq < 0)
|
||||
return syncpt_irq;
|
||||
|
||||
host1x_bo_cache_init(&host->cache);
|
||||
mutex_init(&host->devices_lock);
|
||||
INIT_LIST_HEAD(&host->devices);
|
||||
INIT_LIST_HEAD(&host->list);
|
||||
|
|
@ -489,10 +488,12 @@ static int host1x_probe(struct platform_device *pdev)
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
host1x_bo_cache_init(&host->cache);
|
||||
|
||||
err = host1x_iommu_init(host);
|
||||
if (err < 0) {
|
||||
dev_err(&pdev->dev, "failed to setup IOMMU: %d\n", err);
|
||||
return err;
|
||||
goto destroy_cache;
|
||||
}
|
||||
|
||||
err = host1x_channel_list_init(&host->channel_list,
|
||||
|
|
@ -553,6 +554,8 @@ static int host1x_probe(struct platform_device *pdev)
|
|||
host1x_channel_list_free(&host->channel_list);
|
||||
iommu_exit:
|
||||
host1x_iommu_exit(host);
|
||||
destroy_cache:
|
||||
host1x_bo_cache_destroy(&host->cache);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
|
@ -568,6 +571,7 @@ static int host1x_remove(struct platform_device *pdev)
|
|||
|
||||
host1x_intr_deinit(host);
|
||||
host1x_syncpt_deinit(host);
|
||||
host1x_channel_list_free(&host->channel_list);
|
||||
host1x_iommu_exit(host);
|
||||
host1x_bo_cache_destroy(&host->cache);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user