summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/tegra
diff options
context:
space:
mode:
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/drm.c12
-rw-r--r--drivers/gpu/drm/tegra/dsi.c9
-rw-r--r--drivers/gpu/drm/tegra/fb.c6
-rw-r--r--drivers/gpu/drm/tegra/gem.c4
-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/plane.c3
-rw-r--r--drivers/gpu/drm/tegra/plane.h3
-rw-r--r--drivers/gpu/drm/tegra/sor.c4
12 files changed, 68 insertions, 31 deletions
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index 04d6848d19fc..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",
@@ -1080,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",
@@ -1169,7 +1197,6 @@ static void tegra_crtc_reset(struct drm_crtc *crtc)
tegra_crtc_atomic_destroy_state(crtc, crtc->state);
__drm_atomic_helper_crtc_reset(crtc, &state->base);
- drm_crtc_vblank_reset(crtc);
}
static struct drm_crtc_state *
@@ -2556,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/drm.c b/drivers/gpu/drm/tegra/drm.c
index 211906347f3f..ba9d1c3e7cac 100644
--- a/drivers/gpu/drm/tegra/drm.c
+++ b/drivers/gpu/drm/tegra/drm.c
@@ -328,7 +328,7 @@ int tegra_drm_submit(struct tegra_drm_context *context,
fail:
while (num_refs--)
- drm_gem_object_put_unlocked(refs[num_refs]);
+ drm_gem_object_put(refs[num_refs]);
kfree(refs);
@@ -368,7 +368,7 @@ static int tegra_gem_mmap(struct drm_device *drm, void *data,
args->offset = drm_vma_node_offset_addr(&bo->gem.vma_node);
- drm_gem_object_put_unlocked(gem);
+ drm_gem_object_put(gem);
return 0;
}
@@ -636,7 +636,7 @@ static int tegra_gem_set_tiling(struct drm_device *drm, void *data,
bo->tiling.mode = mode;
bo->tiling.value = value;
- drm_gem_object_put_unlocked(gem);
+ drm_gem_object_put(gem);
return 0;
}
@@ -676,7 +676,7 @@ static int tegra_gem_get_tiling(struct drm_device *drm, void *data,
break;
}
- drm_gem_object_put_unlocked(gem);
+ drm_gem_object_put(gem);
return err;
}
@@ -701,7 +701,7 @@ static int tegra_gem_set_flags(struct drm_device *drm, void *data,
if (args->flags & DRM_TEGRA_GEM_BOTTOM_UP)
bo->flags |= TEGRA_BO_BOTTOM_UP;
- drm_gem_object_put_unlocked(gem);
+ drm_gem_object_put(gem);
return 0;
}
@@ -723,7 +723,7 @@ static int tegra_gem_get_flags(struct drm_device *drm, void *data,
if (bo->flags & TEGRA_BO_BOTTOM_UP)
args->flags |= DRM_TEGRA_GEM_BOTTOM_UP;
- drm_gem_object_put_unlocked(gem);
+ drm_gem_object_put(gem);
return 0;
}
diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c
index 38beab9ab4f8..3820e8dff14b 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,
@@ -1618,7 +1623,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/fb.c b/drivers/gpu/drm/tegra/fb.c
index 2b0666ac681b..01939c57fc74 100644
--- a/drivers/gpu/drm/tegra/fb.c
+++ b/drivers/gpu/drm/tegra/fb.c
@@ -171,7 +171,7 @@ struct drm_framebuffer *tegra_fb_create(struct drm_device *drm,
unreference:
while (i--)
- drm_gem_object_put_unlocked(&planes[i]->gem);
+ drm_gem_object_put(&planes[i]->gem);
return ERR_PTR(err);
}
@@ -235,7 +235,7 @@ static int tegra_fbdev_probe(struct drm_fb_helper *helper,
info = drm_fb_helper_alloc_fbi(helper);
if (IS_ERR(info)) {
dev_err(drm->dev, "failed to allocate framebuffer info\n");
- drm_gem_object_put_unlocked(&bo->gem);
+ drm_gem_object_put(&bo->gem);
return PTR_ERR(info);
}
@@ -244,7 +244,7 @@ static int tegra_fbdev_probe(struct drm_fb_helper *helper,
err = PTR_ERR(fbdev->fb);
dev_err(drm->dev, "failed to allocate DRM framebuffer: %d\n",
err);
- drm_gem_object_put_unlocked(&bo->gem);
+ drm_gem_object_put(&bo->gem);
return PTR_ERR(fbdev->fb);
}
diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c
index 623768100c6a..723df142a981 100644
--- a/drivers/gpu/drm/tegra/gem.c
+++ b/drivers/gpu/drm/tegra/gem.c
@@ -24,7 +24,7 @@ static void tegra_bo_put(struct host1x_bo *bo)
{
struct tegra_bo *obj = host1x_to_tegra_bo(bo);
- drm_gem_object_put_unlocked(&obj->gem);
+ drm_gem_object_put(&obj->gem);
}
/* XXX move this into lib/scatterlist.c? */
@@ -385,7 +385,7 @@ struct tegra_bo *tegra_bo_create_with_handle(struct drm_file *file,
return ERR_PTR(err);
}
- drm_gem_object_put_unlocked(&bo->gem);
+ drm_gem_object_put(&bo->gem);
return bo;
}
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/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));