ipu-common.c 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349
  1. /*
  2. * Copyright (c) 2010 Sascha Hauer <s.hauer@pengutronix.de>
  3. * Copyright (C) 2005-2009 Freescale Semiconductor, Inc.
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms of the GNU General Public License as published by the
  7. * Free Software Foundation; either version 2 of the License, or (at your
  8. * option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  12. * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  13. * for more details.
  14. */
  15. #include <linux/module.h>
  16. #include <linux/export.h>
  17. #include <linux/types.h>
  18. #include <linux/reset.h>
  19. #include <linux/platform_device.h>
  20. #include <linux/err.h>
  21. #include <linux/spinlock.h>
  22. #include <linux/delay.h>
  23. #include <linux/interrupt.h>
  24. #include <linux/io.h>
  25. #include <linux/clk.h>
  26. #include <linux/list.h>
  27. #include <linux/irq.h>
  28. #include <linux/irqchip/chained_irq.h>
  29. #include <linux/irqdomain.h>
  30. #include <linux/of_device.h>
  31. #include <drm/drm_fourcc.h>
  32. #include <video/imx-ipu-v3.h>
  33. #include "ipu-prv.h"
  34. static inline u32 ipu_cm_read(struct ipu_soc *ipu, unsigned offset)
  35. {
  36. return readl(ipu->cm_reg + offset);
  37. }
  38. static inline void ipu_cm_write(struct ipu_soc *ipu, u32 value, unsigned offset)
  39. {
  40. writel(value, ipu->cm_reg + offset);
  41. }
  42. void ipu_srm_dp_sync_update(struct ipu_soc *ipu)
  43. {
  44. u32 val;
  45. val = ipu_cm_read(ipu, IPU_SRM_PRI2);
  46. val |= 0x8;
  47. ipu_cm_write(ipu, val, IPU_SRM_PRI2);
  48. }
  49. EXPORT_SYMBOL_GPL(ipu_srm_dp_sync_update);
  50. enum ipu_color_space ipu_drm_fourcc_to_colorspace(u32 drm_fourcc)
  51. {
  52. switch (drm_fourcc) {
  53. case DRM_FORMAT_RGB565:
  54. case DRM_FORMAT_BGR565:
  55. case DRM_FORMAT_RGB888:
  56. case DRM_FORMAT_BGR888:
  57. case DRM_FORMAT_XRGB8888:
  58. case DRM_FORMAT_XBGR8888:
  59. case DRM_FORMAT_RGBX8888:
  60. case DRM_FORMAT_BGRX8888:
  61. case DRM_FORMAT_ARGB8888:
  62. case DRM_FORMAT_ABGR8888:
  63. case DRM_FORMAT_RGBA8888:
  64. case DRM_FORMAT_BGRA8888:
  65. return IPUV3_COLORSPACE_RGB;
  66. case DRM_FORMAT_YUYV:
  67. case DRM_FORMAT_UYVY:
  68. case DRM_FORMAT_YUV420:
  69. case DRM_FORMAT_YVU420:
  70. case DRM_FORMAT_YUV422:
  71. case DRM_FORMAT_YVU422:
  72. case DRM_FORMAT_NV12:
  73. case DRM_FORMAT_NV21:
  74. case DRM_FORMAT_NV16:
  75. case DRM_FORMAT_NV61:
  76. return IPUV3_COLORSPACE_YUV;
  77. default:
  78. return IPUV3_COLORSPACE_UNKNOWN;
  79. }
  80. }
  81. EXPORT_SYMBOL_GPL(ipu_drm_fourcc_to_colorspace);
  82. enum ipu_color_space ipu_pixelformat_to_colorspace(u32 pixelformat)
  83. {
  84. switch (pixelformat) {
  85. case V4L2_PIX_FMT_YUV420:
  86. case V4L2_PIX_FMT_YVU420:
  87. case V4L2_PIX_FMT_YUV422P:
  88. case V4L2_PIX_FMT_UYVY:
  89. case V4L2_PIX_FMT_YUYV:
  90. case V4L2_PIX_FMT_NV12:
  91. case V4L2_PIX_FMT_NV21:
  92. case V4L2_PIX_FMT_NV16:
  93. case V4L2_PIX_FMT_NV61:
  94. return IPUV3_COLORSPACE_YUV;
  95. case V4L2_PIX_FMT_RGB32:
  96. case V4L2_PIX_FMT_BGR32:
  97. case V4L2_PIX_FMT_RGB24:
  98. case V4L2_PIX_FMT_BGR24:
  99. case V4L2_PIX_FMT_RGB565:
  100. return IPUV3_COLORSPACE_RGB;
  101. default:
  102. return IPUV3_COLORSPACE_UNKNOWN;
  103. }
  104. }
  105. EXPORT_SYMBOL_GPL(ipu_pixelformat_to_colorspace);
  106. bool ipu_pixelformat_is_planar(u32 pixelformat)
  107. {
  108. switch (pixelformat) {
  109. case V4L2_PIX_FMT_YUV420:
  110. case V4L2_PIX_FMT_YVU420:
  111. case V4L2_PIX_FMT_YUV422P:
  112. case V4L2_PIX_FMT_NV12:
  113. case V4L2_PIX_FMT_NV21:
  114. case V4L2_PIX_FMT_NV16:
  115. case V4L2_PIX_FMT_NV61:
  116. return true;
  117. }
  118. return false;
  119. }
  120. EXPORT_SYMBOL_GPL(ipu_pixelformat_is_planar);
  121. enum ipu_color_space ipu_mbus_code_to_colorspace(u32 mbus_code)
  122. {
  123. switch (mbus_code & 0xf000) {
  124. case 0x1000:
  125. return IPUV3_COLORSPACE_RGB;
  126. case 0x2000:
  127. return IPUV3_COLORSPACE_YUV;
  128. default:
  129. return IPUV3_COLORSPACE_UNKNOWN;
  130. }
  131. }
  132. EXPORT_SYMBOL_GPL(ipu_mbus_code_to_colorspace);
  133. int ipu_stride_to_bytes(u32 pixel_stride, u32 pixelformat)
  134. {
  135. switch (pixelformat) {
  136. case V4L2_PIX_FMT_YUV420:
  137. case V4L2_PIX_FMT_YVU420:
  138. case V4L2_PIX_FMT_YUV422P:
  139. case V4L2_PIX_FMT_NV12:
  140. case V4L2_PIX_FMT_NV21:
  141. case V4L2_PIX_FMT_NV16:
  142. case V4L2_PIX_FMT_NV61:
  143. /*
  144. * for the planar YUV formats, the stride passed to
  145. * cpmem must be the stride in bytes of the Y plane.
  146. * And all the planar YUV formats have an 8-bit
  147. * Y component.
  148. */
  149. return (8 * pixel_stride) >> 3;
  150. case V4L2_PIX_FMT_RGB565:
  151. case V4L2_PIX_FMT_YUYV:
  152. case V4L2_PIX_FMT_UYVY:
  153. return (16 * pixel_stride) >> 3;
  154. case V4L2_PIX_FMT_BGR24:
  155. case V4L2_PIX_FMT_RGB24:
  156. return (24 * pixel_stride) >> 3;
  157. case V4L2_PIX_FMT_BGR32:
  158. case V4L2_PIX_FMT_RGB32:
  159. return (32 * pixel_stride) >> 3;
  160. default:
  161. break;
  162. }
  163. return -EINVAL;
  164. }
  165. EXPORT_SYMBOL_GPL(ipu_stride_to_bytes);
  166. int ipu_degrees_to_rot_mode(enum ipu_rotate_mode *mode, int degrees,
  167. bool hflip, bool vflip)
  168. {
  169. u32 r90, vf, hf;
  170. switch (degrees) {
  171. case 0:
  172. vf = hf = r90 = 0;
  173. break;
  174. case 90:
  175. vf = hf = 0;
  176. r90 = 1;
  177. break;
  178. case 180:
  179. vf = hf = 1;
  180. r90 = 0;
  181. break;
  182. case 270:
  183. vf = hf = r90 = 1;
  184. break;
  185. default:
  186. return -EINVAL;
  187. }
  188. hf ^= (u32)hflip;
  189. vf ^= (u32)vflip;
  190. *mode = (enum ipu_rotate_mode)((r90 << 2) | (hf << 1) | vf);
  191. return 0;
  192. }
  193. EXPORT_SYMBOL_GPL(ipu_degrees_to_rot_mode);
  194. int ipu_rot_mode_to_degrees(int *degrees, enum ipu_rotate_mode mode,
  195. bool hflip, bool vflip)
  196. {
  197. u32 r90, vf, hf;
  198. r90 = ((u32)mode >> 2) & 0x1;
  199. hf = ((u32)mode >> 1) & 0x1;
  200. vf = ((u32)mode >> 0) & 0x1;
  201. hf ^= (u32)hflip;
  202. vf ^= (u32)vflip;
  203. switch ((enum ipu_rotate_mode)((r90 << 2) | (hf << 1) | vf)) {
  204. case IPU_ROTATE_NONE:
  205. *degrees = 0;
  206. break;
  207. case IPU_ROTATE_90_RIGHT:
  208. *degrees = 90;
  209. break;
  210. case IPU_ROTATE_180:
  211. *degrees = 180;
  212. break;
  213. case IPU_ROTATE_90_LEFT:
  214. *degrees = 270;
  215. break;
  216. default:
  217. return -EINVAL;
  218. }
  219. return 0;
  220. }
  221. EXPORT_SYMBOL_GPL(ipu_rot_mode_to_degrees);
  222. struct ipuv3_channel *ipu_idmac_get(struct ipu_soc *ipu, unsigned num)
  223. {
  224. struct ipuv3_channel *channel;
  225. dev_dbg(ipu->dev, "%s %d\n", __func__, num);
  226. if (num > 63)
  227. return ERR_PTR(-ENODEV);
  228. mutex_lock(&ipu->channel_lock);
  229. channel = &ipu->channel[num];
  230. if (channel->busy) {
  231. channel = ERR_PTR(-EBUSY);
  232. goto out;
  233. }
  234. channel->busy = true;
  235. channel->num = num;
  236. out:
  237. mutex_unlock(&ipu->channel_lock);
  238. return channel;
  239. }
  240. EXPORT_SYMBOL_GPL(ipu_idmac_get);
  241. void ipu_idmac_put(struct ipuv3_channel *channel)
  242. {
  243. struct ipu_soc *ipu = channel->ipu;
  244. dev_dbg(ipu->dev, "%s %d\n", __func__, channel->num);
  245. mutex_lock(&ipu->channel_lock);
  246. channel->busy = false;
  247. mutex_unlock(&ipu->channel_lock);
  248. }
  249. EXPORT_SYMBOL_GPL(ipu_idmac_put);
  250. #define idma_mask(ch) (1 << ((ch) & 0x1f))
  251. /*
  252. * This is an undocumented feature, a write one to a channel bit in
  253. * IPU_CHA_CUR_BUF and IPU_CHA_TRIPLE_CUR_BUF will reset the channel's
  254. * internal current buffer pointer so that transfers start from buffer
  255. * 0 on the next channel enable (that's the theory anyway, the imx6 TRM
  256. * only says these are read-only registers). This operation is required
  257. * for channel linking to work correctly, for instance video capture
  258. * pipelines that carry out image rotations will fail after the first
  259. * streaming unless this function is called for each channel before
  260. * re-enabling the channels.
  261. */
  262. static void __ipu_idmac_reset_current_buffer(struct ipuv3_channel *channel)
  263. {
  264. struct ipu_soc *ipu = channel->ipu;
  265. unsigned int chno = channel->num;
  266. ipu_cm_write(ipu, idma_mask(chno), IPU_CHA_CUR_BUF(chno));
  267. }
  268. void ipu_idmac_set_double_buffer(struct ipuv3_channel *channel,
  269. bool doublebuffer)
  270. {
  271. struct ipu_soc *ipu = channel->ipu;
  272. unsigned long flags;
  273. u32 reg;
  274. spin_lock_irqsave(&ipu->lock, flags);
  275. reg = ipu_cm_read(ipu, IPU_CHA_DB_MODE_SEL(channel->num));
  276. if (doublebuffer)
  277. reg |= idma_mask(channel->num);
  278. else
  279. reg &= ~idma_mask(channel->num);
  280. ipu_cm_write(ipu, reg, IPU_CHA_DB_MODE_SEL(channel->num));
  281. __ipu_idmac_reset_current_buffer(channel);
  282. spin_unlock_irqrestore(&ipu->lock, flags);
  283. }
  284. EXPORT_SYMBOL_GPL(ipu_idmac_set_double_buffer);
  285. static const struct {
  286. int chnum;
  287. u32 reg;
  288. int shift;
  289. } idmac_lock_en_info[] = {
  290. { .chnum = 5, .reg = IDMAC_CH_LOCK_EN_1, .shift = 0, },
  291. { .chnum = 11, .reg = IDMAC_CH_LOCK_EN_1, .shift = 2, },
  292. { .chnum = 12, .reg = IDMAC_CH_LOCK_EN_1, .shift = 4, },
  293. { .chnum = 14, .reg = IDMAC_CH_LOCK_EN_1, .shift = 6, },
  294. { .chnum = 15, .reg = IDMAC_CH_LOCK_EN_1, .shift = 8, },
  295. { .chnum = 20, .reg = IDMAC_CH_LOCK_EN_1, .shift = 10, },
  296. { .chnum = 21, .reg = IDMAC_CH_LOCK_EN_1, .shift = 12, },
  297. { .chnum = 22, .reg = IDMAC_CH_LOCK_EN_1, .shift = 14, },
  298. { .chnum = 23, .reg = IDMAC_CH_LOCK_EN_1, .shift = 16, },
  299. { .chnum = 27, .reg = IDMAC_CH_LOCK_EN_1, .shift = 18, },
  300. { .chnum = 28, .reg = IDMAC_CH_LOCK_EN_1, .shift = 20, },
  301. { .chnum = 45, .reg = IDMAC_CH_LOCK_EN_2, .shift = 0, },
  302. { .chnum = 46, .reg = IDMAC_CH_LOCK_EN_2, .shift = 2, },
  303. { .chnum = 47, .reg = IDMAC_CH_LOCK_EN_2, .shift = 4, },
  304. { .chnum = 48, .reg = IDMAC_CH_LOCK_EN_2, .shift = 6, },
  305. { .chnum = 49, .reg = IDMAC_CH_LOCK_EN_2, .shift = 8, },
  306. { .chnum = 50, .reg = IDMAC_CH_LOCK_EN_2, .shift = 10, },
  307. };
  308. int ipu_idmac_lock_enable(struct ipuv3_channel *channel, int num_bursts)
  309. {
  310. struct ipu_soc *ipu = channel->ipu;
  311. unsigned long flags;
  312. u32 bursts, regval;
  313. int i;
  314. switch (num_bursts) {
  315. case 0:
  316. case 1:
  317. bursts = 0x00; /* locking disabled */
  318. break;
  319. case 2:
  320. bursts = 0x01;
  321. break;
  322. case 4:
  323. bursts = 0x02;
  324. break;
  325. case 8:
  326. bursts = 0x03;
  327. break;
  328. default:
  329. return -EINVAL;
  330. }
  331. for (i = 0; i < ARRAY_SIZE(idmac_lock_en_info); i++) {
  332. if (channel->num == idmac_lock_en_info[i].chnum)
  333. break;
  334. }
  335. if (i >= ARRAY_SIZE(idmac_lock_en_info))
  336. return -EINVAL;
  337. spin_lock_irqsave(&ipu->lock, flags);
  338. regval = ipu_idmac_read(ipu, idmac_lock_en_info[i].reg);
  339. regval &= ~(0x03 << idmac_lock_en_info[i].shift);
  340. regval |= (bursts << idmac_lock_en_info[i].shift);
  341. ipu_idmac_write(ipu, regval, idmac_lock_en_info[i].reg);
  342. spin_unlock_irqrestore(&ipu->lock, flags);
  343. return 0;
  344. }
  345. EXPORT_SYMBOL_GPL(ipu_idmac_lock_enable);
  346. int ipu_module_enable(struct ipu_soc *ipu, u32 mask)
  347. {
  348. unsigned long lock_flags;
  349. u32 val;
  350. spin_lock_irqsave(&ipu->lock, lock_flags);
  351. val = ipu_cm_read(ipu, IPU_DISP_GEN);
  352. if (mask & IPU_CONF_DI0_EN)
  353. val |= IPU_DI0_COUNTER_RELEASE;
  354. if (mask & IPU_CONF_DI1_EN)
  355. val |= IPU_DI1_COUNTER_RELEASE;
  356. ipu_cm_write(ipu, val, IPU_DISP_GEN);
  357. val = ipu_cm_read(ipu, IPU_CONF);
  358. val |= mask;
  359. ipu_cm_write(ipu, val, IPU_CONF);
  360. spin_unlock_irqrestore(&ipu->lock, lock_flags);
  361. return 0;
  362. }
  363. EXPORT_SYMBOL_GPL(ipu_module_enable);
  364. int ipu_module_disable(struct ipu_soc *ipu, u32 mask)
  365. {
  366. unsigned long lock_flags;
  367. u32 val;
  368. spin_lock_irqsave(&ipu->lock, lock_flags);
  369. val = ipu_cm_read(ipu, IPU_CONF);
  370. val &= ~mask;
  371. ipu_cm_write(ipu, val, IPU_CONF);
  372. val = ipu_cm_read(ipu, IPU_DISP_GEN);
  373. if (mask & IPU_CONF_DI0_EN)
  374. val &= ~IPU_DI0_COUNTER_RELEASE;
  375. if (mask & IPU_CONF_DI1_EN)
  376. val &= ~IPU_DI1_COUNTER_RELEASE;
  377. ipu_cm_write(ipu, val, IPU_DISP_GEN);
  378. spin_unlock_irqrestore(&ipu->lock, lock_flags);
  379. return 0;
  380. }
  381. EXPORT_SYMBOL_GPL(ipu_module_disable);
  382. int ipu_idmac_get_current_buffer(struct ipuv3_channel *channel)
  383. {
  384. struct ipu_soc *ipu = channel->ipu;
  385. unsigned int chno = channel->num;
  386. return (ipu_cm_read(ipu, IPU_CHA_CUR_BUF(chno)) & idma_mask(chno)) ? 1 : 0;
  387. }
  388. EXPORT_SYMBOL_GPL(ipu_idmac_get_current_buffer);
  389. bool ipu_idmac_buffer_is_ready(struct ipuv3_channel *channel, u32 buf_num)
  390. {
  391. struct ipu_soc *ipu = channel->ipu;
  392. unsigned long flags;
  393. u32 reg = 0;
  394. spin_lock_irqsave(&ipu->lock, flags);
  395. switch (buf_num) {
  396. case 0:
  397. reg = ipu_cm_read(ipu, IPU_CHA_BUF0_RDY(channel->num));
  398. break;
  399. case 1:
  400. reg = ipu_cm_read(ipu, IPU_CHA_BUF1_RDY(channel->num));
  401. break;
  402. case 2:
  403. reg = ipu_cm_read(ipu, IPU_CHA_BUF2_RDY(channel->num));
  404. break;
  405. }
  406. spin_unlock_irqrestore(&ipu->lock, flags);
  407. return ((reg & idma_mask(channel->num)) != 0);
  408. }
  409. EXPORT_SYMBOL_GPL(ipu_idmac_buffer_is_ready);
  410. void ipu_idmac_select_buffer(struct ipuv3_channel *channel, u32 buf_num)
  411. {
  412. struct ipu_soc *ipu = channel->ipu;
  413. unsigned int chno = channel->num;
  414. unsigned long flags;
  415. spin_lock_irqsave(&ipu->lock, flags);
  416. /* Mark buffer as ready. */
  417. if (buf_num == 0)
  418. ipu_cm_write(ipu, idma_mask(chno), IPU_CHA_BUF0_RDY(chno));
  419. else
  420. ipu_cm_write(ipu, idma_mask(chno), IPU_CHA_BUF1_RDY(chno));
  421. spin_unlock_irqrestore(&ipu->lock, flags);
  422. }
  423. EXPORT_SYMBOL_GPL(ipu_idmac_select_buffer);
  424. void ipu_idmac_clear_buffer(struct ipuv3_channel *channel, u32 buf_num)
  425. {
  426. struct ipu_soc *ipu = channel->ipu;
  427. unsigned int chno = channel->num;
  428. unsigned long flags;
  429. spin_lock_irqsave(&ipu->lock, flags);
  430. ipu_cm_write(ipu, 0xF0300000, IPU_GPR); /* write one to clear */
  431. switch (buf_num) {
  432. case 0:
  433. ipu_cm_write(ipu, idma_mask(chno), IPU_CHA_BUF0_RDY(chno));
  434. break;
  435. case 1:
  436. ipu_cm_write(ipu, idma_mask(chno), IPU_CHA_BUF1_RDY(chno));
  437. break;
  438. case 2:
  439. ipu_cm_write(ipu, idma_mask(chno), IPU_CHA_BUF2_RDY(chno));
  440. break;
  441. default:
  442. break;
  443. }
  444. ipu_cm_write(ipu, 0x0, IPU_GPR); /* write one to set */
  445. spin_unlock_irqrestore(&ipu->lock, flags);
  446. }
  447. EXPORT_SYMBOL_GPL(ipu_idmac_clear_buffer);
  448. int ipu_idmac_enable_channel(struct ipuv3_channel *channel)
  449. {
  450. struct ipu_soc *ipu = channel->ipu;
  451. u32 val;
  452. unsigned long flags;
  453. spin_lock_irqsave(&ipu->lock, flags);
  454. val = ipu_idmac_read(ipu, IDMAC_CHA_EN(channel->num));
  455. val |= idma_mask(channel->num);
  456. ipu_idmac_write(ipu, val, IDMAC_CHA_EN(channel->num));
  457. spin_unlock_irqrestore(&ipu->lock, flags);
  458. return 0;
  459. }
  460. EXPORT_SYMBOL_GPL(ipu_idmac_enable_channel);
  461. bool ipu_idmac_channel_busy(struct ipu_soc *ipu, unsigned int chno)
  462. {
  463. return (ipu_idmac_read(ipu, IDMAC_CHA_BUSY(chno)) & idma_mask(chno));
  464. }
  465. EXPORT_SYMBOL_GPL(ipu_idmac_channel_busy);
  466. int ipu_idmac_wait_busy(struct ipuv3_channel *channel, int ms)
  467. {
  468. struct ipu_soc *ipu = channel->ipu;
  469. unsigned long timeout;
  470. timeout = jiffies + msecs_to_jiffies(ms);
  471. while (ipu_idmac_read(ipu, IDMAC_CHA_BUSY(channel->num)) &
  472. idma_mask(channel->num)) {
  473. if (time_after(jiffies, timeout))
  474. return -ETIMEDOUT;
  475. cpu_relax();
  476. }
  477. return 0;
  478. }
  479. EXPORT_SYMBOL_GPL(ipu_idmac_wait_busy);
  480. int ipu_wait_interrupt(struct ipu_soc *ipu, int irq, int ms)
  481. {
  482. unsigned long timeout;
  483. timeout = jiffies + msecs_to_jiffies(ms);
  484. ipu_cm_write(ipu, BIT(irq % 32), IPU_INT_STAT(irq / 32));
  485. while (!(ipu_cm_read(ipu, IPU_INT_STAT(irq / 32) & BIT(irq % 32)))) {
  486. if (time_after(jiffies, timeout))
  487. return -ETIMEDOUT;
  488. cpu_relax();
  489. }
  490. return 0;
  491. }
  492. EXPORT_SYMBOL_GPL(ipu_wait_interrupt);
  493. int ipu_idmac_disable_channel(struct ipuv3_channel *channel)
  494. {
  495. struct ipu_soc *ipu = channel->ipu;
  496. u32 val;
  497. unsigned long flags;
  498. spin_lock_irqsave(&ipu->lock, flags);
  499. /* Disable DMA channel(s) */
  500. val = ipu_idmac_read(ipu, IDMAC_CHA_EN(channel->num));
  501. val &= ~idma_mask(channel->num);
  502. ipu_idmac_write(ipu, val, IDMAC_CHA_EN(channel->num));
  503. __ipu_idmac_reset_current_buffer(channel);
  504. /* Set channel buffers NOT to be ready */
  505. ipu_cm_write(ipu, 0xf0000000, IPU_GPR); /* write one to clear */
  506. if (ipu_cm_read(ipu, IPU_CHA_BUF0_RDY(channel->num)) &
  507. idma_mask(channel->num)) {
  508. ipu_cm_write(ipu, idma_mask(channel->num),
  509. IPU_CHA_BUF0_RDY(channel->num));
  510. }
  511. if (ipu_cm_read(ipu, IPU_CHA_BUF1_RDY(channel->num)) &
  512. idma_mask(channel->num)) {
  513. ipu_cm_write(ipu, idma_mask(channel->num),
  514. IPU_CHA_BUF1_RDY(channel->num));
  515. }
  516. ipu_cm_write(ipu, 0x0, IPU_GPR); /* write one to set */
  517. /* Reset the double buffer */
  518. val = ipu_cm_read(ipu, IPU_CHA_DB_MODE_SEL(channel->num));
  519. val &= ~idma_mask(channel->num);
  520. ipu_cm_write(ipu, val, IPU_CHA_DB_MODE_SEL(channel->num));
  521. spin_unlock_irqrestore(&ipu->lock, flags);
  522. return 0;
  523. }
  524. EXPORT_SYMBOL_GPL(ipu_idmac_disable_channel);
  525. /*
  526. * The imx6 rev. D TRM says that enabling the WM feature will increase
  527. * a channel's priority. Refer to Table 36-8 Calculated priority value.
  528. * The sub-module that is the sink or source for the channel must enable
  529. * watermark signal for this to take effect (SMFC_WM for instance).
  530. */
  531. void ipu_idmac_enable_watermark(struct ipuv3_channel *channel, bool enable)
  532. {
  533. struct ipu_soc *ipu = channel->ipu;
  534. unsigned long flags;
  535. u32 val;
  536. spin_lock_irqsave(&ipu->lock, flags);
  537. val = ipu_idmac_read(ipu, IDMAC_WM_EN(channel->num));
  538. if (enable)
  539. val |= 1 << (channel->num % 32);
  540. else
  541. val &= ~(1 << (channel->num % 32));
  542. ipu_idmac_write(ipu, val, IDMAC_WM_EN(channel->num));
  543. spin_unlock_irqrestore(&ipu->lock, flags);
  544. }
  545. EXPORT_SYMBOL_GPL(ipu_idmac_enable_watermark);
  546. static int ipu_memory_reset(struct ipu_soc *ipu)
  547. {
  548. unsigned long timeout;
  549. ipu_cm_write(ipu, 0x807FFFFF, IPU_MEM_RST);
  550. timeout = jiffies + msecs_to_jiffies(1000);
  551. while (ipu_cm_read(ipu, IPU_MEM_RST) & 0x80000000) {
  552. if (time_after(jiffies, timeout))
  553. return -ETIME;
  554. cpu_relax();
  555. }
  556. return 0;
  557. }
  558. /*
  559. * Set the source mux for the given CSI. Selects either parallel or
  560. * MIPI CSI2 sources.
  561. */
  562. void ipu_set_csi_src_mux(struct ipu_soc *ipu, int csi_id, bool mipi_csi2)
  563. {
  564. unsigned long flags;
  565. u32 val, mask;
  566. mask = (csi_id == 1) ? IPU_CONF_CSI1_DATA_SOURCE :
  567. IPU_CONF_CSI0_DATA_SOURCE;
  568. spin_lock_irqsave(&ipu->lock, flags);
  569. val = ipu_cm_read(ipu, IPU_CONF);
  570. if (mipi_csi2)
  571. val |= mask;
  572. else
  573. val &= ~mask;
  574. ipu_cm_write(ipu, val, IPU_CONF);
  575. spin_unlock_irqrestore(&ipu->lock, flags);
  576. }
  577. EXPORT_SYMBOL_GPL(ipu_set_csi_src_mux);
  578. /*
  579. * Set the source mux for the IC. Selects either CSI[01] or the VDI.
  580. */
  581. void ipu_set_ic_src_mux(struct ipu_soc *ipu, int csi_id, bool vdi)
  582. {
  583. unsigned long flags;
  584. u32 val;
  585. spin_lock_irqsave(&ipu->lock, flags);
  586. val = ipu_cm_read(ipu, IPU_CONF);
  587. if (vdi) {
  588. val |= IPU_CONF_IC_INPUT;
  589. } else {
  590. val &= ~IPU_CONF_IC_INPUT;
  591. if (csi_id == 1)
  592. val |= IPU_CONF_CSI_SEL;
  593. else
  594. val &= ~IPU_CONF_CSI_SEL;
  595. }
  596. ipu_cm_write(ipu, val, IPU_CONF);
  597. spin_unlock_irqrestore(&ipu->lock, flags);
  598. }
  599. EXPORT_SYMBOL_GPL(ipu_set_ic_src_mux);
  600. struct ipu_devtype {
  601. const char *name;
  602. unsigned long cm_ofs;
  603. unsigned long cpmem_ofs;
  604. unsigned long srm_ofs;
  605. unsigned long tpm_ofs;
  606. unsigned long csi0_ofs;
  607. unsigned long csi1_ofs;
  608. unsigned long ic_ofs;
  609. unsigned long disp0_ofs;
  610. unsigned long disp1_ofs;
  611. unsigned long dc_tmpl_ofs;
  612. unsigned long vdi_ofs;
  613. enum ipuv3_type type;
  614. };
  615. static struct ipu_devtype ipu_type_imx51 = {
  616. .name = "IPUv3EX",
  617. .cm_ofs = 0x1e000000,
  618. .cpmem_ofs = 0x1f000000,
  619. .srm_ofs = 0x1f040000,
  620. .tpm_ofs = 0x1f060000,
  621. .csi0_ofs = 0x1f030000,
  622. .csi1_ofs = 0x1f038000,
  623. .ic_ofs = 0x1e020000,
  624. .disp0_ofs = 0x1e040000,
  625. .disp1_ofs = 0x1e048000,
  626. .dc_tmpl_ofs = 0x1f080000,
  627. .vdi_ofs = 0x1e068000,
  628. .type = IPUV3EX,
  629. };
  630. static struct ipu_devtype ipu_type_imx53 = {
  631. .name = "IPUv3M",
  632. .cm_ofs = 0x06000000,
  633. .cpmem_ofs = 0x07000000,
  634. .srm_ofs = 0x07040000,
  635. .tpm_ofs = 0x07060000,
  636. .csi0_ofs = 0x07030000,
  637. .csi1_ofs = 0x07038000,
  638. .ic_ofs = 0x06020000,
  639. .disp0_ofs = 0x06040000,
  640. .disp1_ofs = 0x06048000,
  641. .dc_tmpl_ofs = 0x07080000,
  642. .vdi_ofs = 0x06068000,
  643. .type = IPUV3M,
  644. };
  645. static struct ipu_devtype ipu_type_imx6q = {
  646. .name = "IPUv3H",
  647. .cm_ofs = 0x00200000,
  648. .cpmem_ofs = 0x00300000,
  649. .srm_ofs = 0x00340000,
  650. .tpm_ofs = 0x00360000,
  651. .csi0_ofs = 0x00230000,
  652. .csi1_ofs = 0x00238000,
  653. .ic_ofs = 0x00220000,
  654. .disp0_ofs = 0x00240000,
  655. .disp1_ofs = 0x00248000,
  656. .dc_tmpl_ofs = 0x00380000,
  657. .vdi_ofs = 0x00268000,
  658. .type = IPUV3H,
  659. };
  660. static const struct of_device_id imx_ipu_dt_ids[] = {
  661. { .compatible = "fsl,imx51-ipu", .data = &ipu_type_imx51, },
  662. { .compatible = "fsl,imx53-ipu", .data = &ipu_type_imx53, },
  663. { .compatible = "fsl,imx6q-ipu", .data = &ipu_type_imx6q, },
  664. { /* sentinel */ }
  665. };
  666. MODULE_DEVICE_TABLE(of, imx_ipu_dt_ids);
  667. static int ipu_submodules_init(struct ipu_soc *ipu,
  668. struct platform_device *pdev, unsigned long ipu_base,
  669. struct clk *ipu_clk)
  670. {
  671. char *unit;
  672. int ret;
  673. struct device *dev = &pdev->dev;
  674. const struct ipu_devtype *devtype = ipu->devtype;
  675. ret = ipu_cpmem_init(ipu, dev, ipu_base + devtype->cpmem_ofs);
  676. if (ret) {
  677. unit = "cpmem";
  678. goto err_cpmem;
  679. }
  680. ret = ipu_csi_init(ipu, dev, 0, ipu_base + devtype->csi0_ofs,
  681. IPU_CONF_CSI0_EN, ipu_clk);
  682. if (ret) {
  683. unit = "csi0";
  684. goto err_csi_0;
  685. }
  686. ret = ipu_csi_init(ipu, dev, 1, ipu_base + devtype->csi1_ofs,
  687. IPU_CONF_CSI1_EN, ipu_clk);
  688. if (ret) {
  689. unit = "csi1";
  690. goto err_csi_1;
  691. }
  692. ret = ipu_ic_init(ipu, dev,
  693. ipu_base + devtype->ic_ofs,
  694. ipu_base + devtype->tpm_ofs);
  695. if (ret) {
  696. unit = "ic";
  697. goto err_ic;
  698. }
  699. ret = ipu_di_init(ipu, dev, 0, ipu_base + devtype->disp0_ofs,
  700. IPU_CONF_DI0_EN, ipu_clk);
  701. if (ret) {
  702. unit = "di0";
  703. goto err_di_0;
  704. }
  705. ret = ipu_di_init(ipu, dev, 1, ipu_base + devtype->disp1_ofs,
  706. IPU_CONF_DI1_EN, ipu_clk);
  707. if (ret) {
  708. unit = "di1";
  709. goto err_di_1;
  710. }
  711. ret = ipu_dc_init(ipu, dev, ipu_base + devtype->cm_ofs +
  712. IPU_CM_DC_REG_OFS, ipu_base + devtype->dc_tmpl_ofs);
  713. if (ret) {
  714. unit = "dc_template";
  715. goto err_dc;
  716. }
  717. ret = ipu_dmfc_init(ipu, dev, ipu_base +
  718. devtype->cm_ofs + IPU_CM_DMFC_REG_OFS, ipu_clk);
  719. if (ret) {
  720. unit = "dmfc";
  721. goto err_dmfc;
  722. }
  723. ret = ipu_dp_init(ipu, dev, ipu_base + devtype->srm_ofs);
  724. if (ret) {
  725. unit = "dp";
  726. goto err_dp;
  727. }
  728. ret = ipu_smfc_init(ipu, dev, ipu_base +
  729. devtype->cm_ofs + IPU_CM_SMFC_REG_OFS);
  730. if (ret) {
  731. unit = "smfc";
  732. goto err_smfc;
  733. }
  734. return 0;
  735. err_smfc:
  736. ipu_dp_exit(ipu);
  737. err_dp:
  738. ipu_dmfc_exit(ipu);
  739. err_dmfc:
  740. ipu_dc_exit(ipu);
  741. err_dc:
  742. ipu_di_exit(ipu, 1);
  743. err_di_1:
  744. ipu_di_exit(ipu, 0);
  745. err_di_0:
  746. ipu_ic_exit(ipu);
  747. err_ic:
  748. ipu_csi_exit(ipu, 1);
  749. err_csi_1:
  750. ipu_csi_exit(ipu, 0);
  751. err_csi_0:
  752. ipu_cpmem_exit(ipu);
  753. err_cpmem:
  754. dev_err(&pdev->dev, "init %s failed with %d\n", unit, ret);
  755. return ret;
  756. }
  757. static void ipu_irq_handle(struct ipu_soc *ipu, const int *regs, int num_regs)
  758. {
  759. unsigned long status;
  760. int i, bit, irq;
  761. for (i = 0; i < num_regs; i++) {
  762. status = ipu_cm_read(ipu, IPU_INT_STAT(regs[i]));
  763. status &= ipu_cm_read(ipu, IPU_INT_CTRL(regs[i]));
  764. for_each_set_bit(bit, &status, 32) {
  765. irq = irq_linear_revmap(ipu->domain,
  766. regs[i] * 32 + bit);
  767. if (irq)
  768. generic_handle_irq(irq);
  769. }
  770. }
  771. }
  772. static void ipu_irq_handler(struct irq_desc *desc)
  773. {
  774. struct ipu_soc *ipu = irq_desc_get_handler_data(desc);
  775. struct irq_chip *chip = irq_desc_get_chip(desc);
  776. const int int_reg[] = { 0, 1, 2, 3, 10, 11, 12, 13, 14};
  777. chained_irq_enter(chip, desc);
  778. ipu_irq_handle(ipu, int_reg, ARRAY_SIZE(int_reg));
  779. chained_irq_exit(chip, desc);
  780. }
  781. static void ipu_err_irq_handler(struct irq_desc *desc)
  782. {
  783. struct ipu_soc *ipu = irq_desc_get_handler_data(desc);
  784. struct irq_chip *chip = irq_desc_get_chip(desc);
  785. const int int_reg[] = { 4, 5, 8, 9};
  786. chained_irq_enter(chip, desc);
  787. ipu_irq_handle(ipu, int_reg, ARRAY_SIZE(int_reg));
  788. chained_irq_exit(chip, desc);
  789. }
  790. int ipu_map_irq(struct ipu_soc *ipu, int irq)
  791. {
  792. int virq;
  793. virq = irq_linear_revmap(ipu->domain, irq);
  794. if (!virq)
  795. virq = irq_create_mapping(ipu->domain, irq);
  796. return virq;
  797. }
  798. EXPORT_SYMBOL_GPL(ipu_map_irq);
  799. int ipu_idmac_channel_irq(struct ipu_soc *ipu, struct ipuv3_channel *channel,
  800. enum ipu_channel_irq irq_type)
  801. {
  802. return ipu_map_irq(ipu, irq_type + channel->num);
  803. }
  804. EXPORT_SYMBOL_GPL(ipu_idmac_channel_irq);
  805. static void ipu_submodules_exit(struct ipu_soc *ipu)
  806. {
  807. ipu_smfc_exit(ipu);
  808. ipu_dp_exit(ipu);
  809. ipu_dmfc_exit(ipu);
  810. ipu_dc_exit(ipu);
  811. ipu_di_exit(ipu, 1);
  812. ipu_di_exit(ipu, 0);
  813. ipu_ic_exit(ipu);
  814. ipu_csi_exit(ipu, 1);
  815. ipu_csi_exit(ipu, 0);
  816. ipu_cpmem_exit(ipu);
  817. }
  818. static int platform_remove_devices_fn(struct device *dev, void *unused)
  819. {
  820. struct platform_device *pdev = to_platform_device(dev);
  821. platform_device_unregister(pdev);
  822. return 0;
  823. }
  824. static void platform_device_unregister_children(struct platform_device *pdev)
  825. {
  826. device_for_each_child(&pdev->dev, NULL, platform_remove_devices_fn);
  827. }
  828. struct ipu_platform_reg {
  829. struct ipu_client_platformdata pdata;
  830. const char *name;
  831. int reg_offset;
  832. };
  833. static const struct ipu_platform_reg client_reg[] = {
  834. {
  835. .pdata = {
  836. .di = 0,
  837. .dc = 5,
  838. .dp = IPU_DP_FLOW_SYNC_BG,
  839. .dma[0] = IPUV3_CHANNEL_MEM_BG_SYNC,
  840. .dma[1] = IPUV3_CHANNEL_MEM_FG_SYNC,
  841. },
  842. .name = "imx-ipuv3-crtc",
  843. }, {
  844. .pdata = {
  845. .di = 1,
  846. .dc = 1,
  847. .dp = -EINVAL,
  848. .dma[0] = IPUV3_CHANNEL_MEM_DC_SYNC,
  849. .dma[1] = -EINVAL,
  850. },
  851. .name = "imx-ipuv3-crtc",
  852. }, {
  853. .pdata = {
  854. .csi = 0,
  855. .dma[0] = IPUV3_CHANNEL_CSI0,
  856. .dma[1] = -EINVAL,
  857. },
  858. .reg_offset = IPU_CM_CSI0_REG_OFS,
  859. .name = "imx-ipuv3-camera",
  860. }, {
  861. .pdata = {
  862. .csi = 1,
  863. .dma[0] = IPUV3_CHANNEL_CSI1,
  864. .dma[1] = -EINVAL,
  865. },
  866. .reg_offset = IPU_CM_CSI1_REG_OFS,
  867. .name = "imx-ipuv3-camera",
  868. },
  869. };
  870. static DEFINE_MUTEX(ipu_client_id_mutex);
  871. static int ipu_client_id;
  872. static int ipu_add_client_devices(struct ipu_soc *ipu, unsigned long ipu_base)
  873. {
  874. struct device *dev = ipu->dev;
  875. unsigned i;
  876. int id, ret;
  877. mutex_lock(&ipu_client_id_mutex);
  878. id = ipu_client_id;
  879. ipu_client_id += ARRAY_SIZE(client_reg);
  880. mutex_unlock(&ipu_client_id_mutex);
  881. for (i = 0; i < ARRAY_SIZE(client_reg); i++) {
  882. const struct ipu_platform_reg *reg = &client_reg[i];
  883. struct platform_device *pdev;
  884. struct resource res;
  885. if (reg->reg_offset) {
  886. memset(&res, 0, sizeof(res));
  887. res.flags = IORESOURCE_MEM;
  888. res.start = ipu_base + ipu->devtype->cm_ofs + reg->reg_offset;
  889. res.end = res.start + PAGE_SIZE - 1;
  890. pdev = platform_device_register_resndata(dev, reg->name,
  891. id++, &res, 1, &reg->pdata, sizeof(reg->pdata));
  892. } else {
  893. pdev = platform_device_register_data(dev, reg->name,
  894. id++, &reg->pdata, sizeof(reg->pdata));
  895. }
  896. if (IS_ERR(pdev)) {
  897. ret = PTR_ERR(pdev);
  898. goto err_register;
  899. }
  900. }
  901. return 0;
  902. err_register:
  903. platform_device_unregister_children(to_platform_device(dev));
  904. return ret;
  905. }
  906. static int ipu_irq_init(struct ipu_soc *ipu)
  907. {
  908. struct irq_chip_generic *gc;
  909. struct irq_chip_type *ct;
  910. unsigned long unused[IPU_NUM_IRQS / 32] = {
  911. 0x400100d0, 0xffe000fd,
  912. 0x400100d0, 0xffe000fd,
  913. 0x400100d0, 0xffe000fd,
  914. 0x4077ffff, 0xffe7e1fd,
  915. 0x23fffffe, 0x8880fff0,
  916. 0xf98fe7d0, 0xfff81fff,
  917. 0x400100d0, 0xffe000fd,
  918. 0x00000000,
  919. };
  920. int ret, i;
  921. ipu->domain = irq_domain_add_linear(ipu->dev->of_node, IPU_NUM_IRQS,
  922. &irq_generic_chip_ops, ipu);
  923. if (!ipu->domain) {
  924. dev_err(ipu->dev, "failed to add irq domain\n");
  925. return -ENODEV;
  926. }
  927. ret = irq_alloc_domain_generic_chips(ipu->domain, 32, 1, "IPU",
  928. handle_level_irq, 0, 0, 0);
  929. if (ret < 0) {
  930. dev_err(ipu->dev, "failed to alloc generic irq chips\n");
  931. irq_domain_remove(ipu->domain);
  932. return ret;
  933. }
  934. for (i = 0; i < IPU_NUM_IRQS; i += 32)
  935. ipu_cm_write(ipu, 0, IPU_INT_CTRL(i / 32));
  936. for (i = 0; i < IPU_NUM_IRQS; i += 32) {
  937. gc = irq_get_domain_generic_chip(ipu->domain, i);
  938. gc->reg_base = ipu->cm_reg;
  939. gc->unused = unused[i / 32];
  940. ct = gc->chip_types;
  941. ct->chip.irq_ack = irq_gc_ack_set_bit;
  942. ct->chip.irq_mask = irq_gc_mask_clr_bit;
  943. ct->chip.irq_unmask = irq_gc_mask_set_bit;
  944. ct->regs.ack = IPU_INT_STAT(i / 32);
  945. ct->regs.mask = IPU_INT_CTRL(i / 32);
  946. }
  947. irq_set_chained_handler_and_data(ipu->irq_sync, ipu_irq_handler, ipu);
  948. irq_set_chained_handler_and_data(ipu->irq_err, ipu_err_irq_handler,
  949. ipu);
  950. return 0;
  951. }
  952. static void ipu_irq_exit(struct ipu_soc *ipu)
  953. {
  954. int i, irq;
  955. irq_set_chained_handler_and_data(ipu->irq_err, NULL, NULL);
  956. irq_set_chained_handler_and_data(ipu->irq_sync, NULL, NULL);
  957. /* TODO: remove irq_domain_generic_chips */
  958. for (i = 0; i < IPU_NUM_IRQS; i++) {
  959. irq = irq_linear_revmap(ipu->domain, i);
  960. if (irq)
  961. irq_dispose_mapping(irq);
  962. }
  963. irq_domain_remove(ipu->domain);
  964. }
  965. void ipu_dump(struct ipu_soc *ipu)
  966. {
  967. int i;
  968. dev_dbg(ipu->dev, "IPU_CONF = \t0x%08X\n",
  969. ipu_cm_read(ipu, IPU_CONF));
  970. dev_dbg(ipu->dev, "IDMAC_CONF = \t0x%08X\n",
  971. ipu_idmac_read(ipu, IDMAC_CONF));
  972. dev_dbg(ipu->dev, "IDMAC_CHA_EN1 = \t0x%08X\n",
  973. ipu_idmac_read(ipu, IDMAC_CHA_EN(0)));
  974. dev_dbg(ipu->dev, "IDMAC_CHA_EN2 = \t0x%08X\n",
  975. ipu_idmac_read(ipu, IDMAC_CHA_EN(32)));
  976. dev_dbg(ipu->dev, "IDMAC_CHA_PRI1 = \t0x%08X\n",
  977. ipu_idmac_read(ipu, IDMAC_CHA_PRI(0)));
  978. dev_dbg(ipu->dev, "IDMAC_CHA_PRI2 = \t0x%08X\n",
  979. ipu_idmac_read(ipu, IDMAC_CHA_PRI(32)));
  980. dev_dbg(ipu->dev, "IDMAC_BAND_EN1 = \t0x%08X\n",
  981. ipu_idmac_read(ipu, IDMAC_BAND_EN(0)));
  982. dev_dbg(ipu->dev, "IDMAC_BAND_EN2 = \t0x%08X\n",
  983. ipu_idmac_read(ipu, IDMAC_BAND_EN(32)));
  984. dev_dbg(ipu->dev, "IPU_CHA_DB_MODE_SEL0 = \t0x%08X\n",
  985. ipu_cm_read(ipu, IPU_CHA_DB_MODE_SEL(0)));
  986. dev_dbg(ipu->dev, "IPU_CHA_DB_MODE_SEL1 = \t0x%08X\n",
  987. ipu_cm_read(ipu, IPU_CHA_DB_MODE_SEL(32)));
  988. dev_dbg(ipu->dev, "IPU_FS_PROC_FLOW1 = \t0x%08X\n",
  989. ipu_cm_read(ipu, IPU_FS_PROC_FLOW1));
  990. dev_dbg(ipu->dev, "IPU_FS_PROC_FLOW2 = \t0x%08X\n",
  991. ipu_cm_read(ipu, IPU_FS_PROC_FLOW2));
  992. dev_dbg(ipu->dev, "IPU_FS_PROC_FLOW3 = \t0x%08X\n",
  993. ipu_cm_read(ipu, IPU_FS_PROC_FLOW3));
  994. dev_dbg(ipu->dev, "IPU_FS_DISP_FLOW1 = \t0x%08X\n",
  995. ipu_cm_read(ipu, IPU_FS_DISP_FLOW1));
  996. for (i = 0; i < 15; i++)
  997. dev_dbg(ipu->dev, "IPU_INT_CTRL(%d) = \t%08X\n", i,
  998. ipu_cm_read(ipu, IPU_INT_CTRL(i)));
  999. }
  1000. EXPORT_SYMBOL_GPL(ipu_dump);
  1001. static int ipu_probe(struct platform_device *pdev)
  1002. {
  1003. const struct of_device_id *of_id =
  1004. of_match_device(imx_ipu_dt_ids, &pdev->dev);
  1005. struct ipu_soc *ipu;
  1006. struct resource *res;
  1007. unsigned long ipu_base;
  1008. int i, ret, irq_sync, irq_err;
  1009. const struct ipu_devtype *devtype;
  1010. devtype = of_id->data;
  1011. irq_sync = platform_get_irq(pdev, 0);
  1012. irq_err = platform_get_irq(pdev, 1);
  1013. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  1014. dev_dbg(&pdev->dev, "irq_sync: %d irq_err: %d\n",
  1015. irq_sync, irq_err);
  1016. if (!res || irq_sync < 0 || irq_err < 0)
  1017. return -ENODEV;
  1018. ipu_base = res->start;
  1019. ipu = devm_kzalloc(&pdev->dev, sizeof(*ipu), GFP_KERNEL);
  1020. if (!ipu)
  1021. return -ENODEV;
  1022. for (i = 0; i < 64; i++)
  1023. ipu->channel[i].ipu = ipu;
  1024. ipu->devtype = devtype;
  1025. ipu->ipu_type = devtype->type;
  1026. spin_lock_init(&ipu->lock);
  1027. mutex_init(&ipu->channel_lock);
  1028. dev_dbg(&pdev->dev, "cm_reg: 0x%08lx\n",
  1029. ipu_base + devtype->cm_ofs);
  1030. dev_dbg(&pdev->dev, "idmac: 0x%08lx\n",
  1031. ipu_base + devtype->cm_ofs + IPU_CM_IDMAC_REG_OFS);
  1032. dev_dbg(&pdev->dev, "cpmem: 0x%08lx\n",
  1033. ipu_base + devtype->cpmem_ofs);
  1034. dev_dbg(&pdev->dev, "csi0: 0x%08lx\n",
  1035. ipu_base + devtype->csi0_ofs);
  1036. dev_dbg(&pdev->dev, "csi1: 0x%08lx\n",
  1037. ipu_base + devtype->csi1_ofs);
  1038. dev_dbg(&pdev->dev, "ic: 0x%08lx\n",
  1039. ipu_base + devtype->ic_ofs);
  1040. dev_dbg(&pdev->dev, "disp0: 0x%08lx\n",
  1041. ipu_base + devtype->disp0_ofs);
  1042. dev_dbg(&pdev->dev, "disp1: 0x%08lx\n",
  1043. ipu_base + devtype->disp1_ofs);
  1044. dev_dbg(&pdev->dev, "srm: 0x%08lx\n",
  1045. ipu_base + devtype->srm_ofs);
  1046. dev_dbg(&pdev->dev, "tpm: 0x%08lx\n",
  1047. ipu_base + devtype->tpm_ofs);
  1048. dev_dbg(&pdev->dev, "dc: 0x%08lx\n",
  1049. ipu_base + devtype->cm_ofs + IPU_CM_DC_REG_OFS);
  1050. dev_dbg(&pdev->dev, "ic: 0x%08lx\n",
  1051. ipu_base + devtype->cm_ofs + IPU_CM_IC_REG_OFS);
  1052. dev_dbg(&pdev->dev, "dmfc: 0x%08lx\n",
  1053. ipu_base + devtype->cm_ofs + IPU_CM_DMFC_REG_OFS);
  1054. dev_dbg(&pdev->dev, "vdi: 0x%08lx\n",
  1055. ipu_base + devtype->vdi_ofs);
  1056. ipu->cm_reg = devm_ioremap(&pdev->dev,
  1057. ipu_base + devtype->cm_ofs, PAGE_SIZE);
  1058. ipu->idmac_reg = devm_ioremap(&pdev->dev,
  1059. ipu_base + devtype->cm_ofs + IPU_CM_IDMAC_REG_OFS,
  1060. PAGE_SIZE);
  1061. if (!ipu->cm_reg || !ipu->idmac_reg)
  1062. return -ENOMEM;
  1063. ipu->clk = devm_clk_get(&pdev->dev, "bus");
  1064. if (IS_ERR(ipu->clk)) {
  1065. ret = PTR_ERR(ipu->clk);
  1066. dev_err(&pdev->dev, "clk_get failed with %d", ret);
  1067. return ret;
  1068. }
  1069. platform_set_drvdata(pdev, ipu);
  1070. ret = clk_prepare_enable(ipu->clk);
  1071. if (ret) {
  1072. dev_err(&pdev->dev, "clk_prepare_enable failed: %d\n", ret);
  1073. return ret;
  1074. }
  1075. ipu->dev = &pdev->dev;
  1076. ipu->irq_sync = irq_sync;
  1077. ipu->irq_err = irq_err;
  1078. ret = ipu_irq_init(ipu);
  1079. if (ret)
  1080. goto out_failed_irq;
  1081. ret = device_reset(&pdev->dev);
  1082. if (ret) {
  1083. dev_err(&pdev->dev, "failed to reset: %d\n", ret);
  1084. goto out_failed_reset;
  1085. }
  1086. ret = ipu_memory_reset(ipu);
  1087. if (ret)
  1088. goto out_failed_reset;
  1089. /* Set MCU_T to divide MCU access window into 2 */
  1090. ipu_cm_write(ipu, 0x00400000L | (IPU_MCU_T_DEFAULT << 18),
  1091. IPU_DISP_GEN);
  1092. ret = ipu_submodules_init(ipu, pdev, ipu_base, ipu->clk);
  1093. if (ret)
  1094. goto failed_submodules_init;
  1095. ret = ipu_add_client_devices(ipu, ipu_base);
  1096. if (ret) {
  1097. dev_err(&pdev->dev, "adding client devices failed with %d\n",
  1098. ret);
  1099. goto failed_add_clients;
  1100. }
  1101. dev_info(&pdev->dev, "%s probed\n", devtype->name);
  1102. return 0;
  1103. failed_add_clients:
  1104. ipu_submodules_exit(ipu);
  1105. failed_submodules_init:
  1106. out_failed_reset:
  1107. ipu_irq_exit(ipu);
  1108. out_failed_irq:
  1109. clk_disable_unprepare(ipu->clk);
  1110. return ret;
  1111. }
  1112. static int ipu_remove(struct platform_device *pdev)
  1113. {
  1114. struct ipu_soc *ipu = platform_get_drvdata(pdev);
  1115. platform_device_unregister_children(pdev);
  1116. ipu_submodules_exit(ipu);
  1117. ipu_irq_exit(ipu);
  1118. clk_disable_unprepare(ipu->clk);
  1119. return 0;
  1120. }
  1121. static struct platform_driver imx_ipu_driver = {
  1122. .driver = {
  1123. .name = "imx-ipuv3",
  1124. .of_match_table = imx_ipu_dt_ids,
  1125. },
  1126. .probe = ipu_probe,
  1127. .remove = ipu_remove,
  1128. };
  1129. module_platform_driver(imx_ipu_driver);
  1130. MODULE_ALIAS("platform:imx-ipuv3");
  1131. MODULE_DESCRIPTION("i.MX IPU v3 driver");
  1132. MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
  1133. MODULE_LICENSE("GPL");