|
@@ -170,6 +170,7 @@ struct vop_win_phy {
|
|
|
|
|
|
struct vop_reg enable;
|
|
|
struct vop_reg format;
|
|
|
+ struct vop_reg rb_swap;
|
|
|
struct vop_reg act_info;
|
|
|
struct vop_reg dsp_info;
|
|
|
struct vop_reg dsp_st;
|
|
@@ -199,8 +200,12 @@ struct vop_data {
|
|
|
static const uint32_t formats_01[] = {
|
|
|
DRM_FORMAT_XRGB8888,
|
|
|
DRM_FORMAT_ARGB8888,
|
|
|
+ DRM_FORMAT_XBGR8888,
|
|
|
+ DRM_FORMAT_ABGR8888,
|
|
|
DRM_FORMAT_RGB888,
|
|
|
+ DRM_FORMAT_BGR888,
|
|
|
DRM_FORMAT_RGB565,
|
|
|
+ DRM_FORMAT_BGR565,
|
|
|
DRM_FORMAT_NV12,
|
|
|
DRM_FORMAT_NV16,
|
|
|
DRM_FORMAT_NV24,
|
|
@@ -209,8 +214,12 @@ static const uint32_t formats_01[] = {
|
|
|
static const uint32_t formats_234[] = {
|
|
|
DRM_FORMAT_XRGB8888,
|
|
|
DRM_FORMAT_ARGB8888,
|
|
|
+ DRM_FORMAT_XBGR8888,
|
|
|
+ DRM_FORMAT_ABGR8888,
|
|
|
DRM_FORMAT_RGB888,
|
|
|
+ DRM_FORMAT_BGR888,
|
|
|
DRM_FORMAT_RGB565,
|
|
|
+ DRM_FORMAT_BGR565,
|
|
|
};
|
|
|
|
|
|
static const struct vop_win_phy win01_data = {
|
|
@@ -218,6 +227,7 @@ static const struct vop_win_phy win01_data = {
|
|
|
.nformats = ARRAY_SIZE(formats_01),
|
|
|
.enable = VOP_REG(WIN0_CTRL0, 0x1, 0),
|
|
|
.format = VOP_REG(WIN0_CTRL0, 0x7, 1),
|
|
|
+ .rb_swap = VOP_REG(WIN0_CTRL0, 0x1, 12),
|
|
|
.act_info = VOP_REG(WIN0_ACT_INFO, 0x1fff1fff, 0),
|
|
|
.dsp_info = VOP_REG(WIN0_DSP_INFO, 0x0fff0fff, 0),
|
|
|
.dsp_st = VOP_REG(WIN0_DSP_ST, 0x1fff1fff, 0),
|
|
@@ -234,6 +244,7 @@ static const struct vop_win_phy win23_data = {
|
|
|
.nformats = ARRAY_SIZE(formats_234),
|
|
|
.enable = VOP_REG(WIN2_CTRL0, 0x1, 0),
|
|
|
.format = VOP_REG(WIN2_CTRL0, 0x7, 1),
|
|
|
+ .rb_swap = VOP_REG(WIN2_CTRL0, 0x1, 12),
|
|
|
.dsp_info = VOP_REG(WIN2_DSP_INFO0, 0x0fff0fff, 0),
|
|
|
.dsp_st = VOP_REG(WIN2_DSP_ST0, 0x1fff1fff, 0),
|
|
|
.yrgb_mst = VOP_REG(WIN2_MST0, 0xffffffff, 0),
|
|
@@ -242,15 +253,6 @@ static const struct vop_win_phy win23_data = {
|
|
|
.dst_alpha_ctl = VOP_REG(WIN2_DST_ALPHA_CTRL, 0xff, 0),
|
|
|
};
|
|
|
|
|
|
-static const struct vop_win_phy cursor_data = {
|
|
|
- .data_formats = formats_234,
|
|
|
- .nformats = ARRAY_SIZE(formats_234),
|
|
|
- .enable = VOP_REG(HWC_CTRL0, 0x1, 0),
|
|
|
- .format = VOP_REG(HWC_CTRL0, 0x7, 1),
|
|
|
- .dsp_st = VOP_REG(HWC_DSP_ST, 0x1fff1fff, 0),
|
|
|
- .yrgb_mst = VOP_REG(HWC_MST, 0xffffffff, 0),
|
|
|
-};
|
|
|
-
|
|
|
static const struct vop_ctrl ctrl_data = {
|
|
|
.standby = VOP_REG(SYS_CTRL, 0x1, 22),
|
|
|
.gate_en = VOP_REG(SYS_CTRL, 0x1, 23),
|
|
@@ -282,14 +284,14 @@ static const struct vop_reg_data vop_init_reg_table[] = {
|
|
|
/*
|
|
|
* Note: rk3288 has a dedicated 'cursor' window, however, that window requires
|
|
|
* special support to get alpha blending working. For now, just use overlay
|
|
|
- * window 1 for the drm cursor.
|
|
|
+ * window 3 for the drm cursor.
|
|
|
+ *
|
|
|
*/
|
|
|
static const struct vop_win_data rk3288_vop_win_data[] = {
|
|
|
{ .base = 0x00, .phy = &win01_data, .type = DRM_PLANE_TYPE_PRIMARY },
|
|
|
- { .base = 0x40, .phy = &win01_data, .type = DRM_PLANE_TYPE_CURSOR },
|
|
|
+ { .base = 0x40, .phy = &win01_data, .type = DRM_PLANE_TYPE_OVERLAY },
|
|
|
{ .base = 0x00, .phy = &win23_data, .type = DRM_PLANE_TYPE_OVERLAY },
|
|
|
- { .base = 0x50, .phy = &win23_data, .type = DRM_PLANE_TYPE_OVERLAY },
|
|
|
- { .base = 0x00, .phy = &cursor_data, .type = DRM_PLANE_TYPE_OVERLAY },
|
|
|
+ { .base = 0x50, .phy = &win23_data, .type = DRM_PLANE_TYPE_CURSOR },
|
|
|
};
|
|
|
|
|
|
static const struct vop_data rk3288_vop = {
|
|
@@ -352,15 +354,32 @@ static inline void vop_mask_write_relaxed(struct vop *vop, uint32_t offset,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+static bool has_rb_swapped(uint32_t format)
|
|
|
+{
|
|
|
+ switch (format) {
|
|
|
+ case DRM_FORMAT_XBGR8888:
|
|
|
+ case DRM_FORMAT_ABGR8888:
|
|
|
+ case DRM_FORMAT_BGR888:
|
|
|
+ case DRM_FORMAT_BGR565:
|
|
|
+ return true;
|
|
|
+ default:
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
static enum vop_data_format vop_convert_format(uint32_t format)
|
|
|
{
|
|
|
switch (format) {
|
|
|
case DRM_FORMAT_XRGB8888:
|
|
|
case DRM_FORMAT_ARGB8888:
|
|
|
+ case DRM_FORMAT_XBGR8888:
|
|
|
+ case DRM_FORMAT_ABGR8888:
|
|
|
return VOP_FMT_ARGB8888;
|
|
|
case DRM_FORMAT_RGB888:
|
|
|
+ case DRM_FORMAT_BGR888:
|
|
|
return VOP_FMT_RGB888;
|
|
|
case DRM_FORMAT_RGB565:
|
|
|
+ case DRM_FORMAT_BGR565:
|
|
|
return VOP_FMT_RGB565;
|
|
|
case DRM_FORMAT_NV12:
|
|
|
return VOP_FMT_YUV420SP;
|
|
@@ -378,6 +397,7 @@ static bool is_alpha_support(uint32_t format)
|
|
|
{
|
|
|
switch (format) {
|
|
|
case DRM_FORMAT_ARGB8888:
|
|
|
+ case DRM_FORMAT_ABGR8888:
|
|
|
return true;
|
|
|
default:
|
|
|
return false;
|
|
@@ -588,6 +608,7 @@ static int vop_update_plane_event(struct drm_plane *plane,
|
|
|
enum vop_data_format format;
|
|
|
uint32_t val;
|
|
|
bool is_alpha;
|
|
|
+ bool rb_swap;
|
|
|
bool visible;
|
|
|
int ret;
|
|
|
struct drm_rect dest = {
|
|
@@ -621,6 +642,7 @@ static int vop_update_plane_event(struct drm_plane *plane,
|
|
|
return 0;
|
|
|
|
|
|
is_alpha = is_alpha_support(fb->pixel_format);
|
|
|
+ rb_swap = has_rb_swapped(fb->pixel_format);
|
|
|
format = vop_convert_format(fb->pixel_format);
|
|
|
if (format < 0)
|
|
|
return format;
|
|
@@ -689,6 +711,7 @@ static int vop_update_plane_event(struct drm_plane *plane,
|
|
|
val = (dsp_sty - 1) << 16;
|
|
|
val |= (dsp_stx - 1) & 0xffff;
|
|
|
VOP_WIN_SET(vop, win, dsp_st, val);
|
|
|
+ VOP_WIN_SET(vop, win, rb_swap, rb_swap);
|
|
|
|
|
|
if (is_alpha) {
|
|
|
VOP_WIN_SET(vop, win, dst_alpha_ctl,
|