drm/rockchip: Add BGR formats to VOP
diff mbox

Message ID 1431072968-12696-1-git-send-email-tfiga@chromium.org
State New
Headers show

Commit Message

Tomasz Figa May 8, 2015, 8:16 a.m. UTC
VOP can support BGR formats in all windows thanks to red/blue swap option
provided in WINx_CTRL0 registers. This patch enables support for
ABGR8888, XBGR8888, BGR888 and BGR565 formats by using this feature.

Signed-off-by: Tomasz Figa <tfiga@chromium.org>
---
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 33 +++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

Comments

yao mark May 8, 2015, 8:40 a.m. UTC | #1
Hi Tomasz
     Thanks for the fix, but some register is wrong.

On 2015?05?08? 16:16, Tomasz Figa wrote:
> VOP can support BGR formats in all windows thanks to red/blue swap option
> provided in WINx_CTRL0 registers. This patch enables support for
> ABGR8888, XBGR8888, BGR888 and BGR565 formats by using this feature.
>
> Signed-off-by: Tomasz Figa <tfiga@chromium.org>
> ---
>   drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 33 +++++++++++++++++++++++++++++
>   1 file changed, 33 insertions(+)
>
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> index 4557f33..45fa11c 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> @@ -169,6 +169,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;
> @@ -198,8 +199,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,
> @@ -208,8 +213,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 = {
> @@ -217,6 +226,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),
> @@ -233,6 +243,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(WIN0_CTRL0, 0x1, 12),
Should be:

	.rb_swap = VOP_REG(VOP_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),
> @@ -246,6 +257,7 @@ static const struct vop_win_phy cursor_data = {
>   	.nformats = ARRAY_SIZE(formats_234),
>   	.enable = VOP_REG(HWC_CTRL0, 0x1, 0),
>   	.format = VOP_REG(HWC_CTRL0, 0x7, 1),
> +	.rb_swap = VOP_REG(WIN0_CTRL0, 0x1, 12),
cursor win not support rb_swap, remove it.
>   	.dsp_st = VOP_REG(HWC_DSP_ST, 0x1fff1fff, 0),
>   	.yrgb_mst = VOP_REG(HWC_MST, 0xffffffff, 0),
>   };
> @@ -351,15 +363,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;
> @@ -377,6 +406,7 @@ static bool is_alpha_support(uint32_t format)
>   {
>   	switch (format) {
>   	case DRM_FORMAT_ARGB8888:
> +	case DRM_FORMAT_ABGR8888:
>   		return true;
>   	default:
>   		return false;
> @@ -587,6 +617,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 = {
> @@ -620,6 +651,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;
> @@ -688,6 +720,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,
Tomasz Figa May 8, 2015, 8:49 a.m. UTC | #2
Hi Mark,

Thanks for review.

On Fri, May 8, 2015 at 5:40 PM, Mark yao <mark.yao@rock-chips.com> wrote:
>> @@ -233,6 +243,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(WIN0_CTRL0, 0x1, 12),
>
> Should be:
>
>         .rb_swap = VOP_REG(VOP_WIN2_CTRL0, 0x1, 12),
>

Right, good catch.

>>         .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),
>> @@ -246,6 +257,7 @@ static const struct vop_win_phy cursor_data = {
>>         .nformats = ARRAY_SIZE(formats_234),
>>         .enable = VOP_REG(HWC_CTRL0, 0x1, 0),
>>         .format = VOP_REG(HWC_CTRL0, 0x7, 1),
>> +       .rb_swap = VOP_REG(WIN0_CTRL0, 0x1, 12),
>
> cursor win not support rb_swap, remove it.
>

Hmm, according to the datasheet of RK3288 I have (0.7, October 2014),
there is a field called hwc_rb_swap at bit 12 of HWC_CTRL0 register.
Is it an error in the datasheet?

Best regards,
Tomasz
yao mark May 8, 2015, 9:31 a.m. UTC | #3
On 2015?05?08? 16:49, Tomasz Figa wrote:
> Hi Mark,
>
> Thanks for review.
>
> On Fri, May 8, 2015 at 5:40 PM, Mark yao <mark.yao@rock-chips.com> wrote:
>>> @@ -233,6 +243,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(WIN0_CTRL0, 0x1, 12),
>> Should be:
>>
>>          .rb_swap = VOP_REG(VOP_WIN2_CTRL0, 0x1, 12),
>>
> Right, good catch.
>
>>>          .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),
>>> @@ -246,6 +257,7 @@ static const struct vop_win_phy cursor_data = {
>>>          .nformats = ARRAY_SIZE(formats_234),
>>>          .enable = VOP_REG(HWC_CTRL0, 0x1, 0),
>>>          .format = VOP_REG(HWC_CTRL0, 0x7, 1),
>>> +       .rb_swap = VOP_REG(WIN0_CTRL0, 0x1, 12),
>> cursor win not support rb_swap, remove it.
>>
> Hmm, according to the datasheet of RK3288 I have (0.7, October 2014),
> there is a field called hwc_rb_swap at bit 12 of HWC_CTRL0 register.
> Is it an error in the datasheet?
>
> Best regards,
> Tomasz
>
>
>
Oh, yes, I find it, rb_swap at HWC_CTRL0 bit 12. you are right.
Thanks :-)

Patch
diff mbox

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 4557f33..45fa11c 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -169,6 +169,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;
@@ -198,8 +199,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,
@@ -208,8 +213,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 = {
@@ -217,6 +226,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),
@@ -233,6 +243,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(WIN0_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),
@@ -246,6 +257,7 @@  static const struct vop_win_phy cursor_data = {
 	.nformats = ARRAY_SIZE(formats_234),
 	.enable = VOP_REG(HWC_CTRL0, 0x1, 0),
 	.format = VOP_REG(HWC_CTRL0, 0x7, 1),
+	.rb_swap = VOP_REG(WIN0_CTRL0, 0x1, 12),
 	.dsp_st = VOP_REG(HWC_DSP_ST, 0x1fff1fff, 0),
 	.yrgb_mst = VOP_REG(HWC_MST, 0xffffffff, 0),
 };
@@ -351,15 +363,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;
@@ -377,6 +406,7 @@  static bool is_alpha_support(uint32_t format)
 {
 	switch (format) {
 	case DRM_FORMAT_ARGB8888:
+	case DRM_FORMAT_ABGR8888:
 		return true;
 	default:
 		return false;
@@ -587,6 +617,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 = {
@@ -620,6 +651,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;
@@ -688,6 +720,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,