Merge 570e257621 ("drm/rockchip: vop: clear DMA stop bit on RK3066") into android12-5.10-lts

Steps on the way to 5.10.227

Change-Id: I91493ff89340657e9b05839438143526a89905e7
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Greg Kroah-Hartman 2024-11-16 10:17:03 +00:00
commit 96a5139526
5 changed files with 103 additions and 37 deletions

View File

@ -9,6 +9,7 @@
#include <linux/delay.h>
#include <linux/iopoll.h>
#include <linux/kernel.h>
#include <linux/log2.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
@ -65,6 +66,9 @@
#define VOP_REG_SET(vop, group, name, v) \
vop_reg_set(vop, &vop->data->group->name, 0, ~0, v, #name)
#define VOP_HAS_REG(vop, group, name) \
(!!(vop->data->group->name.mask))
#define VOP_INTR_SET_TYPE(vop, name, type, v) \
do { \
int i, reg = 0, mask = 0; \
@ -1200,17 +1204,22 @@ static bool vop_dsp_lut_is_enabled(struct vop *vop)
return vop_read_reg(vop, 0, &vop->data->common->dsp_lut_en);
}
static u32 vop_lut_buffer_index(struct vop *vop)
{
return vop_read_reg(vop, 0, &vop->data->common->lut_buffer_index);
}
static void vop_crtc_write_gamma_lut(struct vop *vop, struct drm_crtc *crtc)
{
struct drm_color_lut *lut = crtc->state->gamma_lut->data;
unsigned int i;
unsigned int i, bpc = ilog2(vop->data->lut_size);
for (i = 0; i < crtc->gamma_size; i++) {
u32 word;
word = (drm_color_lut_extract(lut[i].red, 10) << 20) |
(drm_color_lut_extract(lut[i].green, 10) << 10) |
drm_color_lut_extract(lut[i].blue, 10);
word = (drm_color_lut_extract(lut[i].red, bpc) << (2 * bpc)) |
(drm_color_lut_extract(lut[i].green, bpc) << bpc) |
drm_color_lut_extract(lut[i].blue, bpc);
writel(word, vop->lut_regs + i * 4);
}
}
@ -1220,10 +1229,13 @@ static void vop_crtc_gamma_set(struct vop *vop, struct drm_crtc *crtc,
{
struct drm_crtc_state *state = crtc->state;
unsigned int idle;
u32 lut_idx, old_idx;
int ret;
if (!vop->lut_regs)
return;
if (!state->gamma_lut || !VOP_HAS_REG(vop, common, update_gamma_lut)) {
/*
* To disable gamma (gamma_lut is null) or to write
* an update to the LUT, clear dsp_lut_en.
@ -1246,12 +1258,37 @@ static void vop_crtc_gamma_set(struct vop *vop, struct drm_crtc *crtc,
if (!state->gamma_lut)
return;
} else {
/*
* On RK3399 the gamma LUT can updated without clearing dsp_lut_en,
* by setting update_gamma_lut then waiting for lut_buffer_index change
*/
old_idx = vop_lut_buffer_index(vop);
}
spin_lock(&vop->reg_lock);
vop_crtc_write_gamma_lut(vop, crtc);
VOP_REG_SET(vop, common, dsp_lut_en, 1);
VOP_REG_SET(vop, common, update_gamma_lut, 1);
vop_cfg_done(vop);
spin_unlock(&vop->reg_lock);
if (VOP_HAS_REG(vop, common, update_gamma_lut)) {
ret = readx_poll_timeout(vop_lut_buffer_index, vop,
lut_idx, lut_idx != old_idx, 5, 30 * 1000);
if (ret) {
DRM_DEV_ERROR(vop->dev, "gamma LUT update timeout!\n");
return;
}
/*
* update_gamma_lut is auto cleared by HW, but write 0 to clear the bit
* in our backup of the regs.
*/
spin_lock(&vop->reg_lock);
VOP_REG_SET(vop, common, update_gamma_lut, 0);
spin_unlock(&vop->reg_lock);
}
}
static void vop_crtc_atomic_begin(struct drm_crtc *crtc,
@ -1295,14 +1332,6 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc,
return;
}
/*
* If we have a GAMMA LUT in the state, then let's make sure
* it's updated. We might be coming out of suspend,
* which means the LUT internal memory needs to be re-written.
*/
if (crtc->state->gamma_lut)
vop_crtc_gamma_set(vop, crtc, old_state);
mutex_lock(&vop->vop_lock);
WARN_ON(vop->event);
@ -1393,6 +1422,14 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc,
VOP_REG_SET(vop, common, standby, 0);
mutex_unlock(&vop->vop_lock);
/*
* If we have a GAMMA LUT in the state, then let's make sure
* it's updated. We might be coming out of suspend,
* which means the LUT internal memory needs to be re-written.
*/
if (crtc->state->gamma_lut)
vop_crtc_gamma_set(vop, crtc, old_state);
}
static bool vop_fs_irq_is_pending(struct vop *vop)
@ -1486,6 +1523,10 @@ static void vop_crtc_atomic_flush(struct drm_crtc *crtc,
VOP_AFBC_SET(vop, enable, s->enable_afbc);
vop_cfg_done(vop);
/* Ack the DMA transfer of the previous frame (RK3066). */
if (VOP_HAS_REG(vop, common, dma_stop))
VOP_REG_SET(vop, common, dma_stop, 0);
spin_unlock(&vop->reg_lock);
/*
@ -2119,8 +2160,8 @@ static int vop_bind(struct device *dev, struct device *master, void *data)
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
if (res) {
if (!vop_data->lut_size) {
DRM_DEV_ERROR(dev, "no gamma LUT size defined\n");
if (vop_data->lut_size != 1024 && vop_data->lut_size != 256) {
DRM_DEV_ERROR(dev, "unsupported gamma LUT size %d\n", vop_data->lut_size);
return -EINVAL;
}
vop->lut_regs = devm_ioremap_resource(dev, res);

View File

@ -99,8 +99,11 @@ struct vop_common {
struct vop_reg dither_down_en;
struct vop_reg dither_up;
struct vop_reg dsp_lut_en;
struct vop_reg update_gamma_lut;
struct vop_reg lut_buffer_index;
struct vop_reg gate_en;
struct vop_reg mmu_en;
struct vop_reg dma_stop;
struct vop_reg out_mode;
struct vop_reg standby;
};

View File

@ -401,6 +401,7 @@ static const struct vop_output rk3066_output = {
};
static const struct vop_common rk3066_common = {
.dma_stop = VOP_REG(RK3066_SYS_CTRL0, 0x1, 0),
.standby = VOP_REG(RK3066_SYS_CTRL0, 0x1, 1),
.out_mode = VOP_REG(RK3066_DSP_CTRL0, 0xf, 0),
.cfg_done = VOP_REG(RK3066_REG_CFG_DONE, 0x1, 0),
@ -836,6 +837,24 @@ static const struct vop_output rk3399_output = {
.mipi_dual_channel_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 3),
};
static const struct vop_common rk3399_common = {
.standby = VOP_REG_SYNC(RK3399_SYS_CTRL, 0x1, 22),
.gate_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 23),
.mmu_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 20),
.dither_down_sel = VOP_REG(RK3399_DSP_CTRL1, 0x1, 4),
.dither_down_mode = VOP_REG(RK3399_DSP_CTRL1, 0x1, 3),
.dither_down_en = VOP_REG(RK3399_DSP_CTRL1, 0x1, 2),
.pre_dither_down = VOP_REG(RK3399_DSP_CTRL1, 0x1, 1),
.dither_up = VOP_REG(RK3399_DSP_CTRL1, 0x1, 6),
.dsp_lut_en = VOP_REG(RK3399_DSP_CTRL1, 0x1, 0),
.update_gamma_lut = VOP_REG(RK3399_DSP_CTRL1, 0x1, 7),
.lut_buffer_index = VOP_REG(RK3399_DBG_POST_REG1, 0x1, 1),
.data_blank = VOP_REG(RK3399_DSP_CTRL0, 0x1, 19),
.dsp_blank = VOP_REG(RK3399_DSP_CTRL0, 0x3, 18),
.out_mode = VOP_REG(RK3399_DSP_CTRL0, 0xf, 0),
.cfg_done = VOP_REG_SYNC(RK3399_REG_CFG_DONE, 0x1, 0),
};
static const struct vop_yuv2yuv_phy rk3399_yuv2yuv_win01_data = {
.y2r_coefficients = {
VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 0, 0xffff, 0),
@ -917,7 +936,7 @@ static const struct vop_data rk3399_vop_big = {
.version = VOP_VERSION(3, 5),
.feature = VOP_FEATURE_OUTPUT_RGB10,
.intr = &rk3366_vop_intr,
.common = &rk3288_common,
.common = &rk3399_common,
.modeset = &rk3288_modeset,
.output = &rk3399_output,
.afbc = &rk3399_vop_afbc,
@ -925,6 +944,7 @@ static const struct vop_data rk3399_vop_big = {
.win = rk3399_vop_win_data,
.win_size = ARRAY_SIZE(rk3399_vop_win_data),
.win_yuv2yuv = rk3399_vop_big_win_yuv2yuv_data,
.lut_size = 1024,
};
static const struct vop_win_data rk3399_vop_lit_win_data[] = {
@ -943,13 +963,14 @@ static const struct vop_win_yuv2yuv_data rk3399_vop_lit_win_yuv2yuv_data[] = {
static const struct vop_data rk3399_vop_lit = {
.version = VOP_VERSION(3, 6),
.intr = &rk3366_vop_intr,
.common = &rk3288_common,
.common = &rk3399_common,
.modeset = &rk3288_modeset,
.output = &rk3399_output,
.misc = &rk3368_misc,
.win = rk3399_vop_lit_win_data,
.win_size = ARRAY_SIZE(rk3399_vop_lit_win_data),
.win_yuv2yuv = rk3399_vop_lit_win_yuv2yuv_data,
.lut_size = 256,
};
static const struct vop_win_data rk3228_vop_win_data[] = {

View File

@ -628,6 +628,7 @@
#define RK3399_YUV2YUV_WIN 0x02c0
#define RK3399_YUV2YUV_POST 0x02c4
#define RK3399_AUTO_GATING_EN 0x02cc
#define RK3399_DBG_POST_REG1 0x036c
#define RK3399_WIN0_CSC_COE 0x03a0
#define RK3399_WIN1_CSC_COE 0x03c0
#define RK3399_WIN2_CSC_COE 0x03e0

View File

@ -1500,7 +1500,7 @@ static struct xol_area *__create_xol_area(unsigned long vaddr)
area->xol_mapping.name = "[uprobes]";
area->xol_mapping.pages = area->pages;
area->pages[0] = alloc_page(GFP_HIGHUSER);
area->pages[0] = alloc_page(GFP_HIGHUSER | __GFP_ZERO);
if (!area->pages[0])
goto free_bitmap;
area->pages[1] = NULL;