0001
0002
0003
0004
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
0254
0255
0256
0257
0258
0259
0260
0261
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;
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
0344
0345
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
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);
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);
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
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
0558 ipu_cm_write(ipu, 0xf0000000, IPU_GPR);
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);
0573
0574
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
0587
0588
0589
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
0628
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
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
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
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
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
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
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 { }
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
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
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, ®->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
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
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
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");