camss-ispif.c 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * camss-ispif.c
  4. *
  5. * Qualcomm MSM Camera Subsystem - ISPIF (ISP Interface) Module
  6. *
  7. * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
  8. * Copyright (C) 2015-2018 Linaro Ltd.
  9. */
  10. #include <linux/clk.h>
  11. #include <linux/completion.h>
  12. #include <linux/interrupt.h>
  13. #include <linux/io.h>
  14. #include <linux/iopoll.h>
  15. #include <linux/kernel.h>
  16. #include <linux/mutex.h>
  17. #include <linux/platform_device.h>
  18. #include <linux/pm_runtime.h>
  19. #include <media/media-entity.h>
  20. #include <media/v4l2-device.h>
  21. #include <media/v4l2-subdev.h>
  22. #include "camss-ispif.h"
  23. #include "camss.h"
  24. #define MSM_ISPIF_NAME "msm_ispif"
  25. #define ISPIF_RST_CMD_0 0x008
  26. #define ISPIF_RST_CMD_0_STROBED_RST_EN (1 << 0)
  27. #define ISPIF_RST_CMD_0_MISC_LOGIC_RST (1 << 1)
  28. #define ISPIF_RST_CMD_0_SW_REG_RST (1 << 2)
  29. #define ISPIF_RST_CMD_0_PIX_INTF_0_CSID_RST (1 << 3)
  30. #define ISPIF_RST_CMD_0_PIX_INTF_0_VFE_RST (1 << 4)
  31. #define ISPIF_RST_CMD_0_PIX_INTF_1_CSID_RST (1 << 5)
  32. #define ISPIF_RST_CMD_0_PIX_INTF_1_VFE_RST (1 << 6)
  33. #define ISPIF_RST_CMD_0_RDI_INTF_0_CSID_RST (1 << 7)
  34. #define ISPIF_RST_CMD_0_RDI_INTF_0_VFE_RST (1 << 8)
  35. #define ISPIF_RST_CMD_0_RDI_INTF_1_CSID_RST (1 << 9)
  36. #define ISPIF_RST_CMD_0_RDI_INTF_1_VFE_RST (1 << 10)
  37. #define ISPIF_RST_CMD_0_RDI_INTF_2_CSID_RST (1 << 11)
  38. #define ISPIF_RST_CMD_0_RDI_INTF_2_VFE_RST (1 << 12)
  39. #define ISPIF_RST_CMD_0_PIX_OUTPUT_0_MISR_RST (1 << 16)
  40. #define ISPIF_RST_CMD_0_RDI_OUTPUT_0_MISR_RST (1 << 17)
  41. #define ISPIF_RST_CMD_0_RDI_OUTPUT_1_MISR_RST (1 << 18)
  42. #define ISPIF_RST_CMD_0_RDI_OUTPUT_2_MISR_RST (1 << 19)
  43. #define ISPIF_IRQ_GLOBAL_CLEAR_CMD 0x01c
  44. #define ISPIF_VFE_m_CTRL_0(m) (0x200 + 0x200 * (m))
  45. #define ISPIF_VFE_m_CTRL_0_PIX0_LINE_BUF_EN (1 << 6)
  46. #define ISPIF_VFE_m_IRQ_MASK_0(m) (0x208 + 0x200 * (m))
  47. #define ISPIF_VFE_m_IRQ_MASK_0_PIX0_ENABLE 0x00001249
  48. #define ISPIF_VFE_m_IRQ_MASK_0_PIX0_MASK 0x00001fff
  49. #define ISPIF_VFE_m_IRQ_MASK_0_RDI0_ENABLE 0x02492000
  50. #define ISPIF_VFE_m_IRQ_MASK_0_RDI0_MASK 0x03ffe000
  51. #define ISPIF_VFE_m_IRQ_MASK_1(m) (0x20c + 0x200 * (m))
  52. #define ISPIF_VFE_m_IRQ_MASK_1_PIX1_ENABLE 0x00001249
  53. #define ISPIF_VFE_m_IRQ_MASK_1_PIX1_MASK 0x00001fff
  54. #define ISPIF_VFE_m_IRQ_MASK_1_RDI1_ENABLE 0x02492000
  55. #define ISPIF_VFE_m_IRQ_MASK_1_RDI1_MASK 0x03ffe000
  56. #define ISPIF_VFE_m_IRQ_MASK_2(m) (0x210 + 0x200 * (m))
  57. #define ISPIF_VFE_m_IRQ_MASK_2_RDI2_ENABLE 0x00001249
  58. #define ISPIF_VFE_m_IRQ_MASK_2_RDI2_MASK 0x00001fff
  59. #define ISPIF_VFE_m_IRQ_STATUS_0(m) (0x21c + 0x200 * (m))
  60. #define ISPIF_VFE_m_IRQ_STATUS_0_PIX0_OVERFLOW (1 << 12)
  61. #define ISPIF_VFE_m_IRQ_STATUS_0_RDI0_OVERFLOW (1 << 25)
  62. #define ISPIF_VFE_m_IRQ_STATUS_1(m) (0x220 + 0x200 * (m))
  63. #define ISPIF_VFE_m_IRQ_STATUS_1_PIX1_OVERFLOW (1 << 12)
  64. #define ISPIF_VFE_m_IRQ_STATUS_1_RDI1_OVERFLOW (1 << 25)
  65. #define ISPIF_VFE_m_IRQ_STATUS_2(m) (0x224 + 0x200 * (m))
  66. #define ISPIF_VFE_m_IRQ_STATUS_2_RDI2_OVERFLOW (1 << 12)
  67. #define ISPIF_VFE_m_IRQ_CLEAR_0(m) (0x230 + 0x200 * (m))
  68. #define ISPIF_VFE_m_IRQ_CLEAR_1(m) (0x234 + 0x200 * (m))
  69. #define ISPIF_VFE_m_IRQ_CLEAR_2(m) (0x238 + 0x200 * (m))
  70. #define ISPIF_VFE_m_INTF_INPUT_SEL(m) (0x244 + 0x200 * (m))
  71. #define ISPIF_VFE_m_INTF_CMD_0(m) (0x248 + 0x200 * (m))
  72. #define ISPIF_VFE_m_INTF_CMD_1(m) (0x24c + 0x200 * (m))
  73. #define ISPIF_VFE_m_PIX_INTF_n_CID_MASK(m, n) \
  74. (0x254 + 0x200 * (m) + 0x4 * (n))
  75. #define ISPIF_VFE_m_RDI_INTF_n_CID_MASK(m, n) \
  76. (0x264 + 0x200 * (m) + 0x4 * (n))
  77. /* PACK_CFG registers are 8x96 only */
  78. #define ISPIF_VFE_m_RDI_INTF_n_PACK_CFG_0(m, n) \
  79. (0x270 + 0x200 * (m) + 0x4 * (n))
  80. #define ISPIF_VFE_m_RDI_INTF_n_PACK_CFG_1(m, n) \
  81. (0x27c + 0x200 * (m) + 0x4 * (n))
  82. #define ISPIF_VFE_m_RDI_INTF_n_PACK_CFG_0_CID_c_PLAIN(c) \
  83. (1 << ((cid % 8) * 4))
  84. #define ISPIF_VFE_m_PIX_INTF_n_STATUS(m, n) \
  85. (0x2c0 + 0x200 * (m) + 0x4 * (n))
  86. #define ISPIF_VFE_m_RDI_INTF_n_STATUS(m, n) \
  87. (0x2d0 + 0x200 * (m) + 0x4 * (n))
  88. #define CSI_PIX_CLK_MUX_SEL 0x000
  89. #define CSI_RDI_CLK_MUX_SEL 0x008
  90. #define ISPIF_TIMEOUT_SLEEP_US 1000
  91. #define ISPIF_TIMEOUT_ALL_US 1000000
  92. #define ISPIF_RESET_TIMEOUT_MS 500
  93. enum ispif_intf_cmd {
  94. CMD_DISABLE_FRAME_BOUNDARY = 0x0,
  95. CMD_ENABLE_FRAME_BOUNDARY = 0x1,
  96. CMD_DISABLE_IMMEDIATELY = 0x2,
  97. CMD_ALL_DISABLE_IMMEDIATELY = 0xaaaaaaaa,
  98. CMD_ALL_NO_CHANGE = 0xffffffff,
  99. };
  100. static const u32 ispif_formats_8x16[] = {
  101. MEDIA_BUS_FMT_UYVY8_2X8,
  102. MEDIA_BUS_FMT_VYUY8_2X8,
  103. MEDIA_BUS_FMT_YUYV8_2X8,
  104. MEDIA_BUS_FMT_YVYU8_2X8,
  105. MEDIA_BUS_FMT_SBGGR8_1X8,
  106. MEDIA_BUS_FMT_SGBRG8_1X8,
  107. MEDIA_BUS_FMT_SGRBG8_1X8,
  108. MEDIA_BUS_FMT_SRGGB8_1X8,
  109. MEDIA_BUS_FMT_SBGGR10_1X10,
  110. MEDIA_BUS_FMT_SGBRG10_1X10,
  111. MEDIA_BUS_FMT_SGRBG10_1X10,
  112. MEDIA_BUS_FMT_SRGGB10_1X10,
  113. MEDIA_BUS_FMT_SBGGR12_1X12,
  114. MEDIA_BUS_FMT_SGBRG12_1X12,
  115. MEDIA_BUS_FMT_SGRBG12_1X12,
  116. MEDIA_BUS_FMT_SRGGB12_1X12,
  117. MEDIA_BUS_FMT_Y10_1X10,
  118. };
  119. static const u32 ispif_formats_8x96[] = {
  120. MEDIA_BUS_FMT_UYVY8_2X8,
  121. MEDIA_BUS_FMT_VYUY8_2X8,
  122. MEDIA_BUS_FMT_YUYV8_2X8,
  123. MEDIA_BUS_FMT_YVYU8_2X8,
  124. MEDIA_BUS_FMT_SBGGR8_1X8,
  125. MEDIA_BUS_FMT_SGBRG8_1X8,
  126. MEDIA_BUS_FMT_SGRBG8_1X8,
  127. MEDIA_BUS_FMT_SRGGB8_1X8,
  128. MEDIA_BUS_FMT_SBGGR10_1X10,
  129. MEDIA_BUS_FMT_SGBRG10_1X10,
  130. MEDIA_BUS_FMT_SGRBG10_1X10,
  131. MEDIA_BUS_FMT_SRGGB10_1X10,
  132. MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE,
  133. MEDIA_BUS_FMT_SBGGR12_1X12,
  134. MEDIA_BUS_FMT_SGBRG12_1X12,
  135. MEDIA_BUS_FMT_SGRBG12_1X12,
  136. MEDIA_BUS_FMT_SRGGB12_1X12,
  137. MEDIA_BUS_FMT_SBGGR14_1X14,
  138. MEDIA_BUS_FMT_SGBRG14_1X14,
  139. MEDIA_BUS_FMT_SGRBG14_1X14,
  140. MEDIA_BUS_FMT_SRGGB14_1X14,
  141. MEDIA_BUS_FMT_Y10_1X10,
  142. MEDIA_BUS_FMT_Y10_2X8_PADHI_LE,
  143. };
  144. /*
  145. * ispif_isr_8x96 - ISPIF module interrupt handler for 8x96
  146. * @irq: Interrupt line
  147. * @dev: ISPIF device
  148. *
  149. * Return IRQ_HANDLED on success
  150. */
  151. static irqreturn_t ispif_isr_8x96(int irq, void *dev)
  152. {
  153. struct ispif_device *ispif = dev;
  154. u32 value0, value1, value2, value3, value4, value5;
  155. value0 = readl_relaxed(ispif->base + ISPIF_VFE_m_IRQ_STATUS_0(0));
  156. value1 = readl_relaxed(ispif->base + ISPIF_VFE_m_IRQ_STATUS_1(0));
  157. value2 = readl_relaxed(ispif->base + ISPIF_VFE_m_IRQ_STATUS_2(0));
  158. value3 = readl_relaxed(ispif->base + ISPIF_VFE_m_IRQ_STATUS_0(1));
  159. value4 = readl_relaxed(ispif->base + ISPIF_VFE_m_IRQ_STATUS_1(1));
  160. value5 = readl_relaxed(ispif->base + ISPIF_VFE_m_IRQ_STATUS_2(1));
  161. writel_relaxed(value0, ispif->base + ISPIF_VFE_m_IRQ_CLEAR_0(0));
  162. writel_relaxed(value1, ispif->base + ISPIF_VFE_m_IRQ_CLEAR_1(0));
  163. writel_relaxed(value2, ispif->base + ISPIF_VFE_m_IRQ_CLEAR_2(0));
  164. writel_relaxed(value3, ispif->base + ISPIF_VFE_m_IRQ_CLEAR_0(1));
  165. writel_relaxed(value4, ispif->base + ISPIF_VFE_m_IRQ_CLEAR_1(1));
  166. writel_relaxed(value5, ispif->base + ISPIF_VFE_m_IRQ_CLEAR_2(1));
  167. writel(0x1, ispif->base + ISPIF_IRQ_GLOBAL_CLEAR_CMD);
  168. if ((value0 >> 27) & 0x1)
  169. complete(&ispif->reset_complete);
  170. if (unlikely(value0 & ISPIF_VFE_m_IRQ_STATUS_0_PIX0_OVERFLOW))
  171. dev_err_ratelimited(to_device(ispif), "VFE0 pix0 overflow\n");
  172. if (unlikely(value0 & ISPIF_VFE_m_IRQ_STATUS_0_RDI0_OVERFLOW))
  173. dev_err_ratelimited(to_device(ispif), "VFE0 rdi0 overflow\n");
  174. if (unlikely(value1 & ISPIF_VFE_m_IRQ_STATUS_1_PIX1_OVERFLOW))
  175. dev_err_ratelimited(to_device(ispif), "VFE0 pix1 overflow\n");
  176. if (unlikely(value1 & ISPIF_VFE_m_IRQ_STATUS_1_RDI1_OVERFLOW))
  177. dev_err_ratelimited(to_device(ispif), "VFE0 rdi1 overflow\n");
  178. if (unlikely(value2 & ISPIF_VFE_m_IRQ_STATUS_2_RDI2_OVERFLOW))
  179. dev_err_ratelimited(to_device(ispif), "VFE0 rdi2 overflow\n");
  180. if (unlikely(value3 & ISPIF_VFE_m_IRQ_STATUS_0_PIX0_OVERFLOW))
  181. dev_err_ratelimited(to_device(ispif), "VFE1 pix0 overflow\n");
  182. if (unlikely(value3 & ISPIF_VFE_m_IRQ_STATUS_0_RDI0_OVERFLOW))
  183. dev_err_ratelimited(to_device(ispif), "VFE1 rdi0 overflow\n");
  184. if (unlikely(value4 & ISPIF_VFE_m_IRQ_STATUS_1_PIX1_OVERFLOW))
  185. dev_err_ratelimited(to_device(ispif), "VFE1 pix1 overflow\n");
  186. if (unlikely(value4 & ISPIF_VFE_m_IRQ_STATUS_1_RDI1_OVERFLOW))
  187. dev_err_ratelimited(to_device(ispif), "VFE1 rdi1 overflow\n");
  188. if (unlikely(value5 & ISPIF_VFE_m_IRQ_STATUS_2_RDI2_OVERFLOW))
  189. dev_err_ratelimited(to_device(ispif), "VFE1 rdi2 overflow\n");
  190. return IRQ_HANDLED;
  191. }
  192. /*
  193. * ispif_isr_8x16 - ISPIF module interrupt handler for 8x16
  194. * @irq: Interrupt line
  195. * @dev: ISPIF device
  196. *
  197. * Return IRQ_HANDLED on success
  198. */
  199. static irqreturn_t ispif_isr_8x16(int irq, void *dev)
  200. {
  201. struct ispif_device *ispif = dev;
  202. u32 value0, value1, value2;
  203. value0 = readl_relaxed(ispif->base + ISPIF_VFE_m_IRQ_STATUS_0(0));
  204. value1 = readl_relaxed(ispif->base + ISPIF_VFE_m_IRQ_STATUS_1(0));
  205. value2 = readl_relaxed(ispif->base + ISPIF_VFE_m_IRQ_STATUS_2(0));
  206. writel_relaxed(value0, ispif->base + ISPIF_VFE_m_IRQ_CLEAR_0(0));
  207. writel_relaxed(value1, ispif->base + ISPIF_VFE_m_IRQ_CLEAR_1(0));
  208. writel_relaxed(value2, ispif->base + ISPIF_VFE_m_IRQ_CLEAR_2(0));
  209. writel(0x1, ispif->base + ISPIF_IRQ_GLOBAL_CLEAR_CMD);
  210. if ((value0 >> 27) & 0x1)
  211. complete(&ispif->reset_complete);
  212. if (unlikely(value0 & ISPIF_VFE_m_IRQ_STATUS_0_PIX0_OVERFLOW))
  213. dev_err_ratelimited(to_device(ispif), "VFE0 pix0 overflow\n");
  214. if (unlikely(value0 & ISPIF_VFE_m_IRQ_STATUS_0_RDI0_OVERFLOW))
  215. dev_err_ratelimited(to_device(ispif), "VFE0 rdi0 overflow\n");
  216. if (unlikely(value1 & ISPIF_VFE_m_IRQ_STATUS_1_PIX1_OVERFLOW))
  217. dev_err_ratelimited(to_device(ispif), "VFE0 pix1 overflow\n");
  218. if (unlikely(value1 & ISPIF_VFE_m_IRQ_STATUS_1_RDI1_OVERFLOW))
  219. dev_err_ratelimited(to_device(ispif), "VFE0 rdi1 overflow\n");
  220. if (unlikely(value2 & ISPIF_VFE_m_IRQ_STATUS_2_RDI2_OVERFLOW))
  221. dev_err_ratelimited(to_device(ispif), "VFE0 rdi2 overflow\n");
  222. return IRQ_HANDLED;
  223. }
  224. /*
  225. * ispif_reset - Trigger reset on ISPIF module and wait to complete
  226. * @ispif: ISPIF device
  227. *
  228. * Return 0 on success or a negative error code otherwise
  229. */
  230. static int ispif_reset(struct ispif_device *ispif)
  231. {
  232. unsigned long time;
  233. u32 val;
  234. int ret;
  235. ret = camss_pm_domain_on(to_camss(ispif), PM_DOMAIN_VFE0);
  236. if (ret < 0)
  237. return ret;
  238. ret = camss_pm_domain_on(to_camss(ispif), PM_DOMAIN_VFE1);
  239. if (ret < 0)
  240. return ret;
  241. ret = camss_enable_clocks(ispif->nclocks_for_reset,
  242. ispif->clock_for_reset,
  243. to_device(ispif));
  244. if (ret < 0)
  245. return ret;
  246. reinit_completion(&ispif->reset_complete);
  247. val = ISPIF_RST_CMD_0_STROBED_RST_EN |
  248. ISPIF_RST_CMD_0_MISC_LOGIC_RST |
  249. ISPIF_RST_CMD_0_SW_REG_RST |
  250. ISPIF_RST_CMD_0_PIX_INTF_0_CSID_RST |
  251. ISPIF_RST_CMD_0_PIX_INTF_0_VFE_RST |
  252. ISPIF_RST_CMD_0_PIX_INTF_1_CSID_RST |
  253. ISPIF_RST_CMD_0_PIX_INTF_1_VFE_RST |
  254. ISPIF_RST_CMD_0_RDI_INTF_0_CSID_RST |
  255. ISPIF_RST_CMD_0_RDI_INTF_0_VFE_RST |
  256. ISPIF_RST_CMD_0_RDI_INTF_1_CSID_RST |
  257. ISPIF_RST_CMD_0_RDI_INTF_1_VFE_RST |
  258. ISPIF_RST_CMD_0_RDI_INTF_2_CSID_RST |
  259. ISPIF_RST_CMD_0_RDI_INTF_2_VFE_RST |
  260. ISPIF_RST_CMD_0_PIX_OUTPUT_0_MISR_RST |
  261. ISPIF_RST_CMD_0_RDI_OUTPUT_0_MISR_RST |
  262. ISPIF_RST_CMD_0_RDI_OUTPUT_1_MISR_RST |
  263. ISPIF_RST_CMD_0_RDI_OUTPUT_2_MISR_RST;
  264. writel_relaxed(val, ispif->base + ISPIF_RST_CMD_0);
  265. time = wait_for_completion_timeout(&ispif->reset_complete,
  266. msecs_to_jiffies(ISPIF_RESET_TIMEOUT_MS));
  267. if (!time) {
  268. dev_err(to_device(ispif), "ISPIF reset timeout\n");
  269. ret = -EIO;
  270. }
  271. camss_disable_clocks(ispif->nclocks_for_reset, ispif->clock_for_reset);
  272. camss_pm_domain_off(to_camss(ispif), PM_DOMAIN_VFE0);
  273. camss_pm_domain_off(to_camss(ispif), PM_DOMAIN_VFE1);
  274. return ret;
  275. }
  276. /*
  277. * ispif_set_power - Power on/off ISPIF module
  278. * @sd: ISPIF V4L2 subdevice
  279. * @on: Requested power state
  280. *
  281. * Return 0 on success or a negative error code otherwise
  282. */
  283. static int ispif_set_power(struct v4l2_subdev *sd, int on)
  284. {
  285. struct ispif_line *line = v4l2_get_subdevdata(sd);
  286. struct ispif_device *ispif = line->ispif;
  287. struct device *dev = to_device(ispif);
  288. int ret = 0;
  289. mutex_lock(&ispif->power_lock);
  290. if (on) {
  291. if (ispif->power_count) {
  292. /* Power is already on */
  293. ispif->power_count++;
  294. goto exit;
  295. }
  296. ret = pm_runtime_get_sync(dev);
  297. if (ret < 0)
  298. goto exit;
  299. ret = camss_enable_clocks(ispif->nclocks, ispif->clock, dev);
  300. if (ret < 0) {
  301. pm_runtime_put_sync(dev);
  302. goto exit;
  303. }
  304. ret = ispif_reset(ispif);
  305. if (ret < 0) {
  306. pm_runtime_put_sync(dev);
  307. camss_disable_clocks(ispif->nclocks, ispif->clock);
  308. goto exit;
  309. }
  310. ispif->intf_cmd[line->vfe_id].cmd_0 = CMD_ALL_NO_CHANGE;
  311. ispif->intf_cmd[line->vfe_id].cmd_1 = CMD_ALL_NO_CHANGE;
  312. ispif->power_count++;
  313. } else {
  314. if (ispif->power_count == 0) {
  315. dev_err(dev, "ispif power off on power_count == 0\n");
  316. goto exit;
  317. } else if (ispif->power_count == 1) {
  318. camss_disable_clocks(ispif->nclocks, ispif->clock);
  319. pm_runtime_put_sync(dev);
  320. }
  321. ispif->power_count--;
  322. }
  323. exit:
  324. mutex_unlock(&ispif->power_lock);
  325. return ret;
  326. }
  327. /*
  328. * ispif_select_clk_mux - Select clock for PIX/RDI interface
  329. * @ispif: ISPIF device
  330. * @intf: VFE interface
  331. * @csid: CSID HW module id
  332. * @vfe: VFE HW module id
  333. * @enable: enable or disable the selected clock
  334. */
  335. static void ispif_select_clk_mux(struct ispif_device *ispif,
  336. enum ispif_intf intf, u8 csid,
  337. u8 vfe, u8 enable)
  338. {
  339. u32 val;
  340. switch (intf) {
  341. case PIX0:
  342. val = readl_relaxed(ispif->base_clk_mux + CSI_PIX_CLK_MUX_SEL);
  343. val &= ~(0xf << (vfe * 8));
  344. if (enable)
  345. val |= (csid << (vfe * 8));
  346. writel_relaxed(val, ispif->base_clk_mux + CSI_PIX_CLK_MUX_SEL);
  347. break;
  348. case RDI0:
  349. val = readl_relaxed(ispif->base_clk_mux + CSI_RDI_CLK_MUX_SEL);
  350. val &= ~(0xf << (vfe * 12));
  351. if (enable)
  352. val |= (csid << (vfe * 12));
  353. writel_relaxed(val, ispif->base_clk_mux + CSI_RDI_CLK_MUX_SEL);
  354. break;
  355. case PIX1:
  356. val = readl_relaxed(ispif->base_clk_mux + CSI_PIX_CLK_MUX_SEL);
  357. val &= ~(0xf << (4 + (vfe * 8)));
  358. if (enable)
  359. val |= (csid << (4 + (vfe * 8)));
  360. writel_relaxed(val, ispif->base_clk_mux + CSI_PIX_CLK_MUX_SEL);
  361. break;
  362. case RDI1:
  363. val = readl_relaxed(ispif->base_clk_mux + CSI_RDI_CLK_MUX_SEL);
  364. val &= ~(0xf << (4 + (vfe * 12)));
  365. if (enable)
  366. val |= (csid << (4 + (vfe * 12)));
  367. writel_relaxed(val, ispif->base_clk_mux + CSI_RDI_CLK_MUX_SEL);
  368. break;
  369. case RDI2:
  370. val = readl_relaxed(ispif->base_clk_mux + CSI_RDI_CLK_MUX_SEL);
  371. val &= ~(0xf << (8 + (vfe * 12)));
  372. if (enable)
  373. val |= (csid << (8 + (vfe * 12)));
  374. writel_relaxed(val, ispif->base_clk_mux + CSI_RDI_CLK_MUX_SEL);
  375. break;
  376. }
  377. mb();
  378. }
  379. /*
  380. * ispif_validate_intf_status - Validate current status of PIX/RDI interface
  381. * @ispif: ISPIF device
  382. * @intf: VFE interface
  383. * @vfe: VFE HW module id
  384. *
  385. * Return 0 when interface is idle or -EBUSY otherwise
  386. */
  387. static int ispif_validate_intf_status(struct ispif_device *ispif,
  388. enum ispif_intf intf, u8 vfe)
  389. {
  390. int ret = 0;
  391. u32 val = 0;
  392. switch (intf) {
  393. case PIX0:
  394. val = readl_relaxed(ispif->base +
  395. ISPIF_VFE_m_PIX_INTF_n_STATUS(vfe, 0));
  396. break;
  397. case RDI0:
  398. val = readl_relaxed(ispif->base +
  399. ISPIF_VFE_m_RDI_INTF_n_STATUS(vfe, 0));
  400. break;
  401. case PIX1:
  402. val = readl_relaxed(ispif->base +
  403. ISPIF_VFE_m_PIX_INTF_n_STATUS(vfe, 1));
  404. break;
  405. case RDI1:
  406. val = readl_relaxed(ispif->base +
  407. ISPIF_VFE_m_RDI_INTF_n_STATUS(vfe, 1));
  408. break;
  409. case RDI2:
  410. val = readl_relaxed(ispif->base +
  411. ISPIF_VFE_m_RDI_INTF_n_STATUS(vfe, 2));
  412. break;
  413. }
  414. if ((val & 0xf) != 0xf) {
  415. dev_err(to_device(ispif), "%s: ispif is busy: 0x%x\n",
  416. __func__, val);
  417. ret = -EBUSY;
  418. }
  419. return ret;
  420. }
  421. /*
  422. * ispif_wait_for_stop - Wait for PIX/RDI interface to stop
  423. * @ispif: ISPIF device
  424. * @intf: VFE interface
  425. * @vfe: VFE HW module id
  426. *
  427. * Return 0 on success or a negative error code otherwise
  428. */
  429. static int ispif_wait_for_stop(struct ispif_device *ispif,
  430. enum ispif_intf intf, u8 vfe)
  431. {
  432. u32 addr = 0;
  433. u32 stop_flag = 0;
  434. int ret;
  435. switch (intf) {
  436. case PIX0:
  437. addr = ISPIF_VFE_m_PIX_INTF_n_STATUS(vfe, 0);
  438. break;
  439. case RDI0:
  440. addr = ISPIF_VFE_m_RDI_INTF_n_STATUS(vfe, 0);
  441. break;
  442. case PIX1:
  443. addr = ISPIF_VFE_m_PIX_INTF_n_STATUS(vfe, 1);
  444. break;
  445. case RDI1:
  446. addr = ISPIF_VFE_m_RDI_INTF_n_STATUS(vfe, 1);
  447. break;
  448. case RDI2:
  449. addr = ISPIF_VFE_m_RDI_INTF_n_STATUS(vfe, 2);
  450. break;
  451. }
  452. ret = readl_poll_timeout(ispif->base + addr,
  453. stop_flag,
  454. (stop_flag & 0xf) == 0xf,
  455. ISPIF_TIMEOUT_SLEEP_US,
  456. ISPIF_TIMEOUT_ALL_US);
  457. if (ret < 0)
  458. dev_err(to_device(ispif), "%s: ispif stop timeout\n",
  459. __func__);
  460. return ret;
  461. }
  462. /*
  463. * ispif_select_csid - Select CSID HW module for input from
  464. * @ispif: ISPIF device
  465. * @intf: VFE interface
  466. * @csid: CSID HW module id
  467. * @vfe: VFE HW module id
  468. * @enable: enable or disable the selected input
  469. */
  470. static void ispif_select_csid(struct ispif_device *ispif, enum ispif_intf intf,
  471. u8 csid, u8 vfe, u8 enable)
  472. {
  473. u32 val;
  474. val = readl_relaxed(ispif->base + ISPIF_VFE_m_INTF_INPUT_SEL(vfe));
  475. switch (intf) {
  476. case PIX0:
  477. val &= ~(BIT(1) | BIT(0));
  478. if (enable)
  479. val |= csid;
  480. break;
  481. case RDI0:
  482. val &= ~(BIT(5) | BIT(4));
  483. if (enable)
  484. val |= (csid << 4);
  485. break;
  486. case PIX1:
  487. val &= ~(BIT(9) | BIT(8));
  488. if (enable)
  489. val |= (csid << 8);
  490. break;
  491. case RDI1:
  492. val &= ~(BIT(13) | BIT(12));
  493. if (enable)
  494. val |= (csid << 12);
  495. break;
  496. case RDI2:
  497. val &= ~(BIT(21) | BIT(20));
  498. if (enable)
  499. val |= (csid << 20);
  500. break;
  501. }
  502. writel(val, ispif->base + ISPIF_VFE_m_INTF_INPUT_SEL(vfe));
  503. }
  504. /*
  505. * ispif_select_cid - Enable/disable desired CID
  506. * @ispif: ISPIF device
  507. * @intf: VFE interface
  508. * @cid: desired CID to enable/disable
  509. * @vfe: VFE HW module id
  510. * @enable: enable or disable the desired CID
  511. */
  512. static void ispif_select_cid(struct ispif_device *ispif, enum ispif_intf intf,
  513. u8 cid, u8 vfe, u8 enable)
  514. {
  515. u32 cid_mask = 1 << cid;
  516. u32 addr = 0;
  517. u32 val;
  518. switch (intf) {
  519. case PIX0:
  520. addr = ISPIF_VFE_m_PIX_INTF_n_CID_MASK(vfe, 0);
  521. break;
  522. case RDI0:
  523. addr = ISPIF_VFE_m_RDI_INTF_n_CID_MASK(vfe, 0);
  524. break;
  525. case PIX1:
  526. addr = ISPIF_VFE_m_PIX_INTF_n_CID_MASK(vfe, 1);
  527. break;
  528. case RDI1:
  529. addr = ISPIF_VFE_m_RDI_INTF_n_CID_MASK(vfe, 1);
  530. break;
  531. case RDI2:
  532. addr = ISPIF_VFE_m_RDI_INTF_n_CID_MASK(vfe, 2);
  533. break;
  534. }
  535. val = readl_relaxed(ispif->base + addr);
  536. if (enable)
  537. val |= cid_mask;
  538. else
  539. val &= ~cid_mask;
  540. writel(val, ispif->base + addr);
  541. }
  542. /*
  543. * ispif_config_irq - Enable/disable interrupts for PIX/RDI interface
  544. * @ispif: ISPIF device
  545. * @intf: VFE interface
  546. * @vfe: VFE HW module id
  547. * @enable: enable or disable
  548. */
  549. static void ispif_config_irq(struct ispif_device *ispif, enum ispif_intf intf,
  550. u8 vfe, u8 enable)
  551. {
  552. u32 val;
  553. switch (intf) {
  554. case PIX0:
  555. val = readl_relaxed(ispif->base + ISPIF_VFE_m_IRQ_MASK_0(vfe));
  556. val &= ~ISPIF_VFE_m_IRQ_MASK_0_PIX0_MASK;
  557. if (enable)
  558. val |= ISPIF_VFE_m_IRQ_MASK_0_PIX0_ENABLE;
  559. writel_relaxed(val, ispif->base + ISPIF_VFE_m_IRQ_MASK_0(vfe));
  560. writel_relaxed(ISPIF_VFE_m_IRQ_MASK_0_PIX0_ENABLE,
  561. ispif->base + ISPIF_VFE_m_IRQ_CLEAR_0(vfe));
  562. break;
  563. case RDI0:
  564. val = readl_relaxed(ispif->base + ISPIF_VFE_m_IRQ_MASK_0(vfe));
  565. val &= ~ISPIF_VFE_m_IRQ_MASK_0_RDI0_MASK;
  566. if (enable)
  567. val |= ISPIF_VFE_m_IRQ_MASK_0_RDI0_ENABLE;
  568. writel_relaxed(val, ispif->base + ISPIF_VFE_m_IRQ_MASK_0(vfe));
  569. writel_relaxed(ISPIF_VFE_m_IRQ_MASK_0_RDI0_ENABLE,
  570. ispif->base + ISPIF_VFE_m_IRQ_CLEAR_0(vfe));
  571. break;
  572. case PIX1:
  573. val = readl_relaxed(ispif->base + ISPIF_VFE_m_IRQ_MASK_1(vfe));
  574. val &= ~ISPIF_VFE_m_IRQ_MASK_1_PIX1_MASK;
  575. if (enable)
  576. val |= ISPIF_VFE_m_IRQ_MASK_1_PIX1_ENABLE;
  577. writel_relaxed(val, ispif->base + ISPIF_VFE_m_IRQ_MASK_1(vfe));
  578. writel_relaxed(ISPIF_VFE_m_IRQ_MASK_1_PIX1_ENABLE,
  579. ispif->base + ISPIF_VFE_m_IRQ_CLEAR_1(vfe));
  580. break;
  581. case RDI1:
  582. val = readl_relaxed(ispif->base + ISPIF_VFE_m_IRQ_MASK_1(vfe));
  583. val &= ~ISPIF_VFE_m_IRQ_MASK_1_RDI1_MASK;
  584. if (enable)
  585. val |= ISPIF_VFE_m_IRQ_MASK_1_RDI1_ENABLE;
  586. writel_relaxed(val, ispif->base + ISPIF_VFE_m_IRQ_MASK_1(vfe));
  587. writel_relaxed(ISPIF_VFE_m_IRQ_MASK_1_RDI1_ENABLE,
  588. ispif->base + ISPIF_VFE_m_IRQ_CLEAR_1(vfe));
  589. break;
  590. case RDI2:
  591. val = readl_relaxed(ispif->base + ISPIF_VFE_m_IRQ_MASK_2(vfe));
  592. val &= ~ISPIF_VFE_m_IRQ_MASK_2_RDI2_MASK;
  593. if (enable)
  594. val |= ISPIF_VFE_m_IRQ_MASK_2_RDI2_ENABLE;
  595. writel_relaxed(val, ispif->base + ISPIF_VFE_m_IRQ_MASK_2(vfe));
  596. writel_relaxed(ISPIF_VFE_m_IRQ_MASK_2_RDI2_ENABLE,
  597. ispif->base + ISPIF_VFE_m_IRQ_CLEAR_2(vfe));
  598. break;
  599. }
  600. writel(0x1, ispif->base + ISPIF_IRQ_GLOBAL_CLEAR_CMD);
  601. }
  602. /*
  603. * ispif_config_pack - Config packing for PRDI mode
  604. * @ispif: ISPIF device
  605. * @code: media bus format code
  606. * @intf: VFE interface
  607. * @cid: desired CID to handle
  608. * @vfe: VFE HW module id
  609. * @enable: enable or disable
  610. */
  611. static void ispif_config_pack(struct ispif_device *ispif, u32 code,
  612. enum ispif_intf intf, u8 cid, u8 vfe, u8 enable)
  613. {
  614. u32 addr, val;
  615. if (code != MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE &&
  616. code != MEDIA_BUS_FMT_Y10_2X8_PADHI_LE)
  617. return;
  618. switch (intf) {
  619. case RDI0:
  620. if (cid < 8)
  621. addr = ISPIF_VFE_m_RDI_INTF_n_PACK_CFG_0(vfe, 0);
  622. else
  623. addr = ISPIF_VFE_m_RDI_INTF_n_PACK_CFG_1(vfe, 0);
  624. break;
  625. case RDI1:
  626. if (cid < 8)
  627. addr = ISPIF_VFE_m_RDI_INTF_n_PACK_CFG_0(vfe, 1);
  628. else
  629. addr = ISPIF_VFE_m_RDI_INTF_n_PACK_CFG_1(vfe, 1);
  630. break;
  631. case RDI2:
  632. if (cid < 8)
  633. addr = ISPIF_VFE_m_RDI_INTF_n_PACK_CFG_0(vfe, 2);
  634. else
  635. addr = ISPIF_VFE_m_RDI_INTF_n_PACK_CFG_1(vfe, 2);
  636. break;
  637. default:
  638. return;
  639. }
  640. if (enable)
  641. val = ISPIF_VFE_m_RDI_INTF_n_PACK_CFG_0_CID_c_PLAIN(cid);
  642. else
  643. val = 0;
  644. writel_relaxed(val, ispif->base + addr);
  645. }
  646. /*
  647. * ispif_set_intf_cmd - Set command to enable/disable interface
  648. * @ispif: ISPIF device
  649. * @cmd: interface command
  650. * @intf: VFE interface
  651. * @vfe: VFE HW module id
  652. * @vc: virtual channel
  653. */
  654. static void ispif_set_intf_cmd(struct ispif_device *ispif, u8 cmd,
  655. enum ispif_intf intf, u8 vfe, u8 vc)
  656. {
  657. u32 *val;
  658. if (intf == RDI2) {
  659. val = &ispif->intf_cmd[vfe].cmd_1;
  660. *val &= ~(0x3 << (vc * 2 + 8));
  661. *val |= (cmd << (vc * 2 + 8));
  662. wmb();
  663. writel_relaxed(*val, ispif->base + ISPIF_VFE_m_INTF_CMD_1(vfe));
  664. wmb();
  665. } else {
  666. val = &ispif->intf_cmd[vfe].cmd_0;
  667. *val &= ~(0x3 << (vc * 2 + intf * 8));
  668. *val |= (cmd << (vc * 2 + intf * 8));
  669. wmb();
  670. writel_relaxed(*val, ispif->base + ISPIF_VFE_m_INTF_CMD_0(vfe));
  671. wmb();
  672. }
  673. }
  674. /*
  675. * ispif_set_stream - Enable/disable streaming on ISPIF module
  676. * @sd: ISPIF V4L2 subdevice
  677. * @enable: Requested streaming state
  678. *
  679. * Main configuration of ISPIF module is also done here.
  680. *
  681. * Return 0 on success or a negative error code otherwise
  682. */
  683. static int ispif_set_stream(struct v4l2_subdev *sd, int enable)
  684. {
  685. struct ispif_line *line = v4l2_get_subdevdata(sd);
  686. struct ispif_device *ispif = line->ispif;
  687. enum ispif_intf intf = line->interface;
  688. u8 csid = line->csid_id;
  689. u8 vfe = line->vfe_id;
  690. u8 vc = 0; /* Virtual Channel 0 */
  691. u8 cid = vc * 4; /* id of Virtual Channel and Data Type set */
  692. int ret;
  693. if (enable) {
  694. if (!media_entity_remote_pad(&line->pads[MSM_ISPIF_PAD_SINK]))
  695. return -ENOLINK;
  696. /* Config */
  697. mutex_lock(&ispif->config_lock);
  698. ispif_select_clk_mux(ispif, intf, csid, vfe, 1);
  699. ret = ispif_validate_intf_status(ispif, intf, vfe);
  700. if (ret < 0) {
  701. mutex_unlock(&ispif->config_lock);
  702. return ret;
  703. }
  704. ispif_select_csid(ispif, intf, csid, vfe, 1);
  705. ispif_select_cid(ispif, intf, cid, vfe, 1);
  706. ispif_config_irq(ispif, intf, vfe, 1);
  707. if (to_camss(ispif)->version == CAMSS_8x96)
  708. ispif_config_pack(ispif,
  709. line->fmt[MSM_ISPIF_PAD_SINK].code,
  710. intf, cid, vfe, 1);
  711. ispif_set_intf_cmd(ispif, CMD_ENABLE_FRAME_BOUNDARY,
  712. intf, vfe, vc);
  713. } else {
  714. mutex_lock(&ispif->config_lock);
  715. ispif_set_intf_cmd(ispif, CMD_DISABLE_FRAME_BOUNDARY,
  716. intf, vfe, vc);
  717. mutex_unlock(&ispif->config_lock);
  718. ret = ispif_wait_for_stop(ispif, intf, vfe);
  719. if (ret < 0)
  720. return ret;
  721. mutex_lock(&ispif->config_lock);
  722. if (to_camss(ispif)->version == CAMSS_8x96)
  723. ispif_config_pack(ispif,
  724. line->fmt[MSM_ISPIF_PAD_SINK].code,
  725. intf, cid, vfe, 0);
  726. ispif_config_irq(ispif, intf, vfe, 0);
  727. ispif_select_cid(ispif, intf, cid, vfe, 0);
  728. ispif_select_csid(ispif, intf, csid, vfe, 0);
  729. ispif_select_clk_mux(ispif, intf, csid, vfe, 0);
  730. }
  731. mutex_unlock(&ispif->config_lock);
  732. return 0;
  733. }
  734. /*
  735. * __ispif_get_format - Get pointer to format structure
  736. * @ispif: ISPIF line
  737. * @cfg: V4L2 subdev pad configuration
  738. * @pad: pad from which format is requested
  739. * @which: TRY or ACTIVE format
  740. *
  741. * Return pointer to TRY or ACTIVE format structure
  742. */
  743. static struct v4l2_mbus_framefmt *
  744. __ispif_get_format(struct ispif_line *line,
  745. struct v4l2_subdev_pad_config *cfg,
  746. unsigned int pad,
  747. enum v4l2_subdev_format_whence which)
  748. {
  749. if (which == V4L2_SUBDEV_FORMAT_TRY)
  750. return v4l2_subdev_get_try_format(&line->subdev, cfg, pad);
  751. return &line->fmt[pad];
  752. }
  753. /*
  754. * ispif_try_format - Handle try format by pad subdev method
  755. * @ispif: ISPIF line
  756. * @cfg: V4L2 subdev pad configuration
  757. * @pad: pad on which format is requested
  758. * @fmt: pointer to v4l2 format structure
  759. * @which: wanted subdev format
  760. */
  761. static void ispif_try_format(struct ispif_line *line,
  762. struct v4l2_subdev_pad_config *cfg,
  763. unsigned int pad,
  764. struct v4l2_mbus_framefmt *fmt,
  765. enum v4l2_subdev_format_whence which)
  766. {
  767. unsigned int i;
  768. switch (pad) {
  769. case MSM_ISPIF_PAD_SINK:
  770. /* Set format on sink pad */
  771. for (i = 0; i < line->nformats; i++)
  772. if (fmt->code == line->formats[i])
  773. break;
  774. /* If not found, use UYVY as default */
  775. if (i >= line->nformats)
  776. fmt->code = MEDIA_BUS_FMT_UYVY8_2X8;
  777. fmt->width = clamp_t(u32, fmt->width, 1, 8191);
  778. fmt->height = clamp_t(u32, fmt->height, 1, 8191);
  779. fmt->field = V4L2_FIELD_NONE;
  780. fmt->colorspace = V4L2_COLORSPACE_SRGB;
  781. break;
  782. case MSM_ISPIF_PAD_SRC:
  783. /* Set and return a format same as sink pad */
  784. *fmt = *__ispif_get_format(line, cfg, MSM_ISPIF_PAD_SINK,
  785. which);
  786. break;
  787. }
  788. fmt->colorspace = V4L2_COLORSPACE_SRGB;
  789. }
  790. /*
  791. * ispif_enum_mbus_code - Handle pixel format enumeration
  792. * @sd: ISPIF V4L2 subdevice
  793. * @cfg: V4L2 subdev pad configuration
  794. * @code: pointer to v4l2_subdev_mbus_code_enum structure
  795. * return -EINVAL or zero on success
  796. */
  797. static int ispif_enum_mbus_code(struct v4l2_subdev *sd,
  798. struct v4l2_subdev_pad_config *cfg,
  799. struct v4l2_subdev_mbus_code_enum *code)
  800. {
  801. struct ispif_line *line = v4l2_get_subdevdata(sd);
  802. struct v4l2_mbus_framefmt *format;
  803. if (code->pad == MSM_ISPIF_PAD_SINK) {
  804. if (code->index >= line->nformats)
  805. return -EINVAL;
  806. code->code = line->formats[code->index];
  807. } else {
  808. if (code->index > 0)
  809. return -EINVAL;
  810. format = __ispif_get_format(line, cfg, MSM_ISPIF_PAD_SINK,
  811. code->which);
  812. code->code = format->code;
  813. }
  814. return 0;
  815. }
  816. /*
  817. * ispif_enum_frame_size - Handle frame size enumeration
  818. * @sd: ISPIF V4L2 subdevice
  819. * @cfg: V4L2 subdev pad configuration
  820. * @fse: pointer to v4l2_subdev_frame_size_enum structure
  821. * return -EINVAL or zero on success
  822. */
  823. static int ispif_enum_frame_size(struct v4l2_subdev *sd,
  824. struct v4l2_subdev_pad_config *cfg,
  825. struct v4l2_subdev_frame_size_enum *fse)
  826. {
  827. struct ispif_line *line = v4l2_get_subdevdata(sd);
  828. struct v4l2_mbus_framefmt format;
  829. if (fse->index != 0)
  830. return -EINVAL;
  831. format.code = fse->code;
  832. format.width = 1;
  833. format.height = 1;
  834. ispif_try_format(line, cfg, fse->pad, &format, fse->which);
  835. fse->min_width = format.width;
  836. fse->min_height = format.height;
  837. if (format.code != fse->code)
  838. return -EINVAL;
  839. format.code = fse->code;
  840. format.width = -1;
  841. format.height = -1;
  842. ispif_try_format(line, cfg, fse->pad, &format, fse->which);
  843. fse->max_width = format.width;
  844. fse->max_height = format.height;
  845. return 0;
  846. }
  847. /*
  848. * ispif_get_format - Handle get format by pads subdev method
  849. * @sd: ISPIF V4L2 subdevice
  850. * @cfg: V4L2 subdev pad configuration
  851. * @fmt: pointer to v4l2 subdev format structure
  852. *
  853. * Return -EINVAL or zero on success
  854. */
  855. static int ispif_get_format(struct v4l2_subdev *sd,
  856. struct v4l2_subdev_pad_config *cfg,
  857. struct v4l2_subdev_format *fmt)
  858. {
  859. struct ispif_line *line = v4l2_get_subdevdata(sd);
  860. struct v4l2_mbus_framefmt *format;
  861. format = __ispif_get_format(line, cfg, fmt->pad, fmt->which);
  862. if (format == NULL)
  863. return -EINVAL;
  864. fmt->format = *format;
  865. return 0;
  866. }
  867. /*
  868. * ispif_set_format - Handle set format by pads subdev method
  869. * @sd: ISPIF V4L2 subdevice
  870. * @cfg: V4L2 subdev pad configuration
  871. * @fmt: pointer to v4l2 subdev format structure
  872. *
  873. * Return -EINVAL or zero on success
  874. */
  875. static int ispif_set_format(struct v4l2_subdev *sd,
  876. struct v4l2_subdev_pad_config *cfg,
  877. struct v4l2_subdev_format *fmt)
  878. {
  879. struct ispif_line *line = v4l2_get_subdevdata(sd);
  880. struct v4l2_mbus_framefmt *format;
  881. format = __ispif_get_format(line, cfg, fmt->pad, fmt->which);
  882. if (format == NULL)
  883. return -EINVAL;
  884. ispif_try_format(line, cfg, fmt->pad, &fmt->format, fmt->which);
  885. *format = fmt->format;
  886. /* Propagate the format from sink to source */
  887. if (fmt->pad == MSM_ISPIF_PAD_SINK) {
  888. format = __ispif_get_format(line, cfg, MSM_ISPIF_PAD_SRC,
  889. fmt->which);
  890. *format = fmt->format;
  891. ispif_try_format(line, cfg, MSM_ISPIF_PAD_SRC, format,
  892. fmt->which);
  893. }
  894. return 0;
  895. }
  896. /*
  897. * ispif_init_formats - Initialize formats on all pads
  898. * @sd: ISPIF V4L2 subdevice
  899. * @fh: V4L2 subdev file handle
  900. *
  901. * Initialize all pad formats with default values.
  902. *
  903. * Return 0 on success or a negative error code otherwise
  904. */
  905. static int ispif_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
  906. {
  907. struct v4l2_subdev_format format = {
  908. .pad = MSM_ISPIF_PAD_SINK,
  909. .which = fh ? V4L2_SUBDEV_FORMAT_TRY :
  910. V4L2_SUBDEV_FORMAT_ACTIVE,
  911. .format = {
  912. .code = MEDIA_BUS_FMT_UYVY8_2X8,
  913. .width = 1920,
  914. .height = 1080
  915. }
  916. };
  917. return ispif_set_format(sd, fh ? fh->pad : NULL, &format);
  918. }
  919. /*
  920. * msm_ispif_subdev_init - Initialize ISPIF device structure and resources
  921. * @ispif: ISPIF device
  922. * @res: ISPIF module resources table
  923. *
  924. * Return 0 on success or a negative error code otherwise
  925. */
  926. int msm_ispif_subdev_init(struct ispif_device *ispif,
  927. const struct resources_ispif *res)
  928. {
  929. struct device *dev = to_device(ispif);
  930. struct platform_device *pdev = to_platform_device(dev);
  931. struct resource *r;
  932. int i;
  933. int ret;
  934. /* Number of ISPIF lines - same as number of CSID hardware modules */
  935. if (to_camss(ispif)->version == CAMSS_8x16)
  936. ispif->line_num = 2;
  937. else if (to_camss(ispif)->version == CAMSS_8x96)
  938. ispif->line_num = 4;
  939. else
  940. return -EINVAL;
  941. ispif->line = devm_kcalloc(dev, ispif->line_num, sizeof(*ispif->line),
  942. GFP_KERNEL);
  943. if (!ispif->line)
  944. return -ENOMEM;
  945. for (i = 0; i < ispif->line_num; i++) {
  946. ispif->line[i].ispif = ispif;
  947. ispif->line[i].id = i;
  948. if (to_camss(ispif)->version == CAMSS_8x16) {
  949. ispif->line[i].formats = ispif_formats_8x16;
  950. ispif->line[i].nformats =
  951. ARRAY_SIZE(ispif_formats_8x16);
  952. } else if (to_camss(ispif)->version == CAMSS_8x96) {
  953. ispif->line[i].formats = ispif_formats_8x96;
  954. ispif->line[i].nformats =
  955. ARRAY_SIZE(ispif_formats_8x96);
  956. } else {
  957. return -EINVAL;
  958. }
  959. }
  960. /* Memory */
  961. r = platform_get_resource_byname(pdev, IORESOURCE_MEM, res->reg[0]);
  962. ispif->base = devm_ioremap_resource(dev, r);
  963. if (IS_ERR(ispif->base)) {
  964. dev_err(dev, "could not map memory\n");
  965. return PTR_ERR(ispif->base);
  966. }
  967. r = platform_get_resource_byname(pdev, IORESOURCE_MEM, res->reg[1]);
  968. ispif->base_clk_mux = devm_ioremap_resource(dev, r);
  969. if (IS_ERR(ispif->base_clk_mux)) {
  970. dev_err(dev, "could not map memory\n");
  971. return PTR_ERR(ispif->base_clk_mux);
  972. }
  973. /* Interrupt */
  974. r = platform_get_resource_byname(pdev, IORESOURCE_IRQ, res->interrupt);
  975. if (!r) {
  976. dev_err(dev, "missing IRQ\n");
  977. return -EINVAL;
  978. }
  979. ispif->irq = r->start;
  980. snprintf(ispif->irq_name, sizeof(ispif->irq_name), "%s_%s",
  981. dev_name(dev), MSM_ISPIF_NAME);
  982. if (to_camss(ispif)->version == CAMSS_8x16)
  983. ret = devm_request_irq(dev, ispif->irq, ispif_isr_8x16,
  984. IRQF_TRIGGER_RISING, ispif->irq_name, ispif);
  985. else if (to_camss(ispif)->version == CAMSS_8x96)
  986. ret = devm_request_irq(dev, ispif->irq, ispif_isr_8x96,
  987. IRQF_TRIGGER_RISING, ispif->irq_name, ispif);
  988. else
  989. ret = -EINVAL;
  990. if (ret < 0) {
  991. dev_err(dev, "request_irq failed: %d\n", ret);
  992. return ret;
  993. }
  994. /* Clocks */
  995. ispif->nclocks = 0;
  996. while (res->clock[ispif->nclocks])
  997. ispif->nclocks++;
  998. ispif->clock = devm_kcalloc(dev,
  999. ispif->nclocks, sizeof(*ispif->clock),
  1000. GFP_KERNEL);
  1001. if (!ispif->clock)
  1002. return -ENOMEM;
  1003. for (i = 0; i < ispif->nclocks; i++) {
  1004. struct camss_clock *clock = &ispif->clock[i];
  1005. clock->clk = devm_clk_get(dev, res->clock[i]);
  1006. if (IS_ERR(clock->clk))
  1007. return PTR_ERR(clock->clk);
  1008. clock->freq = NULL;
  1009. clock->nfreqs = 0;
  1010. }
  1011. ispif->nclocks_for_reset = 0;
  1012. while (res->clock_for_reset[ispif->nclocks_for_reset])
  1013. ispif->nclocks_for_reset++;
  1014. ispif->clock_for_reset = devm_kcalloc(dev,
  1015. ispif->nclocks_for_reset,
  1016. sizeof(*ispif->clock_for_reset),
  1017. GFP_KERNEL);
  1018. if (!ispif->clock_for_reset)
  1019. return -ENOMEM;
  1020. for (i = 0; i < ispif->nclocks_for_reset; i++) {
  1021. struct camss_clock *clock = &ispif->clock_for_reset[i];
  1022. clock->clk = devm_clk_get(dev, res->clock_for_reset[i]);
  1023. if (IS_ERR(clock->clk))
  1024. return PTR_ERR(clock->clk);
  1025. clock->freq = NULL;
  1026. clock->nfreqs = 0;
  1027. }
  1028. mutex_init(&ispif->power_lock);
  1029. ispif->power_count = 0;
  1030. mutex_init(&ispif->config_lock);
  1031. init_completion(&ispif->reset_complete);
  1032. return 0;
  1033. }
  1034. /*
  1035. * ispif_get_intf - Get ISPIF interface to use by VFE line id
  1036. * @line_id: VFE line id that the ISPIF line is connected to
  1037. *
  1038. * Return ISPIF interface to use
  1039. */
  1040. static enum ispif_intf ispif_get_intf(enum vfe_line_id line_id)
  1041. {
  1042. switch (line_id) {
  1043. case (VFE_LINE_RDI0):
  1044. return RDI0;
  1045. case (VFE_LINE_RDI1):
  1046. return RDI1;
  1047. case (VFE_LINE_RDI2):
  1048. return RDI2;
  1049. case (VFE_LINE_PIX):
  1050. return PIX0;
  1051. default:
  1052. return RDI0;
  1053. }
  1054. }
  1055. /*
  1056. * ispif_link_setup - Setup ISPIF connections
  1057. * @entity: Pointer to media entity structure
  1058. * @local: Pointer to local pad
  1059. * @remote: Pointer to remote pad
  1060. * @flags: Link flags
  1061. *
  1062. * Return 0 on success
  1063. */
  1064. static int ispif_link_setup(struct media_entity *entity,
  1065. const struct media_pad *local,
  1066. const struct media_pad *remote, u32 flags)
  1067. {
  1068. if (flags & MEDIA_LNK_FL_ENABLED) {
  1069. if (media_entity_remote_pad(local))
  1070. return -EBUSY;
  1071. if (local->flags & MEDIA_PAD_FL_SINK) {
  1072. struct v4l2_subdev *sd;
  1073. struct ispif_line *line;
  1074. sd = media_entity_to_v4l2_subdev(entity);
  1075. line = v4l2_get_subdevdata(sd);
  1076. msm_csid_get_csid_id(remote->entity, &line->csid_id);
  1077. } else { /* MEDIA_PAD_FL_SOURCE */
  1078. struct v4l2_subdev *sd;
  1079. struct ispif_line *line;
  1080. enum vfe_line_id id;
  1081. sd = media_entity_to_v4l2_subdev(entity);
  1082. line = v4l2_get_subdevdata(sd);
  1083. msm_vfe_get_vfe_id(remote->entity, &line->vfe_id);
  1084. msm_vfe_get_vfe_line_id(remote->entity, &id);
  1085. line->interface = ispif_get_intf(id);
  1086. }
  1087. }
  1088. return 0;
  1089. }
  1090. static const struct v4l2_subdev_core_ops ispif_core_ops = {
  1091. .s_power = ispif_set_power,
  1092. };
  1093. static const struct v4l2_subdev_video_ops ispif_video_ops = {
  1094. .s_stream = ispif_set_stream,
  1095. };
  1096. static const struct v4l2_subdev_pad_ops ispif_pad_ops = {
  1097. .enum_mbus_code = ispif_enum_mbus_code,
  1098. .enum_frame_size = ispif_enum_frame_size,
  1099. .get_fmt = ispif_get_format,
  1100. .set_fmt = ispif_set_format,
  1101. };
  1102. static const struct v4l2_subdev_ops ispif_v4l2_ops = {
  1103. .core = &ispif_core_ops,
  1104. .video = &ispif_video_ops,
  1105. .pad = &ispif_pad_ops,
  1106. };
  1107. static const struct v4l2_subdev_internal_ops ispif_v4l2_internal_ops = {
  1108. .open = ispif_init_formats,
  1109. };
  1110. static const struct media_entity_operations ispif_media_ops = {
  1111. .link_setup = ispif_link_setup,
  1112. .link_validate = v4l2_subdev_link_validate,
  1113. };
  1114. /*
  1115. * msm_ispif_register_entities - Register subdev node for ISPIF module
  1116. * @ispif: ISPIF device
  1117. * @v4l2_dev: V4L2 device
  1118. *
  1119. * Return 0 on success or a negative error code otherwise
  1120. */
  1121. int msm_ispif_register_entities(struct ispif_device *ispif,
  1122. struct v4l2_device *v4l2_dev)
  1123. {
  1124. struct device *dev = to_device(ispif);
  1125. int ret;
  1126. int i;
  1127. for (i = 0; i < ispif->line_num; i++) {
  1128. struct v4l2_subdev *sd = &ispif->line[i].subdev;
  1129. struct media_pad *pads = ispif->line[i].pads;
  1130. v4l2_subdev_init(sd, &ispif_v4l2_ops);
  1131. sd->internal_ops = &ispif_v4l2_internal_ops;
  1132. sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
  1133. snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d",
  1134. MSM_ISPIF_NAME, i);
  1135. v4l2_set_subdevdata(sd, &ispif->line[i]);
  1136. ret = ispif_init_formats(sd, NULL);
  1137. if (ret < 0) {
  1138. dev_err(dev, "Failed to init format: %d\n", ret);
  1139. goto error;
  1140. }
  1141. pads[MSM_ISPIF_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
  1142. pads[MSM_ISPIF_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE;
  1143. sd->entity.function = MEDIA_ENT_F_IO_V4L;
  1144. sd->entity.ops = &ispif_media_ops;
  1145. ret = media_entity_pads_init(&sd->entity, MSM_ISPIF_PADS_NUM,
  1146. pads);
  1147. if (ret < 0) {
  1148. dev_err(dev, "Failed to init media entity: %d\n", ret);
  1149. goto error;
  1150. }
  1151. ret = v4l2_device_register_subdev(v4l2_dev, sd);
  1152. if (ret < 0) {
  1153. dev_err(dev, "Failed to register subdev: %d\n", ret);
  1154. media_entity_cleanup(&sd->entity);
  1155. goto error;
  1156. }
  1157. }
  1158. return 0;
  1159. error:
  1160. for (i--; i >= 0; i--) {
  1161. struct v4l2_subdev *sd = &ispif->line[i].subdev;
  1162. v4l2_device_unregister_subdev(sd);
  1163. media_entity_cleanup(&sd->entity);
  1164. }
  1165. return ret;
  1166. }
  1167. /*
  1168. * msm_ispif_unregister_entities - Unregister ISPIF module subdev node
  1169. * @ispif: ISPIF device
  1170. */
  1171. void msm_ispif_unregister_entities(struct ispif_device *ispif)
  1172. {
  1173. int i;
  1174. mutex_destroy(&ispif->power_lock);
  1175. mutex_destroy(&ispif->config_lock);
  1176. for (i = 0; i < ispif->line_num; i++) {
  1177. struct v4l2_subdev *sd = &ispif->line[i].subdev;
  1178. v4l2_device_unregister_subdev(sd);
  1179. media_entity_cleanup(&sd->entity);
  1180. }
  1181. }