Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Copyright (c) 2010 Sascha Hauer <s.hauer@pengutronix.de>
0004  * Copyright (C) 2005-2009 Freescale Semiconductor, Inc.
0005  */
0006 #include <linux/module.h>
0007 #include <linux/export.h>
0008 #include <linux/types.h>
0009 #include <linux/reset.h>
0010 #include <linux/platform_device.h>
0011 #include <linux/err.h>
0012 #include <linux/spinlock.h>
0013 #include <linux/delay.h>
0014 #include <linux/interrupt.h>
0015 #include <linux/io.h>
0016 #include <linux/clk.h>
0017 #include <linux/list.h>
0018 #include <linux/irq.h>
0019 #include <linux/irqchip/chained_irq.h>
0020 #include <linux/irqdomain.h>
0021 #include <linux/of_device.h>
0022 #include <linux/of_graph.h>
0023 
0024 #include <drm/drm_fourcc.h>
0025 
0026 #include <video/imx-ipu-v3.h>
0027 #include "ipu-prv.h"
0028 
0029 static inline u32 ipu_cm_read(struct ipu_soc *ipu, unsigned offset)
0030 {
0031     return readl(ipu->cm_reg + offset);
0032 }
0033 
0034 static inline void ipu_cm_write(struct ipu_soc *ipu, u32 value, unsigned offset)
0035 {
0036     writel(value, ipu->cm_reg + offset);
0037 }
0038 
0039 int ipu_get_num(struct ipu_soc *ipu)
0040 {
0041     return ipu->id;
0042 }
0043 EXPORT_SYMBOL_GPL(ipu_get_num);
0044 
0045 void ipu_srm_dp_update(struct ipu_soc *ipu, bool sync)
0046 {
0047     u32 val;
0048 
0049     val = ipu_cm_read(ipu, IPU_SRM_PRI2);
0050     val &= ~DP_S_SRM_MODE_MASK;
0051     val |= sync ? DP_S_SRM_MODE_NEXT_FRAME :
0052               DP_S_SRM_MODE_NOW;
0053     ipu_cm_write(ipu, val, IPU_SRM_PRI2);
0054 }
0055 EXPORT_SYMBOL_GPL(ipu_srm_dp_update);
0056 
0057 enum ipu_color_space ipu_drm_fourcc_to_colorspace(u32 drm_fourcc)
0058 {
0059     switch (drm_fourcc) {
0060     case DRM_FORMAT_ARGB1555:
0061     case DRM_FORMAT_ABGR1555:
0062     case DRM_FORMAT_RGBA5551:
0063     case DRM_FORMAT_BGRA5551:
0064     case DRM_FORMAT_RGB565:
0065     case DRM_FORMAT_BGR565:
0066     case DRM_FORMAT_RGB888:
0067     case DRM_FORMAT_BGR888:
0068     case DRM_FORMAT_ARGB4444:
0069     case DRM_FORMAT_XRGB8888:
0070     case DRM_FORMAT_XBGR8888:
0071     case DRM_FORMAT_RGBX8888:
0072     case DRM_FORMAT_BGRX8888:
0073     case DRM_FORMAT_ARGB8888:
0074     case DRM_FORMAT_ABGR8888:
0075     case DRM_FORMAT_RGBA8888:
0076     case DRM_FORMAT_BGRA8888:
0077     case DRM_FORMAT_RGB565_A8:
0078     case DRM_FORMAT_BGR565_A8:
0079     case DRM_FORMAT_RGB888_A8:
0080     case DRM_FORMAT_BGR888_A8:
0081     case DRM_FORMAT_RGBX8888_A8:
0082     case DRM_FORMAT_BGRX8888_A8:
0083         return IPUV3_COLORSPACE_RGB;
0084     case DRM_FORMAT_YUYV:
0085     case DRM_FORMAT_UYVY:
0086     case DRM_FORMAT_YUV420:
0087     case DRM_FORMAT_YVU420:
0088     case DRM_FORMAT_YUV422:
0089     case DRM_FORMAT_YVU422:
0090     case DRM_FORMAT_YUV444:
0091     case DRM_FORMAT_YVU444:
0092     case DRM_FORMAT_NV12:
0093     case DRM_FORMAT_NV21:
0094     case DRM_FORMAT_NV16:
0095     case DRM_FORMAT_NV61:
0096         return IPUV3_COLORSPACE_YUV;
0097     default:
0098         return IPUV3_COLORSPACE_UNKNOWN;
0099     }
0100 }
0101 EXPORT_SYMBOL_GPL(ipu_drm_fourcc_to_colorspace);
0102 
0103 enum ipu_color_space ipu_pixelformat_to_colorspace(u32 pixelformat)
0104 {
0105     switch (pixelformat) {
0106     case V4L2_PIX_FMT_YUV420:
0107     case V4L2_PIX_FMT_YVU420:
0108     case V4L2_PIX_FMT_YUV422P:
0109     case V4L2_PIX_FMT_UYVY:
0110     case V4L2_PIX_FMT_YUYV:
0111     case V4L2_PIX_FMT_NV12:
0112     case V4L2_PIX_FMT_NV21:
0113     case V4L2_PIX_FMT_NV16:
0114     case V4L2_PIX_FMT_NV61:
0115         return IPUV3_COLORSPACE_YUV;
0116     case V4L2_PIX_FMT_RGB565:
0117     case V4L2_PIX_FMT_BGR24:
0118     case V4L2_PIX_FMT_RGB24:
0119     case V4L2_PIX_FMT_ABGR32:
0120     case V4L2_PIX_FMT_XBGR32:
0121     case V4L2_PIX_FMT_BGRA32:
0122     case V4L2_PIX_FMT_BGRX32:
0123     case V4L2_PIX_FMT_RGBA32:
0124     case V4L2_PIX_FMT_RGBX32:
0125     case V4L2_PIX_FMT_ARGB32:
0126     case V4L2_PIX_FMT_XRGB32:
0127     case V4L2_PIX_FMT_RGB32:
0128     case V4L2_PIX_FMT_BGR32:
0129         return IPUV3_COLORSPACE_RGB;
0130     default:
0131         return IPUV3_COLORSPACE_UNKNOWN;
0132     }
0133 }
0134 EXPORT_SYMBOL_GPL(ipu_pixelformat_to_colorspace);
0135 
0136 int ipu_degrees_to_rot_mode(enum ipu_rotate_mode *mode, int degrees,
0137                 bool hflip, bool vflip)
0138 {
0139     u32 r90, vf, hf;
0140 
0141     switch (degrees) {
0142     case 0:
0143         vf = hf = r90 = 0;
0144         break;
0145     case 90:
0146         vf = hf = 0;
0147         r90 = 1;
0148         break;
0149     case 180:
0150         vf = hf = 1;
0151         r90 = 0;
0152         break;
0153     case 270:
0154         vf = hf = r90 = 1;
0155         break;
0156     default:
0157         return -EINVAL;
0158     }
0159 
0160     hf ^= (u32)hflip;
0161     vf ^= (u32)vflip;
0162 
0163     *mode = (enum ipu_rotate_mode)((r90 << 2) | (hf << 1) | vf);
0164     return 0;
0165 }
0166 EXPORT_SYMBOL_GPL(ipu_degrees_to_rot_mode);
0167 
0168 int ipu_rot_mode_to_degrees(int *degrees, enum ipu_rotate_mode mode,
0169                 bool hflip, bool vflip)
0170 {
0171     u32 r90, vf, hf;
0172 
0173     r90 = ((u32)mode >> 2) & 0x1;
0174     hf = ((u32)mode >> 1) & 0x1;
0175     vf = ((u32)mode >> 0) & 0x1;
0176     hf ^= (u32)hflip;
0177     vf ^= (u32)vflip;
0178 
0179     switch ((enum ipu_rotate_mode)((r90 << 2) | (hf << 1) | vf)) {
0180     case IPU_ROTATE_NONE:
0181         *degrees = 0;
0182         break;
0183     case IPU_ROTATE_90_RIGHT:
0184         *degrees = 90;
0185         break;
0186     case IPU_ROTATE_180:
0187         *degrees = 180;
0188         break;
0189     case IPU_ROTATE_90_LEFT:
0190         *degrees = 270;
0191         break;
0192     default:
0193         return -EINVAL;
0194     }
0195 
0196     return 0;
0197 }
0198 EXPORT_SYMBOL_GPL(ipu_rot_mode_to_degrees);
0199 
0200 struct ipuv3_channel *ipu_idmac_get(struct ipu_soc *ipu, unsigned num)
0201 {
0202     struct ipuv3_channel *channel;
0203 
0204     dev_dbg(ipu->dev, "%s %d\n", __func__, num);
0205 
0206     if (num > 63)
0207         return ERR_PTR(-ENODEV);
0208 
0209     mutex_lock(&ipu->channel_lock);
0210 
0211     list_for_each_entry(channel, &ipu->channels, list) {
0212         if (channel->num == num) {
0213             channel = ERR_PTR(-EBUSY);
0214             goto out;
0215         }
0216     }
0217 
0218     channel = kzalloc(sizeof(*channel), GFP_KERNEL);
0219     if (!channel) {
0220         channel = ERR_PTR(-ENOMEM);
0221         goto out;
0222     }
0223 
0224     channel->num = num;
0225     channel->ipu = ipu;
0226     list_add(&channel->list, &ipu->channels);
0227 
0228 out:
0229     mutex_unlock(&ipu->channel_lock);
0230 
0231     return channel;
0232 }
0233 EXPORT_SYMBOL_GPL(ipu_idmac_get);
0234 
0235 void ipu_idmac_put(struct ipuv3_channel *channel)
0236 {
0237     struct ipu_soc *ipu = channel->ipu;
0238 
0239     dev_dbg(ipu->dev, "%s %d\n", __func__, channel->num);
0240 
0241     mutex_lock(&ipu->channel_lock);
0242 
0243     list_del(&channel->list);
0244     kfree(channel);
0245 
0246     mutex_unlock(&ipu->channel_lock);
0247 }
0248 EXPORT_SYMBOL_GPL(ipu_idmac_put);
0249 
0250 #define idma_mask(ch)           (1 << ((ch) & 0x1f))
0251 
0252 /*
0253  * This is an undocumented feature, a write one to a channel bit in
0254  * IPU_CHA_CUR_BUF and IPU_CHA_TRIPLE_CUR_BUF will reset the channel's
0255  * internal current buffer pointer so that transfers start from buffer
0256  * 0 on the next channel enable (that's the theory anyway, the imx6 TRM
0257  * only says these are read-only registers). This operation is required
0258  * for channel linking to work correctly, for instance video capture
0259  * pipelines that carry out image rotations will fail after the first
0260  * streaming unless this function is called for each channel before
0261  * re-enabling the channels.
0262  */
0263 static void __ipu_idmac_reset_current_buffer(struct ipuv3_channel *channel)
0264 {
0265     struct ipu_soc *ipu = channel->ipu;
0266     unsigned int chno = channel->num;
0267 
0268     ipu_cm_write(ipu, idma_mask(chno), IPU_CHA_CUR_BUF(chno));
0269 }
0270 
0271 void ipu_idmac_set_double_buffer(struct ipuv3_channel *channel,
0272         bool doublebuffer)
0273 {
0274     struct ipu_soc *ipu = channel->ipu;
0275     unsigned long flags;
0276     u32 reg;
0277 
0278     spin_lock_irqsave(&ipu->lock, flags);
0279 
0280     reg = ipu_cm_read(ipu, IPU_CHA_DB_MODE_SEL(channel->num));
0281     if (doublebuffer)
0282         reg |= idma_mask(channel->num);
0283     else
0284         reg &= ~idma_mask(channel->num);
0285     ipu_cm_write(ipu, reg, IPU_CHA_DB_MODE_SEL(channel->num));
0286 
0287     __ipu_idmac_reset_current_buffer(channel);
0288 
0289     spin_unlock_irqrestore(&ipu->lock, flags);
0290 }
0291 EXPORT_SYMBOL_GPL(ipu_idmac_set_double_buffer);
0292 
0293 static const struct {
0294     int chnum;
0295     u32 reg;
0296     int shift;
0297 } idmac_lock_en_info[] = {
0298     { .chnum =  5, .reg = IDMAC_CH_LOCK_EN_1, .shift =  0, },
0299     { .chnum = 11, .reg = IDMAC_CH_LOCK_EN_1, .shift =  2, },
0300     { .chnum = 12, .reg = IDMAC_CH_LOCK_EN_1, .shift =  4, },
0301     { .chnum = 14, .reg = IDMAC_CH_LOCK_EN_1, .shift =  6, },
0302     { .chnum = 15, .reg = IDMAC_CH_LOCK_EN_1, .shift =  8, },
0303     { .chnum = 20, .reg = IDMAC_CH_LOCK_EN_1, .shift = 10, },
0304     { .chnum = 21, .reg = IDMAC_CH_LOCK_EN_1, .shift = 12, },
0305     { .chnum = 22, .reg = IDMAC_CH_LOCK_EN_1, .shift = 14, },
0306     { .chnum = 23, .reg = IDMAC_CH_LOCK_EN_1, .shift = 16, },
0307     { .chnum = 27, .reg = IDMAC_CH_LOCK_EN_1, .shift = 18, },
0308     { .chnum = 28, .reg = IDMAC_CH_LOCK_EN_1, .shift = 20, },
0309     { .chnum = 45, .reg = IDMAC_CH_LOCK_EN_2, .shift =  0, },
0310     { .chnum = 46, .reg = IDMAC_CH_LOCK_EN_2, .shift =  2, },
0311     { .chnum = 47, .reg = IDMAC_CH_LOCK_EN_2, .shift =  4, },
0312     { .chnum = 48, .reg = IDMAC_CH_LOCK_EN_2, .shift =  6, },
0313     { .chnum = 49, .reg = IDMAC_CH_LOCK_EN_2, .shift =  8, },
0314     { .chnum = 50, .reg = IDMAC_CH_LOCK_EN_2, .shift = 10, },
0315 };
0316 
0317 int ipu_idmac_lock_enable(struct ipuv3_channel *channel, int num_bursts)
0318 {
0319     struct ipu_soc *ipu = channel->ipu;
0320     unsigned long flags;
0321     u32 bursts, regval;
0322     int i;
0323 
0324     switch (num_bursts) {
0325     case 0:
0326     case 1:
0327         bursts = 0x00; /* locking disabled */
0328         break;
0329     case 2:
0330         bursts = 0x01;
0331         break;
0332     case 4:
0333         bursts = 0x02;
0334         break;
0335     case 8:
0336         bursts = 0x03;
0337         break;
0338     default:
0339         return -EINVAL;
0340     }
0341 
0342     /*
0343      * IPUv3EX / i.MX51 has a different register layout, and on IPUv3M /
0344      * i.MX53 channel arbitration locking doesn't seem to work properly.
0345      * Allow enabling the lock feature on IPUv3H / i.MX6 only.
0346      */
0347     if (bursts && ipu->ipu_type != IPUV3H)
0348         return -EINVAL;
0349 
0350     for (i = 0; i < ARRAY_SIZE(idmac_lock_en_info); i++) {
0351         if (channel->num == idmac_lock_en_info[i].chnum)
0352             break;
0353     }
0354     if (i >= ARRAY_SIZE(idmac_lock_en_info))
0355         return -EINVAL;
0356 
0357     spin_lock_irqsave(&ipu->lock, flags);
0358 
0359     regval = ipu_idmac_read(ipu, idmac_lock_en_info[i].reg);
0360     regval &= ~(0x03 << idmac_lock_en_info[i].shift);
0361     regval |= (bursts << idmac_lock_en_info[i].shift);
0362     ipu_idmac_write(ipu, regval, idmac_lock_en_info[i].reg);
0363 
0364     spin_unlock_irqrestore(&ipu->lock, flags);
0365 
0366     return 0;
0367 }
0368 EXPORT_SYMBOL_GPL(ipu_idmac_lock_enable);
0369 
0370 int ipu_module_enable(struct ipu_soc *ipu, u32 mask)
0371 {
0372     unsigned long lock_flags;
0373     u32 val;
0374 
0375     spin_lock_irqsave(&ipu->lock, lock_flags);
0376 
0377     val = ipu_cm_read(ipu, IPU_DISP_GEN);
0378 
0379     if (mask & IPU_CONF_DI0_EN)
0380         val |= IPU_DI0_COUNTER_RELEASE;
0381     if (mask & IPU_CONF_DI1_EN)
0382         val |= IPU_DI1_COUNTER_RELEASE;
0383 
0384     ipu_cm_write(ipu, val, IPU_DISP_GEN);
0385 
0386     val = ipu_cm_read(ipu, IPU_CONF);
0387     val |= mask;
0388     ipu_cm_write(ipu, val, IPU_CONF);
0389 
0390     spin_unlock_irqrestore(&ipu->lock, lock_flags);
0391 
0392     return 0;
0393 }
0394 EXPORT_SYMBOL_GPL(ipu_module_enable);
0395 
0396 int ipu_module_disable(struct ipu_soc *ipu, u32 mask)
0397 {
0398     unsigned long lock_flags;
0399     u32 val;
0400 
0401     spin_lock_irqsave(&ipu->lock, lock_flags);
0402 
0403     val = ipu_cm_read(ipu, IPU_CONF);
0404     val &= ~mask;
0405     ipu_cm_write(ipu, val, IPU_CONF);
0406 
0407     val = ipu_cm_read(ipu, IPU_DISP_GEN);
0408 
0409     if (mask & IPU_CONF_DI0_EN)
0410         val &= ~IPU_DI0_COUNTER_RELEASE;
0411     if (mask & IPU_CONF_DI1_EN)
0412         val &= ~IPU_DI1_COUNTER_RELEASE;
0413 
0414     ipu_cm_write(ipu, val, IPU_DISP_GEN);
0415 
0416     spin_unlock_irqrestore(&ipu->lock, lock_flags);
0417 
0418     return 0;
0419 }
0420 EXPORT_SYMBOL_GPL(ipu_module_disable);
0421 
0422 int ipu_idmac_get_current_buffer(struct ipuv3_channel *channel)
0423 {
0424     struct ipu_soc *ipu = channel->ipu;
0425     unsigned int chno = channel->num;
0426 
0427     return (ipu_cm_read(ipu, IPU_CHA_CUR_BUF(chno)) & idma_mask(chno)) ? 1 : 0;
0428 }
0429 EXPORT_SYMBOL_GPL(ipu_idmac_get_current_buffer);
0430 
0431 bool ipu_idmac_buffer_is_ready(struct ipuv3_channel *channel, u32 buf_num)
0432 {
0433     struct ipu_soc *ipu = channel->ipu;
0434     unsigned long flags;
0435     u32 reg = 0;
0436 
0437     spin_lock_irqsave(&ipu->lock, flags);
0438     switch (buf_num) {
0439     case 0:
0440         reg = ipu_cm_read(ipu, IPU_CHA_BUF0_RDY(channel->num));
0441         break;
0442     case 1:
0443         reg = ipu_cm_read(ipu, IPU_CHA_BUF1_RDY(channel->num));
0444         break;
0445     case 2:
0446         reg = ipu_cm_read(ipu, IPU_CHA_BUF2_RDY(channel->num));
0447         break;
0448     }
0449     spin_unlock_irqrestore(&ipu->lock, flags);
0450 
0451     return ((reg & idma_mask(channel->num)) != 0);
0452 }
0453 EXPORT_SYMBOL_GPL(ipu_idmac_buffer_is_ready);
0454 
0455 void ipu_idmac_select_buffer(struct ipuv3_channel *channel, u32 buf_num)
0456 {
0457     struct ipu_soc *ipu = channel->ipu;
0458     unsigned int chno = channel->num;
0459     unsigned long flags;
0460 
0461     spin_lock_irqsave(&ipu->lock, flags);
0462 
0463     /* Mark buffer as ready. */
0464     if (buf_num == 0)
0465         ipu_cm_write(ipu, idma_mask(chno), IPU_CHA_BUF0_RDY(chno));
0466     else
0467         ipu_cm_write(ipu, idma_mask(chno), IPU_CHA_BUF1_RDY(chno));
0468 
0469     spin_unlock_irqrestore(&ipu->lock, flags);
0470 }
0471 EXPORT_SYMBOL_GPL(ipu_idmac_select_buffer);
0472 
0473 void ipu_idmac_clear_buffer(struct ipuv3_channel *channel, u32 buf_num)
0474 {
0475     struct ipu_soc *ipu = channel->ipu;
0476     unsigned int chno = channel->num;
0477     unsigned long flags;
0478 
0479     spin_lock_irqsave(&ipu->lock, flags);
0480 
0481     ipu_cm_write(ipu, 0xF0300000, IPU_GPR); /* write one to clear */
0482     switch (buf_num) {
0483     case 0:
0484         ipu_cm_write(ipu, idma_mask(chno), IPU_CHA_BUF0_RDY(chno));
0485         break;
0486     case 1:
0487         ipu_cm_write(ipu, idma_mask(chno), IPU_CHA_BUF1_RDY(chno));
0488         break;
0489     case 2:
0490         ipu_cm_write(ipu, idma_mask(chno), IPU_CHA_BUF2_RDY(chno));
0491         break;
0492     default:
0493         break;
0494     }
0495     ipu_cm_write(ipu, 0x0, IPU_GPR); /* write one to set */
0496 
0497     spin_unlock_irqrestore(&ipu->lock, flags);
0498 }
0499 EXPORT_SYMBOL_GPL(ipu_idmac_clear_buffer);
0500 
0501 int ipu_idmac_enable_channel(struct ipuv3_channel *channel)
0502 {
0503     struct ipu_soc *ipu = channel->ipu;
0504     u32 val;
0505     unsigned long flags;
0506 
0507     spin_lock_irqsave(&ipu->lock, flags);
0508 
0509     val = ipu_idmac_read(ipu, IDMAC_CHA_EN(channel->num));
0510     val |= idma_mask(channel->num);
0511     ipu_idmac_write(ipu, val, IDMAC_CHA_EN(channel->num));
0512 
0513     spin_unlock_irqrestore(&ipu->lock, flags);
0514 
0515     return 0;
0516 }
0517 EXPORT_SYMBOL_GPL(ipu_idmac_enable_channel);
0518 
0519 bool ipu_idmac_channel_busy(struct ipu_soc *ipu, unsigned int chno)
0520 {
0521     return (ipu_idmac_read(ipu, IDMAC_CHA_BUSY(chno)) & idma_mask(chno));
0522 }
0523 EXPORT_SYMBOL_GPL(ipu_idmac_channel_busy);
0524 
0525 int ipu_idmac_wait_busy(struct ipuv3_channel *channel, int ms)
0526 {
0527     struct ipu_soc *ipu = channel->ipu;
0528     unsigned long timeout;
0529 
0530     timeout = jiffies + msecs_to_jiffies(ms);
0531     while (ipu_idmac_read(ipu, IDMAC_CHA_BUSY(channel->num)) &
0532             idma_mask(channel->num)) {
0533         if (time_after(jiffies, timeout))
0534             return -ETIMEDOUT;
0535         cpu_relax();
0536     }
0537 
0538     return 0;
0539 }
0540 EXPORT_SYMBOL_GPL(ipu_idmac_wait_busy);
0541 
0542 int ipu_idmac_disable_channel(struct ipuv3_channel *channel)
0543 {
0544     struct ipu_soc *ipu = channel->ipu;
0545     u32 val;
0546     unsigned long flags;
0547 
0548     spin_lock_irqsave(&ipu->lock, flags);
0549 
0550     /* Disable DMA channel(s) */
0551     val = ipu_idmac_read(ipu, IDMAC_CHA_EN(channel->num));
0552     val &= ~idma_mask(channel->num);
0553     ipu_idmac_write(ipu, val, IDMAC_CHA_EN(channel->num));
0554 
0555     __ipu_idmac_reset_current_buffer(channel);
0556 
0557     /* Set channel buffers NOT to be ready */
0558     ipu_cm_write(ipu, 0xf0000000, IPU_GPR); /* write one to clear */
0559 
0560     if (ipu_cm_read(ipu, IPU_CHA_BUF0_RDY(channel->num)) &
0561             idma_mask(channel->num)) {
0562         ipu_cm_write(ipu, idma_mask(channel->num),
0563                  IPU_CHA_BUF0_RDY(channel->num));
0564     }
0565 
0566     if (ipu_cm_read(ipu, IPU_CHA_BUF1_RDY(channel->num)) &
0567             idma_mask(channel->num)) {
0568         ipu_cm_write(ipu, idma_mask(channel->num),
0569                  IPU_CHA_BUF1_RDY(channel->num));
0570     }
0571 
0572     ipu_cm_write(ipu, 0x0, IPU_GPR); /* write one to set */
0573 
0574     /* Reset the double buffer */
0575     val = ipu_cm_read(ipu, IPU_CHA_DB_MODE_SEL(channel->num));
0576     val &= ~idma_mask(channel->num);
0577     ipu_cm_write(ipu, val, IPU_CHA_DB_MODE_SEL(channel->num));
0578 
0579     spin_unlock_irqrestore(&ipu->lock, flags);
0580 
0581     return 0;
0582 }
0583 EXPORT_SYMBOL_GPL(ipu_idmac_disable_channel);
0584 
0585 /*
0586  * The imx6 rev. D TRM says that enabling the WM feature will increase
0587  * a channel's priority. Refer to Table 36-8 Calculated priority value.
0588  * The sub-module that is the sink or source for the channel must enable
0589  * watermark signal for this to take effect (SMFC_WM for instance).
0590  */
0591 void ipu_idmac_enable_watermark(struct ipuv3_channel *channel, bool enable)
0592 {
0593     struct ipu_soc *ipu = channel->ipu;
0594     unsigned long flags;
0595     u32 val;
0596 
0597     spin_lock_irqsave(&ipu->lock, flags);
0598 
0599     val = ipu_idmac_read(ipu, IDMAC_WM_EN(channel->num));
0600     if (enable)
0601         val |= 1 << (channel->num % 32);
0602     else
0603         val &= ~(1 << (channel->num % 32));
0604     ipu_idmac_write(ipu, val, IDMAC_WM_EN(channel->num));
0605 
0606     spin_unlock_irqrestore(&ipu->lock, flags);
0607 }
0608 EXPORT_SYMBOL_GPL(ipu_idmac_enable_watermark);
0609 
0610 static int ipu_memory_reset(struct ipu_soc *ipu)
0611 {
0612     unsigned long timeout;
0613 
0614     ipu_cm_write(ipu, 0x807FFFFF, IPU_MEM_RST);
0615 
0616     timeout = jiffies + msecs_to_jiffies(1000);
0617     while (ipu_cm_read(ipu, IPU_MEM_RST) & 0x80000000) {
0618         if (time_after(jiffies, timeout))
0619             return -ETIME;
0620         cpu_relax();
0621     }
0622 
0623     return 0;
0624 }
0625 
0626 /*
0627  * Set the source mux for the given CSI. Selects either parallel or
0628  * MIPI CSI2 sources.
0629  */
0630 void ipu_set_csi_src_mux(struct ipu_soc *ipu, int csi_id, bool mipi_csi2)
0631 {
0632     unsigned long flags;
0633     u32 val, mask;
0634 
0635     mask = (csi_id == 1) ? IPU_CONF_CSI1_DATA_SOURCE :
0636         IPU_CONF_CSI0_DATA_SOURCE;
0637 
0638     spin_lock_irqsave(&ipu->lock, flags);
0639 
0640     val = ipu_cm_read(ipu, IPU_CONF);
0641     if (mipi_csi2)
0642         val |= mask;
0643     else
0644         val &= ~mask;
0645     ipu_cm_write(ipu, val, IPU_CONF);
0646 
0647     spin_unlock_irqrestore(&ipu->lock, flags);
0648 }
0649 EXPORT_SYMBOL_GPL(ipu_set_csi_src_mux);
0650 
0651 /*
0652  * Set the source mux for the IC. Selects either CSI[01] or the VDI.
0653  */
0654 void ipu_set_ic_src_mux(struct ipu_soc *ipu, int csi_id, bool vdi)
0655 {
0656     unsigned long flags;
0657     u32 val;
0658 
0659     spin_lock_irqsave(&ipu->lock, flags);
0660 
0661     val = ipu_cm_read(ipu, IPU_CONF);
0662     if (vdi)
0663         val |= IPU_CONF_IC_INPUT;
0664     else
0665         val &= ~IPU_CONF_IC_INPUT;
0666 
0667     if (csi_id == 1)
0668         val |= IPU_CONF_CSI_SEL;
0669     else
0670         val &= ~IPU_CONF_CSI_SEL;
0671 
0672     ipu_cm_write(ipu, val, IPU_CONF);
0673 
0674     spin_unlock_irqrestore(&ipu->lock, flags);
0675 }
0676 EXPORT_SYMBOL_GPL(ipu_set_ic_src_mux);
0677 
0678 
0679 /* Frame Synchronization Unit Channel Linking */
0680 
0681 struct fsu_link_reg_info {
0682     int chno;
0683     u32 reg;
0684     u32 mask;
0685     u32 val;
0686 };
0687 
0688 struct fsu_link_info {
0689     struct fsu_link_reg_info src;
0690     struct fsu_link_reg_info sink;
0691 };
0692 
0693 static const struct fsu_link_info fsu_link_info[] = {
0694     {
0695         .src  = { IPUV3_CHANNEL_IC_PRP_ENC_MEM, IPU_FS_PROC_FLOW2,
0696               FS_PRP_ENC_DEST_SEL_MASK, FS_PRP_ENC_DEST_SEL_IRT_ENC },
0697         .sink = { IPUV3_CHANNEL_MEM_ROT_ENC, IPU_FS_PROC_FLOW1,
0698               FS_PRPENC_ROT_SRC_SEL_MASK, FS_PRPENC_ROT_SRC_SEL_ENC },
0699     }, {
0700         .src =  { IPUV3_CHANNEL_IC_PRP_VF_MEM, IPU_FS_PROC_FLOW2,
0701               FS_PRPVF_DEST_SEL_MASK, FS_PRPVF_DEST_SEL_IRT_VF },
0702         .sink = { IPUV3_CHANNEL_MEM_ROT_VF, IPU_FS_PROC_FLOW1,
0703               FS_PRPVF_ROT_SRC_SEL_MASK, FS_PRPVF_ROT_SRC_SEL_VF },
0704     }, {
0705         .src =  { IPUV3_CHANNEL_IC_PP_MEM, IPU_FS_PROC_FLOW2,
0706               FS_PP_DEST_SEL_MASK, FS_PP_DEST_SEL_IRT_PP },
0707         .sink = { IPUV3_CHANNEL_MEM_ROT_PP, IPU_FS_PROC_FLOW1,
0708               FS_PP_ROT_SRC_SEL_MASK, FS_PP_ROT_SRC_SEL_PP },
0709     }, {
0710         .src =  { IPUV3_CHANNEL_CSI_DIRECT, 0 },
0711         .sink = { IPUV3_CHANNEL_CSI_VDI_PREV, IPU_FS_PROC_FLOW1,
0712               FS_VDI_SRC_SEL_MASK, FS_VDI_SRC_SEL_CSI_DIRECT },
0713     },
0714 };
0715 
0716 static const struct fsu_link_info *find_fsu_link_info(int src, int sink)
0717 {
0718     int i;
0719 
0720     for (i = 0; i < ARRAY_SIZE(fsu_link_info); i++) {
0721         if (src == fsu_link_info[i].src.chno &&
0722             sink == fsu_link_info[i].sink.chno)
0723             return &fsu_link_info[i];
0724     }
0725 
0726     return NULL;
0727 }
0728 
0729 /*
0730  * Links a source channel to a sink channel in the FSU.
0731  */
0732 int ipu_fsu_link(struct ipu_soc *ipu, int src_ch, int sink_ch)
0733 {
0734     const struct fsu_link_info *link;
0735     u32 src_reg, sink_reg;
0736     unsigned long flags;
0737 
0738     link = find_fsu_link_info(src_ch, sink_ch);
0739     if (!link)
0740         return -EINVAL;
0741 
0742     spin_lock_irqsave(&ipu->lock, flags);
0743 
0744     if (link->src.mask) {
0745         src_reg = ipu_cm_read(ipu, link->src.reg);
0746         src_reg &= ~link->src.mask;
0747         src_reg |= link->src.val;
0748         ipu_cm_write(ipu, src_reg, link->src.reg);
0749     }
0750 
0751     if (link->sink.mask) {
0752         sink_reg = ipu_cm_read(ipu, link->sink.reg);
0753         sink_reg &= ~link->sink.mask;
0754         sink_reg |= link->sink.val;
0755         ipu_cm_write(ipu, sink_reg, link->sink.reg);
0756     }
0757 
0758     spin_unlock_irqrestore(&ipu->lock, flags);
0759     return 0;
0760 }
0761 EXPORT_SYMBOL_GPL(ipu_fsu_link);
0762 
0763 /*
0764  * Unlinks source and sink channels in the FSU.
0765  */
0766 int ipu_fsu_unlink(struct ipu_soc *ipu, int src_ch, int sink_ch)
0767 {
0768     const struct fsu_link_info *link;
0769     u32 src_reg, sink_reg;
0770     unsigned long flags;
0771 
0772     link = find_fsu_link_info(src_ch, sink_ch);
0773     if (!link)
0774         return -EINVAL;
0775 
0776     spin_lock_irqsave(&ipu->lock, flags);
0777 
0778     if (link->src.mask) {
0779         src_reg = ipu_cm_read(ipu, link->src.reg);
0780         src_reg &= ~link->src.mask;
0781         ipu_cm_write(ipu, src_reg, link->src.reg);
0782     }
0783 
0784     if (link->sink.mask) {
0785         sink_reg = ipu_cm_read(ipu, link->sink.reg);
0786         sink_reg &= ~link->sink.mask;
0787         ipu_cm_write(ipu, sink_reg, link->sink.reg);
0788     }
0789 
0790     spin_unlock_irqrestore(&ipu->lock, flags);
0791     return 0;
0792 }
0793 EXPORT_SYMBOL_GPL(ipu_fsu_unlink);
0794 
0795 /* Link IDMAC channels in the FSU */
0796 int ipu_idmac_link(struct ipuv3_channel *src, struct ipuv3_channel *sink)
0797 {
0798     return ipu_fsu_link(src->ipu, src->num, sink->num);
0799 }
0800 EXPORT_SYMBOL_GPL(ipu_idmac_link);
0801 
0802 /* Unlink IDMAC channels in the FSU */
0803 int ipu_idmac_unlink(struct ipuv3_channel *src, struct ipuv3_channel *sink)
0804 {
0805     return ipu_fsu_unlink(src->ipu, src->num, sink->num);
0806 }
0807 EXPORT_SYMBOL_GPL(ipu_idmac_unlink);
0808 
0809 struct ipu_devtype {
0810     const char *name;
0811     unsigned long cm_ofs;
0812     unsigned long cpmem_ofs;
0813     unsigned long srm_ofs;
0814     unsigned long tpm_ofs;
0815     unsigned long csi0_ofs;
0816     unsigned long csi1_ofs;
0817     unsigned long ic_ofs;
0818     unsigned long disp0_ofs;
0819     unsigned long disp1_ofs;
0820     unsigned long dc_tmpl_ofs;
0821     unsigned long vdi_ofs;
0822     enum ipuv3_type type;
0823 };
0824 
0825 static struct ipu_devtype ipu_type_imx51 = {
0826     .name = "IPUv3EX",
0827     .cm_ofs = 0x1e000000,
0828     .cpmem_ofs = 0x1f000000,
0829     .srm_ofs = 0x1f040000,
0830     .tpm_ofs = 0x1f060000,
0831     .csi0_ofs = 0x1e030000,
0832     .csi1_ofs = 0x1e038000,
0833     .ic_ofs = 0x1e020000,
0834     .disp0_ofs = 0x1e040000,
0835     .disp1_ofs = 0x1e048000,
0836     .dc_tmpl_ofs = 0x1f080000,
0837     .vdi_ofs = 0x1e068000,
0838     .type = IPUV3EX,
0839 };
0840 
0841 static struct ipu_devtype ipu_type_imx53 = {
0842     .name = "IPUv3M",
0843     .cm_ofs = 0x06000000,
0844     .cpmem_ofs = 0x07000000,
0845     .srm_ofs = 0x07040000,
0846     .tpm_ofs = 0x07060000,
0847     .csi0_ofs = 0x06030000,
0848     .csi1_ofs = 0x06038000,
0849     .ic_ofs = 0x06020000,
0850     .disp0_ofs = 0x06040000,
0851     .disp1_ofs = 0x06048000,
0852     .dc_tmpl_ofs = 0x07080000,
0853     .vdi_ofs = 0x06068000,
0854     .type = IPUV3M,
0855 };
0856 
0857 static struct ipu_devtype ipu_type_imx6q = {
0858     .name = "IPUv3H",
0859     .cm_ofs = 0x00200000,
0860     .cpmem_ofs = 0x00300000,
0861     .srm_ofs = 0x00340000,
0862     .tpm_ofs = 0x00360000,
0863     .csi0_ofs = 0x00230000,
0864     .csi1_ofs = 0x00238000,
0865     .ic_ofs = 0x00220000,
0866     .disp0_ofs = 0x00240000,
0867     .disp1_ofs = 0x00248000,
0868     .dc_tmpl_ofs = 0x00380000,
0869     .vdi_ofs = 0x00268000,
0870     .type = IPUV3H,
0871 };
0872 
0873 static const struct of_device_id imx_ipu_dt_ids[] = {
0874     { .compatible = "fsl,imx51-ipu", .data = &ipu_type_imx51, },
0875     { .compatible = "fsl,imx53-ipu", .data = &ipu_type_imx53, },
0876     { .compatible = "fsl,imx6q-ipu", .data = &ipu_type_imx6q, },
0877     { .compatible = "fsl,imx6qp-ipu", .data = &ipu_type_imx6q, },
0878     { /* sentinel */ }
0879 };
0880 MODULE_DEVICE_TABLE(of, imx_ipu_dt_ids);
0881 
0882 static int ipu_submodules_init(struct ipu_soc *ipu,
0883         struct platform_device *pdev, unsigned long ipu_base,
0884         struct clk *ipu_clk)
0885 {
0886     char *unit;
0887     int ret;
0888     struct device *dev = &pdev->dev;
0889     const struct ipu_devtype *devtype = ipu->devtype;
0890 
0891     ret = ipu_cpmem_init(ipu, dev, ipu_base + devtype->cpmem_ofs);
0892     if (ret) {
0893         unit = "cpmem";
0894         goto err_cpmem;
0895     }
0896 
0897     ret = ipu_csi_init(ipu, dev, 0, ipu_base + devtype->csi0_ofs,
0898                IPU_CONF_CSI0_EN, ipu_clk);
0899     if (ret) {
0900         unit = "csi0";
0901         goto err_csi_0;
0902     }
0903 
0904     ret = ipu_csi_init(ipu, dev, 1, ipu_base + devtype->csi1_ofs,
0905                IPU_CONF_CSI1_EN, ipu_clk);
0906     if (ret) {
0907         unit = "csi1";
0908         goto err_csi_1;
0909     }
0910 
0911     ret = ipu_ic_init(ipu, dev,
0912               ipu_base + devtype->ic_ofs,
0913               ipu_base + devtype->tpm_ofs);
0914     if (ret) {
0915         unit = "ic";
0916         goto err_ic;
0917     }
0918 
0919     ret = ipu_vdi_init(ipu, dev, ipu_base + devtype->vdi_ofs,
0920                IPU_CONF_VDI_EN | IPU_CONF_ISP_EN |
0921                IPU_CONF_IC_INPUT);
0922     if (ret) {
0923         unit = "vdi";
0924         goto err_vdi;
0925     }
0926 
0927     ret = ipu_image_convert_init(ipu, dev);
0928     if (ret) {
0929         unit = "image_convert";
0930         goto err_image_convert;
0931     }
0932 
0933     ret = ipu_di_init(ipu, dev, 0, ipu_base + devtype->disp0_ofs,
0934               IPU_CONF_DI0_EN, ipu_clk);
0935     if (ret) {
0936         unit = "di0";
0937         goto err_di_0;
0938     }
0939 
0940     ret = ipu_di_init(ipu, dev, 1, ipu_base + devtype->disp1_ofs,
0941             IPU_CONF_DI1_EN, ipu_clk);
0942     if (ret) {
0943         unit = "di1";
0944         goto err_di_1;
0945     }
0946 
0947     ret = ipu_dc_init(ipu, dev, ipu_base + devtype->cm_ofs +
0948             IPU_CM_DC_REG_OFS, ipu_base + devtype->dc_tmpl_ofs);
0949     if (ret) {
0950         unit = "dc_template";
0951         goto err_dc;
0952     }
0953 
0954     ret = ipu_dmfc_init(ipu, dev, ipu_base +
0955             devtype->cm_ofs + IPU_CM_DMFC_REG_OFS, ipu_clk);
0956     if (ret) {
0957         unit = "dmfc";
0958         goto err_dmfc;
0959     }
0960 
0961     ret = ipu_dp_init(ipu, dev, ipu_base + devtype->srm_ofs);
0962     if (ret) {
0963         unit = "dp";
0964         goto err_dp;
0965     }
0966 
0967     ret = ipu_smfc_init(ipu, dev, ipu_base +
0968             devtype->cm_ofs + IPU_CM_SMFC_REG_OFS);
0969     if (ret) {
0970         unit = "smfc";
0971         goto err_smfc;
0972     }
0973 
0974     return 0;
0975 
0976 err_smfc:
0977     ipu_dp_exit(ipu);
0978 err_dp:
0979     ipu_dmfc_exit(ipu);
0980 err_dmfc:
0981     ipu_dc_exit(ipu);
0982 err_dc:
0983     ipu_di_exit(ipu, 1);
0984 err_di_1:
0985     ipu_di_exit(ipu, 0);
0986 err_di_0:
0987     ipu_image_convert_exit(ipu);
0988 err_image_convert:
0989     ipu_vdi_exit(ipu);
0990 err_vdi:
0991     ipu_ic_exit(ipu);
0992 err_ic:
0993     ipu_csi_exit(ipu, 1);
0994 err_csi_1:
0995     ipu_csi_exit(ipu, 0);
0996 err_csi_0:
0997     ipu_cpmem_exit(ipu);
0998 err_cpmem:
0999     dev_err(&pdev->dev, "init %s failed with %d\n", unit, ret);
1000     return ret;
1001 }
1002 
1003 static void ipu_irq_handle(struct ipu_soc *ipu, const int *regs, int num_regs)
1004 {
1005     unsigned long status;
1006     int i, bit;
1007 
1008     for (i = 0; i < num_regs; i++) {
1009 
1010         status = ipu_cm_read(ipu, IPU_INT_STAT(regs[i]));
1011         status &= ipu_cm_read(ipu, IPU_INT_CTRL(regs[i]));
1012 
1013         for_each_set_bit(bit, &status, 32)
1014             generic_handle_domain_irq(ipu->domain,
1015                           regs[i] * 32 + bit);
1016     }
1017 }
1018 
1019 static void ipu_irq_handler(struct irq_desc *desc)
1020 {
1021     struct ipu_soc *ipu = irq_desc_get_handler_data(desc);
1022     struct irq_chip *chip = irq_desc_get_chip(desc);
1023     static const int int_reg[] = { 0, 1, 2, 3, 10, 11, 12, 13, 14};
1024 
1025     chained_irq_enter(chip, desc);
1026 
1027     ipu_irq_handle(ipu, int_reg, ARRAY_SIZE(int_reg));
1028 
1029     chained_irq_exit(chip, desc);
1030 }
1031 
1032 static void ipu_err_irq_handler(struct irq_desc *desc)
1033 {
1034     struct ipu_soc *ipu = irq_desc_get_handler_data(desc);
1035     struct irq_chip *chip = irq_desc_get_chip(desc);
1036     static const int int_reg[] = { 4, 5, 8, 9};
1037 
1038     chained_irq_enter(chip, desc);
1039 
1040     ipu_irq_handle(ipu, int_reg, ARRAY_SIZE(int_reg));
1041 
1042     chained_irq_exit(chip, desc);
1043 }
1044 
1045 int ipu_map_irq(struct ipu_soc *ipu, int irq)
1046 {
1047     int virq;
1048 
1049     virq = irq_linear_revmap(ipu->domain, irq);
1050     if (!virq)
1051         virq = irq_create_mapping(ipu->domain, irq);
1052 
1053     return virq;
1054 }
1055 EXPORT_SYMBOL_GPL(ipu_map_irq);
1056 
1057 int ipu_idmac_channel_irq(struct ipu_soc *ipu, struct ipuv3_channel *channel,
1058         enum ipu_channel_irq irq_type)
1059 {
1060     return ipu_map_irq(ipu, irq_type + channel->num);
1061 }
1062 EXPORT_SYMBOL_GPL(ipu_idmac_channel_irq);
1063 
1064 static void ipu_submodules_exit(struct ipu_soc *ipu)
1065 {
1066     ipu_smfc_exit(ipu);
1067     ipu_dp_exit(ipu);
1068     ipu_dmfc_exit(ipu);
1069     ipu_dc_exit(ipu);
1070     ipu_di_exit(ipu, 1);
1071     ipu_di_exit(ipu, 0);
1072     ipu_image_convert_exit(ipu);
1073     ipu_vdi_exit(ipu);
1074     ipu_ic_exit(ipu);
1075     ipu_csi_exit(ipu, 1);
1076     ipu_csi_exit(ipu, 0);
1077     ipu_cpmem_exit(ipu);
1078 }
1079 
1080 static int platform_remove_devices_fn(struct device *dev, void *unused)
1081 {
1082     struct platform_device *pdev = to_platform_device(dev);
1083 
1084     platform_device_unregister(pdev);
1085 
1086     return 0;
1087 }
1088 
1089 static void platform_device_unregister_children(struct platform_device *pdev)
1090 {
1091     device_for_each_child(&pdev->dev, NULL, platform_remove_devices_fn);
1092 }
1093 
1094 struct ipu_platform_reg {
1095     struct ipu_client_platformdata pdata;
1096     const char *name;
1097 };
1098 
1099 /* These must be in the order of the corresponding device tree port nodes */
1100 static struct ipu_platform_reg client_reg[] = {
1101     {
1102         .pdata = {
1103             .csi = 0,
1104             .dma[0] = IPUV3_CHANNEL_CSI0,
1105             .dma[1] = -EINVAL,
1106         },
1107         .name = "imx-ipuv3-csi",
1108     }, {
1109         .pdata = {
1110             .csi = 1,
1111             .dma[0] = IPUV3_CHANNEL_CSI1,
1112             .dma[1] = -EINVAL,
1113         },
1114         .name = "imx-ipuv3-csi",
1115     }, {
1116         .pdata = {
1117             .di = 0,
1118             .dc = 5,
1119             .dp = IPU_DP_FLOW_SYNC_BG,
1120             .dma[0] = IPUV3_CHANNEL_MEM_BG_SYNC,
1121             .dma[1] = IPUV3_CHANNEL_MEM_FG_SYNC,
1122         },
1123         .name = "imx-ipuv3-crtc",
1124     }, {
1125         .pdata = {
1126             .di = 1,
1127             .dc = 1,
1128             .dp = -EINVAL,
1129             .dma[0] = IPUV3_CHANNEL_MEM_DC_SYNC,
1130             .dma[1] = -EINVAL,
1131         },
1132         .name = "imx-ipuv3-crtc",
1133     },
1134 };
1135 
1136 static DEFINE_MUTEX(ipu_client_id_mutex);
1137 static int ipu_client_id;
1138 
1139 static int ipu_add_client_devices(struct ipu_soc *ipu, unsigned long ipu_base)
1140 {
1141     struct device *dev = ipu->dev;
1142     unsigned i;
1143     int id, ret;
1144 
1145     mutex_lock(&ipu_client_id_mutex);
1146     id = ipu_client_id;
1147     ipu_client_id += ARRAY_SIZE(client_reg);
1148     mutex_unlock(&ipu_client_id_mutex);
1149 
1150     for (i = 0; i < ARRAY_SIZE(client_reg); i++) {
1151         struct ipu_platform_reg *reg = &client_reg[i];
1152         struct platform_device *pdev;
1153         struct device_node *of_node;
1154 
1155         /* Associate subdevice with the corresponding port node */
1156         of_node = of_graph_get_port_by_id(dev->of_node, i);
1157         if (!of_node) {
1158             dev_info(dev,
1159                  "no port@%d node in %pOF, not using %s%d\n",
1160                  i, dev->of_node,
1161                  (i / 2) ? "DI" : "CSI", i % 2);
1162             continue;
1163         }
1164 
1165         pdev = platform_device_alloc(reg->name, id++);
1166         if (!pdev) {
1167             ret = -ENOMEM;
1168             goto err_register;
1169         }
1170 
1171         pdev->dev.parent = dev;
1172 
1173         reg->pdata.of_node = of_node;
1174         ret = platform_device_add_data(pdev, &reg->pdata,
1175                            sizeof(reg->pdata));
1176         if (!ret)
1177             ret = platform_device_add(pdev);
1178         if (ret) {
1179             platform_device_put(pdev);
1180             goto err_register;
1181         }
1182     }
1183 
1184     return 0;
1185 
1186 err_register:
1187     platform_device_unregister_children(to_platform_device(dev));
1188 
1189     return ret;
1190 }
1191 
1192 
1193 static int ipu_irq_init(struct ipu_soc *ipu)
1194 {
1195     struct irq_chip_generic *gc;
1196     struct irq_chip_type *ct;
1197     unsigned long unused[IPU_NUM_IRQS / 32] = {
1198         0x400100d0, 0xffe000fd,
1199         0x400100d0, 0xffe000fd,
1200         0x400100d0, 0xffe000fd,
1201         0x4077ffff, 0xffe7e1fd,
1202         0x23fffffe, 0x8880fff0,
1203         0xf98fe7d0, 0xfff81fff,
1204         0x400100d0, 0xffe000fd,
1205         0x00000000,
1206     };
1207     int ret, i;
1208 
1209     ipu->domain = irq_domain_add_linear(ipu->dev->of_node, IPU_NUM_IRQS,
1210                         &irq_generic_chip_ops, ipu);
1211     if (!ipu->domain) {
1212         dev_err(ipu->dev, "failed to add irq domain\n");
1213         return -ENODEV;
1214     }
1215 
1216     ret = irq_alloc_domain_generic_chips(ipu->domain, 32, 1, "IPU",
1217                          handle_level_irq, 0, 0, 0);
1218     if (ret < 0) {
1219         dev_err(ipu->dev, "failed to alloc generic irq chips\n");
1220         irq_domain_remove(ipu->domain);
1221         return ret;
1222     }
1223 
1224     /* Mask and clear all interrupts */
1225     for (i = 0; i < IPU_NUM_IRQS; i += 32) {
1226         ipu_cm_write(ipu, 0, IPU_INT_CTRL(i / 32));
1227         ipu_cm_write(ipu, ~unused[i / 32], IPU_INT_STAT(i / 32));
1228     }
1229 
1230     for (i = 0; i < IPU_NUM_IRQS; i += 32) {
1231         gc = irq_get_domain_generic_chip(ipu->domain, i);
1232         gc->reg_base = ipu->cm_reg;
1233         gc->unused = unused[i / 32];
1234         ct = gc->chip_types;
1235         ct->chip.irq_ack = irq_gc_ack_set_bit;
1236         ct->chip.irq_mask = irq_gc_mask_clr_bit;
1237         ct->chip.irq_unmask = irq_gc_mask_set_bit;
1238         ct->regs.ack = IPU_INT_STAT(i / 32);
1239         ct->regs.mask = IPU_INT_CTRL(i / 32);
1240     }
1241 
1242     irq_set_chained_handler_and_data(ipu->irq_sync, ipu_irq_handler, ipu);
1243     irq_set_chained_handler_and_data(ipu->irq_err, ipu_err_irq_handler,
1244                      ipu);
1245 
1246     return 0;
1247 }
1248 
1249 static void ipu_irq_exit(struct ipu_soc *ipu)
1250 {
1251     int i, irq;
1252 
1253     irq_set_chained_handler_and_data(ipu->irq_err, NULL, NULL);
1254     irq_set_chained_handler_and_data(ipu->irq_sync, NULL, NULL);
1255 
1256     /* TODO: remove irq_domain_generic_chips */
1257 
1258     for (i = 0; i < IPU_NUM_IRQS; i++) {
1259         irq = irq_linear_revmap(ipu->domain, i);
1260         if (irq)
1261             irq_dispose_mapping(irq);
1262     }
1263 
1264     irq_domain_remove(ipu->domain);
1265 }
1266 
1267 void ipu_dump(struct ipu_soc *ipu)
1268 {
1269     int i;
1270 
1271     dev_dbg(ipu->dev, "IPU_CONF = \t0x%08X\n",
1272         ipu_cm_read(ipu, IPU_CONF));
1273     dev_dbg(ipu->dev, "IDMAC_CONF = \t0x%08X\n",
1274         ipu_idmac_read(ipu, IDMAC_CONF));
1275     dev_dbg(ipu->dev, "IDMAC_CHA_EN1 = \t0x%08X\n",
1276         ipu_idmac_read(ipu, IDMAC_CHA_EN(0)));
1277     dev_dbg(ipu->dev, "IDMAC_CHA_EN2 = \t0x%08X\n",
1278         ipu_idmac_read(ipu, IDMAC_CHA_EN(32)));
1279     dev_dbg(ipu->dev, "IDMAC_CHA_PRI1 = \t0x%08X\n",
1280         ipu_idmac_read(ipu, IDMAC_CHA_PRI(0)));
1281     dev_dbg(ipu->dev, "IDMAC_CHA_PRI2 = \t0x%08X\n",
1282         ipu_idmac_read(ipu, IDMAC_CHA_PRI(32)));
1283     dev_dbg(ipu->dev, "IDMAC_BAND_EN1 = \t0x%08X\n",
1284         ipu_idmac_read(ipu, IDMAC_BAND_EN(0)));
1285     dev_dbg(ipu->dev, "IDMAC_BAND_EN2 = \t0x%08X\n",
1286         ipu_idmac_read(ipu, IDMAC_BAND_EN(32)));
1287     dev_dbg(ipu->dev, "IPU_CHA_DB_MODE_SEL0 = \t0x%08X\n",
1288         ipu_cm_read(ipu, IPU_CHA_DB_MODE_SEL(0)));
1289     dev_dbg(ipu->dev, "IPU_CHA_DB_MODE_SEL1 = \t0x%08X\n",
1290         ipu_cm_read(ipu, IPU_CHA_DB_MODE_SEL(32)));
1291     dev_dbg(ipu->dev, "IPU_FS_PROC_FLOW1 = \t0x%08X\n",
1292         ipu_cm_read(ipu, IPU_FS_PROC_FLOW1));
1293     dev_dbg(ipu->dev, "IPU_FS_PROC_FLOW2 = \t0x%08X\n",
1294         ipu_cm_read(ipu, IPU_FS_PROC_FLOW2));
1295     dev_dbg(ipu->dev, "IPU_FS_PROC_FLOW3 = \t0x%08X\n",
1296         ipu_cm_read(ipu, IPU_FS_PROC_FLOW3));
1297     dev_dbg(ipu->dev, "IPU_FS_DISP_FLOW1 = \t0x%08X\n",
1298         ipu_cm_read(ipu, IPU_FS_DISP_FLOW1));
1299     for (i = 0; i < 15; i++)
1300         dev_dbg(ipu->dev, "IPU_INT_CTRL(%d) = \t%08X\n", i,
1301             ipu_cm_read(ipu, IPU_INT_CTRL(i)));
1302 }
1303 EXPORT_SYMBOL_GPL(ipu_dump);
1304 
1305 static int ipu_probe(struct platform_device *pdev)
1306 {
1307     struct device_node *np = pdev->dev.of_node;
1308     struct ipu_soc *ipu;
1309     struct resource *res;
1310     unsigned long ipu_base;
1311     int ret, irq_sync, irq_err;
1312     const struct ipu_devtype *devtype;
1313 
1314     devtype = of_device_get_match_data(&pdev->dev);
1315     if (!devtype)
1316         return -EINVAL;
1317 
1318     irq_sync = platform_get_irq(pdev, 0);
1319     irq_err = platform_get_irq(pdev, 1);
1320     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1321 
1322     dev_dbg(&pdev->dev, "irq_sync: %d irq_err: %d\n",
1323             irq_sync, irq_err);
1324 
1325     if (!res || irq_sync < 0 || irq_err < 0)
1326         return -ENODEV;
1327 
1328     ipu_base = res->start;
1329 
1330     ipu = devm_kzalloc(&pdev->dev, sizeof(*ipu), GFP_KERNEL);
1331     if (!ipu)
1332         return -ENODEV;
1333 
1334     ipu->id = of_alias_get_id(np, "ipu");
1335     if (ipu->id < 0)
1336         ipu->id = 0;
1337 
1338     if (of_device_is_compatible(np, "fsl,imx6qp-ipu") &&
1339         IS_ENABLED(CONFIG_DRM)) {
1340         ipu->prg_priv = ipu_prg_lookup_by_phandle(&pdev->dev,
1341                               "fsl,prg", ipu->id);
1342         if (!ipu->prg_priv)
1343             return -EPROBE_DEFER;
1344     }
1345 
1346     ipu->devtype = devtype;
1347     ipu->ipu_type = devtype->type;
1348 
1349     spin_lock_init(&ipu->lock);
1350     mutex_init(&ipu->channel_lock);
1351     INIT_LIST_HEAD(&ipu->channels);
1352 
1353     dev_dbg(&pdev->dev, "cm_reg:   0x%08lx\n",
1354             ipu_base + devtype->cm_ofs);
1355     dev_dbg(&pdev->dev, "idmac:    0x%08lx\n",
1356             ipu_base + devtype->cm_ofs + IPU_CM_IDMAC_REG_OFS);
1357     dev_dbg(&pdev->dev, "cpmem:    0x%08lx\n",
1358             ipu_base + devtype->cpmem_ofs);
1359     dev_dbg(&pdev->dev, "csi0:    0x%08lx\n",
1360             ipu_base + devtype->csi0_ofs);
1361     dev_dbg(&pdev->dev, "csi1:    0x%08lx\n",
1362             ipu_base + devtype->csi1_ofs);
1363     dev_dbg(&pdev->dev, "ic:      0x%08lx\n",
1364             ipu_base + devtype->ic_ofs);
1365     dev_dbg(&pdev->dev, "disp0:    0x%08lx\n",
1366             ipu_base + devtype->disp0_ofs);
1367     dev_dbg(&pdev->dev, "disp1:    0x%08lx\n",
1368             ipu_base + devtype->disp1_ofs);
1369     dev_dbg(&pdev->dev, "srm:      0x%08lx\n",
1370             ipu_base + devtype->srm_ofs);
1371     dev_dbg(&pdev->dev, "tpm:      0x%08lx\n",
1372             ipu_base + devtype->tpm_ofs);
1373     dev_dbg(&pdev->dev, "dc:       0x%08lx\n",
1374             ipu_base + devtype->cm_ofs + IPU_CM_DC_REG_OFS);
1375     dev_dbg(&pdev->dev, "ic:       0x%08lx\n",
1376             ipu_base + devtype->cm_ofs + IPU_CM_IC_REG_OFS);
1377     dev_dbg(&pdev->dev, "dmfc:     0x%08lx\n",
1378             ipu_base + devtype->cm_ofs + IPU_CM_DMFC_REG_OFS);
1379     dev_dbg(&pdev->dev, "vdi:      0x%08lx\n",
1380             ipu_base + devtype->vdi_ofs);
1381 
1382     ipu->cm_reg = devm_ioremap(&pdev->dev,
1383             ipu_base + devtype->cm_ofs, PAGE_SIZE);
1384     ipu->idmac_reg = devm_ioremap(&pdev->dev,
1385             ipu_base + devtype->cm_ofs + IPU_CM_IDMAC_REG_OFS,
1386             PAGE_SIZE);
1387 
1388     if (!ipu->cm_reg || !ipu->idmac_reg)
1389         return -ENOMEM;
1390 
1391     ipu->clk = devm_clk_get(&pdev->dev, "bus");
1392     if (IS_ERR(ipu->clk)) {
1393         ret = PTR_ERR(ipu->clk);
1394         dev_err(&pdev->dev, "clk_get failed with %d", ret);
1395         return ret;
1396     }
1397 
1398     platform_set_drvdata(pdev, ipu);
1399 
1400     ret = clk_prepare_enable(ipu->clk);
1401     if (ret) {
1402         dev_err(&pdev->dev, "clk_prepare_enable failed: %d\n", ret);
1403         return ret;
1404     }
1405 
1406     ipu->dev = &pdev->dev;
1407     ipu->irq_sync = irq_sync;
1408     ipu->irq_err = irq_err;
1409 
1410     ret = device_reset(&pdev->dev);
1411     if (ret) {
1412         dev_err(&pdev->dev, "failed to reset: %d\n", ret);
1413         goto out_failed_reset;
1414     }
1415     ret = ipu_memory_reset(ipu);
1416     if (ret)
1417         goto out_failed_reset;
1418 
1419     ret = ipu_irq_init(ipu);
1420     if (ret)
1421         goto out_failed_irq;
1422 
1423     /* Set MCU_T to divide MCU access window into 2 */
1424     ipu_cm_write(ipu, 0x00400000L | (IPU_MCU_T_DEFAULT << 18),
1425             IPU_DISP_GEN);
1426 
1427     ret = ipu_submodules_init(ipu, pdev, ipu_base, ipu->clk);
1428     if (ret)
1429         goto failed_submodules_init;
1430 
1431     ret = ipu_add_client_devices(ipu, ipu_base);
1432     if (ret) {
1433         dev_err(&pdev->dev, "adding client devices failed with %d\n",
1434                 ret);
1435         goto failed_add_clients;
1436     }
1437 
1438     dev_info(&pdev->dev, "%s probed\n", devtype->name);
1439 
1440     return 0;
1441 
1442 failed_add_clients:
1443     ipu_submodules_exit(ipu);
1444 failed_submodules_init:
1445     ipu_irq_exit(ipu);
1446 out_failed_irq:
1447 out_failed_reset:
1448     clk_disable_unprepare(ipu->clk);
1449     return ret;
1450 }
1451 
1452 static int ipu_remove(struct platform_device *pdev)
1453 {
1454     struct ipu_soc *ipu = platform_get_drvdata(pdev);
1455 
1456     platform_device_unregister_children(pdev);
1457     ipu_submodules_exit(ipu);
1458     ipu_irq_exit(ipu);
1459 
1460     clk_disable_unprepare(ipu->clk);
1461 
1462     return 0;
1463 }
1464 
1465 static struct platform_driver imx_ipu_driver = {
1466     .driver = {
1467         .name = "imx-ipuv3",
1468         .of_match_table = imx_ipu_dt_ids,
1469     },
1470     .probe = ipu_probe,
1471     .remove = ipu_remove,
1472 };
1473 
1474 static struct platform_driver * const drivers[] = {
1475 #if IS_ENABLED(CONFIG_DRM)
1476     &ipu_pre_drv,
1477     &ipu_prg_drv,
1478 #endif
1479     &imx_ipu_driver,
1480 };
1481 
1482 static int __init imx_ipu_init(void)
1483 {
1484     return platform_register_drivers(drivers, ARRAY_SIZE(drivers));
1485 }
1486 module_init(imx_ipu_init);
1487 
1488 static void __exit imx_ipu_exit(void)
1489 {
1490     platform_unregister_drivers(drivers, ARRAY_SIZE(drivers));
1491 }
1492 module_exit(imx_ipu_exit);
1493 
1494 MODULE_ALIAS("platform:imx-ipuv3");
1495 MODULE_DESCRIPTION("i.MX IPU v3 driver");
1496 MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
1497 MODULE_LICENSE("GPL");