iss.c 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513
  1. /*
  2. * TI OMAP4 ISS V4L2 Driver
  3. *
  4. * Copyright (C) 2012, Texas Instruments
  5. *
  6. * Author: Sergio Aguirre <sergio.a.aguirre@gmail.com>
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version.
  12. */
  13. #include <linux/clk.h>
  14. #include <linux/delay.h>
  15. #include <linux/device.h>
  16. #include <linux/dma-mapping.h>
  17. #include <linux/i2c.h>
  18. #include <linux/interrupt.h>
  19. #include <linux/mfd/syscon.h>
  20. #include <linux/module.h>
  21. #include <linux/platform_device.h>
  22. #include <linux/slab.h>
  23. #include <linux/sched.h>
  24. #include <linux/vmalloc.h>
  25. #include <media/v4l2-common.h>
  26. #include <media/v4l2-device.h>
  27. #include <media/v4l2-ctrls.h>
  28. #include "iss.h"
  29. #include "iss_regs.h"
  30. #define ISS_PRINT_REGISTER(iss, name)\
  31. dev_dbg(iss->dev, "###ISS " #name "=0x%08x\n", \
  32. iss_reg_read(iss, OMAP4_ISS_MEM_TOP, ISS_##name))
  33. static void iss_print_status(struct iss_device *iss)
  34. {
  35. dev_dbg(iss->dev, "-------------ISS HL Register dump-------------\n");
  36. ISS_PRINT_REGISTER(iss, HL_REVISION);
  37. ISS_PRINT_REGISTER(iss, HL_SYSCONFIG);
  38. ISS_PRINT_REGISTER(iss, HL_IRQSTATUS(5));
  39. ISS_PRINT_REGISTER(iss, HL_IRQENABLE_SET(5));
  40. ISS_PRINT_REGISTER(iss, HL_IRQENABLE_CLR(5));
  41. ISS_PRINT_REGISTER(iss, CTRL);
  42. ISS_PRINT_REGISTER(iss, CLKCTRL);
  43. ISS_PRINT_REGISTER(iss, CLKSTAT);
  44. dev_dbg(iss->dev, "-----------------------------------------------\n");
  45. }
  46. /*
  47. * omap4iss_flush - Post pending L3 bus writes by doing a register readback
  48. * @iss: OMAP4 ISS device
  49. *
  50. * In order to force posting of pending writes, we need to write and
  51. * readback the same register, in this case the revision register.
  52. *
  53. * See this link for reference:
  54. * http://www.mail-archive.com/linux-omap@vger.kernel.org/msg08149.html
  55. */
  56. void omap4iss_flush(struct iss_device *iss)
  57. {
  58. iss_reg_write(iss, OMAP4_ISS_MEM_TOP, ISS_HL_REVISION, 0);
  59. iss_reg_read(iss, OMAP4_ISS_MEM_TOP, ISS_HL_REVISION);
  60. }
  61. /*
  62. * iss_isp_enable_interrupts - Enable ISS ISP interrupts.
  63. * @iss: OMAP4 ISS device
  64. */
  65. static void omap4iss_isp_enable_interrupts(struct iss_device *iss)
  66. {
  67. static const u32 isp_irq = ISP5_IRQ_OCP_ERR |
  68. ISP5_IRQ_RSZ_FIFO_IN_BLK_ERR |
  69. ISP5_IRQ_RSZ_FIFO_OVF |
  70. ISP5_IRQ_RSZ_INT_DMA |
  71. ISP5_IRQ_ISIF_INT(0);
  72. /* Enable ISP interrupts */
  73. iss_reg_write(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_IRQSTATUS(0), isp_irq);
  74. iss_reg_write(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_IRQENABLE_SET(0),
  75. isp_irq);
  76. }
  77. /*
  78. * iss_isp_disable_interrupts - Disable ISS interrupts.
  79. * @iss: OMAP4 ISS device
  80. */
  81. static void omap4iss_isp_disable_interrupts(struct iss_device *iss)
  82. {
  83. iss_reg_write(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_IRQENABLE_CLR(0), ~0);
  84. }
  85. /*
  86. * iss_enable_interrupts - Enable ISS interrupts.
  87. * @iss: OMAP4 ISS device
  88. */
  89. static void iss_enable_interrupts(struct iss_device *iss)
  90. {
  91. static const u32 hl_irq = ISS_HL_IRQ_CSIA | ISS_HL_IRQ_CSIB
  92. | ISS_HL_IRQ_ISP(0);
  93. /* Enable HL interrupts */
  94. iss_reg_write(iss, OMAP4_ISS_MEM_TOP, ISS_HL_IRQSTATUS(5), hl_irq);
  95. iss_reg_write(iss, OMAP4_ISS_MEM_TOP, ISS_HL_IRQENABLE_SET(5), hl_irq);
  96. if (iss->regs[OMAP4_ISS_MEM_ISP_SYS1])
  97. omap4iss_isp_enable_interrupts(iss);
  98. }
  99. /*
  100. * iss_disable_interrupts - Disable ISS interrupts.
  101. * @iss: OMAP4 ISS device
  102. */
  103. static void iss_disable_interrupts(struct iss_device *iss)
  104. {
  105. if (iss->regs[OMAP4_ISS_MEM_ISP_SYS1])
  106. omap4iss_isp_disable_interrupts(iss);
  107. iss_reg_write(iss, OMAP4_ISS_MEM_TOP, ISS_HL_IRQENABLE_CLR(5), ~0);
  108. }
  109. int omap4iss_get_external_info(struct iss_pipeline *pipe,
  110. struct media_link *link)
  111. {
  112. struct iss_device *iss =
  113. container_of(pipe, struct iss_video, pipe)->iss;
  114. struct v4l2_subdev_format fmt;
  115. struct v4l2_ctrl *ctrl;
  116. int ret;
  117. if (!pipe->external)
  118. return 0;
  119. if (pipe->external_rate)
  120. return 0;
  121. memset(&fmt, 0, sizeof(fmt));
  122. fmt.pad = link->source->index;
  123. fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
  124. ret = v4l2_subdev_call(media_entity_to_v4l2_subdev(link->sink->entity),
  125. pad, get_fmt, NULL, &fmt);
  126. if (ret < 0)
  127. return -EPIPE;
  128. pipe->external_bpp = omap4iss_video_format_info(fmt.format.code)->bpp;
  129. ctrl = v4l2_ctrl_find(pipe->external->ctrl_handler,
  130. V4L2_CID_PIXEL_RATE);
  131. if (!ctrl) {
  132. dev_warn(iss->dev, "no pixel rate control in subdev %s\n",
  133. pipe->external->name);
  134. return -EPIPE;
  135. }
  136. pipe->external_rate = v4l2_ctrl_g_ctrl_int64(ctrl);
  137. return 0;
  138. }
  139. /*
  140. * Configure the bridge. Valid inputs are
  141. *
  142. * IPIPEIF_INPUT_CSI2A: CSI2a receiver
  143. * IPIPEIF_INPUT_CSI2B: CSI2b receiver
  144. *
  145. * The bridge and lane shifter are configured according to the selected input
  146. * and the ISP platform data.
  147. */
  148. void omap4iss_configure_bridge(struct iss_device *iss,
  149. enum ipipeif_input_entity input)
  150. {
  151. u32 issctrl_val;
  152. u32 isp5ctrl_val;
  153. issctrl_val = iss_reg_read(iss, OMAP4_ISS_MEM_TOP, ISS_CTRL);
  154. issctrl_val &= ~ISS_CTRL_INPUT_SEL_MASK;
  155. issctrl_val &= ~ISS_CTRL_CLK_DIV_MASK;
  156. isp5ctrl_val = iss_reg_read(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_CTRL);
  157. switch (input) {
  158. case IPIPEIF_INPUT_CSI2A:
  159. issctrl_val |= ISS_CTRL_INPUT_SEL_CSI2A;
  160. break;
  161. case IPIPEIF_INPUT_CSI2B:
  162. issctrl_val |= ISS_CTRL_INPUT_SEL_CSI2B;
  163. break;
  164. default:
  165. return;
  166. }
  167. issctrl_val |= ISS_CTRL_SYNC_DETECT_VS_RAISING;
  168. isp5ctrl_val |= ISP5_CTRL_VD_PULSE_EXT | ISP5_CTRL_PSYNC_CLK_SEL |
  169. ISP5_CTRL_SYNC_ENABLE;
  170. iss_reg_write(iss, OMAP4_ISS_MEM_TOP, ISS_CTRL, issctrl_val);
  171. iss_reg_write(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_CTRL, isp5ctrl_val);
  172. }
  173. #ifdef ISS_ISR_DEBUG
  174. static void iss_isr_dbg(struct iss_device *iss, u32 irqstatus)
  175. {
  176. static const char * const name[] = {
  177. "ISP_0",
  178. "ISP_1",
  179. "ISP_2",
  180. "ISP_3",
  181. "CSIA",
  182. "CSIB",
  183. "CCP2_0",
  184. "CCP2_1",
  185. "CCP2_2",
  186. "CCP2_3",
  187. "CBUFF",
  188. "BTE",
  189. "SIMCOP_0",
  190. "SIMCOP_1",
  191. "SIMCOP_2",
  192. "SIMCOP_3",
  193. "CCP2_8",
  194. "HS_VS",
  195. "18",
  196. "19",
  197. "20",
  198. "21",
  199. "22",
  200. "23",
  201. "24",
  202. "25",
  203. "26",
  204. "27",
  205. "28",
  206. "29",
  207. "30",
  208. "31",
  209. };
  210. unsigned int i;
  211. dev_dbg(iss->dev, "ISS IRQ: ");
  212. for (i = 0; i < ARRAY_SIZE(name); i++) {
  213. if ((1 << i) & irqstatus)
  214. pr_cont("%s ", name[i]);
  215. }
  216. pr_cont("\n");
  217. }
  218. static void iss_isp_isr_dbg(struct iss_device *iss, u32 irqstatus)
  219. {
  220. static const char * const name[] = {
  221. "ISIF_0",
  222. "ISIF_1",
  223. "ISIF_2",
  224. "ISIF_3",
  225. "IPIPEREQ",
  226. "IPIPELAST_PIX",
  227. "IPIPEDMA",
  228. "IPIPEBSC",
  229. "IPIPEHST",
  230. "IPIPEIF",
  231. "AEW",
  232. "AF",
  233. "H3A",
  234. "RSZ_REG",
  235. "RSZ_LAST_PIX",
  236. "RSZ_DMA",
  237. "RSZ_CYC_RZA",
  238. "RSZ_CYC_RZB",
  239. "RSZ_FIFO_OVF",
  240. "RSZ_FIFO_IN_BLK_ERR",
  241. "20",
  242. "21",
  243. "RSZ_EOF0",
  244. "RSZ_EOF1",
  245. "H3A_EOF",
  246. "IPIPE_EOF",
  247. "26",
  248. "IPIPE_DPC_INI",
  249. "IPIPE_DPC_RNEW0",
  250. "IPIPE_DPC_RNEW1",
  251. "30",
  252. "OCP_ERR",
  253. };
  254. unsigned int i;
  255. dev_dbg(iss->dev, "ISP IRQ: ");
  256. for (i = 0; i < ARRAY_SIZE(name); i++) {
  257. if ((1 << i) & irqstatus)
  258. pr_cont("%s ", name[i]);
  259. }
  260. pr_cont("\n");
  261. }
  262. #endif
  263. /*
  264. * iss_isr - Interrupt Service Routine for ISS module.
  265. * @irq: Not used currently.
  266. * @_iss: Pointer to the OMAP4 ISS device
  267. *
  268. * Handles the corresponding callback if plugged in.
  269. *
  270. * Returns IRQ_HANDLED when IRQ was correctly handled, or IRQ_NONE when the
  271. * IRQ wasn't handled.
  272. */
  273. static irqreturn_t iss_isr(int irq, void *_iss)
  274. {
  275. static const u32 ipipeif_events = ISP5_IRQ_IPIPEIF_IRQ |
  276. ISP5_IRQ_ISIF_INT(0);
  277. static const u32 resizer_events = ISP5_IRQ_RSZ_FIFO_IN_BLK_ERR |
  278. ISP5_IRQ_RSZ_FIFO_OVF |
  279. ISP5_IRQ_RSZ_INT_DMA;
  280. struct iss_device *iss = _iss;
  281. u32 irqstatus;
  282. irqstatus = iss_reg_read(iss, OMAP4_ISS_MEM_TOP, ISS_HL_IRQSTATUS(5));
  283. iss_reg_write(iss, OMAP4_ISS_MEM_TOP, ISS_HL_IRQSTATUS(5), irqstatus);
  284. if (irqstatus & ISS_HL_IRQ_CSIA)
  285. omap4iss_csi2_isr(&iss->csi2a);
  286. if (irqstatus & ISS_HL_IRQ_CSIB)
  287. omap4iss_csi2_isr(&iss->csi2b);
  288. if (irqstatus & ISS_HL_IRQ_ISP(0)) {
  289. u32 isp_irqstatus = iss_reg_read(iss, OMAP4_ISS_MEM_ISP_SYS1,
  290. ISP5_IRQSTATUS(0));
  291. iss_reg_write(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_IRQSTATUS(0),
  292. isp_irqstatus);
  293. if (isp_irqstatus & ISP5_IRQ_OCP_ERR)
  294. dev_dbg(iss->dev, "ISP5 OCP Error!\n");
  295. if (isp_irqstatus & ipipeif_events) {
  296. omap4iss_ipipeif_isr(&iss->ipipeif,
  297. isp_irqstatus & ipipeif_events);
  298. }
  299. if (isp_irqstatus & resizer_events)
  300. omap4iss_resizer_isr(&iss->resizer,
  301. isp_irqstatus & resizer_events);
  302. #ifdef ISS_ISR_DEBUG
  303. iss_isp_isr_dbg(iss, isp_irqstatus);
  304. #endif
  305. }
  306. omap4iss_flush(iss);
  307. #ifdef ISS_ISR_DEBUG
  308. iss_isr_dbg(iss, irqstatus);
  309. #endif
  310. return IRQ_HANDLED;
  311. }
  312. /* -----------------------------------------------------------------------------
  313. * Pipeline power management
  314. *
  315. * Entities must be powered up when part of a pipeline that contains at least
  316. * one open video device node.
  317. *
  318. * To achieve this use the entity use_count field to track the number of users.
  319. * For entities corresponding to video device nodes the use_count field stores
  320. * the users count of the node. For entities corresponding to subdevs the
  321. * use_count field stores the total number of users of all video device nodes
  322. * in the pipeline.
  323. *
  324. * The omap4iss_pipeline_pm_use() function must be called in the open() and
  325. * close() handlers of video device nodes. It increments or decrements the use
  326. * count of all subdev entities in the pipeline.
  327. *
  328. * To react to link management on powered pipelines, the link setup notification
  329. * callback updates the use count of all entities in the source and sink sides
  330. * of the link.
  331. */
  332. /*
  333. * iss_pipeline_pm_use_count - Count the number of users of a pipeline
  334. * @entity: The entity
  335. *
  336. * Return the total number of users of all video device nodes in the pipeline.
  337. */
  338. static int iss_pipeline_pm_use_count(struct media_entity *entity)
  339. {
  340. struct media_entity_graph graph;
  341. int use = 0;
  342. media_entity_graph_walk_start(&graph, entity);
  343. while ((entity = media_entity_graph_walk_next(&graph))) {
  344. if (media_entity_type(entity) == MEDIA_ENT_T_DEVNODE)
  345. use += entity->use_count;
  346. }
  347. return use;
  348. }
  349. /*
  350. * iss_pipeline_pm_power_one - Apply power change to an entity
  351. * @entity: The entity
  352. * @change: Use count change
  353. *
  354. * Change the entity use count by @change. If the entity is a subdev update its
  355. * power state by calling the core::s_power operation when the use count goes
  356. * from 0 to != 0 or from != 0 to 0.
  357. *
  358. * Return 0 on success or a negative error code on failure.
  359. */
  360. static int iss_pipeline_pm_power_one(struct media_entity *entity, int change)
  361. {
  362. struct v4l2_subdev *subdev;
  363. subdev = media_entity_type(entity) == MEDIA_ENT_T_V4L2_SUBDEV
  364. ? media_entity_to_v4l2_subdev(entity) : NULL;
  365. if (entity->use_count == 0 && change > 0 && subdev) {
  366. int ret;
  367. ret = v4l2_subdev_call(subdev, core, s_power, 1);
  368. if (ret < 0 && ret != -ENOIOCTLCMD)
  369. return ret;
  370. }
  371. entity->use_count += change;
  372. WARN_ON(entity->use_count < 0);
  373. if (entity->use_count == 0 && change < 0 && subdev)
  374. v4l2_subdev_call(subdev, core, s_power, 0);
  375. return 0;
  376. }
  377. /*
  378. * iss_pipeline_pm_power - Apply power change to all entities in a pipeline
  379. * @entity: The entity
  380. * @change: Use count change
  381. *
  382. * Walk the pipeline to update the use count and the power state of all non-node
  383. * entities.
  384. *
  385. * Return 0 on success or a negative error code on failure.
  386. */
  387. static int iss_pipeline_pm_power(struct media_entity *entity, int change)
  388. {
  389. struct media_entity_graph graph;
  390. struct media_entity *first = entity;
  391. int ret = 0;
  392. if (!change)
  393. return 0;
  394. media_entity_graph_walk_start(&graph, entity);
  395. while (!ret && (entity = media_entity_graph_walk_next(&graph)))
  396. if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE)
  397. ret = iss_pipeline_pm_power_one(entity, change);
  398. if (!ret)
  399. return 0;
  400. media_entity_graph_walk_start(&graph, first);
  401. while ((first = media_entity_graph_walk_next(&graph)) &&
  402. first != entity)
  403. if (media_entity_type(first) != MEDIA_ENT_T_DEVNODE)
  404. iss_pipeline_pm_power_one(first, -change);
  405. return ret;
  406. }
  407. /*
  408. * omap4iss_pipeline_pm_use - Update the use count of an entity
  409. * @entity: The entity
  410. * @use: Use (1) or stop using (0) the entity
  411. *
  412. * Update the use count of all entities in the pipeline and power entities on or
  413. * off accordingly.
  414. *
  415. * Return 0 on success or a negative error code on failure. Powering entities
  416. * off is assumed to never fail. No failure can occur when the use parameter is
  417. * set to 0.
  418. */
  419. int omap4iss_pipeline_pm_use(struct media_entity *entity, int use)
  420. {
  421. int change = use ? 1 : -1;
  422. int ret;
  423. mutex_lock(&entity->parent->graph_mutex);
  424. /* Apply use count to node. */
  425. entity->use_count += change;
  426. WARN_ON(entity->use_count < 0);
  427. /* Apply power change to connected non-nodes. */
  428. ret = iss_pipeline_pm_power(entity, change);
  429. if (ret < 0)
  430. entity->use_count -= change;
  431. mutex_unlock(&entity->parent->graph_mutex);
  432. return ret;
  433. }
  434. /*
  435. * iss_pipeline_link_notify - Link management notification callback
  436. * @link: The link
  437. * @flags: New link flags that will be applied
  438. *
  439. * React to link management on powered pipelines by updating the use count of
  440. * all entities in the source and sink sides of the link. Entities are powered
  441. * on or off accordingly.
  442. *
  443. * Return 0 on success or a negative error code on failure. Powering entities
  444. * off is assumed to never fail. This function will not fail for disconnection
  445. * events.
  446. */
  447. static int iss_pipeline_link_notify(struct media_link *link, u32 flags,
  448. unsigned int notification)
  449. {
  450. struct media_entity *source = link->source->entity;
  451. struct media_entity *sink = link->sink->entity;
  452. int source_use = iss_pipeline_pm_use_count(source);
  453. int sink_use = iss_pipeline_pm_use_count(sink);
  454. int ret;
  455. if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH &&
  456. !(link->flags & MEDIA_LNK_FL_ENABLED)) {
  457. /* Powering off entities is assumed to never fail. */
  458. iss_pipeline_pm_power(source, -sink_use);
  459. iss_pipeline_pm_power(sink, -source_use);
  460. return 0;
  461. }
  462. if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH &&
  463. (flags & MEDIA_LNK_FL_ENABLED)) {
  464. ret = iss_pipeline_pm_power(source, sink_use);
  465. if (ret < 0)
  466. return ret;
  467. ret = iss_pipeline_pm_power(sink, source_use);
  468. if (ret < 0)
  469. iss_pipeline_pm_power(source, -sink_use);
  470. return ret;
  471. }
  472. return 0;
  473. }
  474. /* -----------------------------------------------------------------------------
  475. * Pipeline stream management
  476. */
  477. /*
  478. * iss_pipeline_disable - Disable streaming on a pipeline
  479. * @pipe: ISS pipeline
  480. * @until: entity at which to stop pipeline walk
  481. *
  482. * Walk the entities chain starting at the pipeline output video node and stop
  483. * all modules in the chain. Wait synchronously for the modules to be stopped if
  484. * necessary.
  485. *
  486. * If the until argument isn't NULL, stop the pipeline walk when reaching the
  487. * until entity. This is used to disable a partially started pipeline due to a
  488. * subdev start error.
  489. */
  490. static int iss_pipeline_disable(struct iss_pipeline *pipe,
  491. struct media_entity *until)
  492. {
  493. struct iss_device *iss = pipe->output->iss;
  494. struct media_entity *entity;
  495. struct media_pad *pad;
  496. struct v4l2_subdev *subdev;
  497. int failure = 0;
  498. int ret;
  499. entity = &pipe->output->video.entity;
  500. while (1) {
  501. pad = &entity->pads[0];
  502. if (!(pad->flags & MEDIA_PAD_FL_SINK))
  503. break;
  504. pad = media_entity_remote_pad(pad);
  505. if (!pad ||
  506. media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
  507. break;
  508. entity = pad->entity;
  509. if (entity == until)
  510. break;
  511. subdev = media_entity_to_v4l2_subdev(entity);
  512. ret = v4l2_subdev_call(subdev, video, s_stream, 0);
  513. if (ret < 0) {
  514. dev_dbg(iss->dev, "%s: module stop timeout.\n",
  515. subdev->name);
  516. /* If the entity failed to stopped, assume it has
  517. * crashed. Mark it as such, the ISS will be reset when
  518. * applications will release it.
  519. */
  520. iss->crashed |= 1U << subdev->entity.id;
  521. failure = -ETIMEDOUT;
  522. }
  523. }
  524. return failure;
  525. }
  526. /*
  527. * iss_pipeline_enable - Enable streaming on a pipeline
  528. * @pipe: ISS pipeline
  529. * @mode: Stream mode (single shot or continuous)
  530. *
  531. * Walk the entities chain starting at the pipeline output video node and start
  532. * all modules in the chain in the given mode.
  533. *
  534. * Return 0 if successful, or the return value of the failed video::s_stream
  535. * operation otherwise.
  536. */
  537. static int iss_pipeline_enable(struct iss_pipeline *pipe,
  538. enum iss_pipeline_stream_state mode)
  539. {
  540. struct iss_device *iss = pipe->output->iss;
  541. struct media_entity *entity;
  542. struct media_pad *pad;
  543. struct v4l2_subdev *subdev;
  544. unsigned long flags;
  545. int ret;
  546. /* If one of the entities in the pipeline has crashed it will not work
  547. * properly. Refuse to start streaming in that case. This check must be
  548. * performed before the loop below to avoid starting entities if the
  549. * pipeline won't start anyway (those entities would then likely fail to
  550. * stop, making the problem worse).
  551. */
  552. if (pipe->entities & iss->crashed)
  553. return -EIO;
  554. spin_lock_irqsave(&pipe->lock, flags);
  555. pipe->state &= ~(ISS_PIPELINE_IDLE_INPUT | ISS_PIPELINE_IDLE_OUTPUT);
  556. spin_unlock_irqrestore(&pipe->lock, flags);
  557. pipe->do_propagation = false;
  558. entity = &pipe->output->video.entity;
  559. while (1) {
  560. pad = &entity->pads[0];
  561. if (!(pad->flags & MEDIA_PAD_FL_SINK))
  562. break;
  563. pad = media_entity_remote_pad(pad);
  564. if (!pad ||
  565. media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
  566. break;
  567. entity = pad->entity;
  568. subdev = media_entity_to_v4l2_subdev(entity);
  569. ret = v4l2_subdev_call(subdev, video, s_stream, mode);
  570. if (ret < 0 && ret != -ENOIOCTLCMD) {
  571. iss_pipeline_disable(pipe, entity);
  572. return ret;
  573. }
  574. if (subdev == &iss->csi2a.subdev ||
  575. subdev == &iss->csi2b.subdev)
  576. pipe->do_propagation = true;
  577. }
  578. iss_print_status(pipe->output->iss);
  579. return 0;
  580. }
  581. /*
  582. * omap4iss_pipeline_set_stream - Enable/disable streaming on a pipeline
  583. * @pipe: ISS pipeline
  584. * @state: Stream state (stopped, single shot or continuous)
  585. *
  586. * Set the pipeline to the given stream state. Pipelines can be started in
  587. * single-shot or continuous mode.
  588. *
  589. * Return 0 if successful, or the return value of the failed video::s_stream
  590. * operation otherwise. The pipeline state is not updated when the operation
  591. * fails, except when stopping the pipeline.
  592. */
  593. int omap4iss_pipeline_set_stream(struct iss_pipeline *pipe,
  594. enum iss_pipeline_stream_state state)
  595. {
  596. int ret;
  597. if (state == ISS_PIPELINE_STREAM_STOPPED)
  598. ret = iss_pipeline_disable(pipe, NULL);
  599. else
  600. ret = iss_pipeline_enable(pipe, state);
  601. if (ret == 0 || state == ISS_PIPELINE_STREAM_STOPPED)
  602. pipe->stream_state = state;
  603. return ret;
  604. }
  605. /*
  606. * omap4iss_pipeline_cancel_stream - Cancel stream on a pipeline
  607. * @pipe: ISS pipeline
  608. *
  609. * Cancelling a stream mark all buffers on all video nodes in the pipeline as
  610. * erroneous and makes sure no new buffer can be queued. This function is called
  611. * when a fatal error that prevents any further operation on the pipeline
  612. * occurs.
  613. */
  614. void omap4iss_pipeline_cancel_stream(struct iss_pipeline *pipe)
  615. {
  616. if (pipe->input)
  617. omap4iss_video_cancel_stream(pipe->input);
  618. if (pipe->output)
  619. omap4iss_video_cancel_stream(pipe->output);
  620. }
  621. /*
  622. * iss_pipeline_is_last - Verify if entity has an enabled link to the output
  623. * video node
  624. * @me: ISS module's media entity
  625. *
  626. * Returns 1 if the entity has an enabled link to the output video node or 0
  627. * otherwise. It's true only while pipeline can have no more than one output
  628. * node.
  629. */
  630. static int iss_pipeline_is_last(struct media_entity *me)
  631. {
  632. struct iss_pipeline *pipe;
  633. struct media_pad *pad;
  634. if (!me->pipe)
  635. return 0;
  636. pipe = to_iss_pipeline(me);
  637. if (pipe->stream_state == ISS_PIPELINE_STREAM_STOPPED)
  638. return 0;
  639. pad = media_entity_remote_pad(&pipe->output->pad);
  640. return pad->entity == me;
  641. }
  642. static int iss_reset(struct iss_device *iss)
  643. {
  644. unsigned int timeout;
  645. iss_reg_set(iss, OMAP4_ISS_MEM_TOP, ISS_HL_SYSCONFIG,
  646. ISS_HL_SYSCONFIG_SOFTRESET);
  647. timeout = iss_poll_condition_timeout(
  648. !(iss_reg_read(iss, OMAP4_ISS_MEM_TOP, ISS_HL_SYSCONFIG) &
  649. ISS_HL_SYSCONFIG_SOFTRESET), 1000, 10, 100);
  650. if (timeout) {
  651. dev_err(iss->dev, "ISS reset timeout\n");
  652. return -ETIMEDOUT;
  653. }
  654. iss->crashed = 0;
  655. return 0;
  656. }
  657. static int iss_isp_reset(struct iss_device *iss)
  658. {
  659. unsigned int timeout;
  660. /* Fist, ensure that the ISP is IDLE (no transactions happening) */
  661. iss_reg_update(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_SYSCONFIG,
  662. ISP5_SYSCONFIG_STANDBYMODE_MASK,
  663. ISP5_SYSCONFIG_STANDBYMODE_SMART);
  664. iss_reg_set(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_CTRL, ISP5_CTRL_MSTANDBY);
  665. timeout = iss_poll_condition_timeout(
  666. iss_reg_read(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_CTRL) &
  667. ISP5_CTRL_MSTANDBY_WAIT, 1000000, 1000, 1500);
  668. if (timeout) {
  669. dev_err(iss->dev, "ISP5 standby timeout\n");
  670. return -ETIMEDOUT;
  671. }
  672. /* Now finally, do the reset */
  673. iss_reg_set(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_SYSCONFIG,
  674. ISP5_SYSCONFIG_SOFTRESET);
  675. timeout = iss_poll_condition_timeout(
  676. !(iss_reg_read(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_SYSCONFIG) &
  677. ISP5_SYSCONFIG_SOFTRESET), 1000000, 1000, 1500);
  678. if (timeout) {
  679. dev_err(iss->dev, "ISP5 reset timeout\n");
  680. return -ETIMEDOUT;
  681. }
  682. return 0;
  683. }
  684. /*
  685. * iss_module_sync_idle - Helper to sync module with its idle state
  686. * @me: ISS submodule's media entity
  687. * @wait: ISS submodule's wait queue for streamoff/interrupt synchronization
  688. * @stopping: flag which tells module wants to stop
  689. *
  690. * This function checks if ISS submodule needs to wait for next interrupt. If
  691. * yes, makes the caller to sleep while waiting for such event.
  692. */
  693. int omap4iss_module_sync_idle(struct media_entity *me, wait_queue_head_t *wait,
  694. atomic_t *stopping)
  695. {
  696. struct iss_pipeline *pipe = to_iss_pipeline(me);
  697. struct iss_video *video = pipe->output;
  698. unsigned long flags;
  699. if (pipe->stream_state == ISS_PIPELINE_STREAM_STOPPED ||
  700. (pipe->stream_state == ISS_PIPELINE_STREAM_SINGLESHOT &&
  701. !iss_pipeline_ready(pipe)))
  702. return 0;
  703. /*
  704. * atomic_set() doesn't include memory barrier on ARM platform for SMP
  705. * scenario. We'll call it here to avoid race conditions.
  706. */
  707. atomic_set(stopping, 1);
  708. smp_wmb();
  709. /*
  710. * If module is the last one, it's writing to memory. In this case,
  711. * it's necessary to check if the module is already paused due to
  712. * DMA queue underrun or if it has to wait for next interrupt to be
  713. * idle.
  714. * If it isn't the last one, the function won't sleep but *stopping
  715. * will still be set to warn next submodule caller's interrupt the
  716. * module wants to be idle.
  717. */
  718. if (!iss_pipeline_is_last(me))
  719. return 0;
  720. spin_lock_irqsave(&video->qlock, flags);
  721. if (video->dmaqueue_flags & ISS_VIDEO_DMAQUEUE_UNDERRUN) {
  722. spin_unlock_irqrestore(&video->qlock, flags);
  723. atomic_set(stopping, 0);
  724. smp_wmb();
  725. return 0;
  726. }
  727. spin_unlock_irqrestore(&video->qlock, flags);
  728. if (!wait_event_timeout(*wait, !atomic_read(stopping),
  729. msecs_to_jiffies(1000))) {
  730. atomic_set(stopping, 0);
  731. smp_wmb();
  732. return -ETIMEDOUT;
  733. }
  734. return 0;
  735. }
  736. /*
  737. * omap4iss_module_sync_is_stopped - Helper to verify if module was stopping
  738. * @wait: ISS submodule's wait queue for streamoff/interrupt synchronization
  739. * @stopping: flag which tells module wants to stop
  740. *
  741. * This function checks if ISS submodule was stopping. In case of yes, it
  742. * notices the caller by setting stopping to 0 and waking up the wait queue.
  743. * Returns 1 if it was stopping or 0 otherwise.
  744. */
  745. int omap4iss_module_sync_is_stopping(wait_queue_head_t *wait,
  746. atomic_t *stopping)
  747. {
  748. if (atomic_cmpxchg(stopping, 1, 0)) {
  749. wake_up(wait);
  750. return 1;
  751. }
  752. return 0;
  753. }
  754. /* --------------------------------------------------------------------------
  755. * Clock management
  756. */
  757. #define ISS_CLKCTRL_MASK (ISS_CLKCTRL_CSI2_A |\
  758. ISS_CLKCTRL_CSI2_B |\
  759. ISS_CLKCTRL_ISP)
  760. static int __iss_subclk_update(struct iss_device *iss)
  761. {
  762. u32 clk = 0;
  763. int ret = 0, timeout = 1000;
  764. if (iss->subclk_resources & OMAP4_ISS_SUBCLK_CSI2_A)
  765. clk |= ISS_CLKCTRL_CSI2_A;
  766. if (iss->subclk_resources & OMAP4_ISS_SUBCLK_CSI2_B)
  767. clk |= ISS_CLKCTRL_CSI2_B;
  768. if (iss->subclk_resources & OMAP4_ISS_SUBCLK_ISP)
  769. clk |= ISS_CLKCTRL_ISP;
  770. iss_reg_update(iss, OMAP4_ISS_MEM_TOP, ISS_CLKCTRL,
  771. ISS_CLKCTRL_MASK, clk);
  772. /* Wait for HW assertion */
  773. while (--timeout > 0) {
  774. udelay(1);
  775. if ((iss_reg_read(iss, OMAP4_ISS_MEM_TOP, ISS_CLKSTAT) &
  776. ISS_CLKCTRL_MASK) == clk)
  777. break;
  778. }
  779. if (!timeout)
  780. ret = -EBUSY;
  781. return ret;
  782. }
  783. int omap4iss_subclk_enable(struct iss_device *iss,
  784. enum iss_subclk_resource res)
  785. {
  786. iss->subclk_resources |= res;
  787. return __iss_subclk_update(iss);
  788. }
  789. int omap4iss_subclk_disable(struct iss_device *iss,
  790. enum iss_subclk_resource res)
  791. {
  792. iss->subclk_resources &= ~res;
  793. return __iss_subclk_update(iss);
  794. }
  795. #define ISS_ISP5_CLKCTRL_MASK (ISP5_CTRL_BL_CLK_ENABLE |\
  796. ISP5_CTRL_ISIF_CLK_ENABLE |\
  797. ISP5_CTRL_H3A_CLK_ENABLE |\
  798. ISP5_CTRL_RSZ_CLK_ENABLE |\
  799. ISP5_CTRL_IPIPE_CLK_ENABLE |\
  800. ISP5_CTRL_IPIPEIF_CLK_ENABLE)
  801. static void __iss_isp_subclk_update(struct iss_device *iss)
  802. {
  803. u32 clk = 0;
  804. if (iss->isp_subclk_resources & OMAP4_ISS_ISP_SUBCLK_ISIF)
  805. clk |= ISP5_CTRL_ISIF_CLK_ENABLE;
  806. if (iss->isp_subclk_resources & OMAP4_ISS_ISP_SUBCLK_H3A)
  807. clk |= ISP5_CTRL_H3A_CLK_ENABLE;
  808. if (iss->isp_subclk_resources & OMAP4_ISS_ISP_SUBCLK_RSZ)
  809. clk |= ISP5_CTRL_RSZ_CLK_ENABLE;
  810. if (iss->isp_subclk_resources & OMAP4_ISS_ISP_SUBCLK_IPIPE)
  811. clk |= ISP5_CTRL_IPIPE_CLK_ENABLE;
  812. if (iss->isp_subclk_resources & OMAP4_ISS_ISP_SUBCLK_IPIPEIF)
  813. clk |= ISP5_CTRL_IPIPEIF_CLK_ENABLE;
  814. if (clk)
  815. clk |= ISP5_CTRL_BL_CLK_ENABLE;
  816. iss_reg_update(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_CTRL,
  817. ISS_ISP5_CLKCTRL_MASK, clk);
  818. }
  819. void omap4iss_isp_subclk_enable(struct iss_device *iss,
  820. enum iss_isp_subclk_resource res)
  821. {
  822. iss->isp_subclk_resources |= res;
  823. __iss_isp_subclk_update(iss);
  824. }
  825. void omap4iss_isp_subclk_disable(struct iss_device *iss,
  826. enum iss_isp_subclk_resource res)
  827. {
  828. iss->isp_subclk_resources &= ~res;
  829. __iss_isp_subclk_update(iss);
  830. }
  831. /*
  832. * iss_enable_clocks - Enable ISS clocks
  833. * @iss: OMAP4 ISS device
  834. *
  835. * Return 0 if successful, or clk_enable return value if any of tthem fails.
  836. */
  837. static int iss_enable_clocks(struct iss_device *iss)
  838. {
  839. int ret;
  840. ret = clk_enable(iss->iss_fck);
  841. if (ret) {
  842. dev_err(iss->dev, "clk_enable iss_fck failed\n");
  843. return ret;
  844. }
  845. ret = clk_enable(iss->iss_ctrlclk);
  846. if (ret) {
  847. dev_err(iss->dev, "clk_enable iss_ctrlclk failed\n");
  848. clk_disable(iss->iss_fck);
  849. return ret;
  850. }
  851. return 0;
  852. }
  853. /*
  854. * iss_disable_clocks - Disable ISS clocks
  855. * @iss: OMAP4 ISS device
  856. */
  857. static void iss_disable_clocks(struct iss_device *iss)
  858. {
  859. clk_disable(iss->iss_ctrlclk);
  860. clk_disable(iss->iss_fck);
  861. }
  862. static int iss_get_clocks(struct iss_device *iss)
  863. {
  864. iss->iss_fck = devm_clk_get(iss->dev, "iss_fck");
  865. if (IS_ERR(iss->iss_fck)) {
  866. dev_err(iss->dev, "Unable to get iss_fck clock info\n");
  867. return PTR_ERR(iss->iss_fck);
  868. }
  869. iss->iss_ctrlclk = devm_clk_get(iss->dev, "iss_ctrlclk");
  870. if (IS_ERR(iss->iss_ctrlclk)) {
  871. dev_err(iss->dev, "Unable to get iss_ctrlclk clock info\n");
  872. return PTR_ERR(iss->iss_ctrlclk);
  873. }
  874. return 0;
  875. }
  876. /*
  877. * omap4iss_get - Acquire the ISS resource.
  878. *
  879. * Initializes the clocks for the first acquire.
  880. *
  881. * Increment the reference count on the ISS. If the first reference is taken,
  882. * enable clocks and power-up all submodules.
  883. *
  884. * Return a pointer to the ISS device structure, or NULL if an error occurred.
  885. */
  886. struct iss_device *omap4iss_get(struct iss_device *iss)
  887. {
  888. struct iss_device *__iss = iss;
  889. if (!iss)
  890. return NULL;
  891. mutex_lock(&iss->iss_mutex);
  892. if (iss->ref_count > 0)
  893. goto out;
  894. if (iss_enable_clocks(iss) < 0) {
  895. __iss = NULL;
  896. goto out;
  897. }
  898. iss_enable_interrupts(iss);
  899. out:
  900. if (__iss)
  901. iss->ref_count++;
  902. mutex_unlock(&iss->iss_mutex);
  903. return __iss;
  904. }
  905. /*
  906. * omap4iss_put - Release the ISS
  907. *
  908. * Decrement the reference count on the ISS. If the last reference is released,
  909. * power-down all submodules, disable clocks and free temporary buffers.
  910. */
  911. void omap4iss_put(struct iss_device *iss)
  912. {
  913. if (!iss)
  914. return;
  915. mutex_lock(&iss->iss_mutex);
  916. BUG_ON(iss->ref_count == 0);
  917. if (--iss->ref_count == 0) {
  918. iss_disable_interrupts(iss);
  919. /* Reset the ISS if an entity has failed to stop. This is the
  920. * only way to recover from such conditions, although it would
  921. * be worth investigating whether resetting the ISP only can't
  922. * fix the problem in some cases.
  923. */
  924. if (iss->crashed)
  925. iss_reset(iss);
  926. iss_disable_clocks(iss);
  927. }
  928. mutex_unlock(&iss->iss_mutex);
  929. }
  930. static int iss_map_mem_resource(struct platform_device *pdev,
  931. struct iss_device *iss,
  932. enum iss_mem_resources res)
  933. {
  934. struct resource *mem;
  935. mem = platform_get_resource(pdev, IORESOURCE_MEM, res);
  936. iss->regs[res] = devm_ioremap_resource(iss->dev, mem);
  937. return PTR_ERR_OR_ZERO(iss->regs[res]);
  938. }
  939. static void iss_unregister_entities(struct iss_device *iss)
  940. {
  941. omap4iss_resizer_unregister_entities(&iss->resizer);
  942. omap4iss_ipipe_unregister_entities(&iss->ipipe);
  943. omap4iss_ipipeif_unregister_entities(&iss->ipipeif);
  944. omap4iss_csi2_unregister_entities(&iss->csi2a);
  945. omap4iss_csi2_unregister_entities(&iss->csi2b);
  946. v4l2_device_unregister(&iss->v4l2_dev);
  947. media_device_unregister(&iss->media_dev);
  948. }
  949. /*
  950. * iss_register_subdev_group - Register a group of subdevices
  951. * @iss: OMAP4 ISS device
  952. * @board_info: I2C subdevs board information array
  953. *
  954. * Register all I2C subdevices in the board_info array. The array must be
  955. * terminated by a NULL entry, and the first entry must be the sensor.
  956. *
  957. * Return a pointer to the sensor media entity if it has been successfully
  958. * registered, or NULL otherwise.
  959. */
  960. static struct v4l2_subdev *
  961. iss_register_subdev_group(struct iss_device *iss,
  962. struct iss_subdev_i2c_board_info *board_info)
  963. {
  964. struct v4l2_subdev *sensor = NULL;
  965. unsigned int first;
  966. if (!board_info->board_info)
  967. return NULL;
  968. for (first = 1; board_info->board_info; ++board_info, first = 0) {
  969. struct v4l2_subdev *subdev;
  970. struct i2c_adapter *adapter;
  971. adapter = i2c_get_adapter(board_info->i2c_adapter_id);
  972. if (!adapter) {
  973. dev_err(iss->dev,
  974. "%s: Unable to get I2C adapter %d for device %s\n",
  975. __func__, board_info->i2c_adapter_id,
  976. board_info->board_info->type);
  977. continue;
  978. }
  979. subdev = v4l2_i2c_new_subdev_board(&iss->v4l2_dev, adapter,
  980. board_info->board_info, NULL);
  981. if (!subdev) {
  982. dev_err(iss->dev, "Unable to register subdev %s\n",
  983. board_info->board_info->type);
  984. continue;
  985. }
  986. if (first)
  987. sensor = subdev;
  988. }
  989. return sensor;
  990. }
  991. static int iss_register_entities(struct iss_device *iss)
  992. {
  993. struct iss_platform_data *pdata = iss->pdata;
  994. struct iss_v4l2_subdevs_group *subdevs;
  995. int ret;
  996. iss->media_dev.dev = iss->dev;
  997. strlcpy(iss->media_dev.model, "TI OMAP4 ISS",
  998. sizeof(iss->media_dev.model));
  999. iss->media_dev.hw_revision = iss->revision;
  1000. iss->media_dev.link_notify = iss_pipeline_link_notify;
  1001. ret = media_device_register(&iss->media_dev);
  1002. if (ret < 0) {
  1003. dev_err(iss->dev, "Media device registration failed (%d)\n",
  1004. ret);
  1005. return ret;
  1006. }
  1007. iss->v4l2_dev.mdev = &iss->media_dev;
  1008. ret = v4l2_device_register(iss->dev, &iss->v4l2_dev);
  1009. if (ret < 0) {
  1010. dev_err(iss->dev, "V4L2 device registration failed (%d)\n",
  1011. ret);
  1012. goto done;
  1013. }
  1014. /* Register internal entities */
  1015. ret = omap4iss_csi2_register_entities(&iss->csi2a, &iss->v4l2_dev);
  1016. if (ret < 0)
  1017. goto done;
  1018. ret = omap4iss_csi2_register_entities(&iss->csi2b, &iss->v4l2_dev);
  1019. if (ret < 0)
  1020. goto done;
  1021. ret = omap4iss_ipipeif_register_entities(&iss->ipipeif, &iss->v4l2_dev);
  1022. if (ret < 0)
  1023. goto done;
  1024. ret = omap4iss_ipipe_register_entities(&iss->ipipe, &iss->v4l2_dev);
  1025. if (ret < 0)
  1026. goto done;
  1027. ret = omap4iss_resizer_register_entities(&iss->resizer, &iss->v4l2_dev);
  1028. if (ret < 0)
  1029. goto done;
  1030. /* Register external entities */
  1031. for (subdevs = pdata->subdevs; subdevs && subdevs->subdevs; ++subdevs) {
  1032. struct v4l2_subdev *sensor;
  1033. struct media_entity *input;
  1034. unsigned int flags;
  1035. unsigned int pad;
  1036. sensor = iss_register_subdev_group(iss, subdevs->subdevs);
  1037. if (!sensor)
  1038. continue;
  1039. sensor->host_priv = subdevs;
  1040. /* Connect the sensor to the correct interface module.
  1041. * CSI2a receiver through CSIPHY1, or
  1042. * CSI2b receiver through CSIPHY2
  1043. */
  1044. switch (subdevs->interface) {
  1045. case ISS_INTERFACE_CSI2A_PHY1:
  1046. input = &iss->csi2a.subdev.entity;
  1047. pad = CSI2_PAD_SINK;
  1048. flags = MEDIA_LNK_FL_IMMUTABLE
  1049. | MEDIA_LNK_FL_ENABLED;
  1050. break;
  1051. case ISS_INTERFACE_CSI2B_PHY2:
  1052. input = &iss->csi2b.subdev.entity;
  1053. pad = CSI2_PAD_SINK;
  1054. flags = MEDIA_LNK_FL_IMMUTABLE
  1055. | MEDIA_LNK_FL_ENABLED;
  1056. break;
  1057. default:
  1058. dev_err(iss->dev, "invalid interface type %u\n",
  1059. subdevs->interface);
  1060. ret = -EINVAL;
  1061. goto done;
  1062. }
  1063. ret = media_entity_create_link(&sensor->entity, 0, input, pad,
  1064. flags);
  1065. if (ret < 0)
  1066. goto done;
  1067. }
  1068. ret = v4l2_device_register_subdev_nodes(&iss->v4l2_dev);
  1069. done:
  1070. if (ret < 0)
  1071. iss_unregister_entities(iss);
  1072. return ret;
  1073. }
  1074. static void iss_cleanup_modules(struct iss_device *iss)
  1075. {
  1076. omap4iss_csi2_cleanup(iss);
  1077. omap4iss_ipipeif_cleanup(iss);
  1078. omap4iss_ipipe_cleanup(iss);
  1079. omap4iss_resizer_cleanup(iss);
  1080. }
  1081. static int iss_initialize_modules(struct iss_device *iss)
  1082. {
  1083. int ret;
  1084. ret = omap4iss_csiphy_init(iss);
  1085. if (ret < 0) {
  1086. dev_err(iss->dev, "CSI PHY initialization failed\n");
  1087. goto error_csiphy;
  1088. }
  1089. ret = omap4iss_csi2_init(iss);
  1090. if (ret < 0) {
  1091. dev_err(iss->dev, "CSI2 initialization failed\n");
  1092. goto error_csi2;
  1093. }
  1094. ret = omap4iss_ipipeif_init(iss);
  1095. if (ret < 0) {
  1096. dev_err(iss->dev, "ISP IPIPEIF initialization failed\n");
  1097. goto error_ipipeif;
  1098. }
  1099. ret = omap4iss_ipipe_init(iss);
  1100. if (ret < 0) {
  1101. dev_err(iss->dev, "ISP IPIPE initialization failed\n");
  1102. goto error_ipipe;
  1103. }
  1104. ret = omap4iss_resizer_init(iss);
  1105. if (ret < 0) {
  1106. dev_err(iss->dev, "ISP RESIZER initialization failed\n");
  1107. goto error_resizer;
  1108. }
  1109. /* Connect the submodules. */
  1110. ret = media_entity_create_link(
  1111. &iss->csi2a.subdev.entity, CSI2_PAD_SOURCE,
  1112. &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SINK, 0);
  1113. if (ret < 0)
  1114. goto error_link;
  1115. ret = media_entity_create_link(
  1116. &iss->csi2b.subdev.entity, CSI2_PAD_SOURCE,
  1117. &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SINK, 0);
  1118. if (ret < 0)
  1119. goto error_link;
  1120. ret = media_entity_create_link(
  1121. &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SOURCE_VP,
  1122. &iss->resizer.subdev.entity, RESIZER_PAD_SINK, 0);
  1123. if (ret < 0)
  1124. goto error_link;
  1125. ret = media_entity_create_link(
  1126. &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SOURCE_VP,
  1127. &iss->ipipe.subdev.entity, IPIPE_PAD_SINK, 0);
  1128. if (ret < 0)
  1129. goto error_link;
  1130. ret = media_entity_create_link(
  1131. &iss->ipipe.subdev.entity, IPIPE_PAD_SOURCE_VP,
  1132. &iss->resizer.subdev.entity, RESIZER_PAD_SINK, 0);
  1133. if (ret < 0)
  1134. goto error_link;
  1135. return 0;
  1136. error_link:
  1137. omap4iss_resizer_cleanup(iss);
  1138. error_resizer:
  1139. omap4iss_ipipe_cleanup(iss);
  1140. error_ipipe:
  1141. omap4iss_ipipeif_cleanup(iss);
  1142. error_ipipeif:
  1143. omap4iss_csi2_cleanup(iss);
  1144. error_csi2:
  1145. error_csiphy:
  1146. return ret;
  1147. }
  1148. static int iss_probe(struct platform_device *pdev)
  1149. {
  1150. struct iss_platform_data *pdata = pdev->dev.platform_data;
  1151. struct iss_device *iss;
  1152. unsigned int i;
  1153. int ret;
  1154. if (!pdata)
  1155. return -EINVAL;
  1156. iss = devm_kzalloc(&pdev->dev, sizeof(*iss), GFP_KERNEL);
  1157. if (!iss)
  1158. return -ENOMEM;
  1159. mutex_init(&iss->iss_mutex);
  1160. iss->dev = &pdev->dev;
  1161. iss->pdata = pdata;
  1162. iss->raw_dmamask = DMA_BIT_MASK(32);
  1163. iss->dev->dma_mask = &iss->raw_dmamask;
  1164. iss->dev->coherent_dma_mask = DMA_BIT_MASK(32);
  1165. platform_set_drvdata(pdev, iss);
  1166. /*
  1167. * TODO: When implementing DT support switch to syscon regmap lookup by
  1168. * phandle.
  1169. */
  1170. iss->syscon = syscon_regmap_lookup_by_compatible("syscon");
  1171. if (IS_ERR(iss->syscon)) {
  1172. ret = PTR_ERR(iss->syscon);
  1173. goto error;
  1174. }
  1175. /* Clocks */
  1176. ret = iss_map_mem_resource(pdev, iss, OMAP4_ISS_MEM_TOP);
  1177. if (ret < 0)
  1178. goto error;
  1179. ret = iss_get_clocks(iss);
  1180. if (ret < 0)
  1181. goto error;
  1182. if (!omap4iss_get(iss))
  1183. goto error;
  1184. ret = iss_reset(iss);
  1185. if (ret < 0)
  1186. goto error_iss;
  1187. iss->revision = iss_reg_read(iss, OMAP4_ISS_MEM_TOP, ISS_HL_REVISION);
  1188. dev_info(iss->dev, "Revision %08x found\n", iss->revision);
  1189. for (i = 1; i < OMAP4_ISS_MEM_LAST; i++) {
  1190. ret = iss_map_mem_resource(pdev, iss, i);
  1191. if (ret)
  1192. goto error_iss;
  1193. }
  1194. /* Configure BTE BW_LIMITER field to max recommended value (1 GB) */
  1195. iss_reg_update(iss, OMAP4_ISS_MEM_BTE, BTE_CTRL,
  1196. BTE_CTRL_BW_LIMITER_MASK,
  1197. 18 << BTE_CTRL_BW_LIMITER_SHIFT);
  1198. /* Perform ISP reset */
  1199. ret = omap4iss_subclk_enable(iss, OMAP4_ISS_SUBCLK_ISP);
  1200. if (ret < 0)
  1201. goto error_iss;
  1202. ret = iss_isp_reset(iss);
  1203. if (ret < 0)
  1204. goto error_iss;
  1205. dev_info(iss->dev, "ISP Revision %08x found\n",
  1206. iss_reg_read(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_REVISION));
  1207. /* Interrupt */
  1208. ret = platform_get_irq(pdev, 0);
  1209. if (ret <= 0) {
  1210. dev_err(iss->dev, "No IRQ resource\n");
  1211. ret = -ENODEV;
  1212. goto error_iss;
  1213. }
  1214. iss->irq_num = ret;
  1215. if (devm_request_irq(iss->dev, iss->irq_num, iss_isr, IRQF_SHARED,
  1216. "OMAP4 ISS", iss)) {
  1217. dev_err(iss->dev, "Unable to request IRQ\n");
  1218. ret = -EINVAL;
  1219. goto error_iss;
  1220. }
  1221. /* Entities */
  1222. ret = iss_initialize_modules(iss);
  1223. if (ret < 0)
  1224. goto error_iss;
  1225. ret = iss_register_entities(iss);
  1226. if (ret < 0)
  1227. goto error_modules;
  1228. omap4iss_put(iss);
  1229. return 0;
  1230. error_modules:
  1231. iss_cleanup_modules(iss);
  1232. error_iss:
  1233. omap4iss_put(iss);
  1234. error:
  1235. platform_set_drvdata(pdev, NULL);
  1236. mutex_destroy(&iss->iss_mutex);
  1237. return ret;
  1238. }
  1239. static int iss_remove(struct platform_device *pdev)
  1240. {
  1241. struct iss_device *iss = platform_get_drvdata(pdev);
  1242. iss_unregister_entities(iss);
  1243. iss_cleanup_modules(iss);
  1244. return 0;
  1245. }
  1246. static const struct platform_device_id omap4iss_id_table[] = {
  1247. { "omap4iss", 0 },
  1248. { },
  1249. };
  1250. MODULE_DEVICE_TABLE(platform, omap4iss_id_table);
  1251. static struct platform_driver iss_driver = {
  1252. .probe = iss_probe,
  1253. .remove = iss_remove,
  1254. .id_table = omap4iss_id_table,
  1255. .driver = {
  1256. .name = "omap4iss",
  1257. },
  1258. };
  1259. module_platform_driver(iss_driver);
  1260. MODULE_DESCRIPTION("TI OMAP4 ISS driver");
  1261. MODULE_AUTHOR("Sergio Aguirre <sergio.a.aguirre@gmail.com>");
  1262. MODULE_LICENSE("GPL");
  1263. MODULE_VERSION(ISS_VIDEO_DRIVER_VERSION);