camss-csid.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * camss-csid.c
  4. *
  5. * Qualcomm MSM Camera Subsystem - CSID (CSI Decoder) Module
  6. *
  7. * Copyright (c) 2011-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/kernel.h>
  15. #include <linux/of.h>
  16. #include <linux/platform_device.h>
  17. #include <linux/pm_runtime.h>
  18. #include <linux/regulator/consumer.h>
  19. #include <media/media-entity.h>
  20. #include <media/v4l2-device.h>
  21. #include <media/v4l2-event.h>
  22. #include <media/v4l2-subdev.h>
  23. #include "camss-csid.h"
  24. #include "camss.h"
  25. #define MSM_CSID_NAME "msm_csid"
  26. #define CAMSS_CSID_HW_VERSION 0x0
  27. #define CAMSS_CSID_CORE_CTRL_0 0x004
  28. #define CAMSS_CSID_CORE_CTRL_1 0x008
  29. #define CAMSS_CSID_RST_CMD(v) ((v) == CAMSS_8x16 ? 0x00c : 0x010)
  30. #define CAMSS_CSID_CID_LUT_VC_n(v, n) \
  31. (((v) == CAMSS_8x16 ? 0x010 : 0x014) + 0x4 * (n))
  32. #define CAMSS_CSID_CID_n_CFG(v, n) \
  33. (((v) == CAMSS_8x16 ? 0x020 : 0x024) + 0x4 * (n))
  34. #define CAMSS_CSID_CID_n_CFG_ISPIF_EN BIT(0)
  35. #define CAMSS_CSID_CID_n_CFG_RDI_EN BIT(1)
  36. #define CAMSS_CSID_CID_n_CFG_DECODE_FORMAT_SHIFT 4
  37. #define CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_8 (0 << 8)
  38. #define CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_16 (1 << 8)
  39. #define CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_LSB (0 << 9)
  40. #define CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_MSB (1 << 9)
  41. #define CAMSS_CSID_CID_n_CFG_RDI_MODE_RAW_DUMP (0 << 10)
  42. #define CAMSS_CSID_CID_n_CFG_RDI_MODE_PLAIN_PACKING (1 << 10)
  43. #define CAMSS_CSID_IRQ_CLEAR_CMD(v) ((v) == CAMSS_8x16 ? 0x060 : 0x064)
  44. #define CAMSS_CSID_IRQ_MASK(v) ((v) == CAMSS_8x16 ? 0x064 : 0x068)
  45. #define CAMSS_CSID_IRQ_STATUS(v) ((v) == CAMSS_8x16 ? 0x068 : 0x06c)
  46. #define CAMSS_CSID_TG_CTRL(v) ((v) == CAMSS_8x16 ? 0x0a0 : 0x0a8)
  47. #define CAMSS_CSID_TG_CTRL_DISABLE 0xa06436
  48. #define CAMSS_CSID_TG_CTRL_ENABLE 0xa06437
  49. #define CAMSS_CSID_TG_VC_CFG(v) ((v) == CAMSS_8x16 ? 0x0a4 : 0x0ac)
  50. #define CAMSS_CSID_TG_VC_CFG_H_BLANKING 0x3ff
  51. #define CAMSS_CSID_TG_VC_CFG_V_BLANKING 0x7f
  52. #define CAMSS_CSID_TG_DT_n_CGG_0(v, n) \
  53. (((v) == CAMSS_8x16 ? 0x0ac : 0x0b4) + 0xc * (n))
  54. #define CAMSS_CSID_TG_DT_n_CGG_1(v, n) \
  55. (((v) == CAMSS_8x16 ? 0x0b0 : 0x0b8) + 0xc * (n))
  56. #define CAMSS_CSID_TG_DT_n_CGG_2(v, n) \
  57. (((v) == CAMSS_8x16 ? 0x0b4 : 0x0bc) + 0xc * (n))
  58. #define DATA_TYPE_EMBEDDED_DATA_8BIT 0x12
  59. #define DATA_TYPE_YUV422_8BIT 0x1e
  60. #define DATA_TYPE_RAW_6BIT 0x28
  61. #define DATA_TYPE_RAW_8BIT 0x2a
  62. #define DATA_TYPE_RAW_10BIT 0x2b
  63. #define DATA_TYPE_RAW_12BIT 0x2c
  64. #define DATA_TYPE_RAW_14BIT 0x2d
  65. #define DECODE_FORMAT_UNCOMPRESSED_6_BIT 0x0
  66. #define DECODE_FORMAT_UNCOMPRESSED_8_BIT 0x1
  67. #define DECODE_FORMAT_UNCOMPRESSED_10_BIT 0x2
  68. #define DECODE_FORMAT_UNCOMPRESSED_12_BIT 0x3
  69. #define DECODE_FORMAT_UNCOMPRESSED_14_BIT 0x8
  70. #define CSID_RESET_TIMEOUT_MS 500
  71. struct csid_format {
  72. u32 code;
  73. u8 data_type;
  74. u8 decode_format;
  75. u8 bpp;
  76. u8 spp; /* bus samples per pixel */
  77. };
  78. static const struct csid_format csid_formats_8x16[] = {
  79. {
  80. MEDIA_BUS_FMT_UYVY8_2X8,
  81. DATA_TYPE_YUV422_8BIT,
  82. DECODE_FORMAT_UNCOMPRESSED_8_BIT,
  83. 8,
  84. 2,
  85. },
  86. {
  87. MEDIA_BUS_FMT_VYUY8_2X8,
  88. DATA_TYPE_YUV422_8BIT,
  89. DECODE_FORMAT_UNCOMPRESSED_8_BIT,
  90. 8,
  91. 2,
  92. },
  93. {
  94. MEDIA_BUS_FMT_YUYV8_2X8,
  95. DATA_TYPE_YUV422_8BIT,
  96. DECODE_FORMAT_UNCOMPRESSED_8_BIT,
  97. 8,
  98. 2,
  99. },
  100. {
  101. MEDIA_BUS_FMT_YVYU8_2X8,
  102. DATA_TYPE_YUV422_8BIT,
  103. DECODE_FORMAT_UNCOMPRESSED_8_BIT,
  104. 8,
  105. 2,
  106. },
  107. {
  108. MEDIA_BUS_FMT_SBGGR8_1X8,
  109. DATA_TYPE_RAW_8BIT,
  110. DECODE_FORMAT_UNCOMPRESSED_8_BIT,
  111. 8,
  112. 1,
  113. },
  114. {
  115. MEDIA_BUS_FMT_SGBRG8_1X8,
  116. DATA_TYPE_RAW_8BIT,
  117. DECODE_FORMAT_UNCOMPRESSED_8_BIT,
  118. 8,
  119. 1,
  120. },
  121. {
  122. MEDIA_BUS_FMT_SGRBG8_1X8,
  123. DATA_TYPE_RAW_8BIT,
  124. DECODE_FORMAT_UNCOMPRESSED_8_BIT,
  125. 8,
  126. 1,
  127. },
  128. {
  129. MEDIA_BUS_FMT_SRGGB8_1X8,
  130. DATA_TYPE_RAW_8BIT,
  131. DECODE_FORMAT_UNCOMPRESSED_8_BIT,
  132. 8,
  133. 1,
  134. },
  135. {
  136. MEDIA_BUS_FMT_SBGGR10_1X10,
  137. DATA_TYPE_RAW_10BIT,
  138. DECODE_FORMAT_UNCOMPRESSED_10_BIT,
  139. 10,
  140. 1,
  141. },
  142. {
  143. MEDIA_BUS_FMT_SGBRG10_1X10,
  144. DATA_TYPE_RAW_10BIT,
  145. DECODE_FORMAT_UNCOMPRESSED_10_BIT,
  146. 10,
  147. 1,
  148. },
  149. {
  150. MEDIA_BUS_FMT_SGRBG10_1X10,
  151. DATA_TYPE_RAW_10BIT,
  152. DECODE_FORMAT_UNCOMPRESSED_10_BIT,
  153. 10,
  154. 1,
  155. },
  156. {
  157. MEDIA_BUS_FMT_SRGGB10_1X10,
  158. DATA_TYPE_RAW_10BIT,
  159. DECODE_FORMAT_UNCOMPRESSED_10_BIT,
  160. 10,
  161. 1,
  162. },
  163. {
  164. MEDIA_BUS_FMT_SBGGR12_1X12,
  165. DATA_TYPE_RAW_12BIT,
  166. DECODE_FORMAT_UNCOMPRESSED_12_BIT,
  167. 12,
  168. 1,
  169. },
  170. {
  171. MEDIA_BUS_FMT_SGBRG12_1X12,
  172. DATA_TYPE_RAW_12BIT,
  173. DECODE_FORMAT_UNCOMPRESSED_12_BIT,
  174. 12,
  175. 1,
  176. },
  177. {
  178. MEDIA_BUS_FMT_SGRBG12_1X12,
  179. DATA_TYPE_RAW_12BIT,
  180. DECODE_FORMAT_UNCOMPRESSED_12_BIT,
  181. 12,
  182. 1,
  183. },
  184. {
  185. MEDIA_BUS_FMT_SRGGB12_1X12,
  186. DATA_TYPE_RAW_12BIT,
  187. DECODE_FORMAT_UNCOMPRESSED_12_BIT,
  188. 12,
  189. 1,
  190. },
  191. {
  192. MEDIA_BUS_FMT_Y10_1X10,
  193. DATA_TYPE_RAW_10BIT,
  194. DECODE_FORMAT_UNCOMPRESSED_10_BIT,
  195. 10,
  196. 1,
  197. },
  198. };
  199. static const struct csid_format csid_formats_8x96[] = {
  200. {
  201. MEDIA_BUS_FMT_UYVY8_2X8,
  202. DATA_TYPE_YUV422_8BIT,
  203. DECODE_FORMAT_UNCOMPRESSED_8_BIT,
  204. 8,
  205. 2,
  206. },
  207. {
  208. MEDIA_BUS_FMT_VYUY8_2X8,
  209. DATA_TYPE_YUV422_8BIT,
  210. DECODE_FORMAT_UNCOMPRESSED_8_BIT,
  211. 8,
  212. 2,
  213. },
  214. {
  215. MEDIA_BUS_FMT_YUYV8_2X8,
  216. DATA_TYPE_YUV422_8BIT,
  217. DECODE_FORMAT_UNCOMPRESSED_8_BIT,
  218. 8,
  219. 2,
  220. },
  221. {
  222. MEDIA_BUS_FMT_YVYU8_2X8,
  223. DATA_TYPE_YUV422_8BIT,
  224. DECODE_FORMAT_UNCOMPRESSED_8_BIT,
  225. 8,
  226. 2,
  227. },
  228. {
  229. MEDIA_BUS_FMT_SBGGR8_1X8,
  230. DATA_TYPE_RAW_8BIT,
  231. DECODE_FORMAT_UNCOMPRESSED_8_BIT,
  232. 8,
  233. 1,
  234. },
  235. {
  236. MEDIA_BUS_FMT_SGBRG8_1X8,
  237. DATA_TYPE_RAW_8BIT,
  238. DECODE_FORMAT_UNCOMPRESSED_8_BIT,
  239. 8,
  240. 1,
  241. },
  242. {
  243. MEDIA_BUS_FMT_SGRBG8_1X8,
  244. DATA_TYPE_RAW_8BIT,
  245. DECODE_FORMAT_UNCOMPRESSED_8_BIT,
  246. 8,
  247. 1,
  248. },
  249. {
  250. MEDIA_BUS_FMT_SRGGB8_1X8,
  251. DATA_TYPE_RAW_8BIT,
  252. DECODE_FORMAT_UNCOMPRESSED_8_BIT,
  253. 8,
  254. 1,
  255. },
  256. {
  257. MEDIA_BUS_FMT_SBGGR10_1X10,
  258. DATA_TYPE_RAW_10BIT,
  259. DECODE_FORMAT_UNCOMPRESSED_10_BIT,
  260. 10,
  261. 1,
  262. },
  263. {
  264. MEDIA_BUS_FMT_SGBRG10_1X10,
  265. DATA_TYPE_RAW_10BIT,
  266. DECODE_FORMAT_UNCOMPRESSED_10_BIT,
  267. 10,
  268. 1,
  269. },
  270. {
  271. MEDIA_BUS_FMT_SGRBG10_1X10,
  272. DATA_TYPE_RAW_10BIT,
  273. DECODE_FORMAT_UNCOMPRESSED_10_BIT,
  274. 10,
  275. 1,
  276. },
  277. {
  278. MEDIA_BUS_FMT_SRGGB10_1X10,
  279. DATA_TYPE_RAW_10BIT,
  280. DECODE_FORMAT_UNCOMPRESSED_10_BIT,
  281. 10,
  282. 1,
  283. },
  284. {
  285. MEDIA_BUS_FMT_SBGGR12_1X12,
  286. DATA_TYPE_RAW_12BIT,
  287. DECODE_FORMAT_UNCOMPRESSED_12_BIT,
  288. 12,
  289. 1,
  290. },
  291. {
  292. MEDIA_BUS_FMT_SGBRG12_1X12,
  293. DATA_TYPE_RAW_12BIT,
  294. DECODE_FORMAT_UNCOMPRESSED_12_BIT,
  295. 12,
  296. 1,
  297. },
  298. {
  299. MEDIA_BUS_FMT_SGRBG12_1X12,
  300. DATA_TYPE_RAW_12BIT,
  301. DECODE_FORMAT_UNCOMPRESSED_12_BIT,
  302. 12,
  303. 1,
  304. },
  305. {
  306. MEDIA_BUS_FMT_SRGGB12_1X12,
  307. DATA_TYPE_RAW_12BIT,
  308. DECODE_FORMAT_UNCOMPRESSED_12_BIT,
  309. 12,
  310. 1,
  311. },
  312. {
  313. MEDIA_BUS_FMT_SBGGR14_1X14,
  314. DATA_TYPE_RAW_14BIT,
  315. DECODE_FORMAT_UNCOMPRESSED_14_BIT,
  316. 14,
  317. 1,
  318. },
  319. {
  320. MEDIA_BUS_FMT_SGBRG14_1X14,
  321. DATA_TYPE_RAW_14BIT,
  322. DECODE_FORMAT_UNCOMPRESSED_14_BIT,
  323. 14,
  324. 1,
  325. },
  326. {
  327. MEDIA_BUS_FMT_SGRBG14_1X14,
  328. DATA_TYPE_RAW_14BIT,
  329. DECODE_FORMAT_UNCOMPRESSED_14_BIT,
  330. 14,
  331. 1,
  332. },
  333. {
  334. MEDIA_BUS_FMT_SRGGB14_1X14,
  335. DATA_TYPE_RAW_14BIT,
  336. DECODE_FORMAT_UNCOMPRESSED_14_BIT,
  337. 14,
  338. 1,
  339. },
  340. {
  341. MEDIA_BUS_FMT_Y10_1X10,
  342. DATA_TYPE_RAW_10BIT,
  343. DECODE_FORMAT_UNCOMPRESSED_10_BIT,
  344. 10,
  345. 1,
  346. },
  347. };
  348. static u32 csid_find_code(u32 *code, unsigned int n_code,
  349. unsigned int index, u32 req_code)
  350. {
  351. int i;
  352. if (!req_code && (index >= n_code))
  353. return 0;
  354. for (i = 0; i < n_code; i++)
  355. if (req_code) {
  356. if (req_code == code[i])
  357. return req_code;
  358. } else {
  359. if (i == index)
  360. return code[i];
  361. }
  362. return code[0];
  363. }
  364. static u32 csid_src_pad_code(struct csid_device *csid, u32 sink_code,
  365. unsigned int index, u32 src_req_code)
  366. {
  367. if (csid->camss->version == CAMSS_8x16) {
  368. if (index > 0)
  369. return 0;
  370. return sink_code;
  371. } else if (csid->camss->version == CAMSS_8x96) {
  372. switch (sink_code) {
  373. case MEDIA_BUS_FMT_SBGGR10_1X10:
  374. {
  375. u32 src_code[] = {
  376. MEDIA_BUS_FMT_SBGGR10_1X10,
  377. MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE,
  378. };
  379. return csid_find_code(src_code, ARRAY_SIZE(src_code),
  380. index, src_req_code);
  381. }
  382. case MEDIA_BUS_FMT_Y10_1X10:
  383. {
  384. u32 src_code[] = {
  385. MEDIA_BUS_FMT_Y10_1X10,
  386. MEDIA_BUS_FMT_Y10_2X8_PADHI_LE,
  387. };
  388. return csid_find_code(src_code, ARRAY_SIZE(src_code),
  389. index, src_req_code);
  390. }
  391. default:
  392. if (index > 0)
  393. return 0;
  394. return sink_code;
  395. }
  396. } else {
  397. return 0;
  398. }
  399. }
  400. static const struct csid_format *csid_get_fmt_entry(
  401. const struct csid_format *formats,
  402. unsigned int nformat,
  403. u32 code)
  404. {
  405. unsigned int i;
  406. for (i = 0; i < nformat; i++)
  407. if (code == formats[i].code)
  408. return &formats[i];
  409. WARN(1, "Unknown format\n");
  410. return &formats[0];
  411. }
  412. /*
  413. * csid_isr - CSID module interrupt handler
  414. * @irq: Interrupt line
  415. * @dev: CSID device
  416. *
  417. * Return IRQ_HANDLED on success
  418. */
  419. static irqreturn_t csid_isr(int irq, void *dev)
  420. {
  421. struct csid_device *csid = dev;
  422. enum camss_version ver = csid->camss->version;
  423. u32 value;
  424. value = readl_relaxed(csid->base + CAMSS_CSID_IRQ_STATUS(ver));
  425. writel_relaxed(value, csid->base + CAMSS_CSID_IRQ_CLEAR_CMD(ver));
  426. if ((value >> 11) & 0x1)
  427. complete(&csid->reset_complete);
  428. return IRQ_HANDLED;
  429. }
  430. /*
  431. * csid_set_clock_rates - Calculate and set clock rates on CSID module
  432. * @csiphy: CSID device
  433. */
  434. static int csid_set_clock_rates(struct csid_device *csid)
  435. {
  436. struct device *dev = csid->camss->dev;
  437. u32 pixel_clock;
  438. int i, j;
  439. int ret;
  440. ret = camss_get_pixel_clock(&csid->subdev.entity, &pixel_clock);
  441. if (ret)
  442. pixel_clock = 0;
  443. for (i = 0; i < csid->nclocks; i++) {
  444. struct camss_clock *clock = &csid->clock[i];
  445. if (!strcmp(clock->name, "csi0") ||
  446. !strcmp(clock->name, "csi1") ||
  447. !strcmp(clock->name, "csi2") ||
  448. !strcmp(clock->name, "csi3")) {
  449. const struct csid_format *f = csid_get_fmt_entry(
  450. csid->formats,
  451. csid->nformats,
  452. csid->fmt[MSM_CSIPHY_PAD_SINK].code);
  453. u8 num_lanes = csid->phy.lane_cnt;
  454. u64 min_rate = pixel_clock * f->bpp /
  455. (2 * num_lanes * 4);
  456. long rate;
  457. camss_add_clock_margin(&min_rate);
  458. for (j = 0; j < clock->nfreqs; j++)
  459. if (min_rate < clock->freq[j])
  460. break;
  461. if (j == clock->nfreqs) {
  462. dev_err(dev,
  463. "Pixel clock is too high for CSID\n");
  464. return -EINVAL;
  465. }
  466. /* if sensor pixel clock is not available */
  467. /* set highest possible CSID clock rate */
  468. if (min_rate == 0)
  469. j = clock->nfreqs - 1;
  470. rate = clk_round_rate(clock->clk, clock->freq[j]);
  471. if (rate < 0) {
  472. dev_err(dev, "clk round rate failed: %ld\n",
  473. rate);
  474. return -EINVAL;
  475. }
  476. ret = clk_set_rate(clock->clk, rate);
  477. if (ret < 0) {
  478. dev_err(dev, "clk set rate failed: %d\n", ret);
  479. return ret;
  480. }
  481. }
  482. }
  483. return 0;
  484. }
  485. /*
  486. * csid_reset - Trigger reset on CSID module and wait to complete
  487. * @csid: CSID device
  488. *
  489. * Return 0 on success or a negative error code otherwise
  490. */
  491. static int csid_reset(struct csid_device *csid)
  492. {
  493. unsigned long time;
  494. reinit_completion(&csid->reset_complete);
  495. writel_relaxed(0x7fff, csid->base +
  496. CAMSS_CSID_RST_CMD(csid->camss->version));
  497. time = wait_for_completion_timeout(&csid->reset_complete,
  498. msecs_to_jiffies(CSID_RESET_TIMEOUT_MS));
  499. if (!time) {
  500. dev_err(csid->camss->dev, "CSID reset timeout\n");
  501. return -EIO;
  502. }
  503. return 0;
  504. }
  505. /*
  506. * csid_set_power - Power on/off CSID module
  507. * @sd: CSID V4L2 subdevice
  508. * @on: Requested power state
  509. *
  510. * Return 0 on success or a negative error code otherwise
  511. */
  512. static int csid_set_power(struct v4l2_subdev *sd, int on)
  513. {
  514. struct csid_device *csid = v4l2_get_subdevdata(sd);
  515. struct device *dev = csid->camss->dev;
  516. int ret;
  517. if (on) {
  518. u32 hw_version;
  519. ret = pm_runtime_get_sync(dev);
  520. if (ret < 0)
  521. return ret;
  522. ret = regulator_enable(csid->vdda);
  523. if (ret < 0) {
  524. pm_runtime_put_sync(dev);
  525. return ret;
  526. }
  527. ret = csid_set_clock_rates(csid);
  528. if (ret < 0) {
  529. regulator_disable(csid->vdda);
  530. pm_runtime_put_sync(dev);
  531. return ret;
  532. }
  533. ret = camss_enable_clocks(csid->nclocks, csid->clock, dev);
  534. if (ret < 0) {
  535. regulator_disable(csid->vdda);
  536. pm_runtime_put_sync(dev);
  537. return ret;
  538. }
  539. enable_irq(csid->irq);
  540. ret = csid_reset(csid);
  541. if (ret < 0) {
  542. disable_irq(csid->irq);
  543. camss_disable_clocks(csid->nclocks, csid->clock);
  544. regulator_disable(csid->vdda);
  545. pm_runtime_put_sync(dev);
  546. return ret;
  547. }
  548. hw_version = readl_relaxed(csid->base + CAMSS_CSID_HW_VERSION);
  549. dev_dbg(dev, "CSID HW Version = 0x%08x\n", hw_version);
  550. } else {
  551. disable_irq(csid->irq);
  552. camss_disable_clocks(csid->nclocks, csid->clock);
  553. ret = regulator_disable(csid->vdda);
  554. pm_runtime_put_sync(dev);
  555. }
  556. return ret;
  557. }
  558. /*
  559. * csid_set_stream - Enable/disable streaming on CSID module
  560. * @sd: CSID V4L2 subdevice
  561. * @enable: Requested streaming state
  562. *
  563. * Main configuration of CSID module is also done here.
  564. *
  565. * Return 0 on success or a negative error code otherwise
  566. */
  567. static int csid_set_stream(struct v4l2_subdev *sd, int enable)
  568. {
  569. struct csid_device *csid = v4l2_get_subdevdata(sd);
  570. struct csid_testgen_config *tg = &csid->testgen;
  571. enum camss_version ver = csid->camss->version;
  572. u32 val;
  573. if (enable) {
  574. u8 vc = 0; /* Virtual Channel 0 */
  575. u8 cid = vc * 4; /* id of Virtual Channel and Data Type set */
  576. u8 dt, dt_shift, df;
  577. int ret;
  578. ret = v4l2_ctrl_handler_setup(&csid->ctrls);
  579. if (ret < 0) {
  580. dev_err(csid->camss->dev,
  581. "could not sync v4l2 controls: %d\n", ret);
  582. return ret;
  583. }
  584. if (!tg->enabled &&
  585. !media_entity_remote_pad(&csid->pads[MSM_CSID_PAD_SINK]))
  586. return -ENOLINK;
  587. if (tg->enabled) {
  588. /* Config Test Generator */
  589. struct v4l2_mbus_framefmt *f =
  590. &csid->fmt[MSM_CSID_PAD_SRC];
  591. const struct csid_format *format = csid_get_fmt_entry(
  592. csid->formats, csid->nformats, f->code);
  593. u32 num_bytes_per_line =
  594. f->width * format->bpp * format->spp / 8;
  595. u32 num_lines = f->height;
  596. /* 31:24 V blank, 23:13 H blank, 3:2 num of active DT */
  597. /* 1:0 VC */
  598. val = ((CAMSS_CSID_TG_VC_CFG_V_BLANKING & 0xff) << 24) |
  599. ((CAMSS_CSID_TG_VC_CFG_H_BLANKING & 0x7ff) << 13);
  600. writel_relaxed(val, csid->base +
  601. CAMSS_CSID_TG_VC_CFG(ver));
  602. /* 28:16 bytes per lines, 12:0 num of lines */
  603. val = ((num_bytes_per_line & 0x1fff) << 16) |
  604. (num_lines & 0x1fff);
  605. writel_relaxed(val, csid->base +
  606. CAMSS_CSID_TG_DT_n_CGG_0(ver, 0));
  607. dt = format->data_type;
  608. /* 5:0 data type */
  609. val = dt;
  610. writel_relaxed(val, csid->base +
  611. CAMSS_CSID_TG_DT_n_CGG_1(ver, 0));
  612. /* 2:0 output test pattern */
  613. val = tg->payload_mode;
  614. writel_relaxed(val, csid->base +
  615. CAMSS_CSID_TG_DT_n_CGG_2(ver, 0));
  616. df = format->decode_format;
  617. } else {
  618. struct v4l2_mbus_framefmt *f =
  619. &csid->fmt[MSM_CSID_PAD_SINK];
  620. const struct csid_format *format = csid_get_fmt_entry(
  621. csid->formats, csid->nformats, f->code);
  622. struct csid_phy_config *phy = &csid->phy;
  623. val = phy->lane_cnt - 1;
  624. val |= phy->lane_assign << 4;
  625. writel_relaxed(val,
  626. csid->base + CAMSS_CSID_CORE_CTRL_0);
  627. val = phy->csiphy_id << 17;
  628. val |= 0x9;
  629. writel_relaxed(val,
  630. csid->base + CAMSS_CSID_CORE_CTRL_1);
  631. dt = format->data_type;
  632. df = format->decode_format;
  633. }
  634. /* Config LUT */
  635. dt_shift = (cid % 4) * 8;
  636. val = readl_relaxed(csid->base +
  637. CAMSS_CSID_CID_LUT_VC_n(ver, vc));
  638. val &= ~(0xff << dt_shift);
  639. val |= dt << dt_shift;
  640. writel_relaxed(val, csid->base +
  641. CAMSS_CSID_CID_LUT_VC_n(ver, vc));
  642. val = CAMSS_CSID_CID_n_CFG_ISPIF_EN;
  643. val |= CAMSS_CSID_CID_n_CFG_RDI_EN;
  644. val |= df << CAMSS_CSID_CID_n_CFG_DECODE_FORMAT_SHIFT;
  645. val |= CAMSS_CSID_CID_n_CFG_RDI_MODE_RAW_DUMP;
  646. if (csid->camss->version == CAMSS_8x96) {
  647. u32 sink_code = csid->fmt[MSM_CSID_PAD_SINK].code;
  648. u32 src_code = csid->fmt[MSM_CSID_PAD_SRC].code;
  649. if ((sink_code == MEDIA_BUS_FMT_SBGGR10_1X10 &&
  650. src_code == MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE) ||
  651. (sink_code == MEDIA_BUS_FMT_Y10_1X10 &&
  652. src_code == MEDIA_BUS_FMT_Y10_2X8_PADHI_LE)) {
  653. val |= CAMSS_CSID_CID_n_CFG_RDI_MODE_PLAIN_PACKING;
  654. val |= CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_16;
  655. val |= CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_LSB;
  656. }
  657. }
  658. writel_relaxed(val, csid->base +
  659. CAMSS_CSID_CID_n_CFG(ver, cid));
  660. if (tg->enabled) {
  661. val = CAMSS_CSID_TG_CTRL_ENABLE;
  662. writel_relaxed(val, csid->base +
  663. CAMSS_CSID_TG_CTRL(ver));
  664. }
  665. } else {
  666. if (tg->enabled) {
  667. val = CAMSS_CSID_TG_CTRL_DISABLE;
  668. writel_relaxed(val, csid->base +
  669. CAMSS_CSID_TG_CTRL(ver));
  670. }
  671. }
  672. return 0;
  673. }
  674. /*
  675. * __csid_get_format - Get pointer to format structure
  676. * @csid: CSID device
  677. * @cfg: V4L2 subdev pad configuration
  678. * @pad: pad from which format is requested
  679. * @which: TRY or ACTIVE format
  680. *
  681. * Return pointer to TRY or ACTIVE format structure
  682. */
  683. static struct v4l2_mbus_framefmt *
  684. __csid_get_format(struct csid_device *csid,
  685. struct v4l2_subdev_pad_config *cfg,
  686. unsigned int pad,
  687. enum v4l2_subdev_format_whence which)
  688. {
  689. if (which == V4L2_SUBDEV_FORMAT_TRY)
  690. return v4l2_subdev_get_try_format(&csid->subdev, cfg, pad);
  691. return &csid->fmt[pad];
  692. }
  693. /*
  694. * csid_try_format - Handle try format by pad subdev method
  695. * @csid: CSID device
  696. * @cfg: V4L2 subdev pad configuration
  697. * @pad: pad on which format is requested
  698. * @fmt: pointer to v4l2 format structure
  699. * @which: wanted subdev format
  700. */
  701. static void csid_try_format(struct csid_device *csid,
  702. struct v4l2_subdev_pad_config *cfg,
  703. unsigned int pad,
  704. struct v4l2_mbus_framefmt *fmt,
  705. enum v4l2_subdev_format_whence which)
  706. {
  707. unsigned int i;
  708. switch (pad) {
  709. case MSM_CSID_PAD_SINK:
  710. /* Set format on sink pad */
  711. for (i = 0; i < csid->nformats; i++)
  712. if (fmt->code == csid->formats[i].code)
  713. break;
  714. /* If not found, use UYVY as default */
  715. if (i >= csid->nformats)
  716. fmt->code = MEDIA_BUS_FMT_UYVY8_2X8;
  717. fmt->width = clamp_t(u32, fmt->width, 1, 8191);
  718. fmt->height = clamp_t(u32, fmt->height, 1, 8191);
  719. fmt->field = V4L2_FIELD_NONE;
  720. fmt->colorspace = V4L2_COLORSPACE_SRGB;
  721. break;
  722. case MSM_CSID_PAD_SRC:
  723. if (csid->testgen_mode->cur.val == 0) {
  724. /* Test generator is disabled, */
  725. /* keep pad formats in sync */
  726. u32 code = fmt->code;
  727. *fmt = *__csid_get_format(csid, cfg,
  728. MSM_CSID_PAD_SINK, which);
  729. fmt->code = csid_src_pad_code(csid, fmt->code, 0, code);
  730. } else {
  731. /* Test generator is enabled, set format on source */
  732. /* pad to allow test generator usage */
  733. for (i = 0; i < csid->nformats; i++)
  734. if (csid->formats[i].code == fmt->code)
  735. break;
  736. /* If not found, use UYVY as default */
  737. if (i >= csid->nformats)
  738. fmt->code = MEDIA_BUS_FMT_UYVY8_2X8;
  739. fmt->width = clamp_t(u32, fmt->width, 1, 8191);
  740. fmt->height = clamp_t(u32, fmt->height, 1, 8191);
  741. fmt->field = V4L2_FIELD_NONE;
  742. }
  743. break;
  744. }
  745. fmt->colorspace = V4L2_COLORSPACE_SRGB;
  746. }
  747. /*
  748. * csid_enum_mbus_code - Handle pixel format enumeration
  749. * @sd: CSID V4L2 subdevice
  750. * @cfg: V4L2 subdev pad configuration
  751. * @code: pointer to v4l2_subdev_mbus_code_enum structure
  752. * return -EINVAL or zero on success
  753. */
  754. static int csid_enum_mbus_code(struct v4l2_subdev *sd,
  755. struct v4l2_subdev_pad_config *cfg,
  756. struct v4l2_subdev_mbus_code_enum *code)
  757. {
  758. struct csid_device *csid = v4l2_get_subdevdata(sd);
  759. if (code->pad == MSM_CSID_PAD_SINK) {
  760. if (code->index >= csid->nformats)
  761. return -EINVAL;
  762. code->code = csid->formats[code->index].code;
  763. } else {
  764. if (csid->testgen_mode->cur.val == 0) {
  765. struct v4l2_mbus_framefmt *sink_fmt;
  766. sink_fmt = __csid_get_format(csid, cfg,
  767. MSM_CSID_PAD_SINK,
  768. code->which);
  769. code->code = csid_src_pad_code(csid, sink_fmt->code,
  770. code->index, 0);
  771. if (!code->code)
  772. return -EINVAL;
  773. } else {
  774. if (code->index >= csid->nformats)
  775. return -EINVAL;
  776. code->code = csid->formats[code->index].code;
  777. }
  778. }
  779. return 0;
  780. }
  781. /*
  782. * csid_enum_frame_size - Handle frame size enumeration
  783. * @sd: CSID V4L2 subdevice
  784. * @cfg: V4L2 subdev pad configuration
  785. * @fse: pointer to v4l2_subdev_frame_size_enum structure
  786. * return -EINVAL or zero on success
  787. */
  788. static int csid_enum_frame_size(struct v4l2_subdev *sd,
  789. struct v4l2_subdev_pad_config *cfg,
  790. struct v4l2_subdev_frame_size_enum *fse)
  791. {
  792. struct csid_device *csid = v4l2_get_subdevdata(sd);
  793. struct v4l2_mbus_framefmt format;
  794. if (fse->index != 0)
  795. return -EINVAL;
  796. format.code = fse->code;
  797. format.width = 1;
  798. format.height = 1;
  799. csid_try_format(csid, cfg, fse->pad, &format, fse->which);
  800. fse->min_width = format.width;
  801. fse->min_height = format.height;
  802. if (format.code != fse->code)
  803. return -EINVAL;
  804. format.code = fse->code;
  805. format.width = -1;
  806. format.height = -1;
  807. csid_try_format(csid, cfg, fse->pad, &format, fse->which);
  808. fse->max_width = format.width;
  809. fse->max_height = format.height;
  810. return 0;
  811. }
  812. /*
  813. * csid_get_format - Handle get format by pads subdev method
  814. * @sd: CSID V4L2 subdevice
  815. * @cfg: V4L2 subdev pad configuration
  816. * @fmt: pointer to v4l2 subdev format structure
  817. *
  818. * Return -EINVAL or zero on success
  819. */
  820. static int csid_get_format(struct v4l2_subdev *sd,
  821. struct v4l2_subdev_pad_config *cfg,
  822. struct v4l2_subdev_format *fmt)
  823. {
  824. struct csid_device *csid = v4l2_get_subdevdata(sd);
  825. struct v4l2_mbus_framefmt *format;
  826. format = __csid_get_format(csid, cfg, fmt->pad, fmt->which);
  827. if (format == NULL)
  828. return -EINVAL;
  829. fmt->format = *format;
  830. return 0;
  831. }
  832. /*
  833. * csid_set_format - Handle set format by pads subdev method
  834. * @sd: CSID V4L2 subdevice
  835. * @cfg: V4L2 subdev pad configuration
  836. * @fmt: pointer to v4l2 subdev format structure
  837. *
  838. * Return -EINVAL or zero on success
  839. */
  840. static int csid_set_format(struct v4l2_subdev *sd,
  841. struct v4l2_subdev_pad_config *cfg,
  842. struct v4l2_subdev_format *fmt)
  843. {
  844. struct csid_device *csid = v4l2_get_subdevdata(sd);
  845. struct v4l2_mbus_framefmt *format;
  846. format = __csid_get_format(csid, cfg, fmt->pad, fmt->which);
  847. if (format == NULL)
  848. return -EINVAL;
  849. csid_try_format(csid, cfg, fmt->pad, &fmt->format, fmt->which);
  850. *format = fmt->format;
  851. /* Propagate the format from sink to source */
  852. if (fmt->pad == MSM_CSID_PAD_SINK) {
  853. format = __csid_get_format(csid, cfg, MSM_CSID_PAD_SRC,
  854. fmt->which);
  855. *format = fmt->format;
  856. csid_try_format(csid, cfg, MSM_CSID_PAD_SRC, format,
  857. fmt->which);
  858. }
  859. return 0;
  860. }
  861. /*
  862. * csid_init_formats - Initialize formats on all pads
  863. * @sd: CSID V4L2 subdevice
  864. * @fh: V4L2 subdev file handle
  865. *
  866. * Initialize all pad formats with default values.
  867. *
  868. * Return 0 on success or a negative error code otherwise
  869. */
  870. static int csid_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
  871. {
  872. struct v4l2_subdev_format format = {
  873. .pad = MSM_CSID_PAD_SINK,
  874. .which = fh ? V4L2_SUBDEV_FORMAT_TRY :
  875. V4L2_SUBDEV_FORMAT_ACTIVE,
  876. .format = {
  877. .code = MEDIA_BUS_FMT_UYVY8_2X8,
  878. .width = 1920,
  879. .height = 1080
  880. }
  881. };
  882. return csid_set_format(sd, fh ? fh->pad : NULL, &format);
  883. }
  884. static const char * const csid_test_pattern_menu[] = {
  885. "Disabled",
  886. "Incrementing",
  887. "Alternating 0x55/0xAA",
  888. "All Zeros 0x00",
  889. "All Ones 0xFF",
  890. "Pseudo-random Data",
  891. };
  892. /*
  893. * csid_set_test_pattern - Set test generator's pattern mode
  894. * @csid: CSID device
  895. * @value: desired test pattern mode
  896. *
  897. * Return 0 on success or a negative error code otherwise
  898. */
  899. static int csid_set_test_pattern(struct csid_device *csid, s32 value)
  900. {
  901. struct csid_testgen_config *tg = &csid->testgen;
  902. /* If CSID is linked to CSIPHY, do not allow to enable test generator */
  903. if (value && media_entity_remote_pad(&csid->pads[MSM_CSID_PAD_SINK]))
  904. return -EBUSY;
  905. tg->enabled = !!value;
  906. switch (value) {
  907. case 1:
  908. tg->payload_mode = CSID_PAYLOAD_MODE_INCREMENTING;
  909. break;
  910. case 2:
  911. tg->payload_mode = CSID_PAYLOAD_MODE_ALTERNATING_55_AA;
  912. break;
  913. case 3:
  914. tg->payload_mode = CSID_PAYLOAD_MODE_ALL_ZEROES;
  915. break;
  916. case 4:
  917. tg->payload_mode = CSID_PAYLOAD_MODE_ALL_ONES;
  918. break;
  919. case 5:
  920. tg->payload_mode = CSID_PAYLOAD_MODE_RANDOM;
  921. break;
  922. }
  923. return 0;
  924. }
  925. /*
  926. * csid_s_ctrl - Handle set control subdev method
  927. * @ctrl: pointer to v4l2 control structure
  928. *
  929. * Return 0 on success or a negative error code otherwise
  930. */
  931. static int csid_s_ctrl(struct v4l2_ctrl *ctrl)
  932. {
  933. struct csid_device *csid = container_of(ctrl->handler,
  934. struct csid_device, ctrls);
  935. int ret = -EINVAL;
  936. switch (ctrl->id) {
  937. case V4L2_CID_TEST_PATTERN:
  938. ret = csid_set_test_pattern(csid, ctrl->val);
  939. break;
  940. }
  941. return ret;
  942. }
  943. static const struct v4l2_ctrl_ops csid_ctrl_ops = {
  944. .s_ctrl = csid_s_ctrl,
  945. };
  946. /*
  947. * msm_csid_subdev_init - Initialize CSID device structure and resources
  948. * @csid: CSID device
  949. * @res: CSID module resources table
  950. * @id: CSID module id
  951. *
  952. * Return 0 on success or a negative error code otherwise
  953. */
  954. int msm_csid_subdev_init(struct camss *camss, struct csid_device *csid,
  955. const struct resources *res, u8 id)
  956. {
  957. struct device *dev = camss->dev;
  958. struct platform_device *pdev = to_platform_device(dev);
  959. struct resource *r;
  960. int i, j;
  961. int ret;
  962. csid->camss = camss;
  963. csid->id = id;
  964. if (camss->version == CAMSS_8x16) {
  965. csid->formats = csid_formats_8x16;
  966. csid->nformats =
  967. ARRAY_SIZE(csid_formats_8x16);
  968. } else if (camss->version == CAMSS_8x96) {
  969. csid->formats = csid_formats_8x96;
  970. csid->nformats =
  971. ARRAY_SIZE(csid_formats_8x96);
  972. } else {
  973. return -EINVAL;
  974. }
  975. /* Memory */
  976. r = platform_get_resource_byname(pdev, IORESOURCE_MEM, res->reg[0]);
  977. csid->base = devm_ioremap_resource(dev, r);
  978. if (IS_ERR(csid->base)) {
  979. dev_err(dev, "could not map memory\n");
  980. return PTR_ERR(csid->base);
  981. }
  982. /* Interrupt */
  983. r = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
  984. res->interrupt[0]);
  985. if (!r) {
  986. dev_err(dev, "missing IRQ\n");
  987. return -EINVAL;
  988. }
  989. csid->irq = r->start;
  990. snprintf(csid->irq_name, sizeof(csid->irq_name), "%s_%s%d",
  991. dev_name(dev), MSM_CSID_NAME, csid->id);
  992. ret = devm_request_irq(dev, csid->irq, csid_isr,
  993. IRQF_TRIGGER_RISING, csid->irq_name, csid);
  994. if (ret < 0) {
  995. dev_err(dev, "request_irq failed: %d\n", ret);
  996. return ret;
  997. }
  998. disable_irq(csid->irq);
  999. /* Clocks */
  1000. csid->nclocks = 0;
  1001. while (res->clock[csid->nclocks])
  1002. csid->nclocks++;
  1003. csid->clock = devm_kcalloc(dev, csid->nclocks, sizeof(*csid->clock),
  1004. GFP_KERNEL);
  1005. if (!csid->clock)
  1006. return -ENOMEM;
  1007. for (i = 0; i < csid->nclocks; i++) {
  1008. struct camss_clock *clock = &csid->clock[i];
  1009. clock->clk = devm_clk_get(dev, res->clock[i]);
  1010. if (IS_ERR(clock->clk))
  1011. return PTR_ERR(clock->clk);
  1012. clock->name = res->clock[i];
  1013. clock->nfreqs = 0;
  1014. while (res->clock_rate[i][clock->nfreqs])
  1015. clock->nfreqs++;
  1016. if (!clock->nfreqs) {
  1017. clock->freq = NULL;
  1018. continue;
  1019. }
  1020. clock->freq = devm_kcalloc(dev,
  1021. clock->nfreqs,
  1022. sizeof(*clock->freq),
  1023. GFP_KERNEL);
  1024. if (!clock->freq)
  1025. return -ENOMEM;
  1026. for (j = 0; j < clock->nfreqs; j++)
  1027. clock->freq[j] = res->clock_rate[i][j];
  1028. }
  1029. /* Regulator */
  1030. csid->vdda = devm_regulator_get(dev, res->regulator[0]);
  1031. if (IS_ERR(csid->vdda)) {
  1032. dev_err(dev, "could not get regulator\n");
  1033. return PTR_ERR(csid->vdda);
  1034. }
  1035. init_completion(&csid->reset_complete);
  1036. return 0;
  1037. }
  1038. /*
  1039. * msm_csid_get_csid_id - Get CSID HW module id
  1040. * @entity: Pointer to CSID media entity structure
  1041. * @id: Return CSID HW module id here
  1042. */
  1043. void msm_csid_get_csid_id(struct media_entity *entity, u8 *id)
  1044. {
  1045. struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
  1046. struct csid_device *csid = v4l2_get_subdevdata(sd);
  1047. *id = csid->id;
  1048. }
  1049. /*
  1050. * csid_get_lane_assign - Calculate CSI2 lane assign configuration parameter
  1051. * @lane_cfg - CSI2 lane configuration
  1052. *
  1053. * Return lane assign
  1054. */
  1055. static u32 csid_get_lane_assign(struct csiphy_lanes_cfg *lane_cfg)
  1056. {
  1057. u32 lane_assign = 0;
  1058. int i;
  1059. for (i = 0; i < lane_cfg->num_data; i++)
  1060. lane_assign |= lane_cfg->data[i].pos << (i * 4);
  1061. return lane_assign;
  1062. }
  1063. /*
  1064. * csid_link_setup - Setup CSID connections
  1065. * @entity: Pointer to media entity structure
  1066. * @local: Pointer to local pad
  1067. * @remote: Pointer to remote pad
  1068. * @flags: Link flags
  1069. *
  1070. * Return 0 on success
  1071. */
  1072. static int csid_link_setup(struct media_entity *entity,
  1073. const struct media_pad *local,
  1074. const struct media_pad *remote, u32 flags)
  1075. {
  1076. if (flags & MEDIA_LNK_FL_ENABLED)
  1077. if (media_entity_remote_pad(local))
  1078. return -EBUSY;
  1079. if ((local->flags & MEDIA_PAD_FL_SINK) &&
  1080. (flags & MEDIA_LNK_FL_ENABLED)) {
  1081. struct v4l2_subdev *sd;
  1082. struct csid_device *csid;
  1083. struct csiphy_device *csiphy;
  1084. struct csiphy_lanes_cfg *lane_cfg;
  1085. struct v4l2_subdev_format format = { 0 };
  1086. sd = media_entity_to_v4l2_subdev(entity);
  1087. csid = v4l2_get_subdevdata(sd);
  1088. /* If test generator is enabled */
  1089. /* do not allow a link from CSIPHY to CSID */
  1090. if (csid->testgen_mode->cur.val != 0)
  1091. return -EBUSY;
  1092. sd = media_entity_to_v4l2_subdev(remote->entity);
  1093. csiphy = v4l2_get_subdevdata(sd);
  1094. /* If a sensor is not linked to CSIPHY */
  1095. /* do no allow a link from CSIPHY to CSID */
  1096. if (!csiphy->cfg.csi2)
  1097. return -EPERM;
  1098. csid->phy.csiphy_id = csiphy->id;
  1099. lane_cfg = &csiphy->cfg.csi2->lane_cfg;
  1100. csid->phy.lane_cnt = lane_cfg->num_data;
  1101. csid->phy.lane_assign = csid_get_lane_assign(lane_cfg);
  1102. /* Reset format on source pad to sink pad format */
  1103. format.pad = MSM_CSID_PAD_SRC;
  1104. format.which = V4L2_SUBDEV_FORMAT_ACTIVE;
  1105. csid_set_format(&csid->subdev, NULL, &format);
  1106. }
  1107. return 0;
  1108. }
  1109. static const struct v4l2_subdev_core_ops csid_core_ops = {
  1110. .s_power = csid_set_power,
  1111. .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
  1112. .unsubscribe_event = v4l2_event_subdev_unsubscribe,
  1113. };
  1114. static const struct v4l2_subdev_video_ops csid_video_ops = {
  1115. .s_stream = csid_set_stream,
  1116. };
  1117. static const struct v4l2_subdev_pad_ops csid_pad_ops = {
  1118. .enum_mbus_code = csid_enum_mbus_code,
  1119. .enum_frame_size = csid_enum_frame_size,
  1120. .get_fmt = csid_get_format,
  1121. .set_fmt = csid_set_format,
  1122. };
  1123. static const struct v4l2_subdev_ops csid_v4l2_ops = {
  1124. .core = &csid_core_ops,
  1125. .video = &csid_video_ops,
  1126. .pad = &csid_pad_ops,
  1127. };
  1128. static const struct v4l2_subdev_internal_ops csid_v4l2_internal_ops = {
  1129. .open = csid_init_formats,
  1130. };
  1131. static const struct media_entity_operations csid_media_ops = {
  1132. .link_setup = csid_link_setup,
  1133. .link_validate = v4l2_subdev_link_validate,
  1134. };
  1135. /*
  1136. * msm_csid_register_entity - Register subdev node for CSID module
  1137. * @csid: CSID device
  1138. * @v4l2_dev: V4L2 device
  1139. *
  1140. * Return 0 on success or a negative error code otherwise
  1141. */
  1142. int msm_csid_register_entity(struct csid_device *csid,
  1143. struct v4l2_device *v4l2_dev)
  1144. {
  1145. struct v4l2_subdev *sd = &csid->subdev;
  1146. struct media_pad *pads = csid->pads;
  1147. struct device *dev = csid->camss->dev;
  1148. int ret;
  1149. v4l2_subdev_init(sd, &csid_v4l2_ops);
  1150. sd->internal_ops = &csid_v4l2_internal_ops;
  1151. sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
  1152. V4L2_SUBDEV_FL_HAS_EVENTS;
  1153. snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d",
  1154. MSM_CSID_NAME, csid->id);
  1155. v4l2_set_subdevdata(sd, csid);
  1156. ret = v4l2_ctrl_handler_init(&csid->ctrls, 1);
  1157. if (ret < 0) {
  1158. dev_err(dev, "Failed to init ctrl handler: %d\n", ret);
  1159. return ret;
  1160. }
  1161. csid->testgen_mode = v4l2_ctrl_new_std_menu_items(&csid->ctrls,
  1162. &csid_ctrl_ops, V4L2_CID_TEST_PATTERN,
  1163. ARRAY_SIZE(csid_test_pattern_menu) - 1, 0, 0,
  1164. csid_test_pattern_menu);
  1165. if (csid->ctrls.error) {
  1166. dev_err(dev, "Failed to init ctrl: %d\n", csid->ctrls.error);
  1167. ret = csid->ctrls.error;
  1168. goto free_ctrl;
  1169. }
  1170. csid->subdev.ctrl_handler = &csid->ctrls;
  1171. ret = csid_init_formats(sd, NULL);
  1172. if (ret < 0) {
  1173. dev_err(dev, "Failed to init format: %d\n", ret);
  1174. goto free_ctrl;
  1175. }
  1176. pads[MSM_CSID_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
  1177. pads[MSM_CSID_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE;
  1178. sd->entity.function = MEDIA_ENT_F_IO_V4L;
  1179. sd->entity.ops = &csid_media_ops;
  1180. ret = media_entity_pads_init(&sd->entity, MSM_CSID_PADS_NUM, pads);
  1181. if (ret < 0) {
  1182. dev_err(dev, "Failed to init media entity: %d\n", ret);
  1183. goto free_ctrl;
  1184. }
  1185. ret = v4l2_device_register_subdev(v4l2_dev, sd);
  1186. if (ret < 0) {
  1187. dev_err(dev, "Failed to register subdev: %d\n", ret);
  1188. goto media_cleanup;
  1189. }
  1190. return 0;
  1191. media_cleanup:
  1192. media_entity_cleanup(&sd->entity);
  1193. free_ctrl:
  1194. v4l2_ctrl_handler_free(&csid->ctrls);
  1195. return ret;
  1196. }
  1197. /*
  1198. * msm_csid_unregister_entity - Unregister CSID module subdev node
  1199. * @csid: CSID device
  1200. */
  1201. void msm_csid_unregister_entity(struct csid_device *csid)
  1202. {
  1203. v4l2_device_unregister_subdev(&csid->subdev);
  1204. media_entity_cleanup(&csid->subdev.entity);
  1205. v4l2_ctrl_handler_free(&csid->ctrls);
  1206. }