iMX8X Adjust display brightness contrast saturation

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

iMX8X Adjust display brightness contrast saturation

iMX8X Adjust display brightness contrast saturation

In this doc will show how to adjust display brightness/contrast/saturation by using i.MX8  Display Controller (DC) Subsystem.

 

HW: i.MX8QXP MEK board

SW: Linux 4.14.98_2.0.0 BSP release.

 

See i.MX 8DualXPlus/8QuadXPlus Applications Processor Reference Manual, Rev. D:

pastedImage_1.png

This kind Matrix total number is 5 , that is 0/1/4/5/9.

pastedImage_2.png

pastedImage_3.png

pastedImage_4.png

pastedImage_5.png

pastedImage_6.png

pastedImage_7.png

In this doc using Matrix0 to adjust whole display brightness/contrast/saturation.

Matrix0 unit position is located between FramGen unit and Tcon unit, that means using Matrix0 will impact on the whole display contents.

Note, this Matrix is applied on RGB color space.

  

The Matrix is consist of two parts:

pastedImage_8.pngand pastedImage_9.png

You can program any value into register of A11 to A44 and C1 to C4, Matrix will applied on input RGB data, then output RGB data will changed as you want. In this way, we can change the display brightness/contrast/saturation.

The Matrix entry from A11 to A44, their register format is same as below:

pastedImage_10.png

Each register entry of A11 to A44 , total 13 bit, bit 12 is symbol bit , bit 11 and bit 10 is integer bit, bit 9 to bit 0 is floating point bit.

The Matrix entry from C1 to C4, their format is same as below:

pastedImage_11.png

Each register entry of C1 to C4, total 13 bit, bit 12 is symbol bit, others are integer bit.

Now let us choose the matrix that will be used for adjust brightness/contrast/saturation.

See this link  https://docs.rainmeter.net/tips/colormatrix-guide/

pastedImage_12.png

pastedImage_13.png

So we can set matrix as below to change brightness/contrast/saturation

  A11=c(sr+s)   A12=c(sg)    A13=c(sb)

  A21=c(sb)     A22=c(sg+s)  A23=c(sb)

  A31=c(sr)     A32=c(sg)    A33=c(sb+s)

  C1=C2=C3=t+b

 

b as brightness , range[-1.0, 1.0], zero means no change , >0 will increases brightness, <0 will reduce brightness.

c as contrast, range [0,2.0) , default is 1.0 , >1.0 is increase , <1.0 is reduce.

s is saturation, range [0,1.0], default is 1.0. 

Other matrix entry is related to alpha, in this doc not change it, just keep them as zero.  

 

Note here sr,sb,sg value will depend on lumR/ lumG/ lumB constant value you choose, this value may depend on different color standard.

 

Due to each matrix value is floating point number, and in this doc , i.MX8X run Linux OS.

So you can choose do floating point operation in user space program, then pass related register value into kernel space , let driver write them into register. But in this doc, to make Linux kernel driver more simple, I will convert floating point operation into integer operation , then user space app just pass brightness/contrast/saturation value into kernel space, then kernel driver to do left operation in kernel space.

pastedImage_14.png

So 1024*c and 1024*s is integer number that user space app will passed into kernel space.

And in kernel space could be do left integer number operation, then write register value.

The kernel patch 8qxp_4.14.98_brightness_contrast_saturation.diff could be used on 4.14.98_2.0.0 BSP release.

Test usage, need used one patch that for proptest which from libdrm test case, see 8qxp_prop_test.diff, recompile the proptest case.

root@imx8qxpmek:~# ./proptest     //list current drm property

CRTC 32

        42 bringhtness:

                flags: range

                values: 0 131071

                value:0x0

        43 contrast:

                flags: range

                values: 0 2048

                value:0x400

        44 saturation:

                flags: range

                values: 0 1024

                value:0x400

        45 update:

                flags: range

                values: 0 1

                value:0x0

 

I add four drm property , brightness, contrast, saturation, update. The “update property” should be set as 1 at last, otherwise kernel space will not update related property. Reference API usage ( in 8qxp_prop_test.diff)

+     drmModeObjectSetProperty(fd_rend, obj_id, obj_type, 42, b_int);

+     drmModeObjectSetProperty(fd_rend, obj_id, obj_type, 43, c_int);

+     drmModeObjectSetProperty(fd_rend, obj_id, obj_type, 44, s_int);

+     drmModeObjectSetProperty(fd_rend, obj_id, obj_type, 45, 1);

 

  

//run cmd as below , will ask you input related brightness/contrast/saturation value , then will get result in display

root@imx8qxpmek:~# ./proptest 32 crtc 45 1  

input brightness [-1,1]

0.3

input contrast, >1.0 or <1.0

1.2

input saturation, [0,1]

0.3

brightness 0.300000  0x133 from [-1,1] percent

contrast  1.200000  0x4cc >1.0 or <1.0

saturation 0.300000 0x133  from 0.0 to 1.0

 

Known Issue:

For demo this feature , I need run proptest and weston at same time. Due to the set property drm ioctl default allowed by DRM master and DRM control client. But 4.14. kernel, removed the DRM control device node, so I changed to open drm render node fd, and allow DRM render client to using set property drm ioctl.  This is just a workaround, you may not use it.

Reference:

1.https://www.nxp.com/docs/en/reference-manual/IMX8DQXPRM.pdf 

2.https://docs.rainmeter.net/tips/colormatrix-guide/

Attachments
Comments

I tried. it works as expected. Thanks for your work :smileyhappy:

No ratings
Version history
Last update:
‎07-18-2019 02:40 AM
Updated by: