Lines Matching +full:dc +full:- +full:dc +full:- +full:mode

1 // SPDX-License-Identifier: GPL-2.0-or-later
4 * Copyright (C) 2005-2009 Freescale Semiconductor, Inc.
15 #include <video/imx-ipu-v3.h>
16 #include "ipu-prv.h"
58 #define NULL_WAVE (-1)
90 /* The display interface number assigned to this dc channel */
109 static void dc_link_event(struct ipu_dc *dc, int event, int addr, int priority) in dc_link_event() argument
113 reg = readl(dc->base + DC_RL_CH(event)); in dc_link_event()
116 writel(reg, dc->base + DC_RL_CH(event)); in dc_link_event()
119 static void dc_write_tmpl(struct ipu_dc *dc, int word, u32 opcode, u32 operand, in dc_write_tmpl() argument
122 struct ipu_dc_priv *priv = dc->priv; in dc_write_tmpl()
135 writel(reg1, priv->dc_tmpl_reg + word * 8); in dc_write_tmpl()
136 writel(reg2, priv->dc_tmpl_reg + word * 8 + 4); in dc_write_tmpl()
160 int ipu_dc_init_sync(struct ipu_dc *dc, struct ipu_di *di, bool interlaced, in ipu_dc_init_sync() argument
163 struct ipu_dc_priv *priv = dc->priv; in ipu_dc_init_sync()
168 dc->di = ipu_di_get_num(di); in ipu_dc_init_sync()
171 dev_warn(priv->dev, in ipu_dc_init_sync()
178 * In interlaced mode we need more counters to create the asymmetric in ipu_dc_init_sync()
179 * per-field VSYNC signals. The pixel active signal synchronising DC in ipu_dc_init_sync()
180 * to DI moves to signal generator #6 (see ipu-di.c). In progressive in ipu_dc_init_sync()
181 * mode counter #5 is used. in ipu_dc_init_sync()
186 if (dc->di) in ipu_dc_init_sync()
192 dc_link_event(dc, DC_EVT_NL, addr, 3); in ipu_dc_init_sync()
193 dc_link_event(dc, DC_EVT_EOL, addr, 2); in ipu_dc_init_sync()
194 dc_link_event(dc, DC_EVT_NEW_DATA, addr, 1); in ipu_dc_init_sync()
197 dc_write_tmpl(dc, addr, WROD(0), 0, map, SYNC_WAVE, 0, sync, 1); in ipu_dc_init_sync()
199 dc_link_event(dc, DC_EVT_NL, addr + 2, 3); in ipu_dc_init_sync()
200 dc_link_event(dc, DC_EVT_EOL, addr + 3, 2); in ipu_dc_init_sync()
201 dc_link_event(dc, DC_EVT_NEW_DATA, addr + 1, 1); in ipu_dc_init_sync()
204 dc_write_tmpl(dc, addr + 2, WROD(0), 0, map, SYNC_WAVE, 8, sync, 1); in ipu_dc_init_sync()
205 dc_write_tmpl(dc, addr + 3, WROD(0), 0, map, SYNC_WAVE, 4, sync, 0); in ipu_dc_init_sync()
206 dc_write_tmpl(dc, addr + 4, WRG, 0, map, NULL_WAVE, 0, 0, 1); in ipu_dc_init_sync()
207 dc_write_tmpl(dc, addr + 1, WROD(0), 0, map, SYNC_WAVE, 0, sync, 1); in ipu_dc_init_sync()
210 dc_link_event(dc, DC_EVT_NF, 0, 0); in ipu_dc_init_sync()
211 dc_link_event(dc, DC_EVT_NFIELD, 0, 0); in ipu_dc_init_sync()
212 dc_link_event(dc, DC_EVT_EOF, 0, 0); in ipu_dc_init_sync()
213 dc_link_event(dc, DC_EVT_EOFIELD, 0, 0); in ipu_dc_init_sync()
214 dc_link_event(dc, DC_EVT_NEW_CHAN, 0, 0); in ipu_dc_init_sync()
215 dc_link_event(dc, DC_EVT_NEW_ADDR, 0, 0); in ipu_dc_init_sync()
217 reg = readl(dc->base + DC_WR_CH_CONF); in ipu_dc_init_sync()
222 writel(reg, dc->base + DC_WR_CH_CONF); in ipu_dc_init_sync()
224 writel(0x0, dc->base + DC_WR_CH_ADDR); in ipu_dc_init_sync()
225 writel(width, priv->dc_reg + DC_DISP_CONF2(dc->di)); in ipu_dc_init_sync()
233 struct ipu_dc_priv *priv = ipu->dc_priv; in ipu_dc_enable()
235 mutex_lock(&priv->mutex); in ipu_dc_enable()
237 if (!priv->use_count) in ipu_dc_enable()
238 ipu_module_enable(priv->ipu, IPU_CONF_DC_EN); in ipu_dc_enable()
240 priv->use_count++; in ipu_dc_enable()
242 mutex_unlock(&priv->mutex); in ipu_dc_enable()
246 void ipu_dc_enable_channel(struct ipu_dc *dc) in ipu_dc_enable_channel() argument
250 reg = readl(dc->base + DC_WR_CH_CONF); in ipu_dc_enable_channel()
252 writel(reg, dc->base + DC_WR_CH_CONF); in ipu_dc_enable_channel()
256 void ipu_dc_disable_channel(struct ipu_dc *dc) in ipu_dc_disable_channel() argument
260 val = readl(dc->base + DC_WR_CH_CONF); in ipu_dc_disable_channel()
262 writel(val, dc->base + DC_WR_CH_CONF); in ipu_dc_disable_channel()
268 struct ipu_dc_priv *priv = ipu->dc_priv; in ipu_dc_disable()
270 mutex_lock(&priv->mutex); in ipu_dc_disable()
272 priv->use_count--; in ipu_dc_disable()
273 if (!priv->use_count) in ipu_dc_disable()
274 ipu_module_disable(priv->ipu, IPU_CONF_DC_EN); in ipu_dc_disable()
276 if (priv->use_count < 0) in ipu_dc_disable()
277 priv->use_count = 0; in ipu_dc_disable()
279 mutex_unlock(&priv->mutex); in ipu_dc_disable()
289 reg = readl(priv->dc_reg + DC_MAP_CONF_VAL(ptr)); in ipu_dc_map_config()
292 writel(reg, priv->dc_reg + DC_MAP_CONF_VAL(ptr)); in ipu_dc_map_config()
294 reg = readl(priv->dc_reg + DC_MAP_CONF_PTR(map)); in ipu_dc_map_config()
297 writel(reg, priv->dc_reg + DC_MAP_CONF_PTR(map)); in ipu_dc_map_config()
302 u32 reg = readl(priv->dc_reg + DC_MAP_CONF_PTR(map)); in ipu_dc_map_clear()
305 priv->dc_reg + DC_MAP_CONF_PTR(map)); in ipu_dc_map_clear()
310 struct ipu_dc_priv *priv = ipu->dc_priv; in ipu_dc_get()
311 struct ipu_dc *dc; in ipu_dc_get() local
314 return ERR_PTR(-ENODEV); in ipu_dc_get()
316 dc = &priv->channels[channel]; in ipu_dc_get()
318 mutex_lock(&priv->mutex); in ipu_dc_get()
320 if (dc->in_use) { in ipu_dc_get()
321 mutex_unlock(&priv->mutex); in ipu_dc_get()
322 return ERR_PTR(-EBUSY); in ipu_dc_get()
325 dc->in_use = true; in ipu_dc_get()
327 mutex_unlock(&priv->mutex); in ipu_dc_get()
329 return dc; in ipu_dc_get()
333 void ipu_dc_put(struct ipu_dc *dc) in ipu_dc_put() argument
335 struct ipu_dc_priv *priv = dc->priv; in ipu_dc_put()
337 mutex_lock(&priv->mutex); in ipu_dc_put()
338 dc->in_use = false; in ipu_dc_put()
339 mutex_unlock(&priv->mutex); in ipu_dc_put()
354 return -ENOMEM; in ipu_dc_init()
356 mutex_init(&priv->mutex); in ipu_dc_init()
358 priv->dev = dev; in ipu_dc_init()
359 priv->ipu = ipu; in ipu_dc_init()
360 priv->dc_reg = devm_ioremap(dev, base, PAGE_SIZE); in ipu_dc_init()
361 priv->dc_tmpl_reg = devm_ioremap(dev, template_base, PAGE_SIZE); in ipu_dc_init()
362 if (!priv->dc_reg || !priv->dc_tmpl_reg) in ipu_dc_init()
363 return -ENOMEM; in ipu_dc_init()
366 priv->channels[i].chno = i; in ipu_dc_init()
367 priv->channels[i].priv = priv; in ipu_dc_init()
368 priv->channels[i].base = priv->dc_reg + channel_offsets[i]; in ipu_dc_init()
373 priv->channels[1].base + DC_WR_CH_CONF); in ipu_dc_init()
375 priv->channels[5].base + DC_WR_CH_CONF); in ipu_dc_init()
378 priv->dc_reg + DC_GEN); in ipu_dc_init()
380 ipu->dc_priv = priv; in ipu_dc_init()
382 dev_dbg(dev, "DC base: 0x%08lx template base: 0x%08lx\n", in ipu_dc_init()