summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/tegra
diff options
context:
space:
mode:
authorThomas Zimmermann <tzimmermann@suse.de>2020-08-12 20:17:18 +0300
committerThomas Zimmermann <tzimmermann@suse.de>2020-08-12 21:42:08 +0300
commit534b1f9071d95325044c21d47d9f63a45cdf425e (patch)
tree5c2aa3cd65bfb6b9e73d9ad22c021d800380f0f6 /drivers/gpu/drm/tegra
parent82dd18096c718962379e61cd8a7a0dc219db174f (diff)
parent62975d27d647a40c58d3b96c29b911fc4f33c310 (diff)
downloadlinux-534b1f9071d95325044c21d47d9f63a45cdf425e.tar.xz
Merge drm/drm-next into drm-misc-next
Backmerging drm-next into drm-misc-next for nouveau and panel updates. Resolves a conflict between ttm and nouveau, where struct ttm_mem_res got renamed to struct ttm_resource. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Diffstat (limited to 'drivers/gpu/drm/tegra')
-rw-r--r--drivers/gpu/drm/tegra/dc.c51
-rw-r--r--drivers/gpu/drm/tegra/dc.h3
-rw-r--r--drivers/gpu/drm/tegra/dsi.c9
-rw-r--r--drivers/gpu/drm/tegra/gr2d.c1
-rw-r--r--drivers/gpu/drm/tegra/gr2d.h1
-rw-r--r--drivers/gpu/drm/tegra/gr3d.c2
-rw-r--r--drivers/gpu/drm/tegra/hub.c17
-rw-r--r--drivers/gpu/drm/tegra/plane.c3
-rw-r--r--drivers/gpu/drm/tegra/plane.h3
-rw-r--r--drivers/gpu/drm/tegra/sor.c4
10 files changed, 73 insertions, 21 deletions
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index 9b308b572eac..9a0b3240bc58 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -368,6 +368,12 @@ static void tegra_dc_setup_window(struct tegra_plane *plane,
h_size = window->src.w * bpp;
v_size = window->src.h;
+ if (window->reflect_x)
+ h_offset += (window->src.w - 1) * bpp;
+
+ if (window->reflect_y)
+ v_offset += window->src.h - 1;
+
value = V_PRESCALED_SIZE(v_size) | H_PRESCALED_SIZE(h_size);
tegra_plane_writel(plane, value, DC_WIN_PRESCALED_SIZE);
@@ -404,9 +410,6 @@ static void tegra_dc_setup_window(struct tegra_plane *plane,
tegra_plane_writel(plane, window->stride[0], DC_WIN_LINE_STRIDE);
}
- if (window->bottom_up)
- v_offset += window->src.h - 1;
-
tegra_plane_writel(plane, h_offset, DC_WINBUF_ADDR_H_OFFSET);
tegra_plane_writel(plane, v_offset, DC_WINBUF_ADDR_V_OFFSET);
@@ -470,7 +473,10 @@ static void tegra_dc_setup_window(struct tegra_plane *plane,
value |= COLOR_EXPAND;
}
- if (window->bottom_up)
+ if (window->reflect_x)
+ value |= H_DIRECTION;
+
+ if (window->reflect_y)
value |= V_DIRECTION;
if (tegra_plane_use_horizontal_filtering(plane, window)) {
@@ -601,7 +607,10 @@ static int tegra_plane_atomic_check(struct drm_plane *plane,
struct drm_plane_state *state)
{
struct tegra_plane_state *plane_state = to_tegra_plane_state(state);
- unsigned int rotation = DRM_MODE_ROTATE_0 | DRM_MODE_REFLECT_Y;
+ unsigned int supported_rotation = DRM_MODE_ROTATE_0 |
+ DRM_MODE_REFLECT_X |
+ DRM_MODE_REFLECT_Y;
+ unsigned int rotation = state->rotation;
struct tegra_bo_tiling *tiling = &plane_state->tiling;
struct tegra_plane *tegra = to_tegra_plane(plane);
struct tegra_dc *dc = to_tegra_dc(state->crtc);
@@ -639,12 +648,26 @@ static int tegra_plane_atomic_check(struct drm_plane *plane,
return -EINVAL;
}
- rotation = drm_rotation_simplify(state->rotation, rotation);
+ /*
+ * Older userspace used custom BO flag in order to specify the Y
+ * reflection, while modern userspace uses the generic DRM rotation
+ * property in order to achieve the same result. The legacy BO flag
+ * duplicates the DRM rotation property when both are set.
+ */
+ if (tegra_fb_is_bottom_up(state->fb))
+ rotation |= DRM_MODE_REFLECT_Y;
+
+ rotation = drm_rotation_simplify(rotation, supported_rotation);
+
+ if (rotation & DRM_MODE_REFLECT_X)
+ plane_state->reflect_x = true;
+ else
+ plane_state->reflect_x = false;
if (rotation & DRM_MODE_REFLECT_Y)
- plane_state->bottom_up = true;
+ plane_state->reflect_y = true;
else
- plane_state->bottom_up = false;
+ plane_state->reflect_y = false;
/*
* Tegra doesn't support different strides for U and V planes so we
@@ -706,7 +729,8 @@ static void tegra_plane_atomic_update(struct drm_plane *plane,
window.dst.w = drm_rect_width(&plane->state->dst);
window.dst.h = drm_rect_height(&plane->state->dst);
window.bits_per_pixel = fb->format->cpp[0] * 8;
- window.bottom_up = tegra_fb_is_bottom_up(fb) || state->bottom_up;
+ window.reflect_x = state->reflect_x;
+ window.reflect_y = state->reflect_y;
/* copy from state */
window.zpos = plane->state->normalized_zpos;
@@ -792,6 +816,8 @@ static struct drm_plane *tegra_primary_plane_create(struct drm_device *drm,
err = drm_plane_create_rotation_property(&plane->base,
DRM_MODE_ROTATE_0,
DRM_MODE_ROTATE_0 |
+ DRM_MODE_ROTATE_180 |
+ DRM_MODE_REFLECT_X |
DRM_MODE_REFLECT_Y);
if (err < 0)
dev_err(dc->dev, "failed to create rotation property: %d\n",
@@ -957,6 +983,7 @@ static struct drm_plane *tegra_dc_cursor_plane_create(struct drm_device *drm,
}
drm_plane_helper_add(&plane->base, &tegra_cursor_plane_helper_funcs);
+ drm_plane_create_zpos_immutable_property(&plane->base, 255);
return &plane->base;
}
@@ -1079,6 +1106,8 @@ static struct drm_plane *tegra_dc_overlay_plane_create(struct drm_device *drm,
err = drm_plane_create_rotation_property(&plane->base,
DRM_MODE_ROTATE_0,
DRM_MODE_ROTATE_0 |
+ DRM_MODE_ROTATE_180 |
+ DRM_MODE_REFLECT_X |
DRM_MODE_REFLECT_Y);
if (err < 0)
dev_err(dc->dev, "failed to create rotation property: %d\n",
@@ -2554,10 +2583,8 @@ static int tegra_dc_probe(struct platform_device *pdev)
return PTR_ERR(dc->regs);
dc->irq = platform_get_irq(pdev, 0);
- if (dc->irq < 0) {
- dev_err(&pdev->dev, "failed to get IRQ\n");
+ if (dc->irq < 0)
return -ENXIO;
- }
err = tegra_dc_rgb_probe(dc);
if (err < 0 && err != -ENODEV) {
diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/drm/tegra/dc.h
index 3d8ddccd758f..051d03dcb9b0 100644
--- a/drivers/gpu/drm/tegra/dc.h
+++ b/drivers/gpu/drm/tegra/dc.h
@@ -136,7 +136,8 @@ struct tegra_dc_window {
unsigned int stride[2];
unsigned long base[3];
unsigned int zpos;
- bool bottom_up;
+ bool reflect_x;
+ bool reflect_y;
struct tegra_bo_tiling tiling;
u32 format;
diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c
index 37b89c396d3b..3387de79718b 100644
--- a/drivers/gpu/drm/tegra/dsi.c
+++ b/drivers/gpu/drm/tegra/dsi.c
@@ -670,6 +670,7 @@ static int tegra_dsi_pad_enable(struct tegra_dsi *dsi)
static int tegra_dsi_pad_calibrate(struct tegra_dsi *dsi)
{
u32 value;
+ int err;
/*
* XXX Is this still needed? The module reset is deasserted right
@@ -693,7 +694,11 @@ static int tegra_dsi_pad_calibrate(struct tegra_dsi *dsi)
DSI_PAD_PREEMP_PD(0x03) | DSI_PAD_PREEMP_PU(0x3);
tegra_dsi_writel(dsi, value, DSI_PAD_CONTROL_3);
- return tegra_mipi_calibrate(dsi->mipi);
+ err = tegra_mipi_calibrate(dsi->mipi);
+ if (err < 0)
+ return err;
+
+ return tegra_mipi_wait(dsi->mipi);
}
static void tegra_dsi_set_timeout(struct tegra_dsi *dsi, unsigned long bclk,
@@ -1616,7 +1621,7 @@ static int tegra_dsi_probe(struct platform_device *pdev)
if (IS_ERR(dsi->regs))
return PTR_ERR(dsi->regs);
- dsi->mipi = tegra_mipi_request(&pdev->dev);
+ dsi->mipi = tegra_mipi_request(&pdev->dev, pdev->dev.of_node);
if (IS_ERR(dsi->mipi))
return PTR_ERR(dsi->mipi);
diff --git a/drivers/gpu/drm/tegra/gr2d.c b/drivers/gpu/drm/tegra/gr2d.c
index 48363f744bb9..1a0d3ba6e525 100644
--- a/drivers/gpu/drm/tegra/gr2d.c
+++ b/drivers/gpu/drm/tegra/gr2d.c
@@ -177,6 +177,7 @@ static const u32 gr2d_addr_regs[] = {
GR2D_DSTC_BASE_ADDR,
GR2D_SRCA_BASE_ADDR,
GR2D_SRCB_BASE_ADDR,
+ GR2D_PATBASE_ADDR,
GR2D_SRC_BASE_ADDR_SB,
GR2D_DSTA_BASE_ADDR_SB,
GR2D_DSTB_BASE_ADDR_SB,
diff --git a/drivers/gpu/drm/tegra/gr2d.h b/drivers/gpu/drm/tegra/gr2d.h
index 2398486f0699..9b7d66e15b9f 100644
--- a/drivers/gpu/drm/tegra/gr2d.h
+++ b/drivers/gpu/drm/tegra/gr2d.h
@@ -14,6 +14,7 @@
#define GR2D_DSTC_BASE_ADDR 0x2d
#define GR2D_SRCA_BASE_ADDR 0x31
#define GR2D_SRCB_BASE_ADDR 0x32
+#define GR2D_PATBASE_ADDR 0x47
#define GR2D_SRC_BASE_ADDR_SB 0x48
#define GR2D_DSTA_BASE_ADDR_SB 0x49
#define GR2D_DSTB_BASE_ADDR_SB 0x4a
diff --git a/drivers/gpu/drm/tegra/gr3d.c b/drivers/gpu/drm/tegra/gr3d.c
index c0a528be0369..b0b8154e8104 100644
--- a/drivers/gpu/drm/tegra/gr3d.c
+++ b/drivers/gpu/drm/tegra/gr3d.c
@@ -381,10 +381,12 @@ static int gr3d_remove(struct platform_device *pdev)
}
if (gr3d->clk_secondary) {
+ reset_control_assert(gr3d->rst_secondary);
tegra_powergate_power_off(TEGRA_POWERGATE_3D1);
clk_disable_unprepare(gr3d->clk_secondary);
}
+ reset_control_assert(gr3d->rst);
tegra_powergate_power_off(TEGRA_POWERGATE_3D);
clk_disable_unprepare(gr3d->clk);
diff --git a/drivers/gpu/drm/tegra/hub.c b/drivers/gpu/drm/tegra/hub.c
index 8183e617bf6b..22a03f7ffdc1 100644
--- a/drivers/gpu/drm/tegra/hub.c
+++ b/drivers/gpu/drm/tegra/hub.c
@@ -149,7 +149,9 @@ int tegra_display_hub_prepare(struct tegra_display_hub *hub)
for (i = 0; i < hub->soc->num_wgrps; i++) {
struct tegra_windowgroup *wgrp = &hub->wgrps[i];
- tegra_windowgroup_enable(wgrp);
+ /* Skip orphaned window group whose parent DC is disabled */
+ if (wgrp->parent)
+ tegra_windowgroup_enable(wgrp);
}
return 0;
@@ -166,7 +168,9 @@ void tegra_display_hub_cleanup(struct tegra_display_hub *hub)
for (i = 0; i < hub->soc->num_wgrps; i++) {
struct tegra_windowgroup *wgrp = &hub->wgrps[i];
- tegra_windowgroup_disable(wgrp);
+ /* Skip orphaned window group whose parent DC is disabled */
+ if (wgrp->parent)
+ tegra_windowgroup_disable(wgrp);
}
}
@@ -944,6 +948,15 @@ static int tegra_display_hub_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "failed to register host1x client: %d\n",
err);
+ err = devm_of_platform_populate(&pdev->dev);
+ if (err < 0)
+ goto unregister;
+
+ return err;
+
+unregister:
+ host1x_client_unregister(&hub->client);
+ pm_runtime_disable(&pdev->dev);
return err;
}
diff --git a/drivers/gpu/drm/tegra/plane.c b/drivers/gpu/drm/tegra/plane.c
index 9ccfb56e9b01..4cd0461cc508 100644
--- a/drivers/gpu/drm/tegra/plane.c
+++ b/drivers/gpu/drm/tegra/plane.c
@@ -61,7 +61,8 @@ tegra_plane_atomic_duplicate_state(struct drm_plane *plane)
copy->tiling = state->tiling;
copy->format = state->format;
copy->swap = state->swap;
- copy->bottom_up = state->bottom_up;
+ copy->reflect_x = state->reflect_x;
+ copy->reflect_y = state->reflect_y;
copy->opaque = state->opaque;
for (i = 0; i < 2; i++)
diff --git a/drivers/gpu/drm/tegra/plane.h b/drivers/gpu/drm/tegra/plane.h
index a158a915109a..c691dd79b27b 100644
--- a/drivers/gpu/drm/tegra/plane.h
+++ b/drivers/gpu/drm/tegra/plane.h
@@ -46,7 +46,8 @@ struct tegra_plane_state {
u32 format;
u32 swap;
- bool bottom_up;
+ bool reflect_x;
+ bool reflect_y;
/* used for legacy blending support only */
struct tegra_plane_legacy_blending_state blending[2];
diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c
index 7cbcf9617f5e..45b5258c77a2 100644
--- a/drivers/gpu/drm/tegra/sor.c
+++ b/drivers/gpu/drm/tegra/sor.c
@@ -2946,7 +2946,7 @@ static int tegra_sor_hdmi_probe(struct tegra_sor *sor)
{
int err;
- sor->avdd_io_supply = devm_regulator_get(sor->dev, "avdd-io");
+ sor->avdd_io_supply = devm_regulator_get(sor->dev, "avdd-io-hdmi-dp");
if (IS_ERR(sor->avdd_io_supply)) {
dev_err(sor->dev, "cannot get AVDD I/O supply: %ld\n",
PTR_ERR(sor->avdd_io_supply));
@@ -2960,7 +2960,7 @@ static int tegra_sor_hdmi_probe(struct tegra_sor *sor)
return err;
}
- sor->vdd_pll_supply = devm_regulator_get(sor->dev, "vdd-pll");
+ sor->vdd_pll_supply = devm_regulator_get(sor->dev, "vdd-hdmi-dp-pll");
if (IS_ERR(sor->vdd_pll_supply)) {
dev_err(sor->dev, "cannot get VDD PLL supply: %ld\n",
PTR_ERR(sor->vdd_pll_supply));