0083-media-starfive-Add-basic-driver.patch 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
  1. From 0dc93c9321ba947ac429baeb58202496e4b0f219 Mon Sep 17 00:00:00 2001
  2. From: Jack Zhu <[email protected]>
  3. Date: Fri, 12 May 2023 18:28:41 +0800
  4. Subject: [PATCH 083/122] media: starfive: Add basic driver
  5. Add basic platform driver for StarFive Camera Subsystem.
  6. Signed-off-by: Jack Zhu <[email protected]>
  7. Reviewed-by: Bryan O'Donoghue <[email protected]>
  8. ---
  9. drivers/media/platform/Kconfig | 1 +
  10. drivers/media/platform/Makefile | 1 +
  11. drivers/media/platform/starfive/Kconfig | 19 +
  12. drivers/media/platform/starfive/Makefile | 9 +
  13. drivers/media/platform/starfive/stf_camss.c | 372 +++++++++++++++++++
  14. drivers/media/platform/starfive/stf_camss.h | 153 ++++++++
  15. drivers/media/platform/starfive/stf_common.h | 18 +
  16. 7 files changed, 573 insertions(+)
  17. create mode 100644 drivers/media/platform/starfive/Kconfig
  18. create mode 100644 drivers/media/platform/starfive/Makefile
  19. create mode 100644 drivers/media/platform/starfive/stf_camss.c
  20. create mode 100644 drivers/media/platform/starfive/stf_camss.h
  21. create mode 100644 drivers/media/platform/starfive/stf_common.h
  22. --- a/drivers/media/platform/Kconfig
  23. +++ b/drivers/media/platform/Kconfig
  24. @@ -79,6 +79,7 @@ source "drivers/media/platform/renesas/K
  25. source "drivers/media/platform/rockchip/Kconfig"
  26. source "drivers/media/platform/samsung/Kconfig"
  27. source "drivers/media/platform/st/Kconfig"
  28. +source "drivers/media/platform/starfive/Kconfig"
  29. source "drivers/media/platform/sunxi/Kconfig"
  30. source "drivers/media/platform/ti/Kconfig"
  31. source "drivers/media/platform/verisilicon/Kconfig"
  32. --- a/drivers/media/platform/Makefile
  33. +++ b/drivers/media/platform/Makefile
  34. @@ -22,6 +22,7 @@ obj-y += renesas/
  35. obj-y += rockchip/
  36. obj-y += samsung/
  37. obj-y += st/
  38. +obj-y += starfive/
  39. obj-y += sunxi/
  40. obj-y += ti/
  41. obj-y += verisilicon/
  42. --- /dev/null
  43. +++ b/drivers/media/platform/starfive/Kconfig
  44. @@ -0,0 +1,19 @@
  45. +# SPDX-License-Identifier: GPL-2.0-only
  46. +
  47. +comment "Starfive media platform drivers"
  48. +
  49. +config VIDEO_STARFIVE_CAMSS
  50. + tristate "Starfive Camera Subsystem driver"
  51. + depends on V4L_PLATFORM_DRIVERS
  52. + depends on VIDEO_DEV && OF
  53. + depends on DMA_CMA
  54. + select MEDIA_CONTROLLER
  55. + select VIDEO_V4L2_SUBDEV_API
  56. + select VIDEOBUF2_DMA_CONTIG
  57. + select V4L2_FWNODE
  58. + help
  59. + Enable this to support for the Starfive Camera subsystem
  60. + found on Starfive JH7110 SoC.
  61. +
  62. + To compile this driver as a module, choose M here: the
  63. + module will be called stf-camss.
  64. --- /dev/null
  65. +++ b/drivers/media/platform/starfive/Makefile
  66. @@ -0,0 +1,9 @@
  67. +# SPDX-License-Identifier: GPL-2.0
  68. +#
  69. +# Makefile for StarFive camera subsystem driver.
  70. +#
  71. +
  72. +starfive-camss-objs += \
  73. + stf_camss.o
  74. +
  75. +obj-$(CONFIG_VIDEO_STARFIVE_CAMSS) += starfive-camss.o \
  76. --- /dev/null
  77. +++ b/drivers/media/platform/starfive/stf_camss.c
  78. @@ -0,0 +1,372 @@
  79. +// SPDX-License-Identifier: GPL-2.0
  80. +/*
  81. + * stf_camss.c
  82. + *
  83. + * Starfive Camera Subsystem driver
  84. + *
  85. + * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
  86. + */
  87. +#include <linux/module.h>
  88. +#include <linux/of.h>
  89. +#include <linux/of_graph.h>
  90. +#include <linux/platform_device.h>
  91. +#include <linux/pm_runtime.h>
  92. +#include <linux/videodev2.h>
  93. +#include <media/media-device.h>
  94. +#include <media/v4l2-async.h>
  95. +#include <media/v4l2-fwnode.h>
  96. +#include <media/v4l2-mc.h>
  97. +
  98. +#include "stf_camss.h"
  99. +
  100. +static const char * const stfcamss_clocks[] = {
  101. + "clk_apb_func",
  102. + "clk_wrapper_clk_c",
  103. + "clk_dvp_inv",
  104. + "clk_axiwr",
  105. + "clk_mipi_rx0_pxl",
  106. + "clk_ispcore_2x",
  107. + "clk_isp_axi",
  108. +};
  109. +
  110. +static const char * const stfcamss_resets[] = {
  111. + "rst_wrapper_p",
  112. + "rst_wrapper_c",
  113. + "rst_axird",
  114. + "rst_axiwr",
  115. + "rst_isp_top_n",
  116. + "rst_isp_top_axi",
  117. +};
  118. +
  119. +static int stfcamss_get_mem_res(struct platform_device *pdev,
  120. + struct stfcamss *stfcamss)
  121. +{
  122. + stfcamss->syscon_base =
  123. + devm_platform_ioremap_resource_byname(pdev, "syscon");
  124. + if (IS_ERR(stfcamss->syscon_base))
  125. + return PTR_ERR(stfcamss->syscon_base);
  126. +
  127. + stfcamss->isp_base =
  128. + devm_platform_ioremap_resource_byname(pdev, "isp");
  129. + if (IS_ERR(stfcamss->isp_base))
  130. + return PTR_ERR(stfcamss->isp_base);
  131. +
  132. + return 0;
  133. +}
  134. +
  135. +/*
  136. + * stfcamss_of_parse_endpoint_node - Parse port endpoint node
  137. + * @dev: Device
  138. + * @node: Device node to be parsed
  139. + * @csd: Parsed data from port endpoint node
  140. + *
  141. + * Return 0 on success or a negative error code on failure
  142. + */
  143. +static int stfcamss_of_parse_endpoint_node(struct device *dev,
  144. + struct device_node *node,
  145. + struct stfcamss_async_subdev *csd)
  146. +{
  147. + struct v4l2_fwnode_endpoint vep = { { 0 } };
  148. +
  149. + v4l2_fwnode_endpoint_parse(of_fwnode_handle(node), &vep);
  150. + dev_dbg(dev, "vep.base.port = 0x%x, id = 0x%x\n",
  151. + vep.base.port, vep.base.id);
  152. +
  153. + csd->port = vep.base.port;
  154. +
  155. + return 0;
  156. +}
  157. +
  158. +/*
  159. + * stfcamss_of_parse_ports - Parse ports node
  160. + * @stfcamss: STFCAMSS device
  161. + *
  162. + * Return number of "port" nodes found in "ports" node
  163. + */
  164. +static int stfcamss_of_parse_ports(struct stfcamss *stfcamss)
  165. +{
  166. + struct device *dev = stfcamss->dev;
  167. + struct device_node *node = NULL;
  168. + struct device_node *remote = NULL;
  169. + int ret, num_subdevs = 0;
  170. +
  171. + for_each_endpoint_of_node(dev->of_node, node) {
  172. + struct stfcamss_async_subdev *csd;
  173. +
  174. + if (!of_device_is_available(node))
  175. + continue;
  176. +
  177. + remote = of_graph_get_remote_port_parent(node);
  178. + if (!remote) {
  179. + dev_err(dev, "Cannot get remote parent\n");
  180. + ret = -EINVAL;
  181. + goto err_cleanup;
  182. + }
  183. +
  184. + csd = v4l2_async_nf_add_fwnode(&stfcamss->notifier,
  185. + of_fwnode_handle(remote),
  186. + struct stfcamss_async_subdev);
  187. + of_node_put(remote);
  188. + if (IS_ERR(csd)) {
  189. + ret = PTR_ERR(csd);
  190. + goto err_cleanup;
  191. + }
  192. +
  193. + ret = stfcamss_of_parse_endpoint_node(dev, node, csd);
  194. + if (ret < 0)
  195. + goto err_cleanup;
  196. +
  197. + num_subdevs++;
  198. + }
  199. +
  200. + return num_subdevs;
  201. +
  202. +err_cleanup:
  203. + of_node_put(node);
  204. + return ret;
  205. +}
  206. +
  207. +static int stfcamss_subdev_notifier_bound(struct v4l2_async_notifier *async,
  208. + struct v4l2_subdev *subdev,
  209. + struct v4l2_async_subdev *asd)
  210. +{
  211. + struct stfcamss *stfcamss =
  212. + container_of(async, struct stfcamss, notifier);
  213. + struct host_data *host_data = &stfcamss->host_data;
  214. + struct media_entity *source;
  215. + int i, j;
  216. +
  217. + source = &subdev->entity;
  218. +
  219. + for (i = 0; i < source->num_pads; i++) {
  220. + if (source->pads[i].flags & MEDIA_PAD_FL_SOURCE)
  221. + break;
  222. + }
  223. +
  224. + if (i == source->num_pads) {
  225. + dev_err(stfcamss->dev, "No source pad in external entity\n");
  226. + return -EINVAL;
  227. + }
  228. +
  229. + for (j = 0; host_data->host_entity[j] && (j < HOST_ENTITY_MAX); j++) {
  230. + struct media_entity *input;
  231. + int ret;
  232. +
  233. + input = host_data->host_entity[j];
  234. +
  235. + ret = media_create_pad_link(
  236. + source,
  237. + i,
  238. + input,
  239. + STF_PAD_SINK,
  240. + source->function == MEDIA_ENT_F_CAM_SENSOR ?
  241. + MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED :
  242. + 0);
  243. + if (ret < 0) {
  244. + dev_err(stfcamss->dev,
  245. + "Failed to link %s->%s entities: %d\n",
  246. + source->name, input->name, ret);
  247. + return ret;
  248. + }
  249. + }
  250. +
  251. + return 0;
  252. +}
  253. +
  254. +static int stfcamss_subdev_notifier_complete(struct v4l2_async_notifier *ntf)
  255. +{
  256. + struct stfcamss *stfcamss =
  257. + container_of(ntf, struct stfcamss, notifier);
  258. +
  259. + return v4l2_device_register_subdev_nodes(&stfcamss->v4l2_dev);
  260. +}
  261. +
  262. +static const struct v4l2_async_notifier_operations
  263. +stfcamss_subdev_notifier_ops = {
  264. + .bound = stfcamss_subdev_notifier_bound,
  265. + .complete = stfcamss_subdev_notifier_complete,
  266. +};
  267. +
  268. +static const struct media_device_ops stfcamss_media_ops = {
  269. + .link_notify = v4l2_pipeline_link_notify,
  270. +};
  271. +
  272. +static void stfcamss_mc_init(struct platform_device *pdev,
  273. + struct stfcamss *stfcamss)
  274. +{
  275. + stfcamss->media_dev.dev = stfcamss->dev;
  276. + strscpy(stfcamss->media_dev.model, "Starfive Camera Subsystem",
  277. + sizeof(stfcamss->media_dev.model));
  278. + snprintf(stfcamss->media_dev.bus_info,
  279. + sizeof(stfcamss->media_dev.bus_info),
  280. + "%s:%s", dev_bus_name(&pdev->dev), pdev->name);
  281. + stfcamss->media_dev.hw_revision = 0x01;
  282. + stfcamss->media_dev.ops = &stfcamss_media_ops;
  283. + media_device_init(&stfcamss->media_dev);
  284. +
  285. + stfcamss->v4l2_dev.mdev = &stfcamss->media_dev;
  286. +}
  287. +
  288. +/*
  289. + * stfcamss_probe - Probe STFCAMSS platform device
  290. + * @pdev: Pointer to STFCAMSS platform device
  291. + *
  292. + * Return 0 on success or a negative error code on failure
  293. + */
  294. +static int stfcamss_probe(struct platform_device *pdev)
  295. +{
  296. + struct stfcamss *stfcamss;
  297. + struct device *dev = &pdev->dev;
  298. + int ret = 0, i, num_subdevs;
  299. +
  300. + stfcamss = devm_kzalloc(dev, sizeof(*stfcamss), GFP_KERNEL);
  301. + if (!stfcamss)
  302. + return -ENOMEM;
  303. +
  304. + for (i = 0; i < ARRAY_SIZE(stfcamss->irq); ++i) {
  305. + stfcamss->irq[i] = platform_get_irq(pdev, i);
  306. + if (stfcamss->irq[i] < 0)
  307. + return dev_err_probe(&pdev->dev, stfcamss->irq[i],
  308. + "Failed to get clock%d", i);
  309. + }
  310. +
  311. + stfcamss->nclks = ARRAY_SIZE(stfcamss->sys_clk);
  312. + for (i = 0; i < ARRAY_SIZE(stfcamss->sys_clk); ++i)
  313. + stfcamss->sys_clk[i].id = stfcamss_clocks[i];
  314. + ret = devm_clk_bulk_get(dev, stfcamss->nclks, stfcamss->sys_clk);
  315. + if (ret) {
  316. + dev_err(dev, "Failed to get clk controls\n");
  317. + return ret;
  318. + }
  319. +
  320. + stfcamss->nrsts = ARRAY_SIZE(stfcamss->sys_rst);
  321. + for (i = 0; i < ARRAY_SIZE(stfcamss->sys_rst); ++i)
  322. + stfcamss->sys_rst[i].id = stfcamss_resets[i];
  323. + ret = devm_reset_control_bulk_get_shared(dev, stfcamss->nrsts,
  324. + stfcamss->sys_rst);
  325. + if (ret) {
  326. + dev_err(dev, "Failed to get reset controls\n");
  327. + return ret;
  328. + }
  329. +
  330. + ret = stfcamss_get_mem_res(pdev, stfcamss);
  331. + if (ret) {
  332. + dev_err(dev, "Could not map registers\n");
  333. + return ret;
  334. + }
  335. +
  336. + stfcamss->dev = dev;
  337. + platform_set_drvdata(pdev, stfcamss);
  338. +
  339. + v4l2_async_nf_init(&stfcamss->notifier);
  340. +
  341. + num_subdevs = stfcamss_of_parse_ports(stfcamss);
  342. + if (num_subdevs < 0) {
  343. + dev_err(dev, "Failed to find subdevices\n");
  344. + return -ENODEV;
  345. + }
  346. +
  347. + stfcamss_mc_init(pdev, stfcamss);
  348. +
  349. + ret = v4l2_device_register(stfcamss->dev, &stfcamss->v4l2_dev);
  350. + if (ret < 0) {
  351. + dev_err(dev, "Failed to register V4L2 device: %d\n", ret);
  352. + goto err_cleanup_notifier;
  353. + }
  354. +
  355. + ret = media_device_register(&stfcamss->media_dev);
  356. + if (ret) {
  357. + dev_err(dev, "Failed to register media device: %d\n", ret);
  358. + goto err_unregister_device;
  359. + }
  360. +
  361. + stfcamss->notifier.ops = &stfcamss_subdev_notifier_ops;
  362. + ret = v4l2_async_nf_register(&stfcamss->v4l2_dev, &stfcamss->notifier);
  363. + if (ret) {
  364. + dev_err(dev, "Failed to register async subdev nodes: %d\n",
  365. + ret);
  366. + goto err_unregister_media_dev;
  367. + }
  368. +
  369. + pm_runtime_enable(dev);
  370. +
  371. + return 0;
  372. +
  373. +err_unregister_media_dev:
  374. + media_device_unregister(&stfcamss->media_dev);
  375. +err_unregister_device:
  376. + v4l2_device_unregister(&stfcamss->v4l2_dev);
  377. +err_cleanup_notifier:
  378. + v4l2_async_nf_cleanup(&stfcamss->notifier);
  379. + return ret;
  380. +}
  381. +
  382. +/*
  383. + * stfcamss_remove - Remove STFCAMSS platform device
  384. + * @pdev: Pointer to STFCAMSS platform device
  385. + *
  386. + * Always returns 0.
  387. + */
  388. +static int stfcamss_remove(struct platform_device *pdev)
  389. +{
  390. + struct stfcamss *stfcamss = platform_get_drvdata(pdev);
  391. +
  392. + v4l2_device_unregister(&stfcamss->v4l2_dev);
  393. + media_device_cleanup(&stfcamss->media_dev);
  394. + pm_runtime_disable(&pdev->dev);
  395. +
  396. + return 0;
  397. +}
  398. +
  399. +static const struct of_device_id stfcamss_of_match[] = {
  400. + { .compatible = "starfive,jh7110-camss" },
  401. + { /* sentinel */ },
  402. +};
  403. +
  404. +MODULE_DEVICE_TABLE(of, stfcamss_of_match);
  405. +
  406. +static int __maybe_unused stfcamss_runtime_suspend(struct device *dev)
  407. +{
  408. + struct stfcamss *stfcamss = dev_get_drvdata(dev);
  409. +
  410. + reset_control_assert(stfcamss->sys_rst[STF_RST_ISP_TOP_AXI].rstc);
  411. + reset_control_assert(stfcamss->sys_rst[STF_RST_ISP_TOP_N].rstc);
  412. + clk_disable_unprepare(stfcamss->sys_clk[STF_CLK_ISP_AXI].clk);
  413. + clk_disable_unprepare(stfcamss->sys_clk[STF_CLK_ISPCORE_2X].clk);
  414. +
  415. + return 0;
  416. +}
  417. +
  418. +static int __maybe_unused stfcamss_runtime_resume(struct device *dev)
  419. +{
  420. + struct stfcamss *stfcamss = dev_get_drvdata(dev);
  421. +
  422. + clk_prepare_enable(stfcamss->sys_clk[STF_CLK_ISPCORE_2X].clk);
  423. + clk_prepare_enable(stfcamss->sys_clk[STF_CLK_ISP_AXI].clk);
  424. + reset_control_deassert(stfcamss->sys_rst[STF_RST_ISP_TOP_N].rstc);
  425. + reset_control_deassert(stfcamss->sys_rst[STF_RST_ISP_TOP_AXI].rstc);
  426. +
  427. + return 0;
  428. +}
  429. +
  430. +static const struct dev_pm_ops stfcamss_pm_ops = {
  431. + SET_RUNTIME_PM_OPS(stfcamss_runtime_suspend,
  432. + stfcamss_runtime_resume,
  433. + NULL)
  434. +};
  435. +
  436. +static struct platform_driver stfcamss_driver = {
  437. + .probe = stfcamss_probe,
  438. + .remove = stfcamss_remove,
  439. + .driver = {
  440. + .name = DRV_NAME,
  441. + .pm = &stfcamss_pm_ops,
  442. + .of_match_table = of_match_ptr(stfcamss_of_match),
  443. + },
  444. +};
  445. +
  446. +module_platform_driver(stfcamss_driver);
  447. +
  448. +MODULE_AUTHOR("StarFive Corporation");
  449. +MODULE_DESCRIPTION("StarFive Camera Subsystem driver");
  450. +MODULE_LICENSE("GPL");
  451. --- /dev/null
  452. +++ b/drivers/media/platform/starfive/stf_camss.h
  453. @@ -0,0 +1,153 @@
  454. +/* SPDX-License-Identifier: GPL-2.0 */
  455. +/*
  456. + * stf_camss.h
  457. + *
  458. + * Starfive Camera Subsystem driver
  459. + *
  460. + * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
  461. + */
  462. +
  463. +#ifndef STF_CAMSS_H
  464. +#define STF_CAMSS_H
  465. +
  466. +#include <linux/clk.h>
  467. +#include <linux/delay.h>
  468. +#include <linux/reset.h>
  469. +#include <media/v4l2-device.h>
  470. +
  471. +#include "stf_common.h"
  472. +
  473. +#define DRV_NAME "starfive-camss"
  474. +#define STF_DVP_NAME "stf_dvp"
  475. +#define STF_CSI_NAME "cdns_csi2rx"
  476. +#define STF_ISP_NAME "stf_isp"
  477. +#define STF_VIN_NAME "stf_vin"
  478. +
  479. +#define STF_PAD_SINK 0
  480. +#define STF_PAD_SRC 1
  481. +#define STF_PADS_NUM 2
  482. +
  483. +enum port_num {
  484. + PORT_NUMBER_DVP_SENSOR = 0,
  485. + PORT_NUMBER_CSI2RX
  486. +};
  487. +
  488. +enum stf_clk {
  489. + STF_CLK_APB_FUNC = 0,
  490. + STF_CLK_WRAPPER_CLK_C,
  491. + STF_CLK_DVP_INV,
  492. + STF_CLK_AXIWR,
  493. + STF_CLK_MIPI_RX0_PXL,
  494. + STF_CLK_ISPCORE_2X,
  495. + STF_CLK_ISP_AXI,
  496. + STF_CLK_NUM
  497. +};
  498. +
  499. +enum stf_rst {
  500. + STF_RST_WRAPPER_P = 0,
  501. + STF_RST_WRAPPER_C,
  502. + STF_RST_AXIRD,
  503. + STF_RST_AXIWR,
  504. + STF_RST_ISP_TOP_N,
  505. + STF_RST_ISP_TOP_AXI,
  506. + STF_RST_NUM
  507. +};
  508. +
  509. +enum stf_irq {
  510. + STF_IRQ_VINWR = 0,
  511. + STF_IRQ_ISP,
  512. + STF_IRQ_ISPCSIL,
  513. + STF_IRQ_NUM
  514. +};
  515. +
  516. +#define HOST_ENTITY_MAX 2
  517. +
  518. +struct host_data {
  519. + struct media_entity *host_entity[HOST_ENTITY_MAX];
  520. +};
  521. +
  522. +struct stfcamss {
  523. + struct v4l2_device v4l2_dev;
  524. + struct media_device media_dev;
  525. + struct media_pipeline pipe;
  526. + struct device *dev;
  527. + struct v4l2_async_notifier notifier;
  528. + struct host_data host_data;
  529. + void __iomem *syscon_base;
  530. + void __iomem *isp_base;
  531. + int irq[STF_IRQ_NUM];
  532. + struct clk_bulk_data sys_clk[STF_CLK_NUM];
  533. + int nclks;
  534. + struct reset_control_bulk_data sys_rst[STF_RST_NUM];
  535. + int nrsts;
  536. +};
  537. +
  538. +struct stfcamss_async_subdev {
  539. + struct v4l2_async_subdev asd; /* must be first */
  540. + enum port_num port;
  541. +};
  542. +
  543. +static inline u32 stf_isp_reg_read(struct stfcamss *stfcamss, u32 reg)
  544. +{
  545. + return ioread32(stfcamss->isp_base + reg);
  546. +}
  547. +
  548. +static inline void stf_isp_reg_write(struct stfcamss *stfcamss,
  549. + u32 reg, u32 val)
  550. +{
  551. + iowrite32(val, stfcamss->isp_base + reg);
  552. +}
  553. +
  554. +static inline void stf_isp_reg_write_delay(struct stfcamss *stfcamss,
  555. + u32 reg, u32 val, u32 delay)
  556. +{
  557. + iowrite32(val, stfcamss->isp_base + reg);
  558. + usleep_range(1000 * delay, 1000 * delay + 100);
  559. +}
  560. +
  561. +static inline void stf_isp_reg_set_bit(struct stfcamss *stfcamss,
  562. + u32 reg, u32 mask, u32 val)
  563. +{
  564. + u32 value;
  565. +
  566. + value = ioread32(stfcamss->isp_base + reg) & ~mask;
  567. + val &= mask;
  568. + val |= value;
  569. + iowrite32(val, stfcamss->isp_base + reg);
  570. +}
  571. +
  572. +static inline void stf_isp_reg_set(struct stfcamss *stfcamss, u32 reg, u32 mask)
  573. +{
  574. + iowrite32(ioread32(stfcamss->isp_base + reg) | mask,
  575. + stfcamss->isp_base + reg);
  576. +}
  577. +
  578. +static inline u32 stf_syscon_reg_read(struct stfcamss *stfcamss, u32 reg)
  579. +{
  580. + return ioread32(stfcamss->syscon_base + reg);
  581. +}
  582. +
  583. +static inline void stf_syscon_reg_write(struct stfcamss *stfcamss,
  584. + u32 reg, u32 val)
  585. +{
  586. + iowrite32(val, stfcamss->syscon_base + reg);
  587. +}
  588. +
  589. +static inline void stf_syscon_reg_set_bit(struct stfcamss *stfcamss,
  590. + u32 reg, u32 bit_mask)
  591. +{
  592. + u32 value;
  593. +
  594. + value = ioread32(stfcamss->syscon_base + reg);
  595. + iowrite32(value | bit_mask, stfcamss->syscon_base + reg);
  596. +}
  597. +
  598. +static inline void stf_syscon_reg_clear_bit(struct stfcamss *stfcamss,
  599. + u32 reg, u32 bit_mask)
  600. +{
  601. + u32 value;
  602. +
  603. + value = ioread32(stfcamss->syscon_base + reg);
  604. + iowrite32(value & ~bit_mask, stfcamss->syscon_base + reg);
  605. +}
  606. +#endif /* STF_CAMSS_H */
  607. --- /dev/null
  608. +++ b/drivers/media/platform/starfive/stf_common.h
  609. @@ -0,0 +1,18 @@
  610. +/* SPDX-License-Identifier: GPL-2.0 */
  611. +/*
  612. + * stf_common.h
  613. + *
  614. + * StarFive Camera Subsystem - Common definitions
  615. + *
  616. + * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
  617. + */
  618. +
  619. +#ifndef STF_COMMON_H
  620. +#define STF_COMMON_H
  621. +
  622. +enum stf_subdev_type {
  623. + STF_SUBDEV_TYPE_VIN,
  624. + STF_SUBDEV_TYPE_ISP,
  625. +};
  626. +
  627. +#endif /* STF_COMMON_H */