1 // SPDX-License-Identifier: GPL-2.0
3 * Driver for STM32 Digital Camera Memory Interface Pixel Processor
5 * Copyright (C) STMicroelectronics SA 2023
8 * for STMicroelectronics.
11 #include <linux/clk.h>
12 #include <linux/delay.h>
13 #include <linux/init.h>
14 #include <linux/module.h>
15 #include <linux/pinctrl/consumer.h>
16 #include <linux/platform_device.h>
17 #include <linux/pm_runtime.h>
18 #include <linux/property.h>
19 #include <linux/reset.h>
20 #include <media/media-device.h>
21 #include <media/v4l2-device.h>
22 #include <media/v4l2-fwnode.h>
24 #include "dcmipp-common.h"
26 #define DCMIPP_MDEV_MODEL_NAME "DCMIPP MDEV"
28 #define DCMIPP_ENT_LINK(src, srcpad, sink, sinkpad, link_flags) { \
32 .sink_pad = sinkpad, \
33 .flags = link_flags, \
36 struct dcmipp_device {
37 /* The platform device */
38 struct platform_device pdev;
41 /* Hardware resources */
45 /* The pipeline configuration */
46 const struct dcmipp_pipeline_config *pipe_cfg;
48 /* The Associated media_device parent */
49 struct media_device mdev;
51 /* Internal v4l2 parent device*/
52 struct v4l2_device v4l2_dev;
55 struct dcmipp_ent_device **entity;
57 struct v4l2_async_notifier notifier;
60 static inline struct dcmipp_device *
61 notifier_to_dcmipp(struct v4l2_async_notifier *n)
63 return container_of(n, struct dcmipp_device, notifier);
66 /* Structure which describes individual configuration for each entity */
67 struct dcmipp_ent_config {
69 struct dcmipp_ent_device *(*init)
70 (struct device *dev, const char *entity_name,
71 struct v4l2_device *v4l2_dev, void __iomem *regs);
72 void (*release)(struct dcmipp_ent_device *ved);
75 /* Structure which describes links between entities */
76 struct dcmipp_ent_link {
79 unsigned int sink_ent;
84 /* Structure which describes the whole topology */
85 struct dcmipp_pipeline_config {
86 const struct dcmipp_ent_config *ents;
88 const struct dcmipp_ent_link *links;
92 /* --------------------------------------------------------------------------
93 * Topology Configuration
96 static const struct dcmipp_ent_config stm32mp13_ent_config[] = {
98 .name = "dcmipp_parallel",
99 .init = dcmipp_par_ent_init,
100 .release = dcmipp_par_ent_release,
103 .name = "dcmipp_dump_postproc",
104 .init = dcmipp_byteproc_ent_init,
105 .release = dcmipp_byteproc_ent_release,
108 .name = "dcmipp_dump_capture",
109 .init = dcmipp_bytecap_ent_init,
110 .release = dcmipp_bytecap_ent_release,
114 #define ID_PARALLEL 0
115 #define ID_DUMP_BYTEPROC 1
116 #define ID_DUMP_CAPTURE 2
118 static const struct dcmipp_ent_link stm32mp13_ent_links[] = {
119 DCMIPP_ENT_LINK(ID_PARALLEL, 1, ID_DUMP_BYTEPROC, 0,
120 MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE),
121 DCMIPP_ENT_LINK(ID_DUMP_BYTEPROC, 1, ID_DUMP_CAPTURE, 0,
122 MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE),
125 static const struct dcmipp_pipeline_config stm32mp13_pipe_cfg = {
126 .ents = stm32mp13_ent_config,
127 .num_ents = ARRAY_SIZE(stm32mp13_ent_config),
128 .links = stm32mp13_ent_links,
129 .num_links = ARRAY_SIZE(stm32mp13_ent_links)
132 #define LINK_FLAG_TO_STR(f) ((f) == 0 ? "" :\
133 (f) == MEDIA_LNK_FL_ENABLED ? "ENABLED" :\
134 (f) == MEDIA_LNK_FL_IMMUTABLE ? "IMMUTABLE" :\
135 (f) == (MEDIA_LNK_FL_ENABLED |\
136 MEDIA_LNK_FL_IMMUTABLE) ?\
137 "ENABLED, IMMUTABLE" :\
140 static int dcmipp_create_links(struct dcmipp_device *dcmipp)
145 /* Initialize the links between entities */
146 for (i = 0; i < dcmipp->pipe_cfg->num_links; i++) {
147 const struct dcmipp_ent_link *link =
148 &dcmipp->pipe_cfg->links[i];
149 struct dcmipp_ent_device *ved_src =
150 dcmipp->entity[link->src_ent];
151 struct dcmipp_ent_device *ved_sink =
152 dcmipp->entity[link->sink_ent];
154 dev_dbg(dcmipp->dev, "Create link \"%s\":%d -> %d:\"%s\" [%s]\n",
155 dcmipp->pipe_cfg->ents[link->src_ent].name,
156 link->src_pad, link->sink_pad,
157 dcmipp->pipe_cfg->ents[link->sink_ent].name,
158 LINK_FLAG_TO_STR(link->flags));
160 ret = media_create_pad_link(ved_src->ent, link->src_pad,
161 ved_sink->ent, link->sink_pad,
170 static int dcmipp_graph_init(struct dcmipp_device *dcmipp);
172 static int dcmipp_create_subdevs(struct dcmipp_device *dcmipp)
176 /* Call all subdev inits */
177 for (i = 0; i < dcmipp->pipe_cfg->num_ents; i++) {
178 const char *name = dcmipp->pipe_cfg->ents[i].name;
180 dev_dbg(dcmipp->dev, "add subdev %s\n", name);
182 dcmipp->pipe_cfg->ents[i].init(dcmipp->dev, name,
185 if (IS_ERR(dcmipp->entity[i])) {
186 dev_err(dcmipp->dev, "failed to init subdev %s\n",
188 ret = PTR_ERR(dcmipp->entity[i]);
189 goto err_init_entity;
193 /* Initialize links */
194 ret = dcmipp_create_links(dcmipp);
196 goto err_init_entity;
198 ret = dcmipp_graph_init(dcmipp);
200 goto err_init_entity;
206 dcmipp->pipe_cfg->ents[i].release(dcmipp->entity[i]);
210 static const struct of_device_id dcmipp_of_match[] = {
211 { .compatible = "st,stm32mp13-dcmipp", .data = &stm32mp13_pipe_cfg },
214 MODULE_DEVICE_TABLE(of, dcmipp_of_match);
216 static irqreturn_t dcmipp_irq_thread(int irq, void *arg)
218 struct dcmipp_device *dcmipp = arg;
219 struct dcmipp_ent_device *ved;
222 /* Call irq thread of each entities of pipeline */
223 for (i = 0; i < dcmipp->pipe_cfg->num_ents; i++) {
224 ved = dcmipp->entity[i];
225 if (ved->thread_fn && ved->handler_ret == IRQ_WAKE_THREAD)
226 ved->thread_fn(irq, ved);
232 static irqreturn_t dcmipp_irq_callback(int irq, void *arg)
234 struct dcmipp_device *dcmipp = arg;
235 struct dcmipp_ent_device *ved;
236 irqreturn_t ret = IRQ_HANDLED;
239 /* Call irq handler of each entities of pipeline */
240 for (i = 0; i < dcmipp->pipe_cfg->num_ents; i++) {
241 ved = dcmipp->entity[i];
243 ved->handler_ret = ved->handler(irq, ved);
244 else if (ved->thread_fn)
245 ved->handler_ret = IRQ_WAKE_THREAD;
247 ved->handler_ret = IRQ_HANDLED;
248 if (ved->handler_ret != IRQ_HANDLED)
249 ret = ved->handler_ret;
255 static int dcmipp_graph_notify_bound(struct v4l2_async_notifier *notifier,
256 struct v4l2_subdev *subdev,
257 struct v4l2_async_connection *asd)
259 struct dcmipp_device *dcmipp = notifier_to_dcmipp(notifier);
262 struct dcmipp_ent_device *sink;
263 struct v4l2_fwnode_endpoint vep = { .bus_type = V4L2_MBUS_PARALLEL };
264 struct fwnode_handle *ep;
266 dev_dbg(dcmipp->dev, "Subdev \"%s\" bound\n", subdev->name);
269 * Link this sub-device to DCMIPP, it could be
270 * a parallel camera sensor or a CSI-2 to parallel bridge
272 src_pad = media_entity_get_fwnode_pad(&subdev->entity,
274 MEDIA_PAD_FL_SOURCE);
276 /* Get bus characteristics from devicetree */
277 ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(dcmipp->dev), 0, 0,
278 FWNODE_GRAPH_ENDPOINT_NEXT);
280 dev_err(dcmipp->dev, "Could not find the endpoint\n");
284 /* Check for parallel bus-type first, then bt656 */
285 ret = v4l2_fwnode_endpoint_parse(ep, &vep);
287 vep.bus_type = V4L2_MBUS_BT656;
288 ret = v4l2_fwnode_endpoint_parse(ep, &vep);
290 dev_err(dcmipp->dev, "Could not parse the endpoint\n");
291 fwnode_handle_put(ep);
296 fwnode_handle_put(ep);
298 if (vep.bus.parallel.bus_width == 0) {
299 dev_err(dcmipp->dev, "Invalid parallel interface bus-width\n");
303 /* Only 8 bits bus width supported with BT656 bus */
304 if (vep.bus_type == V4L2_MBUS_BT656 &&
305 vep.bus.parallel.bus_width != 8) {
306 dev_err(dcmipp->dev, "BT656 bus conflicts with %u bits bus width (8 bits required)\n",
307 vep.bus.parallel.bus_width);
311 /* Parallel input device detected, connect it to parallel subdev */
312 sink = dcmipp->entity[ID_PARALLEL];
313 sink->bus.flags = vep.bus.parallel.flags;
314 sink->bus.bus_width = vep.bus.parallel.bus_width;
315 sink->bus.data_shift = vep.bus.parallel.data_shift;
316 sink->bus_type = vep.bus_type;
317 ret = media_create_pad_link(&subdev->entity, src_pad, sink->ent, 0,
318 MEDIA_LNK_FL_IMMUTABLE |
319 MEDIA_LNK_FL_ENABLED);
321 dev_err(dcmipp->dev, "Failed to create media pad link with subdev \"%s\"\n",
326 dev_dbg(dcmipp->dev, "DCMIPP is now linked to \"%s\"\n", subdev->name);
331 static void dcmipp_graph_notify_unbind(struct v4l2_async_notifier *notifier,
332 struct v4l2_subdev *sd,
333 struct v4l2_async_connection *asd)
335 struct dcmipp_device *dcmipp = notifier_to_dcmipp(notifier);
337 dev_dbg(dcmipp->dev, "Removing %s\n", sd->name);
340 static int dcmipp_graph_notify_complete(struct v4l2_async_notifier *notifier)
342 struct dcmipp_device *dcmipp = notifier_to_dcmipp(notifier);
345 /* Register the media device */
346 ret = media_device_register(&dcmipp->mdev);
348 dev_err(dcmipp->mdev.dev,
349 "media device register failed (err=%d)\n", ret);
353 /* Expose all subdev's nodes*/
354 ret = v4l2_device_register_subdev_nodes(&dcmipp->v4l2_dev);
356 dev_err(dcmipp->mdev.dev,
357 "dcmipp subdev nodes registration failed (err=%d)\n",
359 media_device_unregister(&dcmipp->mdev);
363 dev_dbg(dcmipp->dev, "Notify complete !\n");
368 static const struct v4l2_async_notifier_operations dcmipp_graph_notify_ops = {
369 .bound = dcmipp_graph_notify_bound,
370 .unbind = dcmipp_graph_notify_unbind,
371 .complete = dcmipp_graph_notify_complete,
374 static int dcmipp_graph_init(struct dcmipp_device *dcmipp)
376 struct v4l2_async_connection *asd;
377 struct fwnode_handle *ep;
380 ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(dcmipp->dev), 0, 0,
381 FWNODE_GRAPH_ENDPOINT_NEXT);
383 dev_err(dcmipp->dev, "Failed to get next endpoint\n");
387 v4l2_async_nf_init(&dcmipp->notifier, &dcmipp->v4l2_dev);
389 asd = v4l2_async_nf_add_fwnode_remote(&dcmipp->notifier, ep,
390 struct v4l2_async_connection);
392 fwnode_handle_put(ep);
395 dev_err(dcmipp->dev, "Failed to add fwnode remote subdev\n");
399 dcmipp->notifier.ops = &dcmipp_graph_notify_ops;
401 ret = v4l2_async_nf_register(&dcmipp->notifier);
403 dev_err(dcmipp->dev, "Failed to register notifier\n");
404 v4l2_async_nf_cleanup(&dcmipp->notifier);
411 static int dcmipp_probe(struct platform_device *pdev)
413 struct dcmipp_device *dcmipp;
415 const struct dcmipp_pipeline_config *pipe_cfg;
416 struct reset_control *rstc;
420 dcmipp = devm_kzalloc(&pdev->dev, sizeof(*dcmipp), GFP_KERNEL);
424 dcmipp->dev = &pdev->dev;
426 pipe_cfg = device_get_match_data(dcmipp->dev);
428 dev_err(&pdev->dev, "Can't get device data\n");
431 dcmipp->pipe_cfg = pipe_cfg;
433 platform_set_drvdata(pdev, dcmipp);
435 /* Get hardware resources from devicetree */
436 rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
438 return dev_err_probe(&pdev->dev, PTR_ERR(rstc),
439 "Could not get reset control\n");
441 irq = platform_get_irq(pdev, 0);
445 dcmipp->regs = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
446 if (IS_ERR(dcmipp->regs)) {
447 dev_err(&pdev->dev, "Could not map registers\n");
448 return PTR_ERR(dcmipp->regs);
451 ret = devm_request_threaded_irq(&pdev->dev, irq, dcmipp_irq_callback,
452 dcmipp_irq_thread, IRQF_ONESHOT,
453 dev_name(&pdev->dev), dcmipp);
455 dev_err(&pdev->dev, "Unable to request irq %d\n", irq);
460 ret = reset_control_assert(rstc);
462 dev_err(&pdev->dev, "Failed to assert the reset line\n");
466 usleep_range(3000, 5000);
468 ret = reset_control_deassert(rstc);
470 dev_err(&pdev->dev, "Failed to deassert the reset line\n");
474 kclk = devm_clk_get(&pdev->dev, NULL);
476 return dev_err_probe(&pdev->dev, PTR_ERR(kclk),
477 "Unable to get kclk\n");
480 dcmipp->entity = devm_kcalloc(&pdev->dev, dcmipp->pipe_cfg->num_ents,
481 sizeof(*dcmipp->entity), GFP_KERNEL);
485 /* Register the v4l2 struct */
486 ret = v4l2_device_register(&pdev->dev, &dcmipp->v4l2_dev);
489 "v4l2 device register failed (err=%d)\n", ret);
493 /* Link the media device within the v4l2_device */
494 dcmipp->v4l2_dev.mdev = &dcmipp->mdev;
496 /* Initialize media device */
497 strscpy(dcmipp->mdev.model, DCMIPP_MDEV_MODEL_NAME,
498 sizeof(dcmipp->mdev.model));
499 dcmipp->mdev.dev = &pdev->dev;
500 media_device_init(&dcmipp->mdev);
502 /* Initialize subdevs */
503 ret = dcmipp_create_subdevs(dcmipp);
505 media_device_cleanup(&dcmipp->mdev);
506 v4l2_device_unregister(&dcmipp->v4l2_dev);
510 pm_runtime_enable(dcmipp->dev);
512 dev_info(&pdev->dev, "Probe done");
517 static void dcmipp_remove(struct platform_device *pdev)
519 struct dcmipp_device *dcmipp = platform_get_drvdata(pdev);
522 pm_runtime_disable(&pdev->dev);
524 v4l2_async_nf_unregister(&dcmipp->notifier);
525 v4l2_async_nf_cleanup(&dcmipp->notifier);
527 for (i = 0; i < dcmipp->pipe_cfg->num_ents; i++)
528 dcmipp->pipe_cfg->ents[i].release(dcmipp->entity[i]);
530 media_device_unregister(&dcmipp->mdev);
531 media_device_cleanup(&dcmipp->mdev);
533 v4l2_device_unregister(&dcmipp->v4l2_dev);
536 static int dcmipp_runtime_suspend(struct device *dev)
538 struct dcmipp_device *dcmipp = dev_get_drvdata(dev);
540 clk_disable_unprepare(dcmipp->kclk);
545 static int dcmipp_runtime_resume(struct device *dev)
547 struct dcmipp_device *dcmipp = dev_get_drvdata(dev);
550 ret = clk_prepare_enable(dcmipp->kclk);
552 dev_err(dev, "%s: Failed to prepare_enable kclk\n", __func__);
557 static int dcmipp_suspend(struct device *dev)
560 pm_runtime_force_suspend(dev);
562 /* change pinctrl state */
563 pinctrl_pm_select_sleep_state(dev);
568 static int dcmipp_resume(struct device *dev)
570 /* restore pinctl default state */
571 pinctrl_pm_select_default_state(dev);
574 pm_runtime_force_resume(dev);
579 static const struct dev_pm_ops dcmipp_pm_ops = {
580 SYSTEM_SLEEP_PM_OPS(dcmipp_suspend, dcmipp_resume)
581 RUNTIME_PM_OPS(dcmipp_runtime_suspend, dcmipp_runtime_resume, NULL)
584 static struct platform_driver dcmipp_pdrv = {
585 .probe = dcmipp_probe,
586 .remove = dcmipp_remove,
588 .name = DCMIPP_PDEV_NAME,
589 .of_match_table = dcmipp_of_match,
590 .pm = pm_ptr(&dcmipp_pm_ops),
594 module_platform_driver(dcmipp_pdrv);
598 MODULE_DESCRIPTION("STMicroelectronics STM32 Digital Camera Memory Interface with Pixel Processor driver");
599 MODULE_LICENSE("GPL");