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
