* [PATCH 1/3] drm/rockchip: vop: move dma_addr to plane atomic check
@ 2016-09-10 2:29 Mark Yao
2016-09-10 2:29 ` [PATCH 2/3] drm: add ARM vendor format afbc Mark Yao
2016-09-10 2:29 ` [PATCH 3/3] drm/rockchip: vop: support afdc for rk3399 vop Mark Yao
0 siblings, 2 replies; 7+ messages in thread
From: Mark Yao @ 2016-09-10 2:29 UTC (permalink / raw)
To: linux-arm-kernel
Calc dma_addr earlier, then the dma_addr can be used on
crtc atomic check.
Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
---
drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 52 ++++++++++++++++-------------
1 file changed, 29 insertions(+), 23 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 3321115..834456f 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -91,6 +91,7 @@ struct vop_plane_state {
struct drm_plane_state base;
int format;
dma_addr_t yrgb_mst;
+ dma_addr_t uv_mst;
bool enable;
};
@@ -589,12 +590,16 @@ static int vop_plane_atomic_check(struct drm_plane *plane,
struct vop_win *vop_win = to_vop_win(plane);
struct vop_plane_state *vop_plane_state = to_vop_plane_state(state);
const struct vop_win_data *win = vop_win->data;
+ struct drm_gem_object *obj, *uv_obj;
+ struct rockchip_gem_object *rk_obj, *rk_uv_obj;
int ret;
+ struct drm_rect *src = &state->src;
struct drm_rect clip;
int min_scale = win->phy->scl ? FRAC_16_16(1, 8) :
DRM_PLANE_HELPER_NO_SCALING;
int max_scale = win->phy->scl ? FRAC_16_16(8, 1) :
DRM_PLANE_HELPER_NO_SCALING;
+ unsigned long offset;
if (!crtc || !fb)
goto out_disable;
@@ -628,6 +633,29 @@ static int vop_plane_atomic_check(struct drm_plane *plane,
if (is_yuv_support(fb->pixel_format) && ((state->src.x1 >> 16) % 2))
return -EINVAL;
+ obj = rockchip_fb_get_gem_obj(fb, 0);
+ rk_obj = to_rockchip_obj(obj);
+
+ offset = (src->x1 >> 16) * drm_format_plane_cpp(fb->pixel_format, 0);
+ offset += (src->y1 >> 16) * fb->pitches[0];
+ offset += fb->offsets[0];
+ vop_plane_state->yrgb_mst = rk_obj->dma_addr + offset;
+
+ if (is_yuv_support(fb->pixel_format)) {
+ int hsub = drm_format_horz_chroma_subsampling(fb->pixel_format);
+ int vsub = drm_format_vert_chroma_subsampling(fb->pixel_format);
+ int bpp = drm_format_plane_cpp(fb->pixel_format, 1);
+
+ uv_obj = rockchip_fb_get_gem_obj(fb, 1);
+ rk_uv_obj = to_rockchip_obj(uv_obj);
+
+ offset = (src->x1 >> 16) * bpp / hsub;
+ offset += (src->y1 >> 16) * fb->pitches[1] / vsub;
+ offset += fb->offsets[1];
+
+ vop_plane_state->uv_mst = rk_uv_obj->dma_addr + offset;
+ }
+
vop_plane_state->enable = true;
return 0;
@@ -677,10 +705,6 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
uint32_t act_info, dsp_info, dsp_st;
struct drm_rect *src = &state->src;
struct drm_rect *dest = &state->dst;
- struct drm_gem_object *obj, *uv_obj;
- struct rockchip_gem_object *rk_obj, *rk_uv_obj;
- unsigned long offset;
- dma_addr_t dma_addr;
uint32_t val;
bool rb_swap;
@@ -698,9 +722,6 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
return;
}
- obj = rockchip_fb_get_gem_obj(fb, 0);
- rk_obj = to_rockchip_obj(obj);
-
actual_w = drm_rect_width(src) >> 16;
actual_h = drm_rect_height(src) >> 16;
act_info = (actual_h - 1) << 16 | ((actual_w - 1) & 0xffff);
@@ -712,10 +733,6 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
dsp_sty = dest->y1 + crtc->mode.vtotal - crtc->mode.vsync_start;
dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff);
- offset = (src->x1 >> 16) * drm_format_plane_cpp(fb->pixel_format, 0);
- offset += (src->y1 >> 16) * fb->pitches[0];
- vop_plane_state->yrgb_mst = rk_obj->dma_addr + offset + fb->offsets[0];
-
spin_lock_irq(&plane->dev->event_lock);
vop_win->enable = true;
vop_win->yrgb_mst = vop_plane_state->yrgb_mst;
@@ -727,19 +744,8 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
VOP_WIN_SET(vop, win, yrgb_vir, fb->pitches[0] >> 2);
VOP_WIN_SET(vop, win, yrgb_mst, vop_plane_state->yrgb_mst);
if (is_yuv_support(fb->pixel_format)) {
- int hsub = drm_format_horz_chroma_subsampling(fb->pixel_format);
- int vsub = drm_format_vert_chroma_subsampling(fb->pixel_format);
- int bpp = drm_format_plane_cpp(fb->pixel_format, 1);
-
- uv_obj = rockchip_fb_get_gem_obj(fb, 1);
- rk_uv_obj = to_rockchip_obj(uv_obj);
-
- offset = (src->x1 >> 16) * bpp / hsub;
- offset += (src->y1 >> 16) * fb->pitches[1] / vsub;
-
- dma_addr = rk_uv_obj->dma_addr + offset + fb->offsets[1];
VOP_WIN_SET(vop, win, uv_vir, fb->pitches[1] >> 2);
- VOP_WIN_SET(vop, win, uv_mst, dma_addr);
+ VOP_WIN_SET(vop, win, uv_mst, vop_plane_state->uv_mst);
}
if (win->phy->scl)
--
1.9.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/3] drm: add ARM vendor format afbc
2016-09-10 2:29 [PATCH 1/3] drm/rockchip: vop: move dma_addr to plane atomic check Mark Yao
@ 2016-09-10 2:29 ` Mark Yao
2016-09-13 14:13 ` Brian Starkey
2016-09-10 2:29 ` [PATCH 3/3] drm/rockchip: vop: support afdc for rk3399 vop Mark Yao
1 sibling, 1 reply; 7+ messages in thread
From: Mark Yao @ 2016-09-10 2:29 UTC (permalink / raw)
To: linux-arm-kernel
AFBC is arm vendor format, it's a compressed format.
The AFBC format is supported by rk3399 vop big.
We know little about AFBC layout, hope to some guys can
fixme about the afbc comment.
Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
---
include/uapi/drm/drm_fourcc.h | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index a5890bf..9a47d7e 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -159,6 +159,7 @@ extern "C" {
#define DRM_FORMAT_MOD_VENDOR_NV 0x03
#define DRM_FORMAT_MOD_VENDOR_SAMSUNG 0x04
#define DRM_FORMAT_MOD_VENDOR_QCOM 0x05
+#define DRM_FORMAT_MOD_VENDOR_ARM 0x06
/* add more to the end as needed */
#define fourcc_mod_code(vendor, val) \
@@ -233,6 +234,12 @@ extern "C" {
*/
#define DRM_FORMAT_MOD_SAMSUNG_64_32_TILE fourcc_mod_code(SAMSUNG, 1)
+/*
+ * FIXME: AFBC is arm vendor format, it's a compressed format.
+ *
+ */
+#define DRM_FORMAT_MOD_ARM_AFBC fourcc_mod_code(ARM, 1)
+
#if defined(__cplusplus)
}
#endif
--
1.9.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 3/3] drm/rockchip: vop: support afdc for rk3399 vop
2016-09-10 2:29 [PATCH 1/3] drm/rockchip: vop: move dma_addr to plane atomic check Mark Yao
2016-09-10 2:29 ` [PATCH 2/3] drm: add ARM vendor format afbc Mark Yao
@ 2016-09-10 2:29 ` Mark Yao
2016-09-10 3:07 ` [PATCH] drm/rockchip: vop: support afbc format " Mark Yao
2016-09-10 3:10 ` [PATCH 3/3 v1.1] " Mark Yao
1 sibling, 2 replies; 7+ messages in thread
From: Mark Yao @ 2016-09-10 2:29 UTC (permalink / raw)
To: linux-arm-kernel
Rk3399 vop big can support one afbc decoder, the afbdc decoder
can select which overlay window use it.
afbdc window has some limit:
1, not support offset on source buffer.
2, if feed non-afbc buffer to afbc decoder, afbc decoder hardware
would die, we need take care of using it.
AFBC is a compressed format, means lower bandwidth consume,
it's useful to improve performance.
Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
---
drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 6 ++
drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 89 +++++++++++++++++++++++++++++
drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 13 +++++
drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 7 +++
4 files changed, 115 insertions(+)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index ea39329..1e07fd6 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -44,6 +44,12 @@ struct rockchip_crtc_funcs {
struct rockchip_crtc_state {
struct drm_crtc_state base;
+ int afbdc_win_format;
+ int afbdc_win_width;
+ int afbdc_win_height;
+ int afbdc_win_ptr;
+ int afbdc_win_id;
+ int afbdc_en;
int output_type;
int output_mode;
};
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 834456f..6918223 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -99,6 +99,7 @@ struct vop_win {
struct drm_plane base;
const struct vop_win_data *data;
struct vop *vop;
+ int id;
/* protected by dev->event_lock */
bool enable;
@@ -514,6 +515,7 @@ static void vop_crtc_disable(struct drm_crtc *crtc)
VOP_WIN_SET(vop, win, enable, 0);
spin_unlock(&vop->reg_lock);
}
+ VOP_CTRL_SET(vop, afbdc_en, 0);
drm_crtc_vblank_off(crtc);
@@ -1007,9 +1009,81 @@ static void vop_crtc_enable(struct drm_crtc *crtc)
VOP_CTRL_SET(vop, standby, 0);
}
+static int vop_afbdc_atomic_check(struct drm_crtc *crtc,
+ struct drm_crtc_state *crtc_state)
+{
+ struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
+ struct drm_atomic_state *state = crtc_state->state;
+ struct drm_plane *plane;
+ struct drm_plane_state *pstate;
+ struct vop_plane_state *plane_state;
+ struct vop_win *win;
+ int afbdc_format;
+ int i;
+
+ s->afbdc_en = 0;
+
+ for_each_plane_in_state(state, plane, pstate, i) {
+ struct drm_framebuffer *fb = pstate->fb;
+ struct drm_rect *src;
+
+ win = to_vop_win(plane);
+ plane_state = to_vop_plane_state(pstate);
+
+ if (pstate->crtc != crtc || !fb)
+ continue;
+
+ if (fb->modifier[0] != DRM_FORMAT_MOD_ARM_AFBC)
+ continue;
+
+ switch (plane_state->format) {
+ case VOP_FMT_ARGB8888:
+ afbdc_format = AFBDC_FMT_U8U8U8U8;
+ break;
+ case VOP_FMT_RGB888:
+ afbdc_format = AFBDC_FMT_U8U8U8;
+ break;
+ case VOP_FMT_RGB565:
+ afbdc_format = AFBDC_FMT_RGB565;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (s->afbdc_en) {
+ DRM_ERROR("vop only support one afbc layer\n");
+ return -EINVAL;
+ }
+
+ src = &pstate->src;
+ if (src->x1 || src->y1 || fb->offsets[0]) {
+ DRM_ERROR("win[%d] afbdc not support offset display\n",
+ win->id);
+ DRM_ERROR("xpos=%d, ypos=%d, offset=%d\n",
+ src->x1, src->y1, fb->offsets[0]);
+ return -EINVAL;
+ }
+ s->afbdc_win_format = afbdc_format;
+ s->afbdc_win_width = pstate->fb->width - 1;
+ s->afbdc_win_height = (drm_rect_height(src) >> 16) - 1;
+ s->afbdc_win_id = win->id;
+ s->afbdc_win_ptr = plane_state->yrgb_mst;
+ s->afbdc_en = 1;
+ }
+
+ return 0;
+}
+
+static int vop_crtc_atomic_check(struct drm_crtc *crtc,
+ struct drm_crtc_state *crtc_state)
+{
+ return vop_afbdc_atomic_check(crtc, crtc_state);
+}
+
static void vop_crtc_atomic_flush(struct drm_crtc *crtc,
struct drm_crtc_state *old_crtc_state)
{
+ struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc->state);
struct vop *vop = to_vop(crtc);
if (WARN_ON(!vop->is_enabled))
@@ -1017,6 +1091,19 @@ static void vop_crtc_atomic_flush(struct drm_crtc *crtc,
spin_lock(&vop->reg_lock);
+ if (s->afbdc_en) {
+ uint32_t pic_size;
+
+ VOP_CTRL_SET(vop, afbdc_format, s->afbdc_win_format | 1 << 4);
+ VOP_CTRL_SET(vop, afbdc_hreg_block_split, 0);
+ VOP_CTRL_SET(vop, afbdc_sel, s->afbdc_win_id);
+ VOP_CTRL_SET(vop, afbdc_hdr_ptr, s->afbdc_win_ptr);
+ pic_size = (s->afbdc_win_width & 0xffff);
+ pic_size |= s->afbdc_win_height << 16;
+ VOP_CTRL_SET(vop, afbdc_pic_size, pic_size);
+ }
+
+ VOP_CTRL_SET(vop, afbdc_en, s->afbdc_en);
vop_cfg_done(vop);
spin_unlock(&vop->reg_lock);
@@ -1042,6 +1129,7 @@ static const struct drm_crtc_helper_funcs vop_crtc_helper_funcs = {
.enable = vop_crtc_enable,
.disable = vop_crtc_disable,
.mode_fixup = vop_crtc_mode_fixup,
+ .atomic_check = vop_crtc_atomic_check,
.atomic_flush = vop_crtc_atomic_flush,
.atomic_begin = vop_crtc_atomic_begin,
};
@@ -1413,6 +1501,7 @@ static void vop_win_init(struct vop *vop)
struct vop_win *vop_win = &vop->win[i];
const struct vop_win_data *win_data = &vop_data->win[i];
+ vop_win->id = i;
vop_win->data = win_data;
vop_win->vop = vop;
}
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
index ff4f52e..b9b120e 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
@@ -15,6 +15,10 @@
#ifndef _ROCKCHIP_DRM_VOP_H
#define _ROCKCHIP_DRM_VOP_H
+#define AFBDC_FMT_RGB565 0x0
+#define AFBDC_FMT_U8U8U8U8 0x5
+#define AFBDC_FMT_U8U8U8 0x4
+
enum vop_data_format {
VOP_FMT_ARGB8888 = 0,
VOP_FMT_RGB888,
@@ -61,6 +65,15 @@ struct vop_ctrl {
struct vop_reg hpost_st_end;
struct vop_reg vpost_st_end;
+ /* AFBDC */
+ struct vop_reg afbdc_en;
+ struct vop_reg afbdc_sel;
+ struct vop_reg afbdc_format;
+ struct vop_reg afbdc_hreg_block_split;
+ struct vop_reg afbdc_pic_size;
+ struct vop_reg afbdc_hdr_ptr;
+ struct vop_reg afbdc_rstn;
+
struct vop_reg cfg_done;
};
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
index f1a1688..a09437c 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
@@ -300,6 +300,13 @@ static const struct vop_ctrl rk3399_ctrl_data = {
.vact_st_end = VOP_REG(RK3399_DSP_VACT_ST_END, 0x1fff1fff, 0),
.hpost_st_end = VOP_REG(RK3399_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
.vpost_st_end = VOP_REG(RK3399_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
+ .afbdc_rstn = VOP_REG(RK3399_AFBCD0_CTRL, 0x1, 3),
+ .afbdc_en = VOP_REG(RK3399_AFBCD0_CTRL, 0x1, 0),
+ .afbdc_sel = VOP_REG(RK3399_AFBCD0_CTRL, 0x3, 1),
+ .afbdc_format = VOP_REG(RK3399_AFBCD0_CTRL, 0x1f, 16),
+ .afbdc_hreg_block_split = VOP_REG(RK3399_AFBCD0_CTRL, 0x1, 21),
+ .afbdc_hdr_ptr = VOP_REG(RK3399_AFBCD0_HDR_PTR, 0xffffffff, 0),
+ .afbdc_pic_size = VOP_REG(RK3399_AFBCD0_PIC_SIZE, 0xffffffff, 0),
.cfg_done = VOP_REG_MASK(RK3399_REG_CFG_DONE, 0x1, 0),
};
--
1.9.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH] drm/rockchip: vop: support afbc format for rk3399 vop
2016-09-10 2:29 ` [PATCH 3/3] drm/rockchip: vop: support afdc for rk3399 vop Mark Yao
@ 2016-09-10 3:07 ` Mark Yao
2016-09-10 3:12 ` Mark yao
2016-09-10 3:10 ` [PATCH 3/3 v1.1] " Mark Yao
1 sibling, 1 reply; 7+ messages in thread
From: Mark Yao @ 2016-09-10 3:07 UTC (permalink / raw)
To: linux-arm-kernel
Rk3399 vop big can support one afbc decoder, the afbc decoder
can select which overlay window use it.
on vop hardware, we call afbc decoder as afbdc.
afbdc window has some limit:
1, not support offset on source buffer.
2, if feed non-afbc buffer to afbc decoder, afbc decoder hardware
would die, we need take care of using it.
AFBC is a compressed format, means lower bandwidth consume,
it's useful to improve performance.
Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
---
drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 6 ++
drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 89 +++++++++++++++++++++++++++++
drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 13 +++++
drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 7 +++
4 files changed, 115 insertions(+)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index ea39329..1e07fd6 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -44,6 +44,12 @@ struct rockchip_crtc_funcs {
struct rockchip_crtc_state {
struct drm_crtc_state base;
+ int afbdc_win_format;
+ int afbdc_win_width;
+ int afbdc_win_height;
+ int afbdc_win_ptr;
+ int afbdc_win_id;
+ int afbdc_en;
int output_type;
int output_mode;
};
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 834456f..6918223 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -99,6 +99,7 @@ struct vop_win {
struct drm_plane base;
const struct vop_win_data *data;
struct vop *vop;
+ int id;
/* protected by dev->event_lock */
bool enable;
@@ -514,6 +515,7 @@ static void vop_crtc_disable(struct drm_crtc *crtc)
VOP_WIN_SET(vop, win, enable, 0);
spin_unlock(&vop->reg_lock);
}
+ VOP_CTRL_SET(vop, afbdc_en, 0);
drm_crtc_vblank_off(crtc);
@@ -1007,9 +1009,81 @@ static void vop_crtc_enable(struct drm_crtc *crtc)
VOP_CTRL_SET(vop, standby, 0);
}
+static int vop_afbdc_atomic_check(struct drm_crtc *crtc,
+ struct drm_crtc_state *crtc_state)
+{
+ struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
+ struct drm_atomic_state *state = crtc_state->state;
+ struct drm_plane *plane;
+ struct drm_plane_state *pstate;
+ struct vop_plane_state *plane_state;
+ struct vop_win *win;
+ int afbdc_format;
+ int i;
+
+ s->afbdc_en = 0;
+
+ for_each_plane_in_state(state, plane, pstate, i) {
+ struct drm_framebuffer *fb = pstate->fb;
+ struct drm_rect *src;
+
+ win = to_vop_win(plane);
+ plane_state = to_vop_plane_state(pstate);
+
+ if (pstate->crtc != crtc || !fb)
+ continue;
+
+ if (fb->modifier[0] != DRM_FORMAT_MOD_ARM_AFBC)
+ continue;
+
+ switch (plane_state->format) {
+ case VOP_FMT_ARGB8888:
+ afbdc_format = AFBDC_FMT_U8U8U8U8;
+ break;
+ case VOP_FMT_RGB888:
+ afbdc_format = AFBDC_FMT_U8U8U8;
+ break;
+ case VOP_FMT_RGB565:
+ afbdc_format = AFBDC_FMT_RGB565;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (s->afbdc_en) {
+ DRM_ERROR("vop only support one afbc layer\n");
+ return -EINVAL;
+ }
+
+ src = &pstate->src;
+ if (src->x1 || src->y1 || fb->offsets[0]) {
+ DRM_ERROR("win[%d] afbdc not support offset display\n",
+ win->id);
+ DRM_ERROR("xpos=%d, ypos=%d, offset=%d\n",
+ src->x1, src->y1, fb->offsets[0]);
+ return -EINVAL;
+ }
+ s->afbdc_win_format = afbdc_format;
+ s->afbdc_win_width = pstate->fb->width - 1;
+ s->afbdc_win_height = (drm_rect_height(src) >> 16) - 1;
+ s->afbdc_win_id = win->id;
+ s->afbdc_win_ptr = plane_state->yrgb_mst;
+ s->afbdc_en = 1;
+ }
+
+ return 0;
+}
+
+static int vop_crtc_atomic_check(struct drm_crtc *crtc,
+ struct drm_crtc_state *crtc_state)
+{
+ return vop_afbdc_atomic_check(crtc, crtc_state);
+}
+
static void vop_crtc_atomic_flush(struct drm_crtc *crtc,
struct drm_crtc_state *old_crtc_state)
{
+ struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc->state);
struct vop *vop = to_vop(crtc);
if (WARN_ON(!vop->is_enabled))
@@ -1017,6 +1091,19 @@ static void vop_crtc_atomic_flush(struct drm_crtc *crtc,
spin_lock(&vop->reg_lock);
+ if (s->afbdc_en) {
+ uint32_t pic_size;
+
+ VOP_CTRL_SET(vop, afbdc_format, s->afbdc_win_format | 1 << 4);
+ VOP_CTRL_SET(vop, afbdc_hreg_block_split, 0);
+ VOP_CTRL_SET(vop, afbdc_sel, s->afbdc_win_id);
+ VOP_CTRL_SET(vop, afbdc_hdr_ptr, s->afbdc_win_ptr);
+ pic_size = (s->afbdc_win_width & 0xffff);
+ pic_size |= s->afbdc_win_height << 16;
+ VOP_CTRL_SET(vop, afbdc_pic_size, pic_size);
+ }
+
+ VOP_CTRL_SET(vop, afbdc_en, s->afbdc_en);
vop_cfg_done(vop);
spin_unlock(&vop->reg_lock);
@@ -1042,6 +1129,7 @@ static const struct drm_crtc_helper_funcs vop_crtc_helper_funcs = {
.enable = vop_crtc_enable,
.disable = vop_crtc_disable,
.mode_fixup = vop_crtc_mode_fixup,
+ .atomic_check = vop_crtc_atomic_check,
.atomic_flush = vop_crtc_atomic_flush,
.atomic_begin = vop_crtc_atomic_begin,
};
@@ -1413,6 +1501,7 @@ static void vop_win_init(struct vop *vop)
struct vop_win *vop_win = &vop->win[i];
const struct vop_win_data *win_data = &vop_data->win[i];
+ vop_win->id = i;
vop_win->data = win_data;
vop_win->vop = vop;
}
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
index ff4f52e..b9b120e 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
@@ -15,6 +15,10 @@
#ifndef _ROCKCHIP_DRM_VOP_H
#define _ROCKCHIP_DRM_VOP_H
+#define AFBDC_FMT_RGB565 0x0
+#define AFBDC_FMT_U8U8U8U8 0x5
+#define AFBDC_FMT_U8U8U8 0x4
+
enum vop_data_format {
VOP_FMT_ARGB8888 = 0,
VOP_FMT_RGB888,
@@ -61,6 +65,15 @@ struct vop_ctrl {
struct vop_reg hpost_st_end;
struct vop_reg vpost_st_end;
+ /* AFBDC */
+ struct vop_reg afbdc_en;
+ struct vop_reg afbdc_sel;
+ struct vop_reg afbdc_format;
+ struct vop_reg afbdc_hreg_block_split;
+ struct vop_reg afbdc_pic_size;
+ struct vop_reg afbdc_hdr_ptr;
+ struct vop_reg afbdc_rstn;
+
struct vop_reg cfg_done;
};
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
index f1a1688..a09437c 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
@@ -300,6 +300,13 @@ static const struct vop_ctrl rk3399_ctrl_data = {
.vact_st_end = VOP_REG(RK3399_DSP_VACT_ST_END, 0x1fff1fff, 0),
.hpost_st_end = VOP_REG(RK3399_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
.vpost_st_end = VOP_REG(RK3399_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
+ .afbdc_rstn = VOP_REG(RK3399_AFBCD0_CTRL, 0x1, 3),
+ .afbdc_en = VOP_REG(RK3399_AFBCD0_CTRL, 0x1, 0),
+ .afbdc_sel = VOP_REG(RK3399_AFBCD0_CTRL, 0x3, 1),
+ .afbdc_format = VOP_REG(RK3399_AFBCD0_CTRL, 0x1f, 16),
+ .afbdc_hreg_block_split = VOP_REG(RK3399_AFBCD0_CTRL, 0x1, 21),
+ .afbdc_hdr_ptr = VOP_REG(RK3399_AFBCD0_HDR_PTR, 0xffffffff, 0),
+ .afbdc_pic_size = VOP_REG(RK3399_AFBCD0_PIC_SIZE, 0xffffffff, 0),
.cfg_done = VOP_REG_MASK(RK3399_REG_CFG_DONE, 0x1, 0),
};
--
1.9.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 3/3 v1.1] drm/rockchip: vop: support afbc format for rk3399 vop
2016-09-10 2:29 ` [PATCH 3/3] drm/rockchip: vop: support afdc for rk3399 vop Mark Yao
2016-09-10 3:07 ` [PATCH] drm/rockchip: vop: support afbc format " Mark Yao
@ 2016-09-10 3:10 ` Mark Yao
1 sibling, 0 replies; 7+ messages in thread
From: Mark Yao @ 2016-09-10 3:10 UTC (permalink / raw)
To: linux-arm-kernel
Rk3399 vop big can support one afbc decoder, the afbc decoder
can select which overlay window use it.
on vop hardware, we call afbc decoder as afbdc.
afbdc window has some limit:
1, not support offset on source buffer.
2, if feed non-afbc buffer to afbc decoder, afbc decoder hardware
would die, we need take care of using it.
AFBC is a compressed format, means lower bandwidth consume,
it's useful to improve performance.
Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
---
changes in v1.1
correct some comment.
drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 6 ++
drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 89 +++++++++++++++++++++++++++++
drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 13 +++++
drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 7 +++
4 files changed, 115 insertions(+)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index ea39329..1e07fd6 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -44,6 +44,12 @@ struct rockchip_crtc_funcs {
struct rockchip_crtc_state {
struct drm_crtc_state base;
+ int afbdc_win_format;
+ int afbdc_win_width;
+ int afbdc_win_height;
+ int afbdc_win_ptr;
+ int afbdc_win_id;
+ int afbdc_en;
int output_type;
int output_mode;
};
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 834456f..6918223 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -99,6 +99,7 @@ struct vop_win {
struct drm_plane base;
const struct vop_win_data *data;
struct vop *vop;
+ int id;
/* protected by dev->event_lock */
bool enable;
@@ -514,6 +515,7 @@ static void vop_crtc_disable(struct drm_crtc *crtc)
VOP_WIN_SET(vop, win, enable, 0);
spin_unlock(&vop->reg_lock);
}
+ VOP_CTRL_SET(vop, afbdc_en, 0);
drm_crtc_vblank_off(crtc);
@@ -1007,9 +1009,81 @@ static void vop_crtc_enable(struct drm_crtc *crtc)
VOP_CTRL_SET(vop, standby, 0);
}
+static int vop_afbdc_atomic_check(struct drm_crtc *crtc,
+ struct drm_crtc_state *crtc_state)
+{
+ struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
+ struct drm_atomic_state *state = crtc_state->state;
+ struct drm_plane *plane;
+ struct drm_plane_state *pstate;
+ struct vop_plane_state *plane_state;
+ struct vop_win *win;
+ int afbdc_format;
+ int i;
+
+ s->afbdc_en = 0;
+
+ for_each_plane_in_state(state, plane, pstate, i) {
+ struct drm_framebuffer *fb = pstate->fb;
+ struct drm_rect *src;
+
+ win = to_vop_win(plane);
+ plane_state = to_vop_plane_state(pstate);
+
+ if (pstate->crtc != crtc || !fb)
+ continue;
+
+ if (fb->modifier[0] != DRM_FORMAT_MOD_ARM_AFBC)
+ continue;
+
+ switch (plane_state->format) {
+ case VOP_FMT_ARGB8888:
+ afbdc_format = AFBDC_FMT_U8U8U8U8;
+ break;
+ case VOP_FMT_RGB888:
+ afbdc_format = AFBDC_FMT_U8U8U8;
+ break;
+ case VOP_FMT_RGB565:
+ afbdc_format = AFBDC_FMT_RGB565;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (s->afbdc_en) {
+ DRM_ERROR("vop only support one afbc layer\n");
+ return -EINVAL;
+ }
+
+ src = &pstate->src;
+ if (src->x1 || src->y1 || fb->offsets[0]) {
+ DRM_ERROR("win[%d] afbdc not support offset display\n",
+ win->id);
+ DRM_ERROR("xpos=%d, ypos=%d, offset=%d\n",
+ src->x1, src->y1, fb->offsets[0]);
+ return -EINVAL;
+ }
+ s->afbdc_win_format = afbdc_format;
+ s->afbdc_win_width = pstate->fb->width - 1;
+ s->afbdc_win_height = (drm_rect_height(src) >> 16) - 1;
+ s->afbdc_win_id = win->id;
+ s->afbdc_win_ptr = plane_state->yrgb_mst;
+ s->afbdc_en = 1;
+ }
+
+ return 0;
+}
+
+static int vop_crtc_atomic_check(struct drm_crtc *crtc,
+ struct drm_crtc_state *crtc_state)
+{
+ return vop_afbdc_atomic_check(crtc, crtc_state);
+}
+
static void vop_crtc_atomic_flush(struct drm_crtc *crtc,
struct drm_crtc_state *old_crtc_state)
{
+ struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc->state);
struct vop *vop = to_vop(crtc);
if (WARN_ON(!vop->is_enabled))
@@ -1017,6 +1091,19 @@ static void vop_crtc_atomic_flush(struct drm_crtc *crtc,
spin_lock(&vop->reg_lock);
+ if (s->afbdc_en) {
+ uint32_t pic_size;
+
+ VOP_CTRL_SET(vop, afbdc_format, s->afbdc_win_format | 1 << 4);
+ VOP_CTRL_SET(vop, afbdc_hreg_block_split, 0);
+ VOP_CTRL_SET(vop, afbdc_sel, s->afbdc_win_id);
+ VOP_CTRL_SET(vop, afbdc_hdr_ptr, s->afbdc_win_ptr);
+ pic_size = (s->afbdc_win_width & 0xffff);
+ pic_size |= s->afbdc_win_height << 16;
+ VOP_CTRL_SET(vop, afbdc_pic_size, pic_size);
+ }
+
+ VOP_CTRL_SET(vop, afbdc_en, s->afbdc_en);
vop_cfg_done(vop);
spin_unlock(&vop->reg_lock);
@@ -1042,6 +1129,7 @@ static const struct drm_crtc_helper_funcs vop_crtc_helper_funcs = {
.enable = vop_crtc_enable,
.disable = vop_crtc_disable,
.mode_fixup = vop_crtc_mode_fixup,
+ .atomic_check = vop_crtc_atomic_check,
.atomic_flush = vop_crtc_atomic_flush,
.atomic_begin = vop_crtc_atomic_begin,
};
@@ -1413,6 +1501,7 @@ static void vop_win_init(struct vop *vop)
struct vop_win *vop_win = &vop->win[i];
const struct vop_win_data *win_data = &vop_data->win[i];
+ vop_win->id = i;
vop_win->data = win_data;
vop_win->vop = vop;
}
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
index ff4f52e..b9b120e 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
@@ -15,6 +15,10 @@
#ifndef _ROCKCHIP_DRM_VOP_H
#define _ROCKCHIP_DRM_VOP_H
+#define AFBDC_FMT_RGB565 0x0
+#define AFBDC_FMT_U8U8U8U8 0x5
+#define AFBDC_FMT_U8U8U8 0x4
+
enum vop_data_format {
VOP_FMT_ARGB8888 = 0,
VOP_FMT_RGB888,
@@ -61,6 +65,15 @@ struct vop_ctrl {
struct vop_reg hpost_st_end;
struct vop_reg vpost_st_end;
+ /* AFBDC */
+ struct vop_reg afbdc_en;
+ struct vop_reg afbdc_sel;
+ struct vop_reg afbdc_format;
+ struct vop_reg afbdc_hreg_block_split;
+ struct vop_reg afbdc_pic_size;
+ struct vop_reg afbdc_hdr_ptr;
+ struct vop_reg afbdc_rstn;
+
struct vop_reg cfg_done;
};
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
index f1a1688..a09437c 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
@@ -300,6 +300,13 @@ static const struct vop_ctrl rk3399_ctrl_data = {
.vact_st_end = VOP_REG(RK3399_DSP_VACT_ST_END, 0x1fff1fff, 0),
.hpost_st_end = VOP_REG(RK3399_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
.vpost_st_end = VOP_REG(RK3399_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
+ .afbdc_rstn = VOP_REG(RK3399_AFBCD0_CTRL, 0x1, 3),
+ .afbdc_en = VOP_REG(RK3399_AFBCD0_CTRL, 0x1, 0),
+ .afbdc_sel = VOP_REG(RK3399_AFBCD0_CTRL, 0x3, 1),
+ .afbdc_format = VOP_REG(RK3399_AFBCD0_CTRL, 0x1f, 16),
+ .afbdc_hreg_block_split = VOP_REG(RK3399_AFBCD0_CTRL, 0x1, 21),
+ .afbdc_hdr_ptr = VOP_REG(RK3399_AFBCD0_HDR_PTR, 0xffffffff, 0),
+ .afbdc_pic_size = VOP_REG(RK3399_AFBCD0_PIC_SIZE, 0xffffffff, 0),
.cfg_done = VOP_REG_MASK(RK3399_REG_CFG_DONE, 0x1, 0),
};
--
1.9.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH] drm/rockchip: vop: support afbc format for rk3399 vop
2016-09-10 3:07 ` [PATCH] drm/rockchip: vop: support afbc format " Mark Yao
@ 2016-09-10 3:12 ` Mark yao
0 siblings, 0 replies; 7+ messages in thread
From: Mark yao @ 2016-09-10 3:12 UTC (permalink / raw)
To: linux-arm-kernel
Sorry, wrong title on this mail, ignore this mail. I had resent it.
On 2016?09?10? 11:07, Mark Yao wrote:
> Rk3399 vop big can support one afbc decoder, the afbc decoder
> can select which overlay window use it.
>
> on vop hardware, we call afbc decoder as afbdc.
>
> afbdc window has some limit:
> 1, not support offset on source buffer.
> 2, if feed non-afbc buffer to afbc decoder, afbc decoder hardware
> would die, we need take care of using it.
>
> AFBC is a compressed format, means lower bandwidth consume,
> it's useful to improve performance.
>
> Signed-off-by: Mark Yao<mark.yao@rock-chips.com>
> ---
--
?ark Yao
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 2/3] drm: add ARM vendor format afbc
2016-09-10 2:29 ` [PATCH 2/3] drm: add ARM vendor format afbc Mark Yao
@ 2016-09-13 14:13 ` Brian Starkey
0 siblings, 0 replies; 7+ messages in thread
From: Brian Starkey @ 2016-09-13 14:13 UTC (permalink / raw)
To: linux-arm-kernel
Hi Mark,
On Sat, Sep 10, 2016 at 10:29:03AM +0800, Mark Yao wrote:
>AFBC is arm vendor format, it's a compressed format.
>
>The AFBC format is supported by rk3399 vop big.
>
>We know little about AFBC layout, hope to some guys can
>fixme about the afbc comment.
>
>Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
>---
> include/uapi/drm/drm_fourcc.h | 7 +++++++
> 1 file changed, 7 insertions(+)
>
>diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
>index a5890bf..9a47d7e 100644
>--- a/include/uapi/drm/drm_fourcc.h
>+++ b/include/uapi/drm/drm_fourcc.h
>@@ -159,6 +159,7 @@ extern "C" {
> #define DRM_FORMAT_MOD_VENDOR_NV 0x03
> #define DRM_FORMAT_MOD_VENDOR_SAMSUNG 0x04
> #define DRM_FORMAT_MOD_VENDOR_QCOM 0x05
>+#define DRM_FORMAT_MOD_VENDOR_ARM 0x06
> /* add more to the end as needed */
>
> #define fourcc_mod_code(vendor, val) \
>@@ -233,6 +234,12 @@ extern "C" {
> */
> #define DRM_FORMAT_MOD_SAMSUNG_64_32_TILE fourcc_mod_code(SAMSUNG, 1)
>
>+/*
>+ * FIXME: AFBC is arm vendor format, it's a compressed format.
>+ *
>+ */
>+#define DRM_FORMAT_MOD_ARM_AFBC fourcc_mod_code(ARM, 1)
Do you have any details about the exact type of AFBC data you are
consuming here?
We need to agree what exactly a buffer with the modifier
"DRM_FORMAT_MOD_ARM_AFBC" means. For instance the block size, whether
the data has the YUV transform applied, how the data is laid out in
memory etc.
We (ARM) want to make sure that the format modifiers we expose to
userspace for AFBC are precise and non-ambiguous, cover all
possible AFBC modifiers (of which there are many, and the list can
only get longer) and all possible AFBC consuming/producing IPs'
requirements.
We had intended to delay adding any AFBC format modifiers to DRM until
we'd had this kind of discussion internally to agree the exact set
of modifiers we need, but if you need this now then we can start that
discussion here.
Thanks,
Brian
>+
> #if defined(__cplusplus)
> }
> #endif
>--
>1.9.1
>
>
>_______________________________________________
>dri-devel mailing list
>dri-devel at lists.freedesktop.org
>https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2016-09-13 14:13 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-09-10 2:29 [PATCH 1/3] drm/rockchip: vop: move dma_addr to plane atomic check Mark Yao
2016-09-10 2:29 ` [PATCH 2/3] drm: add ARM vendor format afbc Mark Yao
2016-09-13 14:13 ` Brian Starkey
2016-09-10 2:29 ` [PATCH 3/3] drm/rockchip: vop: support afdc for rk3399 vop Mark Yao
2016-09-10 3:07 ` [PATCH] drm/rockchip: vop: support afbc format " Mark Yao
2016-09-10 3:12 ` Mark yao
2016-09-10 3:10 ` [PATCH 3/3 v1.1] " Mark Yao
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).