root/drivers/gpu/ipu-v3/ipu-dmfc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ipu_dmfc_enable_channel
  2. ipu_dmfc_disable_channel
  3. ipu_dmfc_config_wait4eot
  4. ipu_dmfc_get
  5. ipu_dmfc_put
  6. ipu_dmfc_init
  7. ipu_dmfc_exit

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Copyright (c) 2010 Sascha Hauer <s.hauer@pengutronix.de>
   4  * Copyright (C) 2005-2009 Freescale Semiconductor, Inc.
   5  */
   6 #include <linux/export.h>
   7 #include <linux/types.h>
   8 #include <linux/errno.h>
   9 #include <linux/io.h>
  10 
  11 #include <video/imx-ipu-v3.h>
  12 #include "ipu-prv.h"
  13 
  14 #define DMFC_RD_CHAN            0x0000
  15 #define DMFC_WR_CHAN            0x0004
  16 #define DMFC_WR_CHAN_DEF        0x0008
  17 #define DMFC_DP_CHAN            0x000c
  18 #define DMFC_DP_CHAN_DEF        0x0010
  19 #define DMFC_GENERAL1           0x0014
  20 #define DMFC_GENERAL2           0x0018
  21 #define DMFC_IC_CTRL            0x001c
  22 #define DMFC_WR_CHAN_ALT        0x0020
  23 #define DMFC_WR_CHAN_DEF_ALT    0x0024
  24 #define DMFC_DP_CHAN_ALT        0x0028
  25 #define DMFC_DP_CHAN_DEF_ALT    0x002c
  26 #define DMFC_GENERAL1_ALT       0x0030
  27 #define DMFC_STAT               0x0034
  28 
  29 #define DMFC_WR_CHAN_1_28               0
  30 #define DMFC_WR_CHAN_2_41               8
  31 #define DMFC_WR_CHAN_1C_42              16
  32 #define DMFC_WR_CHAN_2C_43              24
  33 
  34 #define DMFC_DP_CHAN_5B_23              0
  35 #define DMFC_DP_CHAN_5F_27              8
  36 #define DMFC_DP_CHAN_6B_24              16
  37 #define DMFC_DP_CHAN_6F_29              24
  38 
  39 struct dmfc_channel_data {
  40         int             ipu_channel;
  41         unsigned long   channel_reg;
  42         unsigned long   shift;
  43         unsigned        eot_shift;
  44         unsigned        max_fifo_lines;
  45 };
  46 
  47 static const struct dmfc_channel_data dmfcdata[] = {
  48         {
  49                 .ipu_channel    = IPUV3_CHANNEL_MEM_BG_SYNC,
  50                 .channel_reg    = DMFC_DP_CHAN,
  51                 .shift          = DMFC_DP_CHAN_5B_23,
  52                 .eot_shift      = 20,
  53                 .max_fifo_lines = 3,
  54         }, {
  55                 .ipu_channel    = 24,
  56                 .channel_reg    = DMFC_DP_CHAN,
  57                 .shift          = DMFC_DP_CHAN_6B_24,
  58                 .eot_shift      = 22,
  59                 .max_fifo_lines = 1,
  60         }, {
  61                 .ipu_channel    = IPUV3_CHANNEL_MEM_FG_SYNC,
  62                 .channel_reg    = DMFC_DP_CHAN,
  63                 .shift          = DMFC_DP_CHAN_5F_27,
  64                 .eot_shift      = 21,
  65                 .max_fifo_lines = 2,
  66         }, {
  67                 .ipu_channel    = IPUV3_CHANNEL_MEM_DC_SYNC,
  68                 .channel_reg    = DMFC_WR_CHAN,
  69                 .shift          = DMFC_WR_CHAN_1_28,
  70                 .eot_shift      = 16,
  71                 .max_fifo_lines = 2,
  72         }, {
  73                 .ipu_channel    = 29,
  74                 .channel_reg    = DMFC_DP_CHAN,
  75                 .shift          = DMFC_DP_CHAN_6F_29,
  76                 .eot_shift      = 23,
  77                 .max_fifo_lines = 1,
  78         },
  79 };
  80 
  81 #define DMFC_NUM_CHANNELS       ARRAY_SIZE(dmfcdata)
  82 
  83 struct ipu_dmfc_priv;
  84 
  85 struct dmfc_channel {
  86         unsigned                        slots;
  87         struct ipu_soc                  *ipu;
  88         struct ipu_dmfc_priv            *priv;
  89         const struct dmfc_channel_data  *data;
  90 };
  91 
  92 struct ipu_dmfc_priv {
  93         struct ipu_soc *ipu;
  94         struct device *dev;
  95         struct dmfc_channel channels[DMFC_NUM_CHANNELS];
  96         struct mutex mutex;
  97         void __iomem *base;
  98         int use_count;
  99 };
 100 
 101 int ipu_dmfc_enable_channel(struct dmfc_channel *dmfc)
 102 {
 103         struct ipu_dmfc_priv *priv = dmfc->priv;
 104         mutex_lock(&priv->mutex);
 105 
 106         if (!priv->use_count)
 107                 ipu_module_enable(priv->ipu, IPU_CONF_DMFC_EN);
 108 
 109         priv->use_count++;
 110 
 111         mutex_unlock(&priv->mutex);
 112 
 113         return 0;
 114 }
 115 EXPORT_SYMBOL_GPL(ipu_dmfc_enable_channel);
 116 
 117 void ipu_dmfc_disable_channel(struct dmfc_channel *dmfc)
 118 {
 119         struct ipu_dmfc_priv *priv = dmfc->priv;
 120 
 121         mutex_lock(&priv->mutex);
 122 
 123         priv->use_count--;
 124 
 125         if (!priv->use_count)
 126                 ipu_module_disable(priv->ipu, IPU_CONF_DMFC_EN);
 127 
 128         if (priv->use_count < 0)
 129                 priv->use_count = 0;
 130 
 131         mutex_unlock(&priv->mutex);
 132 }
 133 EXPORT_SYMBOL_GPL(ipu_dmfc_disable_channel);
 134 
 135 void ipu_dmfc_config_wait4eot(struct dmfc_channel *dmfc, int width)
 136 {
 137         struct ipu_dmfc_priv *priv = dmfc->priv;
 138         u32 dmfc_gen1;
 139 
 140         mutex_lock(&priv->mutex);
 141 
 142         dmfc_gen1 = readl(priv->base + DMFC_GENERAL1);
 143 
 144         if ((dmfc->slots * 64 * 4) / width > dmfc->data->max_fifo_lines)
 145                 dmfc_gen1 |= 1 << dmfc->data->eot_shift;
 146         else
 147                 dmfc_gen1 &= ~(1 << dmfc->data->eot_shift);
 148 
 149         writel(dmfc_gen1, priv->base + DMFC_GENERAL1);
 150 
 151         mutex_unlock(&priv->mutex);
 152 }
 153 EXPORT_SYMBOL_GPL(ipu_dmfc_config_wait4eot);
 154 
 155 struct dmfc_channel *ipu_dmfc_get(struct ipu_soc *ipu, int ipu_channel)
 156 {
 157         struct ipu_dmfc_priv *priv = ipu->dmfc_priv;
 158         int i;
 159 
 160         for (i = 0; i < DMFC_NUM_CHANNELS; i++)
 161                 if (dmfcdata[i].ipu_channel == ipu_channel)
 162                         return &priv->channels[i];
 163         return ERR_PTR(-ENODEV);
 164 }
 165 EXPORT_SYMBOL_GPL(ipu_dmfc_get);
 166 
 167 void ipu_dmfc_put(struct dmfc_channel *dmfc)
 168 {
 169 }
 170 EXPORT_SYMBOL_GPL(ipu_dmfc_put);
 171 
 172 int ipu_dmfc_init(struct ipu_soc *ipu, struct device *dev, unsigned long base,
 173                 struct clk *ipu_clk)
 174 {
 175         struct ipu_dmfc_priv *priv;
 176         int i;
 177 
 178         priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 179         if (!priv)
 180                 return -ENOMEM;
 181 
 182         priv->base = devm_ioremap(dev, base, PAGE_SIZE);
 183         if (!priv->base)
 184                 return -ENOMEM;
 185 
 186         priv->dev = dev;
 187         priv->ipu = ipu;
 188         mutex_init(&priv->mutex);
 189 
 190         ipu->dmfc_priv = priv;
 191 
 192         for (i = 0; i < DMFC_NUM_CHANNELS; i++) {
 193                 priv->channels[i].priv = priv;
 194                 priv->channels[i].ipu = ipu;
 195                 priv->channels[i].data = &dmfcdata[i];
 196 
 197                 if (dmfcdata[i].ipu_channel == IPUV3_CHANNEL_MEM_BG_SYNC ||
 198                     dmfcdata[i].ipu_channel == IPUV3_CHANNEL_MEM_FG_SYNC ||
 199                     dmfcdata[i].ipu_channel == IPUV3_CHANNEL_MEM_DC_SYNC)
 200                         priv->channels[i].slots = 2;
 201         }
 202 
 203         writel(0x00000050, priv->base + DMFC_WR_CHAN);
 204         writel(0x00005654, priv->base + DMFC_DP_CHAN);
 205         writel(0x202020f6, priv->base + DMFC_WR_CHAN_DEF);
 206         writel(0x2020f6f6, priv->base + DMFC_DP_CHAN_DEF);
 207         writel(0x00000003, priv->base + DMFC_GENERAL1);
 208 
 209         return 0;
 210 }
 211 
 212 void ipu_dmfc_exit(struct ipu_soc *ipu)
 213 {
 214 }

/* [<][>][^][v][top][bottom][index][help] */