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