diff mbox

[13/17] drm/sun4i: Add DE2 CSC library

Message ID 20171127205750.19277-14-jernej.skrabec@siol.net (mailing list archive)
State New, archived
Headers show

Commit Message

Jernej Škrabec Nov. 27, 2017, 8:57 p.m. UTC
DE2 have many CSC units - channel input CSC, channel output CSC and
mixer output CSC and maybe more.

Fortunately, they have all same register layout, only base offsets
differs.

Add support only for channel output CSC for now.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/gpu/drm/sun4i/Makefile    |  2 +-
 drivers/gpu/drm/sun4i/sun8i_csc.c | 90 +++++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/sun4i/sun8i_csc.h | 36 ++++++++++++++++
 3 files changed, 127 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/sun4i/sun8i_csc.c
 create mode 100644 drivers/gpu/drm/sun4i/sun8i_csc.h

Comments

Maxime Ripard Nov. 28, 2017, 8:55 p.m. UTC | #1
On Mon, Nov 27, 2017 at 09:57:46PM +0100, Jernej Skrabec wrote:
> DE2 have many CSC units - channel input CSC, channel output CSC and
> mixer output CSC and maybe more.
> 
> Fortunately, they have all same register layout, only base offsets
> differs.
> 
> Add support only for channel output CSC for now.
> 
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> ---
>  drivers/gpu/drm/sun4i/Makefile    |  2 +-
>  drivers/gpu/drm/sun4i/sun8i_csc.c | 90 +++++++++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/sun4i/sun8i_csc.h | 36 ++++++++++++++++
>  3 files changed, 127 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/gpu/drm/sun4i/sun8i_csc.c
>  create mode 100644 drivers/gpu/drm/sun4i/sun8i_csc.h
> 
> diff --git a/drivers/gpu/drm/sun4i/Makefile b/drivers/gpu/drm/sun4i/Makefile
> index 70df480792f9..f82cc69ede72 100644
> --- a/drivers/gpu/drm/sun4i/Makefile
> +++ b/drivers/gpu/drm/sun4i/Makefile
> @@ -9,7 +9,7 @@ sun4i-drm-hdmi-y		+= sun4i_hdmi_enc.o
>  sun4i-drm-hdmi-y		+= sun4i_hdmi_i2c.o
>  sun4i-drm-hdmi-y		+= sun4i_hdmi_tmds_clk.o
>  
> -sun8i-mixer-y			+= sun8i_mixer.o sun8i_layer.o sun8i_scaler.o
> +sun8i-mixer-y			+= sun8i_mixer.o sun8i_layer.o sun8i_scaler.o sun8i_csc.o

Please wrap that line.

