* [PATCH v2 0/3] DCMI set minimum cpufreq requirement @ 2020-06-03 12:45 ` Benjamin Gaignard 0 siblings, 0 replies; 10+ messages in thread From: Benjamin Gaignard @ 2020-06-03 12:45 UTC (permalink / raw) To: hugues.fruchet, mchehab, mcoquelin.stm32, alexandre.torgue Cc: Benjamin Gaignard, rjw, linux-kernel, linux-stm32, valentin.schneider, linux-arm-kernel, linux-media This series allow to STM32 camera interface (DCMI) to require a minimum frequency to the CPUs before start streaming frames from the sensor. The minimum frequency requirement is provided in the devide-tree node. Setting a minimum frequency for the CPUs is needed to ensure a quick handling of the interrupts between two sensor frames and avoid dropping half of them. Benjamin Gaignard (3): dt-bindings: media: stm32-dcmi: Add DCMI min frequency property media: stm32-dcmi: Set minimum cpufreq requirement ARM: dts: stm32: Set DCMI frequency requirement for stm32mp15x .../devicetree/bindings/media/st,stm32-dcmi.yaml | 8 ++ arch/arm/boot/dts/stm32mp151.dtsi | 1 + drivers/media/platform/stm32/stm32-dcmi.c | 90 ++++++++++++++++++++-- 3 files changed, 91 insertions(+), 8 deletions(-) -- 2.15.0 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v2 0/3] DCMI set minimum cpufreq requirement @ 2020-06-03 12:45 ` Benjamin Gaignard 0 siblings, 0 replies; 10+ messages in thread From: Benjamin Gaignard @ 2020-06-03 12:45 UTC (permalink / raw) To: hugues.fruchet, mchehab, mcoquelin.stm32, alexandre.torgue Cc: linux-media, linux-stm32, linux-arm-kernel, linux-kernel, vincent.guittot, valentin.schneider, rjw, Benjamin Gaignard This series allow to STM32 camera interface (DCMI) to require a minimum frequency to the CPUs before start streaming frames from the sensor. The minimum frequency requirement is provided in the devide-tree node. Setting a minimum frequency for the CPUs is needed to ensure a quick handling of the interrupts between two sensor frames and avoid dropping half of them. Benjamin Gaignard (3): dt-bindings: media: stm32-dcmi: Add DCMI min frequency property media: stm32-dcmi: Set minimum cpufreq requirement ARM: dts: stm32: Set DCMI frequency requirement for stm32mp15x .../devicetree/bindings/media/st,stm32-dcmi.yaml | 8 ++ arch/arm/boot/dts/stm32mp151.dtsi | 1 + drivers/media/platform/stm32/stm32-dcmi.c | 90 ++++++++++++++++++++-- 3 files changed, 91 insertions(+), 8 deletions(-) -- 2.15.0 ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v2 1/3] dt-bindings: media: stm32-dcmi: Add DCMI min frequency property 2020-06-03 12:45 ` Benjamin Gaignard @ 2020-06-03 12:45 ` Benjamin Gaignard -1 siblings, 0 replies; 10+ messages in thread From: Benjamin Gaignard @ 2020-06-03 12:45 UTC (permalink / raw) To: hugues.fruchet, mchehab, mcoquelin.stm32, alexandre.torgue Cc: Benjamin Gaignard, rjw, linux-kernel, linux-stm32, valentin.schneider, linux-arm-kernel, linux-media Document st,stm32-dcmi-min-frequency property which is used to request CPUs minimum frequency when streaming frames. Signed-off-by: Benjamin Gaignard <benjamin.gaignard@st.com> --- Documentation/devicetree/bindings/media/st,stm32-dcmi.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Documentation/devicetree/bindings/media/st,stm32-dcmi.yaml b/Documentation/devicetree/bindings/media/st,stm32-dcmi.yaml index 3fe778cb5cc3..05ca85a2411a 100644 --- a/Documentation/devicetree/bindings/media/st,stm32-dcmi.yaml +++ b/Documentation/devicetree/bindings/media/st,stm32-dcmi.yaml @@ -44,6 +44,13 @@ properties: bindings defined in Documentation/devicetree/bindings/media/video-interfaces.txt. + st,stm32-dcmi-min-frequency: + description: DCMI minimum CPUs frequency requirement (in KHz). + allOf: + - $ref: /schemas/types.yaml#/definitions/uint32 + - minimum: 0 + - default: 0 + required: - compatible - reg @@ -71,6 +78,7 @@ examples: clock-names = "mclk"; dmas = <&dmamux1 75 0x400 0x0d>; dma-names = "tx"; + st,stm32-dcmi-min-frequency = <650000>; port { dcmi_0: endpoint { -- 2.15.0 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 1/3] dt-bindings: media: stm32-dcmi: Add DCMI min frequency property @ 2020-06-03 12:45 ` Benjamin Gaignard 0 siblings, 0 replies; 10+ messages in thread From: Benjamin Gaignard @ 2020-06-03 12:45 UTC (permalink / raw) To: hugues.fruchet, mchehab, mcoquelin.stm32, alexandre.torgue Cc: linux-media, linux-stm32, linux-arm-kernel, linux-kernel, vincent.guittot, valentin.schneider, rjw, Benjamin Gaignard Document st,stm32-dcmi-min-frequency property which is used to request CPUs minimum frequency when streaming frames. Signed-off-by: Benjamin Gaignard <benjamin.gaignard@st.com> --- Documentation/devicetree/bindings/media/st,stm32-dcmi.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Documentation/devicetree/bindings/media/st,stm32-dcmi.yaml b/Documentation/devicetree/bindings/media/st,stm32-dcmi.yaml index 3fe778cb5cc3..05ca85a2411a 100644 --- a/Documentation/devicetree/bindings/media/st,stm32-dcmi.yaml +++ b/Documentation/devicetree/bindings/media/st,stm32-dcmi.yaml @@ -44,6 +44,13 @@ properties: bindings defined in Documentation/devicetree/bindings/media/video-interfaces.txt. + st,stm32-dcmi-min-frequency: + description: DCMI minimum CPUs frequency requirement (in KHz). + allOf: + - $ref: /schemas/types.yaml#/definitions/uint32 + - minimum: 0 + - default: 0 + required: - compatible - reg @@ -71,6 +78,7 @@ examples: clock-names = "mclk"; dmas = <&dmamux1 75 0x400 0x0d>; dma-names = "tx"; + st,stm32-dcmi-min-frequency = <650000>; port { dcmi_0: endpoint { -- 2.15.0 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 2/3] media: stm32-dcmi: Set minimum cpufreq requirement 2020-06-03 12:45 ` Benjamin Gaignard @ 2020-06-03 12:45 ` Benjamin Gaignard -1 siblings, 0 replies; 10+ messages in thread From: Benjamin Gaignard @ 2020-06-03 12:45 UTC (permalink / raw) To: hugues.fruchet, mchehab, mcoquelin.stm32, alexandre.torgue Cc: Benjamin Gaignard, rjw, linux-kernel, linux-stm32, valentin.schneider, linux-arm-kernel, linux-media Before start streaming set cpufreq minimum frequency requirement. The cpufreq governor will adapt the frequencies and we will have no latency for handling interrupts. The frequency requirement is retrieved from the device-tree node. Signed-off-by: Benjamin Gaignard <benjamin.gaignard@st.com> --- drivers/media/platform/stm32/stm32-dcmi.c | 90 ++++++++++++++++++++++++++++--- 1 file changed, 82 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/stm32/stm32-dcmi.c b/drivers/media/platform/stm32/stm32-dcmi.c index b8931490b83b..1b9f24986694 100644 --- a/drivers/media/platform/stm32/stm32-dcmi.c +++ b/drivers/media/platform/stm32/stm32-dcmi.c @@ -13,10 +13,12 @@ #include <linux/clk.h> #include <linux/completion.h> +#include <linux/cpufreq.h> #include <linux/delay.h> #include <linux/dmaengine.h> #include <linux/init.h> #include <linux/interrupt.h> +#include <linux/irq.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/of.h> @@ -99,6 +101,9 @@ enum state { #define OVERRUN_ERROR_THRESHOLD 3 +static DEFINE_PER_CPU(struct cpufreq_policy *, policy); +static DEFINE_PER_CPU(struct freq_qos_request, qos_req); + struct dcmi_graph_entity { struct v4l2_async_subdev asd; @@ -133,6 +138,7 @@ struct stm32_dcmi { struct resource *res; struct reset_control *rstc; int sequence; + int irq; struct list_head buffers; struct dcmi_buf *active; @@ -173,6 +179,8 @@ struct stm32_dcmi { struct media_device mdev; struct media_pad vid_cap_pad; struct media_pipeline pipeline; + + u32 min_frequency; }; static inline struct stm32_dcmi *notifier_to_dcmi(struct v4l2_async_notifier *n) @@ -722,6 +730,62 @@ static void dcmi_pipeline_stop(struct stm32_dcmi *dcmi) dcmi_pipeline_s_stream(dcmi, 0); } +static void dcmi_get_min_frequency(struct stm32_dcmi *dcmi) +{ + struct device_node *np = dcmi->mdev.dev->of_node; + + dcmi->min_frequency = FREQ_QOS_MIN_DEFAULT_VALUE; + + of_property_read_u32(np, "st,stm32-dcmi-min-frequency", + &dcmi->min_frequency); +} + +static void dcmi_get_cpu_policy(struct stm32_dcmi *dcmi) +{ + struct cpufreq_policy *p; + int cpu; + + for_each_cpu(cpu, irq_get_affinity_mask(dcmi->irq)) { + p = cpufreq_cpu_get(cpu); + if (!p) + continue; + + freq_qos_add_request(&p->constraints, &per_cpu(qos_req, cpu), + FREQ_QOS_MIN, FREQ_QOS_MIN_DEFAULT_VALUE); + + per_cpu(policy, cpu) = p; + } +} + +static void dcmi_put_cpu_policy(struct stm32_dcmi *dcmi) +{ + struct cpufreq_policy *p; + int cpu; + + for_each_cpu(cpu, irq_get_affinity_mask(dcmi->irq)) { + p = per_cpu(policy, cpu); + if (!p) + continue; + + freq_qos_remove_request(&per_cpu(qos_req, cpu)); + cpufreq_cpu_put(p); + } +} + +static void dcmi_set_min_frequency(struct stm32_dcmi *dcmi, u64 freq) +{ + struct cpufreq_policy *p; + int cpu; + + for_each_cpu(cpu, irq_get_affinity_mask(dcmi->irq)) { + p = per_cpu(policy, cpu); + if (!p) + continue; + + freq_qos_update_request(&per_cpu(qos_req, cpu), freq); + } +} + static int dcmi_start_streaming(struct vb2_queue *vq, unsigned int count) { struct stm32_dcmi *dcmi = vb2_get_drv_priv(vq); @@ -736,11 +800,13 @@ static int dcmi_start_streaming(struct vb2_queue *vq, unsigned int count) goto err_release_buffers; } + dcmi_set_min_frequency(dcmi, dcmi->min_frequency); + ret = media_pipeline_start(&dcmi->vdev->entity, &dcmi->pipeline); if (ret < 0) { dev_err(dcmi->dev, "%s: Failed to start streaming, media pipeline start error (%d)\n", __func__, ret); - goto err_pm_put; + goto err_drop_qos; } ret = dcmi_pipeline_start(dcmi); @@ -835,7 +901,8 @@ static int dcmi_start_streaming(struct vb2_queue *vq, unsigned int count) err_media_pipeline_stop: media_pipeline_stop(&dcmi->vdev->entity); -err_pm_put: +err_drop_qos: + dcmi_set_min_frequency(dcmi, FREQ_QOS_MIN_DEFAULT_VALUE); pm_runtime_put(dcmi->dev); err_release_buffers: @@ -863,6 +930,8 @@ static void dcmi_stop_streaming(struct vb2_queue *vq) media_pipeline_stop(&dcmi->vdev->entity); + dcmi_set_min_frequency(dcmi, FREQ_QOS_MIN_DEFAULT_VALUE); + spin_lock_irq(&dcmi->irqlock); /* Disable interruptions */ @@ -1838,7 +1907,6 @@ static int dcmi_probe(struct platform_device *pdev) struct vb2_queue *q; struct dma_chan *chan; struct clk *mclk; - int irq; int ret = 0; match = of_match_device(of_match_ptr(stm32_dcmi_of_match), &pdev->dev); @@ -1879,9 +1947,9 @@ static int dcmi_probe(struct platform_device *pdev) dcmi->bus.bus_width = ep.bus.parallel.bus_width; dcmi->bus.data_shift = ep.bus.parallel.data_shift; - irq = platform_get_irq(pdev, 0); - if (irq <= 0) - return irq ? irq : -ENXIO; + dcmi->irq = platform_get_irq(pdev, 0); + if (dcmi->irq <= 0) + return dcmi->irq ? dcmi->irq : -ENXIO; dcmi->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!dcmi->res) { @@ -1895,11 +1963,12 @@ static int dcmi_probe(struct platform_device *pdev) return PTR_ERR(dcmi->regs); } - ret = devm_request_threaded_irq(&pdev->dev, irq, dcmi_irq_callback, + ret = devm_request_threaded_irq(&pdev->dev, dcmi->irq, + dcmi_irq_callback, dcmi_irq_thread, IRQF_ONESHOT, dev_name(&pdev->dev), dcmi); if (ret) { - dev_err(&pdev->dev, "Unable to request irq %d\n", irq); + dev_err(&pdev->dev, "Unable to request irq %d\n", dcmi->irq); return ret; } @@ -2022,6 +2091,9 @@ static int dcmi_probe(struct platform_device *pdev) dev_info(&pdev->dev, "Probe done\n"); + dcmi_get_min_frequency(dcmi); + dcmi_get_cpu_policy(dcmi); + platform_set_drvdata(pdev, dcmi); pm_runtime_enable(&pdev->dev); @@ -2049,6 +2121,8 @@ static int dcmi_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); + dcmi_put_cpu_policy(dcmi); + v4l2_async_notifier_unregister(&dcmi->notifier); v4l2_async_notifier_cleanup(&dcmi->notifier); media_entity_cleanup(&dcmi->vdev->entity); -- 2.15.0 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 2/3] media: stm32-dcmi: Set minimum cpufreq requirement @ 2020-06-03 12:45 ` Benjamin Gaignard 0 siblings, 0 replies; 10+ messages in thread From: Benjamin Gaignard @ 2020-06-03 12:45 UTC (permalink / raw) To: hugues.fruchet, mchehab, mcoquelin.stm32, alexandre.torgue Cc: linux-media, linux-stm32, linux-arm-kernel, linux-kernel, vincent.guittot, valentin.schneider, rjw, Benjamin Gaignard Before start streaming set cpufreq minimum frequency requirement. The cpufreq governor will adapt the frequencies and we will have no latency for handling interrupts. The frequency requirement is retrieved from the device-tree node. Signed-off-by: Benjamin Gaignard <benjamin.gaignard@st.com> --- drivers/media/platform/stm32/stm32-dcmi.c | 90 ++++++++++++++++++++++++++++--- 1 file changed, 82 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/stm32/stm32-dcmi.c b/drivers/media/platform/stm32/stm32-dcmi.c index b8931490b83b..1b9f24986694 100644 --- a/drivers/media/platform/stm32/stm32-dcmi.c +++ b/drivers/media/platform/stm32/stm32-dcmi.c @@ -13,10 +13,12 @@ #include <linux/clk.h> #include <linux/completion.h> +#include <linux/cpufreq.h> #include <linux/delay.h> #include <linux/dmaengine.h> #include <linux/init.h> #include <linux/interrupt.h> +#include <linux/irq.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/of.h> @@ -99,6 +101,9 @@ enum state { #define OVERRUN_ERROR_THRESHOLD 3 +static DEFINE_PER_CPU(struct cpufreq_policy *, policy); +static DEFINE_PER_CPU(struct freq_qos_request, qos_req); + struct dcmi_graph_entity { struct v4l2_async_subdev asd; @@ -133,6 +138,7 @@ struct stm32_dcmi { struct resource *res; struct reset_control *rstc; int sequence; + int irq; struct list_head buffers; struct dcmi_buf *active; @@ -173,6 +179,8 @@ struct stm32_dcmi { struct media_device mdev; struct media_pad vid_cap_pad; struct media_pipeline pipeline; + + u32 min_frequency; }; static inline struct stm32_dcmi *notifier_to_dcmi(struct v4l2_async_notifier *n) @@ -722,6 +730,62 @@ static void dcmi_pipeline_stop(struct stm32_dcmi *dcmi) dcmi_pipeline_s_stream(dcmi, 0); } +static void dcmi_get_min_frequency(struct stm32_dcmi *dcmi) +{ + struct device_node *np = dcmi->mdev.dev->of_node; + + dcmi->min_frequency = FREQ_QOS_MIN_DEFAULT_VALUE; + + of_property_read_u32(np, "st,stm32-dcmi-min-frequency", + &dcmi->min_frequency); +} + +static void dcmi_get_cpu_policy(struct stm32_dcmi *dcmi) +{ + struct cpufreq_policy *p; + int cpu; + + for_each_cpu(cpu, irq_get_affinity_mask(dcmi->irq)) { + p = cpufreq_cpu_get(cpu); + if (!p) + continue; + + freq_qos_add_request(&p->constraints, &per_cpu(qos_req, cpu), + FREQ_QOS_MIN, FREQ_QOS_MIN_DEFAULT_VALUE); + + per_cpu(policy, cpu) = p; + } +} + +static void dcmi_put_cpu_policy(struct stm32_dcmi *dcmi) +{ + struct cpufreq_policy *p; + int cpu; + + for_each_cpu(cpu, irq_get_affinity_mask(dcmi->irq)) { + p = per_cpu(policy, cpu); + if (!p) + continue; + + freq_qos_remove_request(&per_cpu(qos_req, cpu)); + cpufreq_cpu_put(p); + } +} + +static void dcmi_set_min_frequency(struct stm32_dcmi *dcmi, u64 freq) +{ + struct cpufreq_policy *p; + int cpu; + + for_each_cpu(cpu, irq_get_affinity_mask(dcmi->irq)) { + p = per_cpu(policy, cpu); + if (!p) + continue; + + freq_qos_update_request(&per_cpu(qos_req, cpu), freq); + } +} + static int dcmi_start_streaming(struct vb2_queue *vq, unsigned int count) { struct stm32_dcmi *dcmi = vb2_get_drv_priv(vq); @@ -736,11 +800,13 @@ static int dcmi_start_streaming(struct vb2_queue *vq, unsigned int count) goto err_release_buffers; } + dcmi_set_min_frequency(dcmi, dcmi->min_frequency); + ret = media_pipeline_start(&dcmi->vdev->entity, &dcmi->pipeline); if (ret < 0) { dev_err(dcmi->dev, "%s: Failed to start streaming, media pipeline start error (%d)\n", __func__, ret); - goto err_pm_put; + goto err_drop_qos; } ret = dcmi_pipeline_start(dcmi); @@ -835,7 +901,8 @@ static int dcmi_start_streaming(struct vb2_queue *vq, unsigned int count) err_media_pipeline_stop: media_pipeline_stop(&dcmi->vdev->entity); -err_pm_put: +err_drop_qos: + dcmi_set_min_frequency(dcmi, FREQ_QOS_MIN_DEFAULT_VALUE); pm_runtime_put(dcmi->dev); err_release_buffers: @@ -863,6 +930,8 @@ static void dcmi_stop_streaming(struct vb2_queue *vq) media_pipeline_stop(&dcmi->vdev->entity); + dcmi_set_min_frequency(dcmi, FREQ_QOS_MIN_DEFAULT_VALUE); + spin_lock_irq(&dcmi->irqlock); /* Disable interruptions */ @@ -1838,7 +1907,6 @@ static int dcmi_probe(struct platform_device *pdev) struct vb2_queue *q; struct dma_chan *chan; struct clk *mclk; - int irq; int ret = 0; match = of_match_device(of_match_ptr(stm32_dcmi_of_match), &pdev->dev); @@ -1879,9 +1947,9 @@ static int dcmi_probe(struct platform_device *pdev) dcmi->bus.bus_width = ep.bus.parallel.bus_width; dcmi->bus.data_shift = ep.bus.parallel.data_shift; - irq = platform_get_irq(pdev, 0); - if (irq <= 0) - return irq ? irq : -ENXIO; + dcmi->irq = platform_get_irq(pdev, 0); + if (dcmi->irq <= 0) + return dcmi->irq ? dcmi->irq : -ENXIO; dcmi->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!dcmi->res) { @@ -1895,11 +1963,12 @@ static int dcmi_probe(struct platform_device *pdev) return PTR_ERR(dcmi->regs); } - ret = devm_request_threaded_irq(&pdev->dev, irq, dcmi_irq_callback, + ret = devm_request_threaded_irq(&pdev->dev, dcmi->irq, + dcmi_irq_callback, dcmi_irq_thread, IRQF_ONESHOT, dev_name(&pdev->dev), dcmi); if (ret) { - dev_err(&pdev->dev, "Unable to request irq %d\n", irq); + dev_err(&pdev->dev, "Unable to request irq %d\n", dcmi->irq); return ret; } @@ -2022,6 +2091,9 @@ static int dcmi_probe(struct platform_device *pdev) dev_info(&pdev->dev, "Probe done\n"); + dcmi_get_min_frequency(dcmi); + dcmi_get_cpu_policy(dcmi); + platform_set_drvdata(pdev, dcmi); pm_runtime_enable(&pdev->dev); @@ -2049,6 +2121,8 @@ static int dcmi_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); + dcmi_put_cpu_policy(dcmi); + v4l2_async_notifier_unregister(&dcmi->notifier); v4l2_async_notifier_cleanup(&dcmi->notifier); media_entity_cleanup(&dcmi->vdev->entity); -- 2.15.0 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v2 2/3] media: stm32-dcmi: Set minimum cpufreq requirement 2020-06-03 12:45 ` Benjamin Gaignard @ 2020-06-03 15:25 ` Valentin Schneider -1 siblings, 0 replies; 10+ messages in thread From: Valentin Schneider @ 2020-06-03 15:25 UTC (permalink / raw) To: Benjamin Gaignard Cc: alexandre.torgue, rjw, linux-kernel, mcoquelin.stm32, hugues.fruchet, mchehab, linux-stm32, linux-arm-kernel, linux-media On 03/06/20 13:45, Benjamin Gaignard wrote: > +static void dcmi_set_min_frequency(struct stm32_dcmi *dcmi, u64 freq) > +{ > + struct cpufreq_policy *p; > + int cpu; > + > + for_each_cpu(cpu, irq_get_affinity_mask(dcmi->irq)) { > + p = per_cpu(policy, cpu); > + if (!p) > + continue; > + > + freq_qos_update_request(&per_cpu(qos_req, cpu), freq); > + } > +} > + You may want to use a "visited" cpumask as I suggested in the previous thread, since a policy can cover more than one CPU (IOW, a frequency domain can span more than one CPU). It's not required per-se, AFAICT, but it makes things a bit neater. I also think you'll have to use the affinity notifier (irq_set_affinity_notifier()), since AFAICT userspace can change the affinity of that IRQ. I suppose you'll want something like: - Check if we currently are in streaming mode - Clear the QoS request for CPUs that were previously boosted but that aren't in the new mask - Add the request for the new CPUs. You'll probably need serialize the reading of the mask in the regular dcmi_set_min_frequency() as well. I concur all of that is somewhat annoying, but AFAICT that's required for a sturdy implementation. > static int dcmi_start_streaming(struct vb2_queue *vq, unsigned int count) > { > struct stm32_dcmi *dcmi = vb2_get_drv_priv(vq); _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2 2/3] media: stm32-dcmi: Set minimum cpufreq requirement @ 2020-06-03 15:25 ` Valentin Schneider 0 siblings, 0 replies; 10+ messages in thread From: Valentin Schneider @ 2020-06-03 15:25 UTC (permalink / raw) To: Benjamin Gaignard Cc: hugues.fruchet, mchehab, mcoquelin.stm32, alexandre.torgue, linux-media, linux-stm32, linux-arm-kernel, linux-kernel, vincent.guittot, rjw On 03/06/20 13:45, Benjamin Gaignard wrote: > +static void dcmi_set_min_frequency(struct stm32_dcmi *dcmi, u64 freq) > +{ > + struct cpufreq_policy *p; > + int cpu; > + > + for_each_cpu(cpu, irq_get_affinity_mask(dcmi->irq)) { > + p = per_cpu(policy, cpu); > + if (!p) > + continue; > + > + freq_qos_update_request(&per_cpu(qos_req, cpu), freq); > + } > +} > + You may want to use a "visited" cpumask as I suggested in the previous thread, since a policy can cover more than one CPU (IOW, a frequency domain can span more than one CPU). It's not required per-se, AFAICT, but it makes things a bit neater. I also think you'll have to use the affinity notifier (irq_set_affinity_notifier()), since AFAICT userspace can change the affinity of that IRQ. I suppose you'll want something like: - Check if we currently are in streaming mode - Clear the QoS request for CPUs that were previously boosted but that aren't in the new mask - Add the request for the new CPUs. You'll probably need serialize the reading of the mask in the regular dcmi_set_min_frequency() as well. I concur all of that is somewhat annoying, but AFAICT that's required for a sturdy implementation. > static int dcmi_start_streaming(struct vb2_queue *vq, unsigned int count) > { > struct stm32_dcmi *dcmi = vb2_get_drv_priv(vq); ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v2 3/3] ARM: dts: stm32: Set DCMI frequency requirement for stm32mp15x 2020-06-03 12:45 ` Benjamin Gaignard @ 2020-06-03 12:45 ` Benjamin Gaignard -1 siblings, 0 replies; 10+ messages in thread From: Benjamin Gaignard @ 2020-06-03 12:45 UTC (permalink / raw) To: hugues.fruchet, mchehab, mcoquelin.stm32, alexandre.torgue Cc: Benjamin Gaignard, rjw, linux-kernel, linux-stm32, valentin.schneider, linux-arm-kernel, linux-media Make sure that CPUs will at least run at 650Mhz when streaming sensor frames. Signed-off-by: Benjamin Gaignard <benjamin.gaignard@st.com> --- arch/arm/boot/dts/stm32mp151.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/stm32mp151.dtsi b/arch/arm/boot/dts/stm32mp151.dtsi index 3ea05ba48215..f6d7bf4f8231 100644 --- a/arch/arm/boot/dts/stm32mp151.dtsi +++ b/arch/arm/boot/dts/stm32mp151.dtsi @@ -1091,6 +1091,7 @@ clock-names = "mclk"; dmas = <&dmamux1 75 0x400 0x0d>; dma-names = "tx"; + st,stm32-dcmi-min-frequency = <650000>; status = "disabled"; }; -- 2.15.0 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 3/3] ARM: dts: stm32: Set DCMI frequency requirement for stm32mp15x @ 2020-06-03 12:45 ` Benjamin Gaignard 0 siblings, 0 replies; 10+ messages in thread From: Benjamin Gaignard @ 2020-06-03 12:45 UTC (permalink / raw) To: hugues.fruchet, mchehab, mcoquelin.stm32, alexandre.torgue Cc: linux-media, linux-stm32, linux-arm-kernel, linux-kernel, vincent.guittot, valentin.schneider, rjw, Benjamin Gaignard Make sure that CPUs will at least run at 650Mhz when streaming sensor frames. Signed-off-by: Benjamin Gaignard <benjamin.gaignard@st.com> --- arch/arm/boot/dts/stm32mp151.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/stm32mp151.dtsi b/arch/arm/boot/dts/stm32mp151.dtsi index 3ea05ba48215..f6d7bf4f8231 100644 --- a/arch/arm/boot/dts/stm32mp151.dtsi +++ b/arch/arm/boot/dts/stm32mp151.dtsi @@ -1091,6 +1091,7 @@ clock-names = "mclk"; dmas = <&dmamux1 75 0x400 0x0d>; dma-names = "tx"; + st,stm32-dcmi-min-frequency = <650000>; status = "disabled"; }; -- 2.15.0 ^ permalink raw reply related [flat|nested] 10+ messages in thread
end of thread, other threads:[~2020-06-03 15:25 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2020-06-03 12:45 [PATCH v2 0/3] DCMI set minimum cpufreq requirement Benjamin Gaignard 2020-06-03 12:45 ` Benjamin Gaignard 2020-06-03 12:45 ` [PATCH v2 1/3] dt-bindings: media: stm32-dcmi: Add DCMI min frequency property Benjamin Gaignard 2020-06-03 12:45 ` Benjamin Gaignard 2020-06-03 12:45 ` [PATCH v2 2/3] media: stm32-dcmi: Set minimum cpufreq requirement Benjamin Gaignard 2020-06-03 12:45 ` Benjamin Gaignard 2020-06-03 15:25 ` Valentin Schneider 2020-06-03 15:25 ` Valentin Schneider 2020-06-03 12:45 ` [PATCH v2 3/3] ARM: dts: stm32: Set DCMI frequency requirement for stm32mp15x Benjamin Gaignard 2020-06-03 12:45 ` Benjamin Gaignard
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.