diff options
author | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2011-06-21 02:34:30 -0400 |
---|---|---|
committer | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2011-07-01 05:07:13 -0400 |
commit | 3c07cae2cccc4e40ff66521701a3c8eeda8726e1 (patch) | |
tree | c9f1b652db85bdbfbb435355009742200ca3753d /drivers/video/omap2 | |
parent | 4df9d104d5bbe356b26bcf221d61f92f1948850e (diff) |
OMAP: DSS2: Add Color Phase Rotation support
Add Color Phase Rotation (CPR) support and sysfs files to enable CPR and
to set the CPR coefficient matrix.
CPR is enabled via manager?/cpr_enable file, and the coefficient matrix
is set via manager?/cpr_coef file. The values in cpr_coef are in the
following order:
RR RG RB GR GG GB BR BG BB
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers/video/omap2')
-rw-r--r-- | drivers/video/omap2/dss/dispc.c | 34 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dss.h | 3 | ||||
-rw-r--r-- | drivers/video/omap2/dss/manager.c | 114 |
3 files changed, 151 insertions, 0 deletions
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index ee2052f2ea02..1abed77e9897 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c | |||
@@ -1034,6 +1034,40 @@ void dispc_enable_gamma_table(bool enable) | |||
1034 | REG_FLD_MOD(DISPC_CONFIG, enable, 9, 9); | 1034 | REG_FLD_MOD(DISPC_CONFIG, enable, 9, 9); |
1035 | } | 1035 | } |
1036 | 1036 | ||
1037 | void dispc_enable_cpr(enum omap_channel channel, bool enable) | ||
1038 | { | ||
1039 | u16 reg; | ||
1040 | |||
1041 | if (channel == OMAP_DSS_CHANNEL_LCD) | ||
1042 | reg = DISPC_CONFIG; | ||
1043 | else if (channel == OMAP_DSS_CHANNEL_LCD2) | ||
1044 | reg = DISPC_CONFIG2; | ||
1045 | else | ||
1046 | return; | ||
1047 | |||
1048 | REG_FLD_MOD(reg, enable, 15, 15); | ||
1049 | } | ||
1050 | |||
1051 | void dispc_set_cpr_coef(enum omap_channel channel, | ||
1052 | struct omap_dss_cpr_coefs *coefs) | ||
1053 | { | ||
1054 | u32 coef_r, coef_g, coef_b; | ||
1055 | |||
1056 | if (channel != OMAP_DSS_CHANNEL_LCD && channel != OMAP_DSS_CHANNEL_LCD2) | ||
1057 | return; | ||
1058 | |||
1059 | coef_r = FLD_VAL(coefs->rr, 31, 22) | FLD_VAL(coefs->rg, 20, 11) | | ||
1060 | FLD_VAL(coefs->rb, 9, 0); | ||
1061 | coef_g = FLD_VAL(coefs->gr, 31, 22) | FLD_VAL(coefs->gg, 20, 11) | | ||
1062 | FLD_VAL(coefs->gb, 9, 0); | ||
1063 | coef_b = FLD_VAL(coefs->br, 31, 22) | FLD_VAL(coefs->bg, 20, 11) | | ||
1064 | FLD_VAL(coefs->bb, 9, 0); | ||
1065 | |||
1066 | dispc_write_reg(DISPC_CPR_COEF_R(channel), coef_r); | ||
1067 | dispc_write_reg(DISPC_CPR_COEF_G(channel), coef_g); | ||
1068 | dispc_write_reg(DISPC_CPR_COEF_B(channel), coef_b); | ||
1069 | } | ||
1070 | |||
1037 | static void _dispc_set_vid_color_conv(enum omap_plane plane, bool enable) | 1071 | static void _dispc_set_vid_color_conv(enum omap_plane plane, bool enable) |
1038 | { | 1072 | { |
1039 | u32 val; | 1073 | u32 val; |
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 8ab6d43329bb..0b4166085b17 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h | |||
@@ -402,6 +402,9 @@ void dispc_setup_plane_fifo(enum omap_plane plane, u32 low, u32 high); | |||
402 | void dispc_enable_fifomerge(bool enable); | 402 | void dispc_enable_fifomerge(bool enable); |
403 | void dispc_set_burst_size(enum omap_plane plane, | 403 | void dispc_set_burst_size(enum omap_plane plane, |
404 | enum omap_burst_size burst_size); | 404 | enum omap_burst_size burst_size); |
405 | void dispc_enable_cpr(enum omap_channel channel, bool enable); | ||
406 | void dispc_set_cpr_coef(enum omap_channel channel, | ||
407 | struct omap_dss_cpr_coefs *coefs); | ||
405 | 408 | ||
406 | void dispc_set_plane_ba0(enum omap_plane plane, u32 paddr); | 409 | void dispc_set_plane_ba0(enum omap_plane plane, u32 paddr); |
407 | void dispc_set_plane_ba1(enum omap_plane plane, u32 paddr); | 410 | void dispc_set_plane_ba1(enum omap_plane plane, u32 paddr); |
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c index 665992d8cc9e..7ebaa40d3b56 100644 --- a/drivers/video/omap2/dss/manager.c +++ b/drivers/video/omap2/dss/manager.c | |||
@@ -275,6 +275,108 @@ static ssize_t manager_alpha_blending_enabled_store( | |||
275 | return size; | 275 | return size; |
276 | } | 276 | } |
277 | 277 | ||
278 | static ssize_t manager_cpr_enable_show(struct omap_overlay_manager *mgr, | ||
279 | char *buf) | ||
280 | { | ||
281 | return snprintf(buf, PAGE_SIZE, "%d\n", mgr->info.cpr_enable); | ||
282 | } | ||
283 | |||
284 | static ssize_t manager_cpr_enable_store(struct omap_overlay_manager *mgr, | ||
285 | const char *buf, size_t size) | ||
286 | { | ||
287 | struct omap_overlay_manager_info info; | ||
288 | int v; | ||
289 | int r; | ||
290 | bool enable; | ||
291 | |||
292 | if (!dss_has_feature(FEAT_CPR)) | ||
293 | return -ENODEV; | ||
294 | |||
295 | r = kstrtoint(buf, 0, &v); | ||
296 | if (r) | ||
297 | return r; | ||
298 | |||
299 | enable = !!v; | ||
300 | |||
301 | mgr->get_manager_info(mgr, &info); | ||
302 | |||
303 | if (info.cpr_enable == enable) | ||
304 | return size; | ||
305 | |||
306 | info.cpr_enable = enable; | ||
307 | |||
308 | r = mgr->set_manager_info(mgr, &info); | ||
309 | if (r) | ||
310 | return r; | ||
311 | |||
312 | r = mgr->apply(mgr); | ||
313 | if (r) | ||
314 | return r; | ||
315 | |||
316 | return size; | ||
317 | } | ||
318 | |||
319 | static ssize_t manager_cpr_coef_show(struct omap_overlay_manager *mgr, | ||
320 | char *buf) | ||
321 | { | ||
322 | struct omap_overlay_manager_info info; | ||
323 | |||
324 | mgr->get_manager_info(mgr, &info); | ||
325 | |||
326 | return snprintf(buf, PAGE_SIZE, | ||
327 | "%d %d %d %d %d %d %d %d %d\n", | ||
328 | info.cpr_coefs.rr, | ||
329 | info.cpr_coefs.rg, | ||
330 | info.cpr_coefs.rb, | ||
331 | info.cpr_coefs.gr, | ||
332 | info.cpr_coefs.gg, | ||
333 | info.cpr_coefs.gb, | ||
334 | info.cpr_coefs.br, | ||
335 | info.cpr_coefs.bg, | ||
336 | info.cpr_coefs.bb); | ||
337 | } | ||
338 | |||
339 | static ssize_t manager_cpr_coef_store(struct omap_overlay_manager *mgr, | ||
340 | const char *buf, size_t size) | ||
341 | { | ||
342 | struct omap_overlay_manager_info info; | ||
343 | struct omap_dss_cpr_coefs coefs; | ||
344 | int r, i; | ||
345 | s16 *arr; | ||
346 | |||
347 | if (!dss_has_feature(FEAT_CPR)) | ||
348 | return -ENODEV; | ||
349 | |||
350 | if (sscanf(buf, "%hd %hd %hd %hd %hd %hd %hd %hd %hd", | ||
351 | &coefs.rr, &coefs.rg, &coefs.rb, | ||
352 | &coefs.gr, &coefs.gg, &coefs.gb, | ||
353 | &coefs.br, &coefs.bg, &coefs.bb) != 9) | ||
354 | return -EINVAL; | ||
355 | |||
356 | arr = (s16[]){ coefs.rr, coefs.rg, coefs.rb, | ||
357 | coefs.gr, coefs.gg, coefs.gb, | ||
358 | coefs.br, coefs.bg, coefs.bb }; | ||
359 | |||
360 | for (i = 0; i < 9; ++i) { | ||
361 | if (arr[i] < -512 || arr[i] > 511) | ||
362 | return -EINVAL; | ||
363 | } | ||
364 | |||
365 | mgr->get_manager_info(mgr, &info); | ||
366 | |||
367 | info.cpr_coefs = coefs; | ||
368 | |||
369 | r = mgr->set_manager_info(mgr, &info); | ||
370 | if (r) | ||
371 | return r; | ||
372 | |||
373 | r = mgr->apply(mgr); | ||
374 | if (r) | ||
375 | return r; | ||
376 | |||
377 | return size; | ||
378 | } | ||
379 | |||
278 | struct manager_attribute { | 380 | struct manager_attribute { |
279 | struct attribute attr; | 381 | struct attribute attr; |
280 | ssize_t (*show)(struct omap_overlay_manager *, char *); | 382 | ssize_t (*show)(struct omap_overlay_manager *, char *); |
@@ -300,6 +402,12 @@ static MANAGER_ATTR(trans_key_enabled, S_IRUGO|S_IWUSR, | |||
300 | static MANAGER_ATTR(alpha_blending_enabled, S_IRUGO|S_IWUSR, | 402 | static MANAGER_ATTR(alpha_blending_enabled, S_IRUGO|S_IWUSR, |
301 | manager_alpha_blending_enabled_show, | 403 | manager_alpha_blending_enabled_show, |
302 | manager_alpha_blending_enabled_store); | 404 | manager_alpha_blending_enabled_store); |
405 | static MANAGER_ATTR(cpr_enable, S_IRUGO|S_IWUSR, | ||
406 | manager_cpr_enable_show, | ||
407 | manager_cpr_enable_store); | ||
408 | static MANAGER_ATTR(cpr_coef, S_IRUGO|S_IWUSR, | ||
409 | manager_cpr_coef_show, | ||
410 | manager_cpr_coef_store); | ||
303 | 411 | ||
304 | 412 | ||
305 | static struct attribute *manager_sysfs_attrs[] = { | 413 | static struct attribute *manager_sysfs_attrs[] = { |
@@ -310,6 +418,8 @@ static struct attribute *manager_sysfs_attrs[] = { | |||
310 | &manager_attr_trans_key_value.attr, | 418 | &manager_attr_trans_key_value.attr, |
311 | &manager_attr_trans_key_enabled.attr, | 419 | &manager_attr_trans_key_enabled.attr, |
312 | &manager_attr_alpha_blending_enabled.attr, | 420 | &manager_attr_alpha_blending_enabled.attr, |
421 | &manager_attr_cpr_enable.attr, | ||
422 | &manager_attr_cpr_coef.attr, | ||
313 | NULL | 423 | NULL |
314 | }; | 424 | }; |
315 | 425 | ||
@@ -858,6 +968,10 @@ static void configure_manager(enum omap_channel channel) | |||
858 | dispc_set_trans_key(channel, mi->trans_key_type, mi->trans_key); | 968 | dispc_set_trans_key(channel, mi->trans_key_type, mi->trans_key); |
859 | dispc_enable_trans_key(channel, mi->trans_enabled); | 969 | dispc_enable_trans_key(channel, mi->trans_enabled); |
860 | dispc_enable_alpha_blending(channel, mi->alpha_enabled); | 970 | dispc_enable_alpha_blending(channel, mi->alpha_enabled); |
971 | if (dss_has_feature(FEAT_CPR)) { | ||
972 | dispc_enable_cpr(channel, mi->cpr_enable); | ||
973 | dispc_set_cpr_coef(channel, &mi->cpr_coefs); | ||
974 | } | ||
861 | } | 975 | } |
862 | 976 | ||
863 | /* configure_dispc() tries to write values from cache to shadow registers. | 977 | /* configure_dispc() tries to write values from cache to shadow registers. |