>  
>  sun4i-tcon-y			+= sun4i_crtc.o
>  sun4i-tcon-y			+= sun4i_dotclock.o
> diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.c b/drivers/gpu/drm/sun4i/sun8i_csc.c
> new file mode 100644
> index 000000000000..d48c28f8d568
> --- /dev/null
> +++ b/drivers/gpu/drm/sun4i/sun8i_csc.c
> @@ -0,0 +1,90 @@
> +/*
> + * Copyright (C) Jernej Skrabec <jernej.skrabec@siol.net>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + */
> +
> +#include "sun8i_csc.h"
> +
> +static const u32 ccsc_base[2][2] = {
> +	{CCSC00_OFFSET, CCSC01_OFFSET},
> +	{CCSC10_OFFSET, CCSC11_OFFSET},
> +};
> +
> +/*
> + * Factors are in two's complement format, 10 bits for fractinal part.
> + * First tree values in each line are multiplication factor and last
> + * value is constant, which is added at the end.
> + */
> +static const u32 yuv2rgb[] = {
> +	0x000004A8, 0x00000000, 0x00000662, 0xFFFC845A,
> +	0x000004A8, 0xFFFFFE6F, 0xFFFFFCBF, 0x00021DF4,
> +	0x000004A8, 0x00000813, 0x00000000, 0xFFFBAC4A,
> +};
> +
> +static const u32 yvu2rgb[] = {
> +	0x000004A8, 0x00000662, 0x00000000, 0xFFFC845A,
> +	0x000004A8, 0xFFFFFCBF, 0xFFFFFE6F, 0x00021DF4,
> +	0x000004A8, 0x00000000, 0x00000813, 0xFFFBAC4A,
> +};
> +
> +static void sun8i_csc_set_coefficients(struct regmap *map, u32 base,
> +				       enum sun8i_csc_mode mode)
> +{
> +	const u32 *table;
> +	int i, data;
> +
> +	switch (mode) {
> +	case SUN8I_CSC_MODE_YUV2RGB:
> +		table = yuv2rgb;
> +		break;
> +	case SUN8I_CSC_MODE_YVU2RGB:
> +		table = yvu2rgb;
> +		break;
> +	default:
> +		WARN(1, "Wrong CSC mode specified.");

A hard warn is a bit overkill here. What about a dev_warn?

Looks good otherwise.

Thanks!
Maxime
Jernej Škrabec Nov. 28, 2017, 9:43 p.m. UTC | #2
Hi!

Dne torek, 28. november 2017 ob 21:55:50 CET je Maxime Ripard napisal(a):
> On Mon, Nov 27, 2017 at 09:57:46PM +0100, Jernej Skrabec wrote:
> > DE2 have many CSC units - channel input CSC, channel output CSC and
> > mixer output CSC and maybe more.
> > 
> > Fortunately, they have all same register layout, only base offsets
> > differs.
> > 
> > Add support only for channel output CSC for now.
> > 
> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> > ---
> > 
> >  drivers/gpu/drm/sun4i/Makefile    |  2 +-
> >  drivers/gpu/drm/sun4i/sun8i_csc.c | 90
> >  +++++++++++++++++++++++++++++++++++++++
> >  drivers/gpu/drm/sun4i/sun8i_csc.h | 36 ++++++++++++++++
> >  3 files changed, 127 insertions(+), 1 deletion(-)
> >  create mode 100644 drivers/gpu/drm/sun4i/sun8i_csc.c
> >  create mode 100644 drivers/gpu/drm/sun4i/sun8i_csc.h
> > 
> > diff --git a/drivers/gpu/drm/sun4i/Makefile
> > b/drivers/gpu/drm/sun4i/Makefile index 70df480792f9..f82cc69ede72 100644
> > --- a/drivers/gpu/drm/sun4i/Makefile
> > +++ b/drivers/gpu/drm/sun4i/Makefile
> > @@ -9,7 +9,7 @@ sun4i-drm-hdmi-y		+= sun4i_hdmi_enc.o
> > 
> >  sun4i-drm-hdmi-y		+= sun4i_hdmi_i2c.o
> >  sun4i-drm-hdmi-y		+= sun4i_hdmi_tmds_clk.o
> > 
> > -sun8i-mixer-y			+= sun8i_mixer.o sun8i_layer.o sun8i_scaler.o
> > +sun8i-mixer-y			+= sun8i_mixer.o sun8i_layer.o sun8i_scaler.o 
sun8i_csc.o
> 
> Please wrap that line.
> 
> >  sun4i-tcon-y			+= sun4i_crtc.o
> >  sun4i-tcon-y			+= sun4i_dotclock.o
> > 
> > diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.c
> > b/drivers/gpu/drm/sun4i/sun8i_csc.c new file mode 100644
> > index 000000000000..d48c28f8d568
> > --- /dev/null
> > +++ b/drivers/gpu/drm/sun4i/sun8i_csc.c
> > @@ -0,0 +1,90 @@
> > +/*
> > + * Copyright (C) Jernej Skrabec <jernej.skrabec@siol.net>
> > + *
> > + * This program is free software; you can redistribute it and/or
> > + * modify it under the terms of the GNU General Public License as
> > + * published by the Free Software Foundation; either version 2 of
> > + * the License, or (at your option) any later version.
> > + */
> > +
> > +#include "sun8i_csc.h"
> > +
> > +static const u32 ccsc_base[2][2] = {
> > +	{CCSC00_OFFSET, CCSC01_OFFSET},
> > +	{CCSC10_OFFSET, CCSC11_OFFSET},
> > +};
> > +
> > +/*
> > + * Factors are in two's complement format, 10 bits for fractinal part.
> > + * First tree values in each line are multiplication factor and last
> > + * value is constant, which is added at the end.
> > + */
> > +static const u32 yuv2rgb[] = {
> > +	0x000004A8, 0x00000000, 0x00000662, 0xFFFC845A,
> > +	0x000004A8, 0xFFFFFE6F, 0xFFFFFCBF, 0x00021DF4,
> > +	0x000004A8, 0x00000813, 0x00000000, 0xFFFBAC4A,
> > +};
> > +
> > +static const u32 yvu2rgb[] = {
> > +	0x000004A8, 0x00000662, 0x00000000, 0xFFFC845A,
> > +	0x000004A8, 0xFFFFFCBF, 0xFFFFFE6F, 0x00021DF4,
> > +	0x000004A8, 0x00000000, 0x00000813, 0xFFFBAC4A,
> > +};
> > +
> > +static void sun8i_csc_set_coefficients(struct regmap *map, u32 base,
> > +				       enum sun8i_csc_mode mode)
> > +{
> > +	const u32 *table;
> > +	int i, data;
> > +
> > +	switch (mode) {
> > +	case SUN8I_CSC_MODE_YUV2RGB:
> > +		table = yuv2rgb;
> > +		break;
> > +	case SUN8I_CSC_MODE_YVU2RGB:
> > +		table = yvu2rgb;
> > +		break;
> > +	default:
> > +		WARN(1, "Wrong CSC mode specified.");
> 
> A hard warn is a bit overkill here. What about a dev_warn?

dev_warn requires device, which is not available here and seems a bit overkill 
to have it as parameter just to print warning. What about DRM_WARN()?

Best regards,
Jernej

> 
> Looks good otherwise.
> 
> Thanks!
> Maxime
> 
> --
> Maxime Ripard, Free Electrons
> Embedded Linux and Kernel engineering
> http://free-electrons.com
Chen-Yu Tsai Nov. 29, 2017, 3:20 a.m. UTC | #3
On Wed, Nov 29, 2017 at 5:43 AM, Jernej Škrabec <jernej.skrabec@siol.net> wrote:
> Hi!
>
> Dne torek, 28. november 2017 ob 21:55:50 CET je Maxime Ripard napisal(a):
>> On Mon, Nov 27, 2017 at 09:57:46PM +0100, Jernej Skrabec wrote:
>> > DE2 have many CSC units - channel input CSC, channel output CSC and
>> > mixer output CSC and maybe more.
>> >
>> > Fortunately, they have all same register layout, only base offsets
>> > differs.
>> >
>> > Add support only for channel output CSC for now.
>> >
>> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
>> > ---
>> >
>> >  drivers/gpu/drm/sun4i/Makefile    |  2 +-
>> >  drivers/gpu/drm/sun4i/sun8i_csc.c | 90
>> >  +++++++++++++++++++++++++++++++++++++++
>> >  drivers/gpu/drm/sun4i/sun8i_csc.h | 36 ++++++++++++++++
>> >  3 files changed, 127 insertions(+), 1 deletion(-)
>> >  create mode 100644 drivers/gpu/drm/sun4i/sun8i_csc.c
>> >  create mode 100644 drivers/gpu/drm/sun4i/sun8i_csc.h
>> >
>> > diff --git a/drivers/gpu/drm/sun4i/Makefile
>> > b/drivers/gpu/drm/sun4i/Makefile index 70df480792f9..f82cc69ede72 100644
>> > --- a/drivers/gpu/drm/sun4i/Makefile
>> > +++ b/drivers/gpu/drm/sun4i/Makefile
>> > @@ -9,7 +9,7 @@ sun4i-drm-hdmi-y            += sun4i_hdmi_enc.o
>> >
>> >  sun4i-drm-hdmi-y           += sun4i_hdmi_i2c.o
>> >  sun4i-drm-hdmi-y           += sun4i_hdmi_tmds_clk.o
>> >
>> > -sun8i-mixer-y                      += sun8i_mixer.o sun8i_layer.o sun8i_scaler.o
>> > +sun8i-mixer-y                      += sun8i_mixer.o sun8i_layer.o sun8i_scaler.o
> sun8i_csc.o
>>
>> Please wrap that line.
>>
>> >  sun4i-tcon-y                       += sun4i_crtc.o
>> >  sun4i-tcon-y                       += sun4i_dotclock.o
>> >
>> > diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.c
>> > b/drivers/gpu/drm/sun4i/sun8i_csc.c new file mode 100644
>> > index 000000000000..d48c28f8d568
>> > --- /dev/null
>> > +++ b/drivers/gpu/drm/sun4i/sun8i_csc.c
>> > @@ -0,0 +1,90 @@
>> > +/*
>> > + * Copyright (C) Jernej Skrabec <jernej.skrabec@siol.net>
>> > + *
>> > + * This program is free software; you can redistribute it and/or
>> > + * modify it under the terms of the GNU General Public License as
>> > + * published by the Free Software Foundation; either version 2 of
>> > + * the License, or (at your option) any later version.
>> > + */
>> > +
>> > +#include "sun8i_csc.h"
>> > +
>> > +static const u32 ccsc_base[2][2] = {
>> > +   {CCSC00_OFFSET, CCSC01_OFFSET},
>> > +   {CCSC10_OFFSET, CCSC11_OFFSET},
>> > +};
>> > +
>> > +/*
>> > + * Factors are in two's complement format, 10 bits for fractinal part.
>> > + * First tree values in each line are multiplication factor and last
>> > + * value is constant, which is added at the end.
>> > + */
>> > +static const u32 yuv2rgb[] = {
>> > +   0x000004A8, 0x00000000, 0x00000662, 0xFFFC845A,
>> > +   0x000004A8, 0xFFFFFE6F, 0xFFFFFCBF, 0x00021DF4,
>> > +   0x000004A8, 0x00000813, 0x00000000, 0xFFFBAC4A,
>> > +};
>> > +
>> > +static const u32 yvu2rgb[] = {
>> > +   0x000004A8, 0x00000662, 0x00000000, 0xFFFC845A,
>> > +   0x000004A8, 0xFFFFFCBF, 0xFFFFFE6F, 0x00021DF4,
>> > +   0x000004A8, 0x00000000, 0x00000813, 0xFFFBAC4A,
>> > +};
>> > +
>> > +static void sun8i_csc_set_coefficients(struct regmap *map, u32 base,
>> > +                                  enum sun8i_csc_mode mode)
>> > +{
>> > +   const u32 *table;
>> > +   int i, data;
>> > +
>> > +   switch (mode) {
>> > +   case SUN8I_CSC_MODE_YUV2RGB:
>> > +           table = yuv2rgb;
>> > +           break;
>> > +   case SUN8I_CSC_MODE_YVU2RGB:
>> > +           table = yvu2rgb;
>> > +           break;
>> > +   default:
>> > +           WARN(1, "Wrong CSC mode specified.");
>>
>> A hard warn is a bit overkill here. What about a dev_warn?
>
> dev_warn requires device, which is not available here and seems a bit overkill
> to have it as parameter just to print warning. What about DRM_WARN()?

dev_warn is just pr_warn that prefixes the device name to the message.
Not sure about DRM_WARN. If it's anything like DRM_DEBUG* then it probably
prefixes the function name.

ChenYu
Maxime Ripard Nov. 29, 2017, 3:27 p.m. UTC | #4
On Tue, Nov 28, 2017 at 10:43:39PM +0100, Jernej Škrabec wrote:
> Hi!
> 
> Dne torek, 28. november 2017 ob 21:55:50 CET je Maxime Ripard napisal(a):
> > On Mon, Nov 27, 2017 at 09:57:46PM +0100, Jernej Skrabec wrote:
> > > DE2 have many CSC units - channel input CSC, channel output CSC and
> > > mixer output CSC and maybe more.
> > > 
> > > Fortunately, they have all same register layout, only base offsets
> > > differs.
> > > 
> > > Add support only for channel output CSC for now.
> > > 
> > > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> > > ---
> > > 
> > >  drivers/gpu/drm/sun4i/Makefile    |  2 +-
> > >  drivers/gpu/drm/sun4i/sun8i_csc.c | 90
> > >  +++++++++++++++++++++++++++++++++++++++
> > >  drivers/gpu/drm/sun4i/sun8i_csc.h | 36 ++++++++++++++++
> > >  3 files changed, 127 insertions(+), 1 deletion(-)
> > >  create mode 100644 drivers/gpu/drm/sun4i/sun8i_csc.c
> > >  create mode 100644 drivers/gpu/drm/sun4i/sun8i_csc.h
> > > 
> > > diff --git a/drivers/gpu/drm/sun4i/Makefile
> > > b/drivers/gpu/drm/sun4i/Makefile index 70df480792f9..f82cc69ede72 100644
> > > --- a/drivers/gpu/drm/sun4i/Makefile
> > > +++ b/drivers/gpu/drm/sun4i/Makefile
> > > @@ -9,7 +9,7 @@ sun4i-drm-hdmi-y		+= sun4i_hdmi_enc.o
> > > 
> > >  sun4i-drm-hdmi-y		+= sun4i_hdmi_i2c.o
> > >  sun4i-drm-hdmi-y		+= sun4i_hdmi_tmds_clk.o
> > > 
> > > -sun8i-mixer-y			+= sun8i_mixer.o sun8i_layer.o sun8i_scaler.o
> > > +sun8i-mixer-y			+= sun8i_mixer.o sun8i_layer.o sun8i_scaler.o 
> sun8i_csc.o
> > 
> > Please wrap that line.
> > 
> > >  sun4i-tcon-y			+= sun4i_crtc.o
> > >  sun4i-tcon-y			+= sun4i_dotclock.o
> > > 
> > > diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.c
> > > b/drivers/gpu/drm/sun4i/sun8i_csc.c new file mode 100644
> > > index 000000000000..d48c28f8d568
> > > --- /dev/null
> > > +++ b/drivers/gpu/drm/sun4i/sun8i_csc.c
> > > @@ -0,0 +1,90 @@
> > > +/*
> > > + * Copyright (C) Jernej Skrabec <jernej.skrabec@siol.net>
> > > + *
> > > + * This program is free software; you can redistribute it and/or
> > > + * modify it under the terms of the GNU General Public License as
> > > + * published by the Free Software Foundation; either version 2 of
> > > + * the License, or (at your option) any later version.
> > > + */
> > > +
> > > +#include "sun8i_csc.h"
> > > +
> > > +static const u32 ccsc_base[2][2] = {
> > > +	{CCSC00_OFFSET, CCSC01_OFFSET},
> > > +	{CCSC10_OFFSET, CCSC11_OFFSET},
> > > +};
> > > +
> > > +/*
> > > + * Factors are in two's complement format, 10 bits for fractinal part.
> > > + * First tree values in each line are multiplication factor and last
> > > + * value is constant, which is added at the end.
> > > + */
> > > +static const u32 yuv2rgb[] = {
> > > +	0x000004A8, 0x00000000, 0x00000662, 0xFFFC845A,
> > > +	0x000004A8, 0xFFFFFE6F, 0xFFFFFCBF, 0x00021DF4,
> > > +	0x000004A8, 0x00000813, 0x00000000, 0xFFFBAC4A,
> > > +};
> > > +
> > > +static const u32 yvu2rgb[] = {
> > > +	0x000004A8, 0x00000662, 0x00000000, 0xFFFC845A,
> > > +	0x000004A8, 0xFFFFFCBF, 0xFFFFFE6F, 0x00021DF4,
> > > +	0x000004A8, 0x00000000, 0x00000813, 0xFFFBAC4A,
> > > +};
> > > +
> > > +static void sun8i_csc_set_coefficients(struct regmap *map, u32 base,
> > > +				       enum sun8i_csc_mode mode)
> > > +{
> > > +	const u32 *table;
> > > +	int i, data;
> > > +
> > > +	switch (mode) {
> > > +	case SUN8I_CSC_MODE_YUV2RGB:
> > > +		table = yuv2rgb;
> > > +		break;
> > > +	case SUN8I_CSC_MODE_YVU2RGB:
> > > +		table = yvu2rgb;
> > > +		break;
> > > +	default:
> > > +		WARN(1, "Wrong CSC mode specified.");
> > 
> > A hard warn is a bit overkill here. What about a dev_warn?
> 
> dev_warn requires device, which is not available here and seems a bit overkill 
> to have it as parameter just to print warning. What about DRM_WARN()?

Anything that doesn't make it look like the world just blew up is fine
by me :)

Maxime
diff mbox

Patch

diff --git a/drivers/gpu/drm/sun4i/Makefile b/drivers/gpu/drm/sun4i/Makefile
index 70df480792f9..f82cc69ede72 100644
--- a/drivers/gpu/drm/sun4i/Makefile
+++ b/drivers/gpu/drm/sun4i/Makefile
@@ -9,7 +9,7 @@  sun4i-drm-hdmi-y		+= sun4i_hdmi_enc.o
 sun4i-drm-hdmi-y		+= sun4i_hdmi_i2c.o
 sun4i-drm-hdmi-y		+= sun4i_hdmi_tmds_clk.o
 
-sun8i-mixer-y			+= sun8i_mixer.o sun8i_layer.o sun8i_scaler.o
+sun8i-mixer-y			+= sun8i_mixer.o sun8i_layer.o sun8i_scaler.o sun8i_csc.o
 
 sun4i-tcon-y			+= sun4i_crtc.o
 sun4i-tcon-y			+= sun4i_dotclock.o
diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.c b/drivers/gpu/drm/sun4i/sun8i_csc.c
new file mode 100644
index 000000000000..d48c28f8d568
--- /dev/null
+++ b/drivers/gpu/drm/sun4i/sun8i_csc.c
@@ -0,0 +1,90 @@ 
+/*
+ * Copyright (C) Jernej Skrabec <jernej.skrabec@siol.net>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+#include "sun8i_csc.h"
+
+static const u32 ccsc_base[2][2] = {
+	{CCSC00_OFFSET, CCSC01_OFFSET},
+	{CCSC10_OFFSET, CCSC11_OFFSET},
+};
+
+/*
+ * Factors are in two's complement format, 10 bits for fractinal part.
+ * First tree values in each line are multiplication factor and last
+ * value is constant, which is added at the end.
+ */
+static const u32 yuv2rgb[] = {
+	0x000004A8, 0x00000000, 0x00000662, 0xFFFC845A,
+	0x000004A8, 0xFFFFFE6F, 0xFFFFFCBF, 0x00021DF4,
+	0x000004A8, 0x00000813, 0x00000000, 0xFFFBAC4A,
+};
+
+static const u32 yvu2rgb[] = {
+	0x000004A8, 0x00000662, 0x00000000, 0xFFFC845A,
+	0x000004A8, 0xFFFFFCBF, 0xFFFFFE6F, 0x00021DF4,
+	0x000004A8, 0x00000000, 0x00000813, 0xFFFBAC4A,
+};
+
+static void sun8i_csc_set_coefficients(struct regmap *map, u32 base,
+				       enum sun8i_csc_mode mode)
+{
+	const u32 *table;
+	int i, data;
+
+	switch (mode) {
+	case SUN8I_CSC_MODE_YUV2RGB:
+		table = yuv2rgb;
+		break;
+	case SUN8I_CSC_MODE_YVU2RGB:
+		table = yvu2rgb;
+		break;
+	default:
+		WARN(1, "Wrong CSC mode specified.");
+		return;
+	}
+
+	for (i = 0; i < 12; i++) {
+		data = table[i];
+		/* For some reason, 0x200 must be added to constant parts */
+		if (((i + 1) & 3) == 0)
+			data += 0x200;
+		regmap_write(map, SUN8I_CSC_COEFF(base, i), data);
+	}
+}
+
+static void sun8i_csc_enable(struct regmap *map, u32 base, bool enable)
+{
+	u32 val;
+
+	if (enable)
+		val = SUN8I_CSC_CTRL_EN;
+	else
+		val = 0;
+
+	regmap_update_bits(map, SUN8I_CSC_CTRL(base), SUN8I_CSC_CTRL_EN, val);
+}
+
+void sun8i_csc_set_ccsc_coefficients(struct sun8i_mixer *mixer, int layer,
+				     enum sun8i_csc_mode mode)
+{
+	u32 base;
+
+	base = ccsc_base[mixer->cfg->ccsc][layer];
+
+	sun8i_csc_set_coefficients(mixer->engine.regs, base, mode);
+}
+
+void sun8i_csc_enable_ccsc(struct sun8i_mixer *mixer, int layer, bool enable)
+{
+	u32 base;
+
+	base = ccsc_base[mixer->cfg->ccsc][layer];
+
+	sun8i_csc_enable(mixer->engine.regs, base, enable);
+}
diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.h b/drivers/gpu/drm/sun4i/sun8i_csc.h
new file mode 100644
index 000000000000..19ae1dda06c4
--- /dev/null
+++ b/drivers/gpu/drm/sun4i/sun8i_csc.h
@@ -0,0 +1,36 @@ 
+/*
+ * Copyright (C) Jernej Skrabec <jernej.skrabec@siol.net>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+#ifndef _SUN8I_CSC_H_
+#define _SUN8I_CSC_H_
+
+#include "sun8i_mixer.h"
+
+/* VI channel CSC units offsets */
+#define CCSC00_OFFSET 0xAA050
+#define CCSC01_OFFSET 0xFA000
+#define CCSC10_OFFSET 0xA0000
+#define CCSC11_OFFSET 0xF0000
+
+#define SUN8I_CSC_CTRL(base)		(base + 0x0)
+#define SUN8I_CSC_COEFF(base, i)	(base + 0x10 + 4 * i)
+
+#define SUN8I_CSC_CTRL_EN		BIT(0)
+
+enum sun8i_csc_mode {
+	SUN8I_CSC_MODE_OFF,
+	SUN8I_CSC_MODE_YUV2RGB,
+	SUN8I_CSC_MODE_YVU2RGB,
+};
+
+void sun8i_csc_set_ccsc_coefficients(struct sun8i_mixer *mixer, int layer,
+				     enum sun8i_csc_mode mode);
+void sun8i_csc_enable_ccsc(struct sun8i_mixer *mixer, int layer, bool enable);
+
+#endif