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:
commit
96a5139526
@ -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);
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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[] = {
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user