162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (c) 2010 Sascha Hauer <s.hauer@pengutronix.de>
462306a36Sopenharmony_ci * Copyright (C) 2005-2009 Freescale Semiconductor, Inc.
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci#include <linux/export.h>
762306a36Sopenharmony_ci#include <linux/kernel.h>
862306a36Sopenharmony_ci#include <linux/types.h>
962306a36Sopenharmony_ci#include <linux/errno.h>
1062306a36Sopenharmony_ci#include <linux/io.h>
1162306a36Sopenharmony_ci#include <linux/err.h>
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#include <drm/drm_color_mgmt.h>
1462306a36Sopenharmony_ci#include <video/imx-ipu-v3.h>
1562306a36Sopenharmony_ci#include "ipu-prv.h"
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci#define DP_SYNC 0
1862306a36Sopenharmony_ci#define DP_ASYNC0 0x60
1962306a36Sopenharmony_ci#define DP_ASYNC1 0xBC
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci#define DP_COM_CONF		0x0
2262306a36Sopenharmony_ci#define DP_GRAPH_WIND_CTRL	0x0004
2362306a36Sopenharmony_ci#define DP_FG_POS		0x0008
2462306a36Sopenharmony_ci#define DP_CSC_A_0		0x0044
2562306a36Sopenharmony_ci#define DP_CSC_A_1		0x0048
2662306a36Sopenharmony_ci#define DP_CSC_A_2		0x004C
2762306a36Sopenharmony_ci#define DP_CSC_A_3		0x0050
2862306a36Sopenharmony_ci#define DP_CSC_0		0x0054
2962306a36Sopenharmony_ci#define DP_CSC_1		0x0058
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci#define DP_COM_CONF_FG_EN		(1 << 0)
3262306a36Sopenharmony_ci#define DP_COM_CONF_GWSEL		(1 << 1)
3362306a36Sopenharmony_ci#define DP_COM_CONF_GWAM		(1 << 2)
3462306a36Sopenharmony_ci#define DP_COM_CONF_GWCKE		(1 << 3)
3562306a36Sopenharmony_ci#define DP_COM_CONF_CSC_DEF_MASK	(3 << 8)
3662306a36Sopenharmony_ci#define DP_COM_CONF_CSC_DEF_OFFSET	8
3762306a36Sopenharmony_ci#define DP_COM_CONF_CSC_DEF_FG		(3 << 8)
3862306a36Sopenharmony_ci#define DP_COM_CONF_CSC_DEF_BG		(2 << 8)
3962306a36Sopenharmony_ci#define DP_COM_CONF_CSC_DEF_BOTH	(1 << 8)
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci#define IPUV3_NUM_FLOWS		3
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_cistruct ipu_dp_priv;
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_cistruct ipu_dp {
4662306a36Sopenharmony_ci	u32 flow;
4762306a36Sopenharmony_ci	bool in_use;
4862306a36Sopenharmony_ci	bool foreground;
4962306a36Sopenharmony_ci	enum ipu_color_space in_cs;
5062306a36Sopenharmony_ci};
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_cistruct ipu_flow {
5362306a36Sopenharmony_ci	struct ipu_dp foreground;
5462306a36Sopenharmony_ci	struct ipu_dp background;
5562306a36Sopenharmony_ci	enum ipu_color_space out_cs;
5662306a36Sopenharmony_ci	void __iomem *base;
5762306a36Sopenharmony_ci	struct ipu_dp_priv *priv;
5862306a36Sopenharmony_ci};
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_cistruct ipu_dp_priv {
6162306a36Sopenharmony_ci	struct ipu_soc *ipu;
6262306a36Sopenharmony_ci	struct device *dev;
6362306a36Sopenharmony_ci	void __iomem *base;
6462306a36Sopenharmony_ci	struct ipu_flow flow[IPUV3_NUM_FLOWS];
6562306a36Sopenharmony_ci	struct mutex mutex;
6662306a36Sopenharmony_ci	int use_count;
6762306a36Sopenharmony_ci};
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_cistatic u32 ipu_dp_flow_base[] = {DP_SYNC, DP_ASYNC0, DP_ASYNC1};
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_cistatic inline struct ipu_flow *to_flow(struct ipu_dp *dp)
7262306a36Sopenharmony_ci{
7362306a36Sopenharmony_ci	if (dp->foreground)
7462306a36Sopenharmony_ci		return container_of(dp, struct ipu_flow, foreground);
7562306a36Sopenharmony_ci	else
7662306a36Sopenharmony_ci		return container_of(dp, struct ipu_flow, background);
7762306a36Sopenharmony_ci}
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ciint ipu_dp_set_global_alpha(struct ipu_dp *dp, bool enable,
8062306a36Sopenharmony_ci		u8 alpha, bool bg_chan)
8162306a36Sopenharmony_ci{
8262306a36Sopenharmony_ci	struct ipu_flow *flow = to_flow(dp);
8362306a36Sopenharmony_ci	struct ipu_dp_priv *priv = flow->priv;
8462306a36Sopenharmony_ci	u32 reg;
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci	mutex_lock(&priv->mutex);
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci	reg = readl(flow->base + DP_COM_CONF);
8962306a36Sopenharmony_ci	if (bg_chan)
9062306a36Sopenharmony_ci		reg &= ~DP_COM_CONF_GWSEL;
9162306a36Sopenharmony_ci	else
9262306a36Sopenharmony_ci		reg |= DP_COM_CONF_GWSEL;
9362306a36Sopenharmony_ci	writel(reg, flow->base + DP_COM_CONF);
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ci	if (enable) {
9662306a36Sopenharmony_ci		reg = readl(flow->base + DP_GRAPH_WIND_CTRL) & 0x00FFFFFFL;
9762306a36Sopenharmony_ci		writel(reg | ((u32) alpha << 24),
9862306a36Sopenharmony_ci			     flow->base + DP_GRAPH_WIND_CTRL);
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci		reg = readl(flow->base + DP_COM_CONF);
10162306a36Sopenharmony_ci		writel(reg | DP_COM_CONF_GWAM, flow->base + DP_COM_CONF);
10262306a36Sopenharmony_ci	} else {
10362306a36Sopenharmony_ci		reg = readl(flow->base + DP_COM_CONF);
10462306a36Sopenharmony_ci		writel(reg & ~DP_COM_CONF_GWAM, flow->base + DP_COM_CONF);
10562306a36Sopenharmony_ci	}
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci	ipu_srm_dp_update(priv->ipu, true);
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ci	mutex_unlock(&priv->mutex);
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_ci	return 0;
11262306a36Sopenharmony_ci}
11362306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ipu_dp_set_global_alpha);
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ciint ipu_dp_set_window_pos(struct ipu_dp *dp, u16 x_pos, u16 y_pos)
11662306a36Sopenharmony_ci{
11762306a36Sopenharmony_ci	struct ipu_flow *flow = to_flow(dp);
11862306a36Sopenharmony_ci	struct ipu_dp_priv *priv = flow->priv;
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_ci	writel((x_pos << 16) | y_pos, flow->base + DP_FG_POS);
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci	ipu_srm_dp_update(priv->ipu, true);
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_ci	return 0;
12562306a36Sopenharmony_ci}
12662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ipu_dp_set_window_pos);
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_cistatic void ipu_dp_csc_init(struct ipu_flow *flow,
12962306a36Sopenharmony_ci		enum drm_color_encoding ycbcr_enc,
13062306a36Sopenharmony_ci		enum drm_color_range range,
13162306a36Sopenharmony_ci		enum ipu_color_space in,
13262306a36Sopenharmony_ci		enum ipu_color_space out,
13362306a36Sopenharmony_ci		u32 place)
13462306a36Sopenharmony_ci{
13562306a36Sopenharmony_ci	u32 reg;
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ci	reg = readl(flow->base + DP_COM_CONF);
13862306a36Sopenharmony_ci	reg &= ~DP_COM_CONF_CSC_DEF_MASK;
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci	if (in == out) {
14162306a36Sopenharmony_ci		writel(reg, flow->base + DP_COM_CONF);
14262306a36Sopenharmony_ci		return;
14362306a36Sopenharmony_ci	}
14462306a36Sopenharmony_ci
14562306a36Sopenharmony_ci	if (in == IPUV3_COLORSPACE_RGB && out == IPUV3_COLORSPACE_YUV) {
14662306a36Sopenharmony_ci		writel(0x099 | (0x12d << 16), flow->base + DP_CSC_A_0);
14762306a36Sopenharmony_ci		writel(0x03a | (0x3a9 << 16), flow->base + DP_CSC_A_1);
14862306a36Sopenharmony_ci		writel(0x356 | (0x100 << 16), flow->base + DP_CSC_A_2);
14962306a36Sopenharmony_ci		writel(0x100 | (0x329 << 16), flow->base + DP_CSC_A_3);
15062306a36Sopenharmony_ci		writel(0x3d6 | (0x0000 << 16) | (2 << 30),
15162306a36Sopenharmony_ci				flow->base + DP_CSC_0);
15262306a36Sopenharmony_ci		writel(0x200 | (2 << 14) | (0x200 << 16) | (2 << 30),
15362306a36Sopenharmony_ci				flow->base + DP_CSC_1);
15462306a36Sopenharmony_ci	} else if (ycbcr_enc == DRM_COLOR_YCBCR_BT709) {
15562306a36Sopenharmony_ci		/* Rec.709 limited range */
15662306a36Sopenharmony_ci		writel(0x095 | (0x000 << 16), flow->base + DP_CSC_A_0);
15762306a36Sopenharmony_ci		writel(0x0e5 | (0x095 << 16), flow->base + DP_CSC_A_1);
15862306a36Sopenharmony_ci		writel(0x3e5 | (0x3bc << 16), flow->base + DP_CSC_A_2);
15962306a36Sopenharmony_ci		writel(0x095 | (0x10e << 16), flow->base + DP_CSC_A_3);
16062306a36Sopenharmony_ci		writel(0x000 | (0x3e10 << 16) | (1 << 30),
16162306a36Sopenharmony_ci				flow->base + DP_CSC_0);
16262306a36Sopenharmony_ci		writel(0x09a | (1 << 14) | (0x3dbe << 16) | (1 << 30),
16362306a36Sopenharmony_ci				flow->base + DP_CSC_1);
16462306a36Sopenharmony_ci	} else {
16562306a36Sopenharmony_ci		/* BT.601 limited range */
16662306a36Sopenharmony_ci		writel(0x095 | (0x000 << 16), flow->base + DP_CSC_A_0);
16762306a36Sopenharmony_ci		writel(0x0cc | (0x095 << 16), flow->base + DP_CSC_A_1);
16862306a36Sopenharmony_ci		writel(0x3ce | (0x398 << 16), flow->base + DP_CSC_A_2);
16962306a36Sopenharmony_ci		writel(0x095 | (0x0ff << 16), flow->base + DP_CSC_A_3);
17062306a36Sopenharmony_ci		writel(0x000 | (0x3e42 << 16) | (1 << 30),
17162306a36Sopenharmony_ci				flow->base + DP_CSC_0);
17262306a36Sopenharmony_ci		writel(0x10a | (1 << 14) | (0x3dd6 << 16) | (1 << 30),
17362306a36Sopenharmony_ci				flow->base + DP_CSC_1);
17462306a36Sopenharmony_ci	}
17562306a36Sopenharmony_ci
17662306a36Sopenharmony_ci	reg |= place;
17762306a36Sopenharmony_ci
17862306a36Sopenharmony_ci	writel(reg, flow->base + DP_COM_CONF);
17962306a36Sopenharmony_ci}
18062306a36Sopenharmony_ci
18162306a36Sopenharmony_ciint ipu_dp_setup_channel(struct ipu_dp *dp,
18262306a36Sopenharmony_ci		enum drm_color_encoding ycbcr_enc,
18362306a36Sopenharmony_ci		enum drm_color_range range,
18462306a36Sopenharmony_ci		enum ipu_color_space in,
18562306a36Sopenharmony_ci		enum ipu_color_space out)
18662306a36Sopenharmony_ci{
18762306a36Sopenharmony_ci	struct ipu_flow *flow = to_flow(dp);
18862306a36Sopenharmony_ci	struct ipu_dp_priv *priv = flow->priv;
18962306a36Sopenharmony_ci
19062306a36Sopenharmony_ci	mutex_lock(&priv->mutex);
19162306a36Sopenharmony_ci
19262306a36Sopenharmony_ci	dp->in_cs = in;
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_ci	if (!dp->foreground)
19562306a36Sopenharmony_ci		flow->out_cs = out;
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_ci	if (flow->foreground.in_cs == flow->background.in_cs) {
19862306a36Sopenharmony_ci		/*
19962306a36Sopenharmony_ci		 * foreground and background are of same colorspace, put
20062306a36Sopenharmony_ci		 * colorspace converter after combining unit.
20162306a36Sopenharmony_ci		 */
20262306a36Sopenharmony_ci		ipu_dp_csc_init(flow, ycbcr_enc, range,
20362306a36Sopenharmony_ci				flow->foreground.in_cs, flow->out_cs,
20462306a36Sopenharmony_ci				DP_COM_CONF_CSC_DEF_BOTH);
20562306a36Sopenharmony_ci	} else {
20662306a36Sopenharmony_ci		if (flow->foreground.in_cs == IPUV3_COLORSPACE_UNKNOWN ||
20762306a36Sopenharmony_ci		    flow->foreground.in_cs == flow->out_cs)
20862306a36Sopenharmony_ci			/*
20962306a36Sopenharmony_ci			 * foreground identical to output, apply color
21062306a36Sopenharmony_ci			 * conversion on background
21162306a36Sopenharmony_ci			 */
21262306a36Sopenharmony_ci			ipu_dp_csc_init(flow, ycbcr_enc, range,
21362306a36Sopenharmony_ci					flow->background.in_cs,
21462306a36Sopenharmony_ci					flow->out_cs, DP_COM_CONF_CSC_DEF_BG);
21562306a36Sopenharmony_ci		else
21662306a36Sopenharmony_ci			ipu_dp_csc_init(flow, ycbcr_enc, range,
21762306a36Sopenharmony_ci					flow->foreground.in_cs,
21862306a36Sopenharmony_ci					flow->out_cs, DP_COM_CONF_CSC_DEF_FG);
21962306a36Sopenharmony_ci	}
22062306a36Sopenharmony_ci
22162306a36Sopenharmony_ci	ipu_srm_dp_update(priv->ipu, true);
22262306a36Sopenharmony_ci
22362306a36Sopenharmony_ci	mutex_unlock(&priv->mutex);
22462306a36Sopenharmony_ci
22562306a36Sopenharmony_ci	return 0;
22662306a36Sopenharmony_ci}
22762306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ipu_dp_setup_channel);
22862306a36Sopenharmony_ci
22962306a36Sopenharmony_ciint ipu_dp_enable(struct ipu_soc *ipu)
23062306a36Sopenharmony_ci{
23162306a36Sopenharmony_ci	struct ipu_dp_priv *priv = ipu->dp_priv;
23262306a36Sopenharmony_ci
23362306a36Sopenharmony_ci	mutex_lock(&priv->mutex);
23462306a36Sopenharmony_ci
23562306a36Sopenharmony_ci	if (!priv->use_count)
23662306a36Sopenharmony_ci		ipu_module_enable(priv->ipu, IPU_CONF_DP_EN);
23762306a36Sopenharmony_ci
23862306a36Sopenharmony_ci	priv->use_count++;
23962306a36Sopenharmony_ci
24062306a36Sopenharmony_ci	mutex_unlock(&priv->mutex);
24162306a36Sopenharmony_ci
24262306a36Sopenharmony_ci	return 0;
24362306a36Sopenharmony_ci}
24462306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ipu_dp_enable);
24562306a36Sopenharmony_ci
24662306a36Sopenharmony_ciint ipu_dp_enable_channel(struct ipu_dp *dp)
24762306a36Sopenharmony_ci{
24862306a36Sopenharmony_ci	struct ipu_flow *flow = to_flow(dp);
24962306a36Sopenharmony_ci	struct ipu_dp_priv *priv = flow->priv;
25062306a36Sopenharmony_ci	u32 reg;
25162306a36Sopenharmony_ci
25262306a36Sopenharmony_ci	if (!dp->foreground)
25362306a36Sopenharmony_ci		return 0;
25462306a36Sopenharmony_ci
25562306a36Sopenharmony_ci	mutex_lock(&priv->mutex);
25662306a36Sopenharmony_ci
25762306a36Sopenharmony_ci	reg = readl(flow->base + DP_COM_CONF);
25862306a36Sopenharmony_ci	reg |= DP_COM_CONF_FG_EN;
25962306a36Sopenharmony_ci	writel(reg, flow->base + DP_COM_CONF);
26062306a36Sopenharmony_ci
26162306a36Sopenharmony_ci	ipu_srm_dp_update(priv->ipu, true);
26262306a36Sopenharmony_ci
26362306a36Sopenharmony_ci	mutex_unlock(&priv->mutex);
26462306a36Sopenharmony_ci
26562306a36Sopenharmony_ci	return 0;
26662306a36Sopenharmony_ci}
26762306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ipu_dp_enable_channel);
26862306a36Sopenharmony_ci
26962306a36Sopenharmony_civoid ipu_dp_disable_channel(struct ipu_dp *dp, bool sync)
27062306a36Sopenharmony_ci{
27162306a36Sopenharmony_ci	struct ipu_flow *flow = to_flow(dp);
27262306a36Sopenharmony_ci	struct ipu_dp_priv *priv = flow->priv;
27362306a36Sopenharmony_ci	u32 reg, csc;
27462306a36Sopenharmony_ci
27562306a36Sopenharmony_ci	dp->in_cs = IPUV3_COLORSPACE_UNKNOWN;
27662306a36Sopenharmony_ci
27762306a36Sopenharmony_ci	if (!dp->foreground)
27862306a36Sopenharmony_ci		return;
27962306a36Sopenharmony_ci
28062306a36Sopenharmony_ci	mutex_lock(&priv->mutex);
28162306a36Sopenharmony_ci
28262306a36Sopenharmony_ci	reg = readl(flow->base + DP_COM_CONF);
28362306a36Sopenharmony_ci	csc = reg & DP_COM_CONF_CSC_DEF_MASK;
28462306a36Sopenharmony_ci	reg &= ~DP_COM_CONF_CSC_DEF_MASK;
28562306a36Sopenharmony_ci	if (csc == DP_COM_CONF_CSC_DEF_BOTH || csc == DP_COM_CONF_CSC_DEF_BG)
28662306a36Sopenharmony_ci		reg |= DP_COM_CONF_CSC_DEF_BG;
28762306a36Sopenharmony_ci
28862306a36Sopenharmony_ci	reg &= ~DP_COM_CONF_FG_EN;
28962306a36Sopenharmony_ci	writel(reg, flow->base + DP_COM_CONF);
29062306a36Sopenharmony_ci
29162306a36Sopenharmony_ci	writel(0, flow->base + DP_FG_POS);
29262306a36Sopenharmony_ci	ipu_srm_dp_update(priv->ipu, sync);
29362306a36Sopenharmony_ci
29462306a36Sopenharmony_ci	mutex_unlock(&priv->mutex);
29562306a36Sopenharmony_ci}
29662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ipu_dp_disable_channel);
29762306a36Sopenharmony_ci
29862306a36Sopenharmony_civoid ipu_dp_disable(struct ipu_soc *ipu)
29962306a36Sopenharmony_ci{
30062306a36Sopenharmony_ci	struct ipu_dp_priv *priv = ipu->dp_priv;
30162306a36Sopenharmony_ci
30262306a36Sopenharmony_ci	mutex_lock(&priv->mutex);
30362306a36Sopenharmony_ci
30462306a36Sopenharmony_ci	priv->use_count--;
30562306a36Sopenharmony_ci
30662306a36Sopenharmony_ci	if (!priv->use_count)
30762306a36Sopenharmony_ci		ipu_module_disable(priv->ipu, IPU_CONF_DP_EN);
30862306a36Sopenharmony_ci
30962306a36Sopenharmony_ci	if (priv->use_count < 0)
31062306a36Sopenharmony_ci		priv->use_count = 0;
31162306a36Sopenharmony_ci
31262306a36Sopenharmony_ci	mutex_unlock(&priv->mutex);
31362306a36Sopenharmony_ci}
31462306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ipu_dp_disable);
31562306a36Sopenharmony_ci
31662306a36Sopenharmony_cistruct ipu_dp *ipu_dp_get(struct ipu_soc *ipu, unsigned int flow)
31762306a36Sopenharmony_ci{
31862306a36Sopenharmony_ci	struct ipu_dp_priv *priv = ipu->dp_priv;
31962306a36Sopenharmony_ci	struct ipu_dp *dp;
32062306a36Sopenharmony_ci
32162306a36Sopenharmony_ci	if ((flow >> 1) >= IPUV3_NUM_FLOWS)
32262306a36Sopenharmony_ci		return ERR_PTR(-EINVAL);
32362306a36Sopenharmony_ci
32462306a36Sopenharmony_ci	if (flow & 1)
32562306a36Sopenharmony_ci		dp = &priv->flow[flow >> 1].foreground;
32662306a36Sopenharmony_ci	else
32762306a36Sopenharmony_ci		dp = &priv->flow[flow >> 1].background;
32862306a36Sopenharmony_ci
32962306a36Sopenharmony_ci	if (dp->in_use)
33062306a36Sopenharmony_ci		return ERR_PTR(-EBUSY);
33162306a36Sopenharmony_ci
33262306a36Sopenharmony_ci	dp->in_use = true;
33362306a36Sopenharmony_ci
33462306a36Sopenharmony_ci	return dp;
33562306a36Sopenharmony_ci}
33662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ipu_dp_get);
33762306a36Sopenharmony_ci
33862306a36Sopenharmony_civoid ipu_dp_put(struct ipu_dp *dp)
33962306a36Sopenharmony_ci{
34062306a36Sopenharmony_ci	dp->in_use = false;
34162306a36Sopenharmony_ci}
34262306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ipu_dp_put);
34362306a36Sopenharmony_ci
34462306a36Sopenharmony_ciint ipu_dp_init(struct ipu_soc *ipu, struct device *dev, unsigned long base)
34562306a36Sopenharmony_ci{
34662306a36Sopenharmony_ci	struct ipu_dp_priv *priv;
34762306a36Sopenharmony_ci	int i;
34862306a36Sopenharmony_ci
34962306a36Sopenharmony_ci	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
35062306a36Sopenharmony_ci	if (!priv)
35162306a36Sopenharmony_ci		return -ENOMEM;
35262306a36Sopenharmony_ci	priv->dev = dev;
35362306a36Sopenharmony_ci	priv->ipu = ipu;
35462306a36Sopenharmony_ci
35562306a36Sopenharmony_ci	ipu->dp_priv = priv;
35662306a36Sopenharmony_ci
35762306a36Sopenharmony_ci	priv->base = devm_ioremap(dev, base, PAGE_SIZE);
35862306a36Sopenharmony_ci	if (!priv->base)
35962306a36Sopenharmony_ci		return -ENOMEM;
36062306a36Sopenharmony_ci
36162306a36Sopenharmony_ci	mutex_init(&priv->mutex);
36262306a36Sopenharmony_ci
36362306a36Sopenharmony_ci	for (i = 0; i < IPUV3_NUM_FLOWS; i++) {
36462306a36Sopenharmony_ci		priv->flow[i].background.in_cs = IPUV3_COLORSPACE_UNKNOWN;
36562306a36Sopenharmony_ci		priv->flow[i].foreground.in_cs = IPUV3_COLORSPACE_UNKNOWN;
36662306a36Sopenharmony_ci		priv->flow[i].foreground.foreground = true;
36762306a36Sopenharmony_ci		priv->flow[i].base = priv->base + ipu_dp_flow_base[i];
36862306a36Sopenharmony_ci		priv->flow[i].priv = priv;
36962306a36Sopenharmony_ci	}
37062306a36Sopenharmony_ci
37162306a36Sopenharmony_ci	return 0;
37262306a36Sopenharmony_ci}
37362306a36Sopenharmony_ci
37462306a36Sopenharmony_civoid ipu_dp_exit(struct ipu_soc *ipu)
37562306a36Sopenharmony_ci{
37662306a36Sopenharmony_ci}
377