diff options
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/arm/malidp_hw.c | 25 | ||||
-rw-r--r-- | drivers/gpu/drm/arm/malidp_hw.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/arm/malidp_mw.c | 25 | ||||
-rw-r--r-- | drivers/gpu/drm/arm/malidp_regs.h | 2 |
4 files changed, 48 insertions, 7 deletions
diff --git a/drivers/gpu/drm/arm/malidp_hw.c b/drivers/gpu/drm/arm/malidp_hw.c index c94a4422e0e9..2781e462c1ed 100644 --- a/drivers/gpu/drm/arm/malidp_hw.c +++ b/drivers/gpu/drm/arm/malidp_hw.c | |||
@@ -384,7 +384,8 @@ static long malidp500_se_calc_mclk(struct malidp_hw_device *hwdev, | |||
384 | 384 | ||
385 | static int malidp500_enable_memwrite(struct malidp_hw_device *hwdev, | 385 | static int malidp500_enable_memwrite(struct malidp_hw_device *hwdev, |
386 | dma_addr_t *addrs, s32 *pitches, | 386 | dma_addr_t *addrs, s32 *pitches, |
387 | int num_planes, u16 w, u16 h, u32 fmt_id) | 387 | int num_planes, u16 w, u16 h, u32 fmt_id, |
388 | const s16 *rgb2yuv_coeffs) | ||
388 | { | 389 | { |
389 | u32 base = MALIDP500_SE_MEMWRITE_BASE; | 390 | u32 base = MALIDP500_SE_MEMWRITE_BASE; |
390 | u32 de_base = malidp_get_block_base(hwdev, MALIDP_DE_BLOCK); | 391 | u32 de_base = malidp_get_block_base(hwdev, MALIDP_DE_BLOCK); |
@@ -416,6 +417,16 @@ static int malidp500_enable_memwrite(struct malidp_hw_device *hwdev, | |||
416 | 417 | ||
417 | malidp_hw_write(hwdev, MALIDP_DE_H_ACTIVE(w) | MALIDP_DE_V_ACTIVE(h), | 418 | malidp_hw_write(hwdev, MALIDP_DE_H_ACTIVE(w) | MALIDP_DE_V_ACTIVE(h), |
418 | MALIDP500_SE_MEMWRITE_OUT_SIZE); | 419 | MALIDP500_SE_MEMWRITE_OUT_SIZE); |
420 | |||
421 | if (rgb2yuv_coeffs) { | ||
422 | int i; | ||
423 | |||
424 | for (i = 0; i < MALIDP_COLORADJ_NUM_COEFFS; i++) { | ||
425 | malidp_hw_write(hwdev, rgb2yuv_coeffs[i], | ||
426 | MALIDP500_SE_RGB_YUV_COEFFS + i * 4); | ||
427 | } | ||
428 | } | ||
429 | |||
419 | malidp_hw_setbits(hwdev, MALIDP_SE_MEMWRITE_EN, MALIDP500_SE_CONTROL); | 430 | malidp_hw_setbits(hwdev, MALIDP_SE_MEMWRITE_EN, MALIDP500_SE_CONTROL); |
420 | 431 | ||
421 | return 0; | 432 | return 0; |
@@ -658,7 +669,8 @@ static long malidp550_se_calc_mclk(struct malidp_hw_device *hwdev, | |||
658 | 669 | ||
659 | static int malidp550_enable_memwrite(struct malidp_hw_device *hwdev, | 670 | static int malidp550_enable_memwrite(struct malidp_hw_device *hwdev, |
660 | dma_addr_t *addrs, s32 *pitches, | 671 | dma_addr_t *addrs, s32 *pitches, |
661 | int num_planes, u16 w, u16 h, u32 fmt_id) | 672 | int num_planes, u16 w, u16 h, u32 fmt_id, |
673 | const s16 *rgb2yuv_coeffs) | ||
662 | { | 674 | { |
663 | u32 base = MALIDP550_SE_MEMWRITE_BASE; | 675 | u32 base = MALIDP550_SE_MEMWRITE_BASE; |
664 | u32 de_base = malidp_get_block_base(hwdev, MALIDP_DE_BLOCK); | 676 | u32 de_base = malidp_get_block_base(hwdev, MALIDP_DE_BLOCK); |
@@ -689,6 +701,15 @@ static int malidp550_enable_memwrite(struct malidp_hw_device *hwdev, | |||
689 | malidp_hw_setbits(hwdev, MALIDP550_SE_MEMWRITE_ONESHOT | MALIDP_SE_MEMWRITE_EN, | 701 | malidp_hw_setbits(hwdev, MALIDP550_SE_MEMWRITE_ONESHOT | MALIDP_SE_MEMWRITE_EN, |
690 | MALIDP550_SE_CONTROL); | 702 | MALIDP550_SE_CONTROL); |
691 | 703 | ||
704 | if (rgb2yuv_coeffs) { | ||
705 | int i; | ||
706 | |||
707 | for (i = 0; i < MALIDP_COLORADJ_NUM_COEFFS; i++) { | ||
708 | malidp_hw_write(hwdev, rgb2yuv_coeffs[i], | ||
709 | MALIDP550_SE_RGB_YUV_COEFFS + i * 4); | ||
710 | } | ||
711 | } | ||
712 | |||
692 | return 0; | 713 | return 0; |
693 | } | 714 | } |
694 | 715 | ||
diff --git a/drivers/gpu/drm/arm/malidp_hw.h b/drivers/gpu/drm/arm/malidp_hw.h index ad2e96915d44..9fc94c08190f 100644 --- a/drivers/gpu/drm/arm/malidp_hw.h +++ b/drivers/gpu/drm/arm/malidp_hw.h | |||
@@ -191,7 +191,8 @@ struct malidp_hw { | |||
191 | * @param fmt_id - internal format ID of output buffer | 191 | * @param fmt_id - internal format ID of output buffer |
192 | */ | 192 | */ |
193 | int (*enable_memwrite)(struct malidp_hw_device *hwdev, dma_addr_t *addrs, | 193 | int (*enable_memwrite)(struct malidp_hw_device *hwdev, dma_addr_t *addrs, |
194 | s32 *pitches, int num_planes, u16 w, u16 h, u32 fmt_id); | 194 | s32 *pitches, int num_planes, u16 w, u16 h, u32 fmt_id, |
195 | const s16 *rgb2yuv_coeffs); | ||
195 | 196 | ||
196 | /* | 197 | /* |
197 | * Disable the writing to memory of the next frame's content. | 198 | * Disable the writing to memory of the next frame's content. |
diff --git a/drivers/gpu/drm/arm/malidp_mw.c b/drivers/gpu/drm/arm/malidp_mw.c index ba6ae66387c9..91472e5e0c8b 100644 --- a/drivers/gpu/drm/arm/malidp_mw.c +++ b/drivers/gpu/drm/arm/malidp_mw.c | |||
@@ -26,6 +26,8 @@ struct malidp_mw_connector_state { | |||
26 | s32 pitches[2]; | 26 | s32 pitches[2]; |
27 | u8 format; | 27 | u8 format; |
28 | u8 n_planes; | 28 | u8 n_planes; |
29 | bool rgb2yuv_initialized; | ||
30 | const s16 *rgb2yuv_coeffs; | ||
29 | }; | 31 | }; |
30 | 32 | ||
31 | static int malidp_mw_connector_get_modes(struct drm_connector *connector) | 33 | static int malidp_mw_connector_get_modes(struct drm_connector *connector) |
@@ -84,7 +86,7 @@ static void malidp_mw_connector_destroy(struct drm_connector *connector) | |||
84 | static struct drm_connector_state * | 86 | static struct drm_connector_state * |
85 | malidp_mw_connector_duplicate_state(struct drm_connector *connector) | 87 | malidp_mw_connector_duplicate_state(struct drm_connector *connector) |
86 | { | 88 | { |
87 | struct malidp_mw_connector_state *mw_state; | 89 | struct malidp_mw_connector_state *mw_state, *mw_current_state; |
88 | 90 | ||
89 | if (WARN_ON(!connector->state)) | 91 | if (WARN_ON(!connector->state)) |
90 | return NULL; | 92 | return NULL; |
@@ -93,7 +95,10 @@ malidp_mw_connector_duplicate_state(struct drm_connector *connector) | |||
93 | if (!mw_state) | 95 | if (!mw_state) |
94 | return NULL; | 96 | return NULL; |
95 | 97 | ||
96 | /* No need to preserve any of our driver-local data */ | 98 | mw_current_state = to_mw_state(connector->state); |
99 | mw_state->rgb2yuv_coeffs = mw_current_state->rgb2yuv_coeffs; | ||
100 | mw_state->rgb2yuv_initialized = mw_current_state->rgb2yuv_initialized; | ||
101 | |||
97 | __drm_atomic_helper_connector_duplicate_state(connector, &mw_state->base); | 102 | __drm_atomic_helper_connector_duplicate_state(connector, &mw_state->base); |
98 | 103 | ||
99 | return &mw_state->base; | 104 | return &mw_state->base; |
@@ -108,6 +113,13 @@ static const struct drm_connector_funcs malidp_mw_connector_funcs = { | |||
108 | .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, | 113 | .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, |
109 | }; | 114 | }; |
110 | 115 | ||
116 | static const s16 rgb2yuv_coeffs_bt709_limited[MALIDP_COLORADJ_NUM_COEFFS] = { | ||
117 | 47, 157, 16, | ||
118 | -26, -87, 112, | ||
119 | 112, -102, -10, | ||
120 | 16, 128, 128 | ||
121 | }; | ||
122 | |||
111 | static int | 123 | static int |
112 | malidp_mw_encoder_atomic_check(struct drm_encoder *encoder, | 124 | malidp_mw_encoder_atomic_check(struct drm_encoder *encoder, |
113 | struct drm_crtc_state *crtc_state, | 125 | struct drm_crtc_state *crtc_state, |
@@ -157,6 +169,9 @@ malidp_mw_encoder_atomic_check(struct drm_encoder *encoder, | |||
157 | } | 169 | } |
158 | mw_state->n_planes = n_planes; | 170 | mw_state->n_planes = n_planes; |
159 | 171 | ||
172 | if (fb->format->is_yuv) | ||
173 | mw_state->rgb2yuv_coeffs = rgb2yuv_coeffs_bt709_limited; | ||
174 | |||
160 | return 0; | 175 | return 0; |
161 | } | 176 | } |
162 | 177 | ||
@@ -239,10 +254,12 @@ void malidp_mw_atomic_commit(struct drm_device *drm, | |||
239 | 254 | ||
240 | drm_writeback_queue_job(mw_conn, conn_state->writeback_job); | 255 | drm_writeback_queue_job(mw_conn, conn_state->writeback_job); |
241 | conn_state->writeback_job = NULL; | 256 | conn_state->writeback_job = NULL; |
242 | |||
243 | hwdev->hw->enable_memwrite(hwdev, mw_state->addrs, | 257 | hwdev->hw->enable_memwrite(hwdev, mw_state->addrs, |
244 | mw_state->pitches, mw_state->n_planes, | 258 | mw_state->pitches, mw_state->n_planes, |
245 | fb->width, fb->height, mw_state->format); | 259 | fb->width, fb->height, mw_state->format, |
260 | !mw_state->rgb2yuv_initialized ? | ||
261 | mw_state->rgb2yuv_coeffs : NULL); | ||
262 | mw_state->rgb2yuv_initialized = !!mw_state->rgb2yuv_coeffs; | ||
246 | } else { | 263 | } else { |
247 | DRM_DEV_DEBUG_DRIVER(drm->dev, "Disable memwrite\n"); | 264 | DRM_DEV_DEBUG_DRIVER(drm->dev, "Disable memwrite\n"); |
248 | hwdev->hw->disable_memwrite(hwdev); | 265 | hwdev->hw->disable_memwrite(hwdev); |
diff --git a/drivers/gpu/drm/arm/malidp_regs.h b/drivers/gpu/drm/arm/malidp_regs.h index 3579d36b2a71..6ffe849774f2 100644 --- a/drivers/gpu/drm/arm/malidp_regs.h +++ b/drivers/gpu/drm/arm/malidp_regs.h | |||
@@ -205,6 +205,7 @@ | |||
205 | #define MALIDP500_SE_BASE 0x00c00 | 205 | #define MALIDP500_SE_BASE 0x00c00 |
206 | #define MALIDP500_SE_CONTROL 0x00c0c | 206 | #define MALIDP500_SE_CONTROL 0x00c0c |
207 | #define MALIDP500_SE_MEMWRITE_OUT_SIZE 0x00c2c | 207 | #define MALIDP500_SE_MEMWRITE_OUT_SIZE 0x00c2c |
208 | #define MALIDP500_SE_RGB_YUV_COEFFS 0x00C74 | ||
208 | #define MALIDP500_SE_MEMWRITE_BASE 0x00e00 | 209 | #define MALIDP500_SE_MEMWRITE_BASE 0x00e00 |
209 | #define MALIDP500_DC_IRQ_BASE 0x00f00 | 210 | #define MALIDP500_DC_IRQ_BASE 0x00f00 |
210 | #define MALIDP500_CONFIG_VALID 0x00f00 | 211 | #define MALIDP500_CONFIG_VALID 0x00f00 |
@@ -238,6 +239,7 @@ | |||
238 | #define MALIDP550_SE_CONTROL 0x08010 | 239 | #define MALIDP550_SE_CONTROL 0x08010 |
239 | #define MALIDP550_SE_MEMWRITE_ONESHOT (1 << 7) | 240 | #define MALIDP550_SE_MEMWRITE_ONESHOT (1 << 7) |
240 | #define MALIDP550_SE_MEMWRITE_OUT_SIZE 0x08030 | 241 | #define MALIDP550_SE_MEMWRITE_OUT_SIZE 0x08030 |
242 | #define MALIDP550_SE_RGB_YUV_COEFFS 0x08078 | ||
241 | #define MALIDP550_SE_MEMWRITE_BASE 0x08100 | 243 | #define MALIDP550_SE_MEMWRITE_BASE 0x08100 |
242 | #define MALIDP550_DC_BASE 0x0c000 | 244 | #define MALIDP550_DC_BASE 0x0c000 |
243 | #define MALIDP550_DC_CONTROL 0x0c010 | 245 | #define MALIDP550_DC_CONTROL 0x0c010 |