Re: [PATCH] drm/msm: log iommu init failure
On Fri, Jun 21, 2024 at 2:48 AM Luca Weiss wrote: > On Fri Jun 21, 2024 at 12:47 AM CEST, Konrad Dybcio wrote: > > On 6/20/24 20:24, Dmitry Baryshkov wrote: > > > Does that mean that we will lose GPU support on MSM8974? > > > > Yeah, that was brought up on #freedreno some time ago > > Also on MSM8226 which I also care about... > > Anyone at all knowledgable on IOMMU would be very welcome to help out > with IOMMU support on these two platforms (and anything else that > old?) in any case, since me and some other people have looked at this > (on and off) for years but haven't gotten to any stable or usable point > unfortunately. I posted in 2020 some details about what I encountered when I tried to enable the IOMMU on msm8974: https://lore.kernel.org/lkml/20200109002606.35653-1-masn...@onstation.org/ Brian
Re: [Freedreno] [PATCH] drm/msm/adreno: Update MODULE_FIRMWARE macros
Hi Juerg, On Fri, Jun 16, 2023 at 02:28:15PM +0200, Juerg Haefliger wrote: > Add missing MODULE_FIRMWARE macros and remove some for firmwares that > the driver no longer references. > > Signed-off-by: Juerg Haefliger > --- > drivers/gpu/drm/msm/adreno/adreno_device.c | 23 ++ > 1 file changed, 19 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c > b/drivers/gpu/drm/msm/adreno/adreno_device.c > index 8cff86e9d35c..9f70d7c1a72a 100644 > --- a/drivers/gpu/drm/msm/adreno/adreno_device.c > +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c > @@ -364,17 +364,32 @@ MODULE_FIRMWARE("qcom/a330_pm4.fw"); > MODULE_FIRMWARE("qcom/a330_pfp.fw"); > MODULE_FIRMWARE("qcom/a420_pm4.fw"); > MODULE_FIRMWARE("qcom/a420_pfp.fw"); > +MODULE_FIRMWARE("qcom/a506_zap.mdt"); > +MODULE_FIRMWARE("qcom/a508_zap.mdt"); > +MODULE_FIRMWARE("qcom/a512_zap.mdt"); > MODULE_FIRMWARE("qcom/a530_pm4.fw"); > MODULE_FIRMWARE("qcom/a530_pfp.fw"); > MODULE_FIRMWARE("qcom/a530v3_gpmu.fw2"); > MODULE_FIRMWARE("qcom/a530_zap.mdt"); > -MODULE_FIRMWARE("qcom/a530_zap.b00"); > -MODULE_FIRMWARE("qcom/a530_zap.b01"); > -MODULE_FIRMWARE("qcom/a530_zap.b02"); > +MODULE_FIRMWARE("qcom/a540_gpmu.fw2"); > +MODULE_FIRMWARE("qcom/a540_zap.mdt"); > +MODULE_FIRMWARE("qcom/a615_zap.mdt"); > MODULE_FIRMWARE("qcom/a619_gmu.bin"); > MODULE_FIRMWARE("qcom/a630_sqe.fw"); > MODULE_FIRMWARE("qcom/a630_gmu.bin"); > -MODULE_FIRMWARE("qcom/a630_zap.mbn"); > +MODULE_FIRMWARE("qcom/a630_zap.mdt"); > +MODULE_FIRMWARE("qcom/a640_gmu.bin"); > +MODULE_FIRMWARE("qcom/a640_zap.mdt"); > +MODULE_FIRMWARE("qcom/a650_gmu.bin"); > +MODULE_FIRMWARE("qcom/a650_sqe.fw"); > +MODULE_FIRMWARE("qcom/a650_zap.mdt"); > +MODULE_FIRMWARE("qcom/a660_gmu.bin"); > +MODULE_FIRMWARE("qcom/a660_sqe.fw"); > +MODULE_FIRMWARE("qcom/a660_zap.mdt"); > +MODULE_FIRMWARE("qcom/leia_pfp_470.fw"); > +MODULE_FIRMWARE("qcom/leia_pm4_470.fw"); > +MODULE_FIRMWARE("qcom/yamato_pfp.fw"); > +MODULE_FIRMWARE("qcom/yamato_pm4.fw"); You should rebase this on top of the latest -next since the a690 needs to be added as well. Brian
Re: [Freedreno] [PATCH] drm/msm/mdp5: Fix wait-for-commit for cmd panels
On Wed, Jan 27, 2021 at 05:24:40PM +0200, Iskren Chernev wrote: > Before the offending commit in msm_atomic_commit_tail wait_flush was > called once per frame, after the commit was submitted. After it > wait_flush is also called at the beginning to ensure previous > potentially async commits are done. > > For cmd panels the source of wait_flush is a ping-pong irq notifying > a completion. The completion needs to be notified with complete_all so > multiple waiting parties (new async committers) can proceed. > > Signed-off-by: Iskren Chernev > Suggested-by: Rob Clark > Fixes: 2d99ced787e3d ("drm/msm: async commit support") Nice job tracking down this fix! Reviewed-by: Brian Masney Tested-by: Brian Masney ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
Re: [Freedreno] [PATCH 1/2] drm/msm: Call msm_init_vram before binding the gpu
On Wed, Dec 30, 2020 at 05:29:42PM +0200, Iskren Chernev wrote: > From: Craig Tatlor > > vram.size is needed when binding a gpu without an iommu and is defined > in msm_init_vram(), so run that before binding it. > > Signed-off-by: Craig Tatlor For the series: Reviewed-by: Brian Masney Next time, please include a cover letter so that tags added to the cover letter can be applied to all patches in the series via patchwork. Brian ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH] dt-bindings: display: msm: gmu: move sram property to gpu bindings
The sram property was incorrectly added to the GMU binding when it really belongs with the GPU binding instead. Let's go ahead and move it. While changes are being made here, let's update the sram property description to mention that this property is only valid for a3xx and a4xx GPUs. The a3xx/a4xx example in the GPU is replaced with what was in the GMU. Signed-off-by: Brian Masney Fixes: 198a72c8f9ee ("dt-bindings: display: msm: gmu: add optional ocmem property") --- Background thread: https://lore.kernel.org/lkml/20200303170159.ga13...@jcrouse1-lnx.qualcomm.com/ I started to look at what it would take to convert the GPU bindings to YAML, however I am unsure of the complete list of "qcom,adreno-XYZ.W" compatibles that are valid. .../devicetree/bindings/display/msm/gmu.txt | 51 - .../devicetree/bindings/display/msm/gpu.txt | 55 ++- 2 files changed, 42 insertions(+), 64 deletions(-) diff --git a/Documentation/devicetree/bindings/display/msm/gmu.txt b/Documentation/devicetree/bindings/display/msm/gmu.txt index bf9c7a2a495c..90af5b0a56a9 100644 --- a/Documentation/devicetree/bindings/display/msm/gmu.txt +++ b/Documentation/devicetree/bindings/display/msm/gmu.txt @@ -31,10 +31,6 @@ Required properties: - iommus: phandle to the adreno iommu - operating-points-v2: phandle to the OPP operating points -Optional properties: -- sram: phandle to the On Chip Memory (OCMEM) that's present on some Snapdragon -SoCs. See Documentation/devicetree/bindings/sram/qcom,ocmem.yaml. - Example: / { @@ -67,50 +63,3 @@ Example: operating-points-v2 = <&gmu_opp_table>; }; }; - -a3xx example with OCMEM support: - -/ { - ... - - gpu: adreno@fdb0 { - compatible = "qcom,adreno-330.2", -"qcom,adreno"; - reg = <0xfdb0 0x1>; - reg-names = "kgsl_3d0_reg_memory"; - interrupts = ; - interrupt-names = "kgsl_3d0_irq"; - clock-names = "core", - "iface", - "mem_iface"; - clocks = <&mmcc OXILI_GFX3D_CLK>, -<&mmcc OXILICX_AHB_CLK>, -<&mmcc OXILICX_AXI_CLK>; - sram = <&gmu_sram>; - power-domains = <&mmcc OXILICX_GDSC>; - operating-points-v2 = <&gpu_opp_table>; - iommus = <&gpu_iommu 0>; - }; - - ocmem@fdd0 { - compatible = "qcom,msm8974-ocmem"; - - reg = <0xfdd0 0x2000>, - <0xfec0 0x18>; - reg-names = "ctrl", -"mem"; - - clocks = <&rpmcc RPM_SMD_OCMEMGX_CLK>, -<&mmcc OCMEMCX_OCMEMNOC_CLK>; - clock-names = "core", - "iface"; - - #address-cells = <1>; - #size-cells = <1>; - - gmu_sram: gmu-sram@0 { - reg = <0x0 0x10>; - ranges = <0 0 0xfec0 0x10>; - }; - }; -}; diff --git a/Documentation/devicetree/bindings/display/msm/gpu.txt b/Documentation/devicetree/bindings/display/msm/gpu.txt index 7edc298a15f2..fd779cd6994d 100644 --- a/Documentation/devicetree/bindings/display/msm/gpu.txt +++ b/Documentation/devicetree/bindings/display/msm/gpu.txt @@ -35,25 +35,54 @@ Required properties: bring the GPU out of secure mode. - firmware-name: optional property of the 'zap-shader' node, listing the relative path of the device specific zap firmware. +- sram: phandle to the On Chip Memory (OCMEM) that's present on some a3xx and +a4xx Snapdragon SoCs. See +Documentation/devicetree/bindings/sram/qcom,ocmem.yaml. -Example 3xx/4xx/a5xx: +Example 3xx/4xx: / { ... - gpu: qcom,kgsl-3d0@430 { - compatible = "qcom,adreno-320.2", "qcom,adreno"; - reg = <0x0430 0x2>; + gpu: adreno@fdb0 { + compatible = "qcom,adreno-330.2", +"qcom,adreno"; + reg = <0xfdb0 0x1>; reg-names = "kgsl_3d0_reg_memory"; - interrupts = ; - clock-names = - "core", - "iface", - "mem_iface"; - clocks = - <&mmcc GFX3D_CLK>, - <&mmcc GFX3D_AHB_CLK>, - <&mmcc MMSS_
Re: [Freedreno] [PATCH v3 1/2] dt-bindings: display: msm: Convert GMU bindings to YAML
On Tue, Mar 03, 2020 at 10:01:59AM -0700, Jordan Crouse wrote: > On Tue, Mar 03, 2020 at 10:54:05AM -0500, Brian Masney wrote: > > On Tue, Mar 03, 2020 at 08:50:28AM -0700, Jeffrey Hugo wrote: > > > On Tue, Mar 3, 2020 at 8:43 AM Jordan Crouse > > > wrote: > > > > > > > > On Mon, Mar 02, 2020 at 09:49:06PM +0100, Sam Ravnborg wrote: > > > > > Hi Jordan. > > > > > > > > > > On Mon, Mar 02, 2020 at 11:23:43AM -0700, Jordan Crouse wrote: > > > > > > Convert display/msm/gmu.txt to display/msm/gmu.yaml and remove the > > > > > > old > > > > > > text bindings. > > > > > > > > > > > > Signed-off-by: Jordan Crouse > > > > > > --- > > > > > > > > > > > > .../devicetree/bindings/display/msm/gmu.txt| 116 > > > > > > --- > > > > > > - > > > > > > -Required properties: > > > > > > -- compatible: "qcom,adreno-gmu-XYZ.W", "qcom,adreno-gmu" > > > > > > -for example: "qcom,adreno-gmu-630.2", "qcom,adreno-gmu" > > > > > > - Note that you need to list the less specific "qcom,adreno-gmu" > > > > > > - for generic matches and the more specific identifier to identify > > > > > > - the specific device. > > > > > > -- reg: Physical base address and length of the GMU registers. > > > > > > -- reg-names: Matching names for the register regions > > > > > > - * "gmu" > > > > > > - * "gmu_pdc" > > > > > > - * "gmu_pdc_seg" > > > > > > -- interrupts: The interrupt signals from the GMU. > > > > > > -- interrupt-names: Matching names for the interrupts > > > > > > - * "hfi" > > > > > > - * "gmu" > > > > > > -- clocks: phandles to the device clocks > > > > > > -- clock-names: Matching names for the clocks > > > > > > - * "gmu" > > > > > > - * "cxo" > > > > > > - * "axi" > > > > > > - * "mnoc" > > > > > The new binding - and arch/arm64/boot/dts/qcom/sdm845.dtsi agrees that > > > > > "mnoc" is wrong. > > > > > > > > > > > -- power-domains: should be: > > > > > > - <&clock_gpucc GPU_CX_GDSC> > > > > > > - <&clock_gpucc GPU_GX_GDSC> > > > > > > -- power-domain-names: Matching names for the power domains > > > > > > -- iommus: phandle to the adreno iommu > > > > > > -- operating-points-v2: phandle to the OPP operating points > > > > > > - > > > > > > -Optional properties: > > > > > > -- sram: phandle to the On Chip Memory (OCMEM) that's present on > > > > > > some Snapdragon > > > > > > -SoCs. See > > > > > > Documentation/devicetree/bindings/sram/qcom,ocmem.yaml. > > > > > This property is not included in the new binding. > > > > > > > > Yeah, that guy shouldn't be here. I'm not sure how it got there in the > > > > first > > > > place but I'll update the commit log. Thanks for the poke. > > > > > > I thought this was something Brian M added for older targets (A4XX?). > > > Perhaps he should chime in? > > > > Yes, this is needed for older systems with a3xx and a4xx GPUs. > > Okay, this got added to the wrong place. The GMU is a specific entity only > valid for a6xx targets. From the looks of the example the sram should be in > the > GPU definition. Do you want to submit a patch to move it or should I (and lets > hope Rob doesn't insist on converting GPU to YAML). I can take care of cleaning this up. I'll do that in a few days. Brian ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
Re: [Freedreno] [PATCH v3 1/2] dt-bindings: display: msm: Convert GMU bindings to YAML
On Tue, Mar 03, 2020 at 08:50:28AM -0700, Jeffrey Hugo wrote: > On Tue, Mar 3, 2020 at 8:43 AM Jordan Crouse wrote: > > > > On Mon, Mar 02, 2020 at 09:49:06PM +0100, Sam Ravnborg wrote: > > > Hi Jordan. > > > > > > On Mon, Mar 02, 2020 at 11:23:43AM -0700, Jordan Crouse wrote: > > > > Convert display/msm/gmu.txt to display/msm/gmu.yaml and remove the old > > > > text bindings. > > > > > > > > Signed-off-by: Jordan Crouse > > > > --- > > > > > > > > .../devicetree/bindings/display/msm/gmu.txt| 116 > > > > --- > > > > - > > > > -Required properties: > > > > -- compatible: "qcom,adreno-gmu-XYZ.W", "qcom,adreno-gmu" > > > > -for example: "qcom,adreno-gmu-630.2", "qcom,adreno-gmu" > > > > - Note that you need to list the less specific "qcom,adreno-gmu" > > > > - for generic matches and the more specific identifier to identify > > > > - the specific device. > > > > -- reg: Physical base address and length of the GMU registers. > > > > -- reg-names: Matching names for the register regions > > > > - * "gmu" > > > > - * "gmu_pdc" > > > > - * "gmu_pdc_seg" > > > > -- interrupts: The interrupt signals from the GMU. > > > > -- interrupt-names: Matching names for the interrupts > > > > - * "hfi" > > > > - * "gmu" > > > > -- clocks: phandles to the device clocks > > > > -- clock-names: Matching names for the clocks > > > > - * "gmu" > > > > - * "cxo" > > > > - * "axi" > > > > - * "mnoc" > > > The new binding - and arch/arm64/boot/dts/qcom/sdm845.dtsi agrees that > > > "mnoc" is wrong. > > > > > > > -- power-domains: should be: > > > > - <&clock_gpucc GPU_CX_GDSC> > > > > - <&clock_gpucc GPU_GX_GDSC> > > > > -- power-domain-names: Matching names for the power domains > > > > -- iommus: phandle to the adreno iommu > > > > -- operating-points-v2: phandle to the OPP operating points > > > > - > > > > -Optional properties: > > > > -- sram: phandle to the On Chip Memory (OCMEM) that's present on some > > > > Snapdragon > > > > -SoCs. See > > > > Documentation/devicetree/bindings/sram/qcom,ocmem.yaml. > > > This property is not included in the new binding. > > > > Yeah, that guy shouldn't be here. I'm not sure how it got there in the first > > place but I'll update the commit log. Thanks for the poke. > > I thought this was something Brian M added for older targets (A4XX?). > Perhaps he should chime in? Yes, this is needed for older systems with a3xx and a4xx GPUs. Brian ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
Re: [Freedreno] [PATCH RFC v2] drm/msm/mdp5: enable autorefresh
On Tue, Dec 31, 2019 at 10:50:27PM -0500, Brian Masney wrote: > On Sun, Dec 29, 2019 at 09:00:53PM -0500, Brian Masney wrote: > > Since the introduction of commit 2d99ced787e3 ("drm/msm: async commit > > support"), command-mode panels began throwing the following errors: > > > > msm fd90.mdss: pp done time out, lm=0 > > > > Let's fix this by enabling the autorefresh feature that's available in > > the MDP starting at version 1.0. This will cause the MDP to > > automatically send a frame to the panel every time the panel invokes the > > TE signal, which will trigger the PP_DONE IRQ. This requires only > > sending a single START signal for command-mode panels. > > > > This gives us a counter for command-mode panels that we can use to > > implement async commit support for the MDP5 in a follow up patch. > > > > Signed-off-by: Brian Masney > > Suggested-by: Jeffrey Hugo > > Fixes: 2d99ced787e3 ("drm/msm: async commit support") > > --- > > Changes since v1: > > - Send a single start command to kick off the pipeline. > > > > The reason I marked this patch as a RFC is that the display during some > > small percentage of boots will stop updating after a minute or so, and > > the ping pong IRQs stop. Most of the time it works with no issues and I > > haven't been able to find a way to reproduce the issue. I tried > > suspending the phone by toggling /sys/power/state since I thought that > > the issue could potentially be related to power management. > > After working to get the IOMMU up on msm8974, I suspect that the issue > that I describe above is caused by a device probe deferral, which > explains the intermittent nature of what I'm seeing. First driver load > sets up the autorefresh registers, sends a single START signal, then a > -EPROBE_DEFER is thrown later on. Second driver load lost the state, and > sends a second START signal and overloads the DSI. The issue was not caused by an -EPROBE_DEFER error. The most consistent way that I've found to reproduce the issue is to compile the MSM DRM driver into the kernel (not as a module), boot the phone, don't change the screen contents, and after ~2 minutes the 'pp done time out' warnings start. I enabled all DRM debug information and included at the bottom of my message the relevant messages from dmesg at the point where the IRQs stop. I feel like I'm at a dead end on this since I'm not too familiar with this particular hardware and there's no publicly-available documents. Unless anyone has any suggestions for other things to try, I'm planning to stop looking into this issue and will instead look into getting the IOMMU working on this board. I would love to get this fixed though. --- The point in dmesg right before the ping/pong IRQs stop. This sequence of messages appears consistently like this prior to this. [ 128.915574] [drm:mdp5_crtc_vblank_irq] crtc-0: send event: 4c4a50e5 [ 128.928610] [drm:dsi_host_irq] isr=0x2000700, id=0 [ 128.945398] [drm:dsi_host_irq] isr=0x2000700, id=0 [ 128.962185] [drm:dsi_host_irq] isr=0x2000700, id=0 [ 128.978974] [drm:dsi_host_irq] isr=0x2000700, id=0 [ 128.995761] [drm:dsi_host_irq] isr=0x2000700, id=0 [ 129.015163] [drm:dsi_host_irq] isr=0x2000700, id=0 [ 129.031826] [drm:dsi_host_irq] isr=0x2000700, id=0 [ 129.048492] [drm:dsi_host_irq] isr=0x2000700, id=0 [ 129.065160] [drm:dsi_host_irq] isr=0x2000700, id=0 [ 129.081826] [drm:dsi_host_irq] isr=0x2000700, id=0 [ 129.098493] [drm:dsi_host_irq] isr=0x2000700, id=0 [ 129.115694] [drm:dsi_host_irq] isr=0x2000700, id=0 [ 129.115787] [drm:drm_atomic_state_init] Allocated atomic state f90dd658 [ 129.115810] [drm:drm_mode_object_get] OBJ ID: 51 (2) [ 129.115823] [drm:drm_atomic_get_plane_state] Added [PLANE:33:plane-0] d172526a state to f90dd658 [ 129.115836] [drm:drm_mode_object_get] OBJ ID: 52 (1) [ 129.115848] [drm:drm_atomic_get_crtc_state] Added [CRTC:50:crtc-0] 00606fa5 state to f90dd658 [ 129.115858
[Freedreno] [PATCH] drm/msm/mdp5: rate limit pp done timeout warnings
Add rate limiting of the 'pp done time out' warnings since these warnings can quickly fill the dmesg buffer. Signed-off-by: Brian Masney --- drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c index 05cc04f729d6..e1cc541e0ef2 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c @@ -1109,8 +1109,8 @@ static void mdp5_crtc_wait_for_pp_done(struct drm_crtc *crtc) ret = wait_for_completion_timeout(&mdp5_crtc->pp_completion, msecs_to_jiffies(50)); if (ret == 0) - dev_warn(dev->dev, "pp done time out, lm=%d\n", -mdp5_cstate->pipeline.mixer->lm); + dev_warn_ratelimited(dev->dev, "pp done time out, lm=%d\n", +mdp5_cstate->pipeline.mixer->lm); } static void mdp5_crtc_wait_for_flush_done(struct drm_crtc *crtc) -- 2.24.1 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH RFC] ARM: dts: qcom: msm8974: add mdp5 iommu support
This adds preliminary IOMMU support for the MDP5 on msm8974. It appears that the qcom-iommu driver in upstream can be used on this SoC. I marked this patch as a RFC since the frame buffer becomes corrupted when I boot the Nexus 5 phone with this patch: https://raw.githubusercontent.com/masneyb/nexus-5-upstream/master/images/broken-mdp5-iommu.jpg A quick note about the ranges of the context banks below: Based on the downstream sources, I believe that the memory addresses should be mapped out like this: mdp_iommu: iommu@fd928000 { reg = <0xfd928000 0x8000>; ranges = <0 0xfd93 0x8000>; ... iommu-ctx@0 { reg = <0x0 0x1000>; ... }; iommu-ctx@1000 { reg = <0x1000 0x1000>; ... }; iommu-ctx@2000 { reg = <0x2000 0x1000>; ... }; }; However, the qcom-iommu driver in upstream expects the first context bank to exist at address 0x1000, and the address space identifier (asid) to be greater than 0. See get_asid() and qcom_iommu_of_xlate() in the upstream qcom-iommu.c driver. I put in the patch below what the driver expects. I modified the driver in my local tree to allow the mapping that I have above so that the extra 0x1000 of memory is mapped into the global address space and still experience the same screen corruption issue. Downstream MSM 3.4 IOMMU dts snippet for reference: https://github.com/AICP/kernel_lge_hammerhead/blob/n7.1/arch/arm/boot/dts/msm-iommu-v1.dtsi#L110 I'm hoping that someone that's more familiar with this hardware has a suggestion for something to try. Signed-off-by: Brian Masney --- arch/arm/boot/dts/qcom-msm8974.dtsi | 44 + 1 file changed, 44 insertions(+) diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi index 4b161b809dd5..2515a3bd4aa7 100644 --- a/arch/arm/boot/dts/qcom-msm8974.dtsi +++ b/arch/arm/boot/dts/qcom-msm8974.dtsi @@ -1305,6 +1305,46 @@ etm3_out: endpoint { }; }; + mdp_iommu: iommu@fd928000 { + compatible = "qcom,msm8974-iommu", +"qcom,msm-iommu-v1"; + reg = <0xfd928000 0x7000>; + #address-cells = <1>; + #size-cells = <1>; + #iommu-cells = <1>; + ranges = <0 0xfd92f000 0x9000>; + + clocks = <&mmcc MDSS_AHB_CLK>, +<&mmcc MDSS_AXI_CLK>; + clock-names = "iface", + "bus"; + + qcom,iommu-secure-id = <1>; + + // mdp_0 + iommu-ctx@1000 { + compatible = "qcom,msm-iommu-v1-ns"; + reg = <0x1000 0x1000>; + interrupts = ; + }; + + // mdp_1 + iommu-ctx@2000 { + compatible = "qcom,msm-iommu-v1-sec"; + reg = <0x2000 0x1000>; + interrupts = , +; + }; + + // mdp_2 + iommu-ctx@3000 { + compatible = "qcom,msm-iommu-v1-sec"; + reg = <0x3000 0x1000>; + interrupts = , +; + }; +}; + ocmem@fdd0 { compatible = "qcom,msm8974-ocmem"; reg = <0xfdd0 0x2000>, @@ -1427,6 +1467,10 @@ mdp: mdp@fd90 { interconnects = <&mmssnoc MNOC_MAS_MDP_PORT0 &bimc BIMC_SLV_EBI_CH0>; interconnect-names = "mdp0-mem"; + iommus = <&mdp_iommu 1 + &mdp_iommu 2 + &mdp_iommu 3>; + ports { #address-cells = <1>; #size-cells = <0>; -- 2.24.1 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
Re: [Freedreno] [PATCH RFC v2] drm/msm/mdp5: enable autorefresh
On Sun, Dec 29, 2019 at 09:00:53PM -0500, Brian Masney wrote: > Since the introduction of commit 2d99ced787e3 ("drm/msm: async commit > support"), command-mode panels began throwing the following errors: > > msm fd90.mdss: pp done time out, lm=0 > > Let's fix this by enabling the autorefresh feature that's available in > the MDP starting at version 1.0. This will cause the MDP to > automatically send a frame to the panel every time the panel invokes the > TE signal, which will trigger the PP_DONE IRQ. This requires only > sending a single START signal for command-mode panels. > > This gives us a counter for command-mode panels that we can use to > implement async commit support for the MDP5 in a follow up patch. > > Signed-off-by: Brian Masney > Suggested-by: Jeffrey Hugo > Fixes: 2d99ced787e3 ("drm/msm: async commit support") > --- > Changes since v1: > - Send a single start command to kick off the pipeline. > > The reason I marked this patch as a RFC is that the display during some > small percentage of boots will stop updating after a minute or so, and > the ping pong IRQs stop. Most of the time it works with no issues and I > haven't been able to find a way to reproduce the issue. I tried > suspending the phone by toggling /sys/power/state since I thought that > the issue could potentially be related to power management. After working to get the IOMMU up on msm8974, I suspect that the issue that I describe above is caused by a device probe deferral, which explains the intermittent nature of what I'm seeing. First driver load sets up the autorefresh registers, sends a single START signal, then a -EPROBE_DEFER is thrown later on. Second driver load lost the state, and sends a second START signal and overloads the DSI. If that's the case, then potentially the solution may be to do both of the following: 1) Disable autorefresh when the driver is unloaded. 2) Before sending the START signal, check to make sure that autorefresh is actually disabled. I likely won't be able to work on any this until Sunday evening. Brian ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH RFC v2] drm/msm/mdp5: enable autorefresh
Since the introduction of commit 2d99ced787e3 ("drm/msm: async commit support"), command-mode panels began throwing the following errors: msm fd90.mdss: pp done time out, lm=0 Let's fix this by enabling the autorefresh feature that's available in the MDP starting at version 1.0. This will cause the MDP to automatically send a frame to the panel every time the panel invokes the TE signal, which will trigger the PP_DONE IRQ. This requires only sending a single START signal for command-mode panels. This gives us a counter for command-mode panels that we can use to implement async commit support for the MDP5 in a follow up patch. Signed-off-by: Brian Masney Suggested-by: Jeffrey Hugo Fixes: 2d99ced787e3 ("drm/msm: async commit support") --- Changes since v1: - Send a single start command to kick off the pipeline. The reason I marked this patch as a RFC is that the display during some small percentage of boots will stop updating after a minute or so, and the ping pong IRQs stop. Most of the time it works with no issues and I haven't been able to find a way to reproduce the issue. I tried suspending the phone by toggling /sys/power/state since I thought that the issue could potentially be related to power management. drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c | 17 - drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c | 31 --- drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.h | 3 +-- 3 files changed, 44 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c index 05cc04f729d6..39dd144295b3 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c @@ -436,6 +436,8 @@ static void mdp5_crtc_atomic_disable(struct drm_crtc *crtc, spin_unlock_irqrestore(&mdp5_kms->dev->event_lock, flags); } + mdp5_ctl_disable(mdp5_cstate->ctl, &mdp5_cstate->pipeline); + mdp5_crtc->enabled = false; } @@ -456,6 +458,7 @@ static void mdp5_crtc_atomic_enable(struct drm_crtc *crtc, { struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state); + struct mdp5_pipeline *pipeline = &mdp5_cstate->pipeline; struct mdp5_kms *mdp5_kms = get_kms(crtc); struct device *dev = &mdp5_kms->pdev->dev; @@ -493,9 +496,21 @@ static void mdp5_crtc_atomic_enable(struct drm_crtc *crtc, mdp_irq_register(&mdp5_kms->base, &mdp5_crtc->err); - if (mdp5_cstate->cmd_mode) + if (mdp5_cstate->cmd_mode) { mdp_irq_register(&mdp5_kms->base, &mdp5_crtc->pp_done); + /* +* Enable autorefresh so we get regular ping/pong IRQs. +* - Bit 31 is the enable bit +* - Bits 0-15 represent the frame count, specifically how many +* TE events before the MDP sends a frame. +*/ + mdp5_write(mdp5_kms, + REG_MDP5_PP_AUTOREFRESH_CONFIG(pipeline->mixer->pp), + BIT(31) | BIT(0)); + crtc_flush_all(crtc); + } + mdp5_crtc->enabled = true; } diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c index 030279d7b64b..965757d4f356 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c @@ -50,6 +50,13 @@ struct mdp5_ctl { bool flush_pending; struct mdp5_ctl *pair; /* Paired CTL to be flushed together */ + + /* +* The command mode panels are ran with autorefresh enabled. Only a +* single START command can be sent so keep track on a per ping pong +* basis. +*/ + bool start_sent_by_pp[4]; }; struct mdp5_ctl_manager { @@ -191,7 +198,8 @@ static bool start_signal_needed(struct mdp5_ctl *ctl, case INTF_WB: return true; case INTF_DSI: - return intf->mode == MDP5_INTF_DSI_MODE_COMMAND; + return intf->mode == MDP5_INTF_DSI_MODE_COMMAND && + !ctl->start_sent_by_pp[pipeline->mixer->pp]; default: return false; } @@ -204,13 +212,17 @@ static bool start_signal_needed(struct mdp5_ctl *ctl, * executed in order to kick off operation and activate all layers. * e.g.: DSI command mode, Writeback */ -static void send_start_signal(struct mdp5_ctl *ctl) +static void send_start_signal(struct mdp5_ctl *ctl, + struct mdp5_pipeline *pipeline) { unsigned long flags; spin_lock_irqsave(&ctl->hw_lock, flags); ctl_write(ctl, REG_MDP5_CTL_START(ctl->id), 1); spin_unlock_irqrestore(&ctl->hw_lock, flags); + +
[Freedreno] [PATCH RFC v2] drm/msm/mdp5: enable autorefresh
Since the introduction of commit 2d99ced787e3 ("drm/msm: async commit support"), command-mode panels began throwing the following errors: msm fd90.mdss: pp done time out, lm=0 Let's fix this by enabling the autorefresh feature that's available in the MDP starting at version 1.0. This will cause the MDP to automatically send a frame to the panel every time the panel invokes the TE signal, which will trigger the PP_DONE IRQ. This requires only sending a single START signal for command-mode panels. This gives us a counter for command-mode panels that we can use to implement async commit support for the MDP5 in a follow up patch. Signed-off-by: Brian Masney Suggested-by: Jeffrey Hugo Fixes: 2d99ced787e3 ("drm/msm: async commit support") --- Changes since v1: - Send a single start command to kick off the pipeline. The reason I marked this patch as a RFC is that the display during some small percentage of boots will stop updating after a minute or so, and the ping pong IRQs stop. Most of the time it works with no issues and I haven't been able to find a way to reproduce the issue. I tried suspending the phone by toggling /sys/power/state since I thought that the issue could potentially be related to power management. drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c | 17 - drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c | 31 --- drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.h | 3 +-- 3 files changed, 44 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c index 05cc04f729d6..39dd144295b3 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c @@ -436,6 +436,8 @@ static void mdp5_crtc_atomic_disable(struct drm_crtc *crtc, spin_unlock_irqrestore(&mdp5_kms->dev->event_lock, flags); } + mdp5_ctl_disable(mdp5_cstate->ctl, &mdp5_cstate->pipeline); + mdp5_crtc->enabled = false; } @@ -456,6 +458,7 @@ static void mdp5_crtc_atomic_enable(struct drm_crtc *crtc, { struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state); + struct mdp5_pipeline *pipeline = &mdp5_cstate->pipeline; struct mdp5_kms *mdp5_kms = get_kms(crtc); struct device *dev = &mdp5_kms->pdev->dev; @@ -493,9 +496,21 @@ static void mdp5_crtc_atomic_enable(struct drm_crtc *crtc, mdp_irq_register(&mdp5_kms->base, &mdp5_crtc->err); - if (mdp5_cstate->cmd_mode) + if (mdp5_cstate->cmd_mode) { mdp_irq_register(&mdp5_kms->base, &mdp5_crtc->pp_done); + /* +* Enable autorefresh so we get regular ping/pong IRQs. +* - Bit 31 is the enable bit +* - Bits 0-15 represent the frame count, specifically how many +* TE events before the MDP sends a frame. +*/ + mdp5_write(mdp5_kms, + REG_MDP5_PP_AUTOREFRESH_CONFIG(pipeline->mixer->pp), + BIT(31) | BIT(0)); + crtc_flush_all(crtc); + } + mdp5_crtc->enabled = true; } diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c index 030279d7b64b..965757d4f356 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c @@ -50,6 +50,13 @@ struct mdp5_ctl { bool flush_pending; struct mdp5_ctl *pair; /* Paired CTL to be flushed together */ + + /* +* The command mode panels are ran with autorefresh enabled. Only a +* single START command can be sent so keep track on a per ping pong +* basis. +*/ + bool start_sent_by_pp[4]; }; struct mdp5_ctl_manager { @@ -191,7 +198,8 @@ static bool start_signal_needed(struct mdp5_ctl *ctl, case INTF_WB: return true; case INTF_DSI: - return intf->mode == MDP5_INTF_DSI_MODE_COMMAND; + return intf->mode == MDP5_INTF_DSI_MODE_COMMAND && + !ctl->start_sent_by_pp[pipeline->mixer->pp]; default: return false; } @@ -204,13 +212,17 @@ static bool start_signal_needed(struct mdp5_ctl *ctl, * executed in order to kick off operation and activate all layers. * e.g.: DSI command mode, Writeback */ -static void send_start_signal(struct mdp5_ctl *ctl) +static void send_start_signal(struct mdp5_ctl *ctl, + struct mdp5_pipeline *pipeline) { unsigned long flags; spin_lock_irqsave(&ctl->hw_lock, flags); ctl_write(ctl, REG_MDP5_CTL_START(ctl->id), 1); spin_unlock_irqrestore(&ctl->hw_lock, flags); + +
Re: [Freedreno] [PATCH] drm/msm/mdp5: enable autocommit
Hi Jeffrey, On Tue, Dec 03, 2019 at 07:18:31AM -0700, Jeffrey Hugo wrote: > On Mon, Dec 2, 2019 at 6:40 PM Brian Masney wrote: > > On Wed, Nov 13, 2019 at 06:23:34AM -0500, Brian Masney wrote: > > > On Tue, Nov 12, 2019 at 08:38:27AM -0700, Jeffrey Hugo wrote: > > > > On Tue, Nov 12, 2019 at 3:49 AM Brian Masney > > > > wrote: > > > > > > > > > > Since the introduction of commit 2d99ced787e3 ("drm/msm: async commit > > > > > support"), command-mode panels began throwing the following errors: > > > > > > > > > > msm fd90.mdss: pp done time out, lm=0 > > > > > > > > > > Let's fix this by enabling the autorefresh feature that's available in > > > > > the MDP starting at version 1.0. This will cause the MDP to > > > > > automatically send a frame to the panel every time the panel invokes > > > > > the TE signal, which will trigger the PP_DONE IRQ. This requires not > > > > > sending a START signal for command-mode panels. > > > > > > > > > > This fixes the error and gives us a counter for command-mode panels > > > > > that > > > > > we can use to implement async commit support for the MDP5 in a follow > > > > > up > > > > > patch. > > > > > > > > > > Signed-off-by: Brian Masney > > > > > Suggested-by: Jeffrey Hugo > > > > > --- > > > > > drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c | 15 ++- > > > > > drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c | 9 + > > > > > 2 files changed, 15 insertions(+), 9 deletions(-) > > > > > > > > > > diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c > > > > > b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c > > > > > index 05cc04f729d6..539348cb6331 100644 > > > > > --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c > > > > > +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c > > > > > @@ -456,6 +456,7 @@ static void mdp5_crtc_atomic_enable(struct > > > > > drm_crtc *crtc, > > > > > { > > > > > struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); > > > > > struct mdp5_crtc_state *mdp5_cstate = > > > > > to_mdp5_crtc_state(crtc->state); > > > > > + struct mdp5_pipeline *pipeline = &mdp5_cstate->pipeline; > > > > > struct mdp5_kms *mdp5_kms = get_kms(crtc); > > > > > struct device *dev = &mdp5_kms->pdev->dev; > > > > > > > > > > @@ -493,9 +494,21 @@ static void mdp5_crtc_atomic_enable(struct > > > > > drm_crtc *crtc, > > > > > > > > > > mdp_irq_register(&mdp5_kms->base, &mdp5_crtc->err); > > > > > > > > > > - if (mdp5_cstate->cmd_mode) > > > > > + if (mdp5_cstate->cmd_mode) { > > > > > mdp_irq_register(&mdp5_kms->base, > > > > > &mdp5_crtc->pp_done); > > > > > > > > > > + /* > > > > > +* Enable autorefresh so we get regular ping/pong > > > > > IRQs. > > > > > +* - Bit 31 is the enable bit > > > > > +* - Bits 0-15 represent the frame count, > > > > > specifically how many > > > > > +* TE events before the MDP sends a frame. > > > > > +*/ > > > > > + mdp5_write(mdp5_kms, > > > > > + > > > > > REG_MDP5_PP_AUTOREFRESH_CONFIG(pipeline->mixer->pp), > > > > > + BIT(31) | BIT(0)); > > > > > + crtc_flush_all(crtc); > > > > > + } > > > > > + > > > > > mdp5_crtc->enabled = true; > > > > > } > > > > > > > > > > diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c > > > > > b/drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c > > > > > index 030279d7b64b..aee295abada3 100644 > > > > > --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c > > > > > +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c > > > > > @@ -187,14 +187,7 @@ static bool start_signal_needed(struct mdp5_ctl > > > > > *ctl, >
Re: [Freedreno] [PATCH] drm/msm/mdp5: enable autocommit
Hi Jeffrey, On Wed, Nov 13, 2019 at 06:23:34AM -0500, Brian Masney wrote: > On Tue, Nov 12, 2019 at 08:38:27AM -0700, Jeffrey Hugo wrote: > > On Tue, Nov 12, 2019 at 3:49 AM Brian Masney wrote: > > > > > > Since the introduction of commit 2d99ced787e3 ("drm/msm: async commit > > > support"), command-mode panels began throwing the following errors: > > > > > > msm fd90.mdss: pp done time out, lm=0 > > > > > > Let's fix this by enabling the autorefresh feature that's available in > > > the MDP starting at version 1.0. This will cause the MDP to > > > automatically send a frame to the panel every time the panel invokes > > > the TE signal, which will trigger the PP_DONE IRQ. This requires not > > > sending a START signal for command-mode panels. > > > > > > This fixes the error and gives us a counter for command-mode panels that > > > we can use to implement async commit support for the MDP5 in a follow up > > > patch. > > > > > > Signed-off-by: Brian Masney > > > Suggested-by: Jeffrey Hugo > > > --- > > > drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c | 15 ++- > > > drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c | 9 + > > > 2 files changed, 15 insertions(+), 9 deletions(-) > > > > > > diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c > > > b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c > > > index 05cc04f729d6..539348cb6331 100644 > > > --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c > > > +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c > > > @@ -456,6 +456,7 @@ static void mdp5_crtc_atomic_enable(struct drm_crtc > > > *crtc, > > > { > > > struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); > > > struct mdp5_crtc_state *mdp5_cstate = > > > to_mdp5_crtc_state(crtc->state); > > > + struct mdp5_pipeline *pipeline = &mdp5_cstate->pipeline; > > > struct mdp5_kms *mdp5_kms = get_kms(crtc); > > > struct device *dev = &mdp5_kms->pdev->dev; > > > > > > @@ -493,9 +494,21 @@ static void mdp5_crtc_atomic_enable(struct drm_crtc > > > *crtc, > > > > > > mdp_irq_register(&mdp5_kms->base, &mdp5_crtc->err); > > > > > > - if (mdp5_cstate->cmd_mode) > > > + if (mdp5_cstate->cmd_mode) { > > > mdp_irq_register(&mdp5_kms->base, &mdp5_crtc->pp_done); > > > > > > + /* > > > +* Enable autorefresh so we get regular ping/pong IRQs. > > > +* - Bit 31 is the enable bit > > > +* - Bits 0-15 represent the frame count, specifically > > > how many > > > +* TE events before the MDP sends a frame. > > > +*/ > > > + mdp5_write(mdp5_kms, > > > + > > > REG_MDP5_PP_AUTOREFRESH_CONFIG(pipeline->mixer->pp), > > > + BIT(31) | BIT(0)); > > > + crtc_flush_all(crtc); > > > + } > > > + > > > mdp5_crtc->enabled = true; > > > } > > > > > > diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c > > > b/drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c > > > index 030279d7b64b..aee295abada3 100644 > > > --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c > > > +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c > > > @@ -187,14 +187,7 @@ static bool start_signal_needed(struct mdp5_ctl *ctl, > > > if (!ctl->encoder_enabled) > > > return false; > > > > > > - switch (intf->type) { > > > - case INTF_WB: > > > - return true; > > > - case INTF_DSI: > > > - return intf->mode == MDP5_INTF_DSI_MODE_COMMAND; > > > - default: > > > - return false; > > > - } > > > + return intf->type == INTF_WB; > > > } > > > > I don't think this fully works. > > > > The whole "flush" thing exists because the configuration is double > > buffered. You write to the flush register to tell the hardware to > > pickup the new configuration, but it doesn't do that automatically. > > It only picks up the new config on the next "vsync". When you have a > > video mode panel, you have the timing engine runni
[Freedreno] [PATCH v2 3/4] drm/msm/a3xx: set interconnect bandwidth vote
Set the two interconnect paths for the GPU to maximum speed for now to work towards getting the GPU working upstream. We can revisit a later time to optimize this for battery life. Signed-off-by: Brian Masney --- drivers/gpu/drm/msm/adreno/a3xx_gpu.c | 8 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c index 07ddcc529573..eff0ecd4e81a 100644 --- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c @@ -504,6 +504,14 @@ struct msm_gpu *a3xx_gpu_init(struct drm_device *dev) DRM_DEV_ERROR(dev->dev, "No memory protection without IOMMU\n"); } + /* +* Set the ICC path to maximum speed for now by multiplying the fastest +* frequency by the bus width (8). We'll want to scale this later on to +* improve battery life. +*/ + icc_set_bw(gpu->icc_path, 0, Bps_to_icc(gpu->fast_rate) * 8); + icc_set_bw(gpu->ocmem_icc_path, 0, Bps_to_icc(gpu->fast_rate) * 8); + return gpu; fail: -- 2.21.0 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v2 0/4] drm/msm/gpu: add support for ocmem interconnect
Some A3xx and all A4xx Adreno GPUs do not have GMEM inside the GPU core and must use the On Chip MEMory (OCMEM) in order to be functional. There's a separate interconnect path that needs to be setup to OCMEM. This patch series adds support for that path, and sets the votes for the two interconnect paths to the highest speed for a3xx and a4xx-based platforms. Changes since v1: - Don't rename icc_path to gfx_mem_icc_path. Leave existing variable named as is and add comment to declaration in struct msm_gpu. Brian Masney (4): dt-bindings: drm/msm/gpu: document second interconnect drm/msm/gpu: add support for ocmem interconnect path drm/msm/a3xx: set interconnect bandwidth vote drm/msm/a4xx: set interconnect bandwidth vote .../devicetree/bindings/display/msm/gpu.txt| 6 +- drivers/gpu/drm/msm/adreno/a3xx_gpu.c | 8 drivers/gpu/drm/msm/adreno/a4xx_gpu.c | 8 drivers/gpu/drm/msm/adreno/adreno_gpu.c| 14 +- drivers/gpu/drm/msm/msm_gpu.h | 7 +++ 5 files changed, 41 insertions(+), 2 deletions(-) -- 2.21.0 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v2 4/4] drm/msm/a4xx: set interconnect bandwidth vote
Set the two interconnect paths for the GPU to maximum speed for now to work towards getting the GPU working upstream. We can revisit a later time to optimize this for battery life. Signed-off-by: Brian Masney --- drivers/gpu/drm/msm/adreno/a4xx_gpu.c | 8 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c index b01388a9e89e..253d8d85daad 100644 --- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c @@ -591,6 +591,14 @@ struct msm_gpu *a4xx_gpu_init(struct drm_device *dev) goto fail; } + /* +* Set the ICC path to maximum speed for now by multiplying the fastest +* frequency by the bus width (8). We'll want to scale this later on to +* improve battery life. +*/ + icc_set_bw(gpu->icc_path, 0, Bps_to_icc(gpu->fast_rate) * 8); + icc_set_bw(gpu->ocmem_icc_path, 0, Bps_to_icc(gpu->fast_rate) * 8); + return gpu; fail: -- 2.21.0 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v2 1/4] dt-bindings: drm/msm/gpu: document second interconnect
Some A3xx and all A4xx Adreno GPUs do not have GMEM inside the GPU core and must use the On Chip MEMory (OCMEM) in order to be functional. There's a separate interconnect path that needs to be setup to OCMEM. Let's document this second interconnect path that's available. Since there's now two available interconnects, let's add the interconnect-names property. Signed-off-by: Brian Masney --- Documentation/devicetree/bindings/display/msm/gpu.txt | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/display/msm/gpu.txt b/Documentation/devicetree/bindings/display/msm/gpu.txt index 2b8fd26c43b0..3e6cd3f64a78 100644 --- a/Documentation/devicetree/bindings/display/msm/gpu.txt +++ b/Documentation/devicetree/bindings/display/msm/gpu.txt @@ -23,7 +23,10 @@ Required properties: - iommus: optional phandle to an adreno iommu instance - operating-points-v2: optional phandle to the OPP operating points - interconnects: optional phandle to an interconnect provider. See - ../interconnect/interconnect.txt for details. + ../interconnect/interconnect.txt for details. Some A3xx and all A4xx platforms + will have two paths; all others will have one path. +- interconnect-names: The names of the interconnect paths that correspond to the + interconnects property. Values must be gfx-mem and ocmem. - qcom,gmu: For GMU attached devices a phandle to the GMU device that will control the power for the GPU. Applicable targets: - qcom,adreno-630.2 @@ -76,6 +79,7 @@ Example a6xx (with GMU): operating-points-v2 = <&gpu_opp_table>; interconnects = <&rsc_hlos MASTER_GFX3D &rsc_hlos SLAVE_EBI1>; + interconnect-names = "gfx-mem"; qcom,gmu = <&gmu>; -- 2.21.0 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v2 2/4] drm/msm/gpu: add support for ocmem interconnect path
Some A3xx and all A4xx Adreno GPUs do not have GMEM inside the GPU core and must use the On Chip MEMory (OCMEM) in order to be functional. There's a separate interconnect path that needs to be setup to OCMEM. Add support for this second path to the GPU core. In the downstream MSM 3.4 sources, the two interconnect paths for the GPU are between: - MSM_BUS_MASTER_GRAPHICS_3D and MSM_BUS_SLAVE_EBI_CH0 - MSM_BUS_MASTER_V_OCMEM_GFX3D and MSM_BUS_SLAVE_OCMEM Signed-off-by: Brian Masney --- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 14 +- drivers/gpu/drm/msm/msm_gpu.h | 7 +++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 0783e4b5486a..d27bdc999777 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -887,10 +887,21 @@ static int adreno_get_pwrlevels(struct device *dev, DBG("fast_rate=%u, slow_rate=2700", gpu->fast_rate); /* Check for an interconnect path for the bus */ - gpu->icc_path = of_icc_get(dev, NULL); + gpu->icc_path = of_icc_get(dev, "gfx-mem"); + if (!gpu->icc_path) { + /* +* Keep compatbility with device trees that don't have an +* interconnect-names property. +*/ + gpu->icc_path = of_icc_get(dev, NULL); + } if (IS_ERR(gpu->icc_path)) gpu->icc_path = NULL; + gpu->ocmem_icc_path = of_icc_get(dev, "ocmem"); + if (IS_ERR(gpu->ocmem_icc_path)) + gpu->ocmem_icc_path = NULL; + return 0; } @@ -977,6 +988,7 @@ void adreno_gpu_cleanup(struct adreno_gpu *adreno_gpu) release_firmware(adreno_gpu->fw[i]); icc_put(gpu->icc_path); + icc_put(gpu->ocmem_icc_path); msm_gpu_cleanup(&adreno_gpu->base); } diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index ab8f0f9c9dc8..be5bc2e8425c 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -111,8 +111,15 @@ struct msm_gpu { struct clk *ebi1_clk, *core_clk, *rbbmtimer_clk; uint32_t fast_rate; + /* The gfx-mem interconnect path that's used by all GPU types. */ struct icc_path *icc_path; + /* +* Second interconnect path for some A3xx and all A4xx GPUs to the +* On Chip MEMory (OCMEM). +*/ + struct icc_path *ocmem_icc_path; + /* Hang and Inactivity Detection: */ #define DRM_MSM_INACTIVE_PERIOD 66 /* in ms (roughly four frames) */ -- 2.21.0 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH 0/4] drm/msm/gpu: add support for ocmem interconnect
Some A3xx and all A4xx Adreno GPUs do not have GMEM inside the GPU core and must use the On Chip MEMory (OCMEM) in order to be functional. There's a separate interconnect path that needs to be setup to OCMEM. This patch series adds support for that path, and sets the votes for the two interconnect paths to the highest speed for a3xx and a4xx-based platforms. Brian Masney (4): dt-bindings: drm/msm/gpu: document second interconnect drm/msm/gpu: add support for ocmem interconnect path drm/msm/a3xx: set interconnect bandwidth vote drm/msm/a4xx: set interconnect bandwidth vote .../devicetree/bindings/display/msm/gpu.txt | 6 +- drivers/gpu/drm/msm/adreno/a3xx_gpu.c | 8 drivers/gpu/drm/msm/adreno/a4xx_gpu.c | 8 drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 6 +++--- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 20 +++ drivers/gpu/drm/msm/msm_gpu.h | 3 ++- 6 files changed, 42 insertions(+), 9 deletions(-) -- 2.21.0 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH 2/4] drm/msm/gpu: add support for ocmem interconnect path
Some A3xx and all A4xx Adreno GPUs do not have GMEM inside the GPU core and must use the On Chip MEMory (OCMEM) in order to be functional. There's a separate interconnect path that needs to be setup to OCMEM. Add support for this second path to the GPU core. In the downstream MSM 3.4 sources, the two interconnect paths for the GPU are between: - MSM_BUS_MASTER_GRAPHICS_3D and MSM_BUS_SLAVE_EBI_CH0 - MSM_BUS_MASTER_V_OCMEM_GFX3D and MSM_BUS_SLAVE_OCMEM Signed-off-by: Brian Masney --- drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 6 +++--- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 20 drivers/gpu/drm/msm/msm_gpu.h | 3 ++- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index 85f14feafdec..7885e382fb8f 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -132,7 +132,7 @@ static void __a6xx_gmu_set_freq(struct a6xx_gmu *gmu, int index) * Eventually we will want to scale the path vote with the frequency but * for now leave it at max so that the performance is nominal. */ - icc_set_bw(gpu->icc_path, 0, MBps_to_icc(7216)); + icc_set_bw(gpu->gfx_mem_icc_path, 0, MBps_to_icc(7216)); } void a6xx_gmu_set_freq(struct msm_gpu *gpu, unsigned long freq) @@ -714,7 +714,7 @@ int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu) } /* Set the bus quota to a reasonable value for boot */ - icc_set_bw(gpu->icc_path, 0, MBps_to_icc(3072)); + icc_set_bw(gpu->gfx_mem_icc_path, 0, MBps_to_icc(3072)); /* Enable the GMU interrupt */ gmu_write(gmu, REG_A6XX_GMU_AO_HOST_INTERRUPT_CLR, ~0); @@ -858,7 +858,7 @@ int a6xx_gmu_stop(struct a6xx_gpu *a6xx_gpu) a6xx_gmu_shutdown(gmu); /* Remove the bus vote */ - icc_set_bw(gpu->icc_path, 0, 0); + icc_set_bw(gpu->gfx_mem_icc_path, 0, 0); /* * Make sure the GX domain is off before turning off the GMU (CX) diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 0783e4b5486a..d1cc021c012c 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -887,9 +887,20 @@ static int adreno_get_pwrlevels(struct device *dev, DBG("fast_rate=%u, slow_rate=2700", gpu->fast_rate); /* Check for an interconnect path for the bus */ - gpu->icc_path = of_icc_get(dev, NULL); - if (IS_ERR(gpu->icc_path)) - gpu->icc_path = NULL; + gpu->gfx_mem_icc_path = of_icc_get(dev, "gfx-mem"); + if (!gpu->gfx_mem_icc_path) { + /* +* Keep compatbility with device trees that don't have an +* interconnect-names property. +*/ + gpu->gfx_mem_icc_path = of_icc_get(dev, NULL); + } + if (IS_ERR(gpu->gfx_mem_icc_path)) + gpu->gfx_mem_icc_path = NULL; + + gpu->ocmem_icc_path = of_icc_get(dev, "ocmem"); + if (IS_ERR(gpu->ocmem_icc_path)) + gpu->ocmem_icc_path = NULL; return 0; } @@ -976,7 +987,8 @@ void adreno_gpu_cleanup(struct adreno_gpu *adreno_gpu) for (i = 0; i < ARRAY_SIZE(adreno_gpu->info->fw); i++) release_firmware(adreno_gpu->fw[i]); - icc_put(gpu->icc_path); + icc_put(gpu->gfx_mem_icc_path); + icc_put(gpu->ocmem_icc_path); msm_gpu_cleanup(&adreno_gpu->base); } diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index ab8f0f9c9dc8..e72e56f7b0ef 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -111,7 +111,8 @@ struct msm_gpu { struct clk *ebi1_clk, *core_clk, *rbbmtimer_clk; uint32_t fast_rate; - struct icc_path *icc_path; + struct icc_path *gfx_mem_icc_path; + struct icc_path *ocmem_icc_path; /* Hang and Inactivity Detection: */ -- 2.21.0 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH 1/4] dt-bindings: drm/msm/gpu: document second interconnect
Some A3xx and all A4xx Adreno GPUs do not have GMEM inside the GPU core and must use the On Chip MEMory (OCMEM) in order to be functional. There's a separate interconnect path that needs to be setup to OCMEM. Let's document this second interconnect path that's available. Signed-off-by: Brian Masney --- Documentation/devicetree/bindings/display/msm/gpu.txt | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/display/msm/gpu.txt b/Documentation/devicetree/bindings/display/msm/gpu.txt index 2b8fd26c43b0..3e6cd3f64a78 100644 --- a/Documentation/devicetree/bindings/display/msm/gpu.txt +++ b/Documentation/devicetree/bindings/display/msm/gpu.txt @@ -23,7 +23,10 @@ Required properties: - iommus: optional phandle to an adreno iommu instance - operating-points-v2: optional phandle to the OPP operating points - interconnects: optional phandle to an interconnect provider. See - ../interconnect/interconnect.txt for details. + ../interconnect/interconnect.txt for details. Some A3xx and all A4xx platforms + will have two paths; all others will have one path. +- interconnect-names: The names of the interconnect paths that correspond to the + interconnects property. Values must be gfx-mem and ocmem. - qcom,gmu: For GMU attached devices a phandle to the GMU device that will control the power for the GPU. Applicable targets: - qcom,adreno-630.2 @@ -76,6 +79,7 @@ Example a6xx (with GMU): operating-points-v2 = <&gpu_opp_table>; interconnects = <&rsc_hlos MASTER_GFX3D &rsc_hlos SLAVE_EBI1>; + interconnect-names = "gfx-mem"; qcom,gmu = <&gmu>; -- 2.21.0 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH 3/4] drm/msm/a3xx: set interconnect bandwidth vote
Set the two interconnect paths for the GPU to maximum speed for now to work towards getting the GPU working upstream. We can revisit a later time to optimize this for battery life. Signed-off-by: Brian Masney --- drivers/gpu/drm/msm/adreno/a3xx_gpu.c | 8 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c index 07ddcc529573..f05adf9bc752 100644 --- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c @@ -504,6 +504,14 @@ struct msm_gpu *a3xx_gpu_init(struct drm_device *dev) DRM_DEV_ERROR(dev->dev, "No memory protection without IOMMU\n"); } + /* +* Set the ICC path to maximum speed for now by multiplying the fastest +* frequency by the bus width (8). We'll want to scale this later on to +* improve battery life. +*/ + icc_set_bw(gpu->gfx_mem_icc_path, 0, Bps_to_icc(gpu->fast_rate) * 8); + icc_set_bw(gpu->ocmem_icc_path, 0, Bps_to_icc(gpu->fast_rate) * 8); + return gpu; fail: -- 2.21.0 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH 4/4] drm/msm/a4xx: set interconnect bandwidth vote
Set the two interconnect paths for the GPU to maximum speed for now to work towards getting the GPU working upstream. We can revisit a later time to optimize this for battery life. Signed-off-by: Brian Masney --- drivers/gpu/drm/msm/adreno/a4xx_gpu.c | 8 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c index b01388a9e89e..c631d1df7751 100644 --- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c @@ -591,6 +591,14 @@ struct msm_gpu *a4xx_gpu_init(struct drm_device *dev) goto fail; } + /* +* Set the ICC path to maximum speed for now by multiplying the fastest +* frequency by the bus width (8). We'll want to scale this later on to +* improve battery life. +*/ + icc_set_bw(gpu->gfx_mem_icc_path, 0, Bps_to_icc(gpu->fast_rate) * 8); + icc_set_bw(gpu->ocmem_icc_path, 0, Bps_to_icc(gpu->fast_rate) * 8); + return gpu; fail: -- 2.21.0 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
Re: [Freedreno] [PATCH] drm/msm/mdp5: enable autocommit
On Tue, Nov 12, 2019 at 08:38:27AM -0700, Jeffrey Hugo wrote: > On Tue, Nov 12, 2019 at 3:49 AM Brian Masney wrote: > > > > Since the introduction of commit 2d99ced787e3 ("drm/msm: async commit > > support"), command-mode panels began throwing the following errors: > > > > msm fd90.mdss: pp done time out, lm=0 > > > > Let's fix this by enabling the autorefresh feature that's available in > > the MDP starting at version 1.0. This will cause the MDP to > > automatically send a frame to the panel every time the panel invokes > > the TE signal, which will trigger the PP_DONE IRQ. This requires not > > sending a START signal for command-mode panels. > > > > This fixes the error and gives us a counter for command-mode panels that > > we can use to implement async commit support for the MDP5 in a follow up > > patch. > > > > Signed-off-by: Brian Masney > > Suggested-by: Jeffrey Hugo > > --- > > drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c | 15 ++- > > drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c | 9 + > > 2 files changed, 15 insertions(+), 9 deletions(-) > > > > diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c > > b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c > > index 05cc04f729d6..539348cb6331 100644 > > --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c > > +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c > > @@ -456,6 +456,7 @@ static void mdp5_crtc_atomic_enable(struct drm_crtc > > *crtc, > > { > > struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); > > struct mdp5_crtc_state *mdp5_cstate = > > to_mdp5_crtc_state(crtc->state); > > + struct mdp5_pipeline *pipeline = &mdp5_cstate->pipeline; > > struct mdp5_kms *mdp5_kms = get_kms(crtc); > > struct device *dev = &mdp5_kms->pdev->dev; > > > > @@ -493,9 +494,21 @@ static void mdp5_crtc_atomic_enable(struct drm_crtc > > *crtc, > > > > mdp_irq_register(&mdp5_kms->base, &mdp5_crtc->err); > > > > - if (mdp5_cstate->cmd_mode) > > + if (mdp5_cstate->cmd_mode) { > > mdp_irq_register(&mdp5_kms->base, &mdp5_crtc->pp_done); > > > > + /* > > +* Enable autorefresh so we get regular ping/pong IRQs. > > +* - Bit 31 is the enable bit > > +* - Bits 0-15 represent the frame count, specifically how > > many > > +* TE events before the MDP sends a frame. > > +*/ > > + mdp5_write(mdp5_kms, > > + > > REG_MDP5_PP_AUTOREFRESH_CONFIG(pipeline->mixer->pp), > > + BIT(31) | BIT(0)); > > + crtc_flush_all(crtc); > > + } > > + > > mdp5_crtc->enabled = true; > > } > > > > diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c > > b/drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c > > index 030279d7b64b..aee295abada3 100644 > > --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c > > +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c > > @@ -187,14 +187,7 @@ static bool start_signal_needed(struct mdp5_ctl *ctl, > > if (!ctl->encoder_enabled) > > return false; > > > > - switch (intf->type) { > > - case INTF_WB: > > - return true; > > - case INTF_DSI: > > - return intf->mode == MDP5_INTF_DSI_MODE_COMMAND; > > - default: > > - return false; > > - } > > + return intf->type == INTF_WB; > > } > > I don't think this fully works. > > The whole "flush" thing exists because the configuration is double > buffered. You write to the flush register to tell the hardware to > pickup the new configuration, but it doesn't do that automatically. > It only picks up the new config on the next "vsync". When you have a > video mode panel, you have the timing engine running, which drives > that. With a command mode panel, you have either the start signal, or > the auto refresh to do the same, but you have a bit of a chicken and > egg situation where if you are programming the hardware from scratch, > autorefresh isn't already enabled to then pickup the config to enable > autorefresh. In this case, you'll need a single start to kick > everything off. However, if say the bootloader already configured > things and has autorefresh run
Re: [Freedreno] drm/msm: 'pp done time out' errors after async commit changes
On Mon, Nov 11, 2019 at 07:51:22AM -0700, Jeffrey Hugo wrote: > On Mon, Nov 11, 2019 at 4:38 AM Brian Masney wrote: > > > > On Sun, Nov 10, 2019 at 10:37:33AM -0700, Jeffrey Hugo wrote: > > > On Sun, Nov 10, 2019 at 6:53 AM Brian Masney > > > wrote: > > > > > > > > On Fri, Nov 08, 2019 at 07:56:25AM -0700, Jeffrey Hugo wrote: > > > > There's a REG_MDP5_PP_AUTOREFRESH_CONFIG() macro upstream here: > > > > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/msm/disp/mdp5/mdp5.xml.h#n1383 > > > > > > > > I'm not sure what to put in that register but I tried configuring it > > > > with a 1 this way and still have the same issue. > > > > > > > > diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c > > > > b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c > > > > index eeef41fcd4e1..6b9acf68fd2c 100644 > > > > --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c > > > > +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c > > > > @@ -80,6 +80,7 @@ static int pingpong_tearcheck_setup(struct > > > > drm_encoder *encoder, > > > > mdp5_write(mdp5_kms, REG_MDP5_PP_SYNC_THRESH(pp_id), > > > > MDP5_PP_SYNC_THRESH_START(4) | > > > > MDP5_PP_SYNC_THRESH_CONTINUE(4)); > > > > + mdp5_write(mdp5_kms, REG_MDP5_PP_AUTOREFRESH_CONFIG(pp_id), 1); > > > > > > > > return 0; > > > > } > > > > > > bit 31 is the enable bit (set that to 1), bits 15:0 are the > > > frame_count (how many te events before the MDP sends a frame, I'd > > > recommend set to 1). Then after its programmed, you'll have to flush > > > the config, and probably use a _START to make sure the flush takes > > > effect. > > > > I think that I initially get autorefresh enabled based on your > > description above since the ping pong IRQs occur much more frequently. > > However pretty quickly the error 'dsi_err_worker: status=c' is shown, > > the contents on the screen shift to the right, and the screen no longer > > updates after that. That error decodes to > > DSI_ERR_STATE_DLN0_PHY | DSI_ERR_STATE_FIFO according to dsi_host.c. > > > > Here's the relevant code that I have so far: > > So, Unless I missed it, you haven't disabled using _start when > autorefresh is enabled. If you are using both at the same time, > you'll overload the DSI and get those kinds of errors. That fixed the issue. Just to close out this thread, I submitted a patch with what I have here: https://lore.kernel.org/lkml/20191112104854.20850-1-masn...@onstation.org/T/#u I'll work on async commit support for the MDP5. Thanks Jeff and Rob! Brian ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH] drm/msm/mdp5: enable autocommit
Since the introduction of commit 2d99ced787e3 ("drm/msm: async commit support"), command-mode panels began throwing the following errors: msm fd90.mdss: pp done time out, lm=0 Let's fix this by enabling the autorefresh feature that's available in the MDP starting at version 1.0. This will cause the MDP to automatically send a frame to the panel every time the panel invokes the TE signal, which will trigger the PP_DONE IRQ. This requires not sending a START signal for command-mode panels. This fixes the error and gives us a counter for command-mode panels that we can use to implement async commit support for the MDP5 in a follow up patch. Signed-off-by: Brian Masney Suggested-by: Jeffrey Hugo --- drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c | 15 ++- drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c | 9 + 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c index 05cc04f729d6..539348cb6331 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c @@ -456,6 +456,7 @@ static void mdp5_crtc_atomic_enable(struct drm_crtc *crtc, { struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state); + struct mdp5_pipeline *pipeline = &mdp5_cstate->pipeline; struct mdp5_kms *mdp5_kms = get_kms(crtc); struct device *dev = &mdp5_kms->pdev->dev; @@ -493,9 +494,21 @@ static void mdp5_crtc_atomic_enable(struct drm_crtc *crtc, mdp_irq_register(&mdp5_kms->base, &mdp5_crtc->err); - if (mdp5_cstate->cmd_mode) + if (mdp5_cstate->cmd_mode) { mdp_irq_register(&mdp5_kms->base, &mdp5_crtc->pp_done); + /* +* Enable autorefresh so we get regular ping/pong IRQs. +* - Bit 31 is the enable bit +* - Bits 0-15 represent the frame count, specifically how many +* TE events before the MDP sends a frame. +*/ + mdp5_write(mdp5_kms, + REG_MDP5_PP_AUTOREFRESH_CONFIG(pipeline->mixer->pp), + BIT(31) | BIT(0)); + crtc_flush_all(crtc); + } + mdp5_crtc->enabled = true; } diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c index 030279d7b64b..aee295abada3 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c @@ -187,14 +187,7 @@ static bool start_signal_needed(struct mdp5_ctl *ctl, if (!ctl->encoder_enabled) return false; - switch (intf->type) { - case INTF_WB: - return true; - case INTF_DSI: - return intf->mode == MDP5_INTF_DSI_MODE_COMMAND; - default: - return false; - } + return intf->type == INTF_WB; } /* -- 2.21.0 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
Re: [Freedreno] drm/msm: 'pp done time out' errors after async commit changes
On Sun, Nov 10, 2019 at 10:37:33AM -0700, Jeffrey Hugo wrote: > On Sun, Nov 10, 2019 at 6:53 AM Brian Masney wrote: > > > > On Fri, Nov 08, 2019 at 07:56:25AM -0700, Jeffrey Hugo wrote: > > There's a REG_MDP5_PP_AUTOREFRESH_CONFIG() macro upstream here: > > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/msm/disp/mdp5/mdp5.xml.h#n1383 > > > > I'm not sure what to put in that register but I tried configuring it > > with a 1 this way and still have the same issue. > > > > diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c > > b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c > > index eeef41fcd4e1..6b9acf68fd2c 100644 > > --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c > > +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c > > @@ -80,6 +80,7 @@ static int pingpong_tearcheck_setup(struct drm_encoder > > *encoder, > > mdp5_write(mdp5_kms, REG_MDP5_PP_SYNC_THRESH(pp_id), > > MDP5_PP_SYNC_THRESH_START(4) | > > MDP5_PP_SYNC_THRESH_CONTINUE(4)); > > + mdp5_write(mdp5_kms, REG_MDP5_PP_AUTOREFRESH_CONFIG(pp_id), 1); > > > > return 0; > > } > > bit 31 is the enable bit (set that to 1), bits 15:0 are the > frame_count (how many te events before the MDP sends a frame, I'd > recommend set to 1). Then after its programmed, you'll have to flush > the config, and probably use a _START to make sure the flush takes > effect. I think that I initially get autorefresh enabled based on your description above since the ping pong IRQs occur much more frequently. However pretty quickly the error 'dsi_err_worker: status=c' is shown, the contents on the screen shift to the right, and the screen no longer updates after that. That error decodes to DSI_ERR_STATE_DLN0_PHY | DSI_ERR_STATE_FIFO according to dsi_host.c. Here's the relevant code that I have so far: diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c index eeef41fcd4e1..85a5cfe54ce8 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c @@ -157,6 +157,7 @@ void mdp5_cmd_encoder_enable(struct drm_encoder *encoder) struct mdp5_ctl *ctl = mdp5_cmd_enc->ctl; struct mdp5_interface *intf = mdp5_cmd_enc->intf; struct mdp5_pipeline *pipeline = mdp5_crtc_get_pipeline(encoder->crtc); + struct mdp5_kms *mdp5_kms = get_kms(encoder);; if (WARN_ON(mdp5_cmd_enc->enabled)) return; @@ -167,6 +168,14 @@ void mdp5_cmd_encoder_enable(struct drm_encoder *encoder) mdp5_ctl_commit(ctl, pipeline, mdp_ctl_flush_mask_encoder(intf), true); + if (intf->type == INTF_DSI && + intf->mode == MDP5_INTF_DSI_MODE_COMMAND) { + mdp5_write(mdp5_kms, + REG_MDP5_PP_AUTOREFRESH_CONFIG(pipeline->mixer->pp), + BIT(31) | BIT(0)); + mdp5_crtc_flush_all(encoder->crtc); + } + mdp5_ctl_set_encoder_state(ctl, pipeline, true); mdp5_cmd_enc->enabled = true; diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c index 05cc04f729d6..369746ebbc42 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c @@ -103,7 +104,7 @@ static u32 crtc_flush(struct drm_crtc *crtc, u32 flush_mask) * so that we can safely queue unref to current fb (ie. next * vblank we know hw is done w/ previous scanout_fb). */ -static u32 crtc_flush_all(struct drm_crtc *crtc) +u32 mdp5_crtc_flush_all(struct drm_crtc *crtc) { struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state); struct mdp5_hw_mixer *mixer, *r_mixer; @@ -734,7 +735,7 @@ static void mdp5_crtc_atomic_flush(struct drm_crtc *crtc, if (mdp5_cstate->cmd_mode) request_pp_done_pending(crtc); - mdp5_crtc->flushed_mask = crtc_flush_all(crtc); + mdp5_crtc->flushed_mask = mdp5_crtc_flush_all(crtc); /* XXX are we leaking out state here? */ mdp5_crtc->vblank.irqmask = mdp5_cstate->vblank_irqmask; diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h index 128866742593..3490328ab63e 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h @@ -278,6 +278,7 @@ enum mdp5_pipe mdp5_plane_right_pipe(struct drm_plane *plane); struct drm_plane *mdp5_plane_init(struct drm_device *dev, enum drm_plane_type type); +u32 mdp5_crtc_flush_all(struct drm_crtc *crtc); struct mdp5_ctl *mdp5_crtc_get_ctl(struct drm_crtc *crtc); uin
Re: [Freedreno] drm/msm: 'pp done time out' errors after async commit changes
On Fri, Nov 08, 2019 at 07:56:25AM -0700, Jeffrey Hugo wrote: > On Thu, Nov 7, 2019 at 7:03 PM Rob Clark wrote: > > > > On Thu, Nov 7, 2019 at 9:40 AM Jeffrey Hugo > > wrote: > > > > > > On Thu, Nov 7, 2019 at 9:17 AM Rob Clark wrote: > > > > > > > > On Thu, Nov 7, 2019 at 3:10 AM Brian Masney > > > > wrote: > > > > > > > > > > On Wed, Nov 06, 2019 at 08:58:59AM -0800, Rob Clark wrote: > > > > > > On Wed, Nov 6, 2019 at 8:47 AM Jeffrey Hugo > > > > > > wrote: > > > > > > > > > > > > > > On Wed, Nov 6, 2019 at 9:30 AM Rob Clark > > > > > > > wrote: > > > > > > > > > > > > > > > > On Wed, Nov 6, 2019 at 1:13 AM Brian Masney > > > > > > > > wrote: > > > > > > > > > > > > > > > > > > On Tue, Nov 05, 2019 at 08:23:27AM -0800, Rob Clark wrote: > > > > > > > > > > On Tue, Nov 5, 2019 at 2:08 AM Brian Masney > > > > > > > > > > wrote: > > > > > > > > > > > The 'pp done time out' errors go away if I revert the > > > > > > > > > > > following three > > > > > > > > > > > commits: > > > > > > > > > > > > > > > > > > > > > > cd6d923167b1 ("drm/msm/dpu: async commit support") > > > > > > > > > > > d934a712c5e6 ("drm/msm: add atomic traces") > > > > > > > > > > > 2d99ced787e3 ("drm/msm: async commit support") > > > > > > > > > > > > > > > > > > > > > > I reverted the first one to fix a compiler error, and the > > > > > > > > > > > second one so > > > > > > > > > > > that the last patch can be reverted without any merge > > > > > > > > > > > conflicts. > > > > > > > > > > > > > > > > > > > > > > I see that crtc_flush() calls mdp5_ctl_commit(). I tried > > > > > > > > > > > to use > > > > > > > > > > > crtc_flush_all() in mdp5_flush_commit() and the contents > > > > > > > > > > > of the frame > > > > > > > > > > > buffer dance around the screen like its out of sync. I > > > > > > > > > > > renamed > > > > > > > > > > > crtc_flush_all() to mdp5_crtc_flush_all() and removed the > > > > > > > > > > > static > > > > > > > > > > > declaration. Here's the relevant part of what I tried: > > > > > > > > > > > > > > > > > > > > > > --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c > > > > > > > > > > > +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c > > > > > > > > > > > @@ -171,7 +171,15 @@ static void > > > > > > > > > > > mdp5_prepare_commit(struct msm_kms *kms, struct > > > > > > > > > > > drm_atomic_state *st > > > > > > > > > > > > > > > > > > > > > > static void mdp5_flush_commit(struct msm_kms *kms, > > > > > > > > > > > unsigned crtc_mask) > > > > > > > > > > > { > > > > > > > > > > > - /* TODO */ > > > > > > > > > > > + struct mdp5_kms *mdp5_kms = > > > > > > > > > > > to_mdp5_kms(to_mdp_kms(kms)); > > > > > > > > > > > + struct drm_crtc *crtc; > > > > > > > > > > > + > > > > > > > > > > > + for_each_crtc_mask(mdp5_kms->dev, crtc, > > > > > > > > > > > crtc_mask) { > > > > > > > > > > > + if (!crtc->state->active) > > > > > > > > > > > + continue; > > > > > > > > > > > + > > > > > > > > > > > + mdp5_crtc_flush_all(crtc); > > > > > > > > > > > + } > > &
Re: [Freedreno] drm/msm: 'pp done time out' errors after async commit changes
On Wed, Nov 06, 2019 at 08:58:59AM -0800, Rob Clark wrote: > On Wed, Nov 6, 2019 at 8:47 AM Jeffrey Hugo wrote: > > > > On Wed, Nov 6, 2019 at 9:30 AM Rob Clark wrote: > > > > > > On Wed, Nov 6, 2019 at 1:13 AM Brian Masney wrote: > > > > > > > > On Tue, Nov 05, 2019 at 08:23:27AM -0800, Rob Clark wrote: > > > > > On Tue, Nov 5, 2019 at 2:08 AM Brian Masney > > > > > wrote: > > > > > > The 'pp done time out' errors go away if I revert the following > > > > > > three > > > > > > commits: > > > > > > > > > > > > cd6d923167b1 ("drm/msm/dpu: async commit support") > > > > > > d934a712c5e6 ("drm/msm: add atomic traces") > > > > > > 2d99ced787e3 ("drm/msm: async commit support") > > > > > > > > > > > > I reverted the first one to fix a compiler error, and the second > > > > > > one so > > > > > > that the last patch can be reverted without any merge conflicts. > > > > > > > > > > > > I see that crtc_flush() calls mdp5_ctl_commit(). I tried to use > > > > > > crtc_flush_all() in mdp5_flush_commit() and the contents of the > > > > > > frame > > > > > > buffer dance around the screen like its out of sync. I renamed > > > > > > crtc_flush_all() to mdp5_crtc_flush_all() and removed the static > > > > > > declaration. Here's the relevant part of what I tried: > > > > > > > > > > > > --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c > > > > > > +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c > > > > > > @@ -171,7 +171,15 @@ static void mdp5_prepare_commit(struct msm_kms > > > > > > *kms, struct drm_atomic_state *st > > > > > > > > > > > > static void mdp5_flush_commit(struct msm_kms *kms, unsigned > > > > > > crtc_mask) > > > > > > { > > > > > > - /* TODO */ > > > > > > + struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); > > > > > > + struct drm_crtc *crtc; > > > > > > + > > > > > > + for_each_crtc_mask(mdp5_kms->dev, crtc, crtc_mask) { > > > > > > + if (!crtc->state->active) > > > > > > + continue; > > > > > > + > > > > > > + mdp5_crtc_flush_all(crtc); > > > > > > + } > > > > > > } > > > > > > > > > > > > Any tips would be appreciated. > > > > > > > > > > > > > > > I think this is along the lines of what we need to enable async commit > > > > > for mdp5 (but also removing the flush from the atomic-commit path).. > > > > > the principle behind the async commit is to do all the atomic state > > > > > commit normally, but defer writing the flush bits. This way, if you > > > > > get another async update before the next vblank, you just apply it > > > > > immediately instead of waiting for vblank. > > > > > > > > > > But I guess you are on a command mode panel, if I remember? Which is > > > > > a case I didn't have a way to test. And I'm not entirely about how > > > > > kms_funcs->vsync_time() should be implemented for cmd mode panels. > > > > > > > > Yes, this is a command-mode panel and there's no hardware frame counter > > > > available. The key to getting the display working on this phone was this > > > > patch: > > > > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=2bab52af6fe68c43b327a57e5ce5fc10eefdfadf > > > > > > > > > That all said, I think we should first fix what is broken, before > > > > > worrying about extending async commit support to mdp5.. which > > > > > shouldn't hit the async==true path, due to not implementing > > > > > kms_funcs->vsync_time(). > > > > > > > > > > What I think is going on is that, in the cmd mode case, > > > > > mdp5_wait_flush() (indirectly) calls mdp5_crtc_wait_for_pp_done(), > > > > > which waits for a pp-done irq regardless of whether there is a flush > > > > > in progress. Since there is no fl
Re: [Freedreno] drm/msm: 'pp done time out' errors after async commit changes
On Tue, Nov 05, 2019 at 08:23:27AM -0800, Rob Clark wrote: > On Tue, Nov 5, 2019 at 2:08 AM Brian Masney wrote: > > The 'pp done time out' errors go away if I revert the following three > > commits: > > > > cd6d923167b1 ("drm/msm/dpu: async commit support") > > d934a712c5e6 ("drm/msm: add atomic traces") > > 2d99ced787e3 ("drm/msm: async commit support") > > > > I reverted the first one to fix a compiler error, and the second one so > > that the last patch can be reverted without any merge conflicts. > > > > I see that crtc_flush() calls mdp5_ctl_commit(). I tried to use > > crtc_flush_all() in mdp5_flush_commit() and the contents of the frame > > buffer dance around the screen like its out of sync. I renamed > > crtc_flush_all() to mdp5_crtc_flush_all() and removed the static > > declaration. Here's the relevant part of what I tried: > > > > --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c > > +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c > > @@ -171,7 +171,15 @@ static void mdp5_prepare_commit(struct msm_kms *kms, > > struct drm_atomic_state *st > > > > static void mdp5_flush_commit(struct msm_kms *kms, unsigned crtc_mask) > > { > > - /* TODO */ > > + struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); > > + struct drm_crtc *crtc; > > + > > + for_each_crtc_mask(mdp5_kms->dev, crtc, crtc_mask) { > > + if (!crtc->state->active) > > + continue; > > + > > + mdp5_crtc_flush_all(crtc); > > + } > > } > > > > Any tips would be appreciated. > > > I think this is along the lines of what we need to enable async commit > for mdp5 (but also removing the flush from the atomic-commit path).. > the principle behind the async commit is to do all the atomic state > commit normally, but defer writing the flush bits. This way, if you > get another async update before the next vblank, you just apply it > immediately instead of waiting for vblank. > > But I guess you are on a command mode panel, if I remember? Which is > a case I didn't have a way to test. And I'm not entirely about how > kms_funcs->vsync_time() should be implemented for cmd mode panels. Yes, this is a command-mode panel and there's no hardware frame counter available. The key to getting the display working on this phone was this patch: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=2bab52af6fe68c43b327a57e5ce5fc10eefdfadf > That all said, I think we should first fix what is broken, before > worrying about extending async commit support to mdp5.. which > shouldn't hit the async==true path, due to not implementing > kms_funcs->vsync_time(). > > What I think is going on is that, in the cmd mode case, > mdp5_wait_flush() (indirectly) calls mdp5_crtc_wait_for_pp_done(), > which waits for a pp-done irq regardless of whether there is a flush > in progress. Since there is no flush pending, the irq never comes. > But the expectation is that kms_funcs->wait_flush() returns > immediately if there is nothing to wait for. I don't think that's happening in this case. I added some pr_info() statements to request_pp_done_pending() and mdp5_crtc_pp_done_irq(). Here's the first two sets of messages that appear in dmesg: [ 14.018907] msm fd90.mdss: pp done time out, lm=0 [ 14.018993] request_pp_done_pending: HERE [ 14.074208] mdp5_crtc_pp_done_irq: HERE [ 14.074368] Console: switching to colour frame buffer device 135x120 [ 14.138938] msm fd90.mdss: pp done time out, lm=0 [ 14.139021] request_pp_done_pending: HERE [ 14.158097] mdp5_crtc_pp_done_irq: HERE The messages go on like this with the same pattern. I tried two different changes: 1) I moved the request_pp_done_pending() and corresponding if statement from mdp5_crtc_atomic_flush() and into mdp5_crtc_atomic_begin(). 2) I increased the timeout in wait_for_completion_timeout() by several increments; all the way to 5 seconds. I haven't dug into the new code anymore. Brian ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
Re: [Freedreno] drm/msm: 'pp done time out' errors after async commit changes
On Mon, Nov 04, 2019 at 04:19:07PM -0800, Rob Clark wrote: > On Mon, Nov 4, 2019 at 4:01 PM Brian Masney wrote: > > > > Hey Rob, > > > > Since commit 2d99ced787e3 ("drm/msm: async commit support"), the frame > > buffer console on my Nexus 5 began throwing these errors: > > > > msm fd90.mdss: pp done time out, lm=0 > > > > The display still works. > > > > I see that mdp5_flush_commit() was introduced in commit 9f6b65642bd2 > > ("drm/msm: add kms->flush_commit()") with a TODO comment and the commit > > description mentions flushing registers. I assume that this is the > > proper fix. If so, can you point me to where these registers are > > defined and I can work on the mdp5 implementation. > > See mdp5_ctl_commit(), which writes the CTL_FLUSH registers.. the idea > would be to defer writing CTL_FLUSH[ctl_id] = flush_mask until > kms->flush() (which happens from a timer shortly before vblank). > > But I think the async flush case should not come up with fbcon? It > was really added to cope with hwcursor updates (and userspace that > assumes it can do an unlimited # of cursor updates per frame).. the > intention was that nothing should change in the sequence for mdp5 (but > I guess that was not the case). The 'pp done time out' errors go away if I revert the following three commits: cd6d923167b1 ("drm/msm/dpu: async commit support") d934a712c5e6 ("drm/msm: add atomic traces") 2d99ced787e3 ("drm/msm: async commit support") I reverted the first one to fix a compiler error, and the second one so that the last patch can be reverted without any merge conflicts. I see that crtc_flush() calls mdp5_ctl_commit(). I tried to use crtc_flush_all() in mdp5_flush_commit() and the contents of the frame buffer dance around the screen like its out of sync. I renamed crtc_flush_all() to mdp5_crtc_flush_all() and removed the static declaration. Here's the relevant part of what I tried: --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c @@ -171,7 +171,15 @@ static void mdp5_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *st static void mdp5_flush_commit(struct msm_kms *kms, unsigned crtc_mask) { - /* TODO */ + struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); + struct drm_crtc *crtc; + + for_each_crtc_mask(mdp5_kms->dev, crtc, crtc_mask) { + if (!crtc->state->active) + continue; + + mdp5_crtc_flush_all(crtc); + } } Any tips would be appreciated. Brian ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] drm/msm: 'pp done time out' errors after async commit changes
Hey Rob, Since commit 2d99ced787e3 ("drm/msm: async commit support"), the frame buffer console on my Nexus 5 began throwing these errors: msm fd90.mdss: pp done time out, lm=0 The display still works. I see that mdp5_flush_commit() was introduced in commit 9f6b65642bd2 ("drm/msm: add kms->flush_commit()") with a TODO comment and the commit description mentions flushing registers. I assume that this is the proper fix. If so, can you point me to where these registers are defined and I can work on the mdp5 implementation. Thanks, Brian ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
Re: [Freedreno] [PATCH RFC v2 4/5] ARM: dts: qcom: msm8974: add HDMI nodes
On Wed, Oct 09, 2019 at 08:39:26AM -0700, Stephen Boyd wrote: > Quoting Brian Masney (2019-10-08 23:05:20) > > On Tue, Oct 08, 2019 at 07:21:30PM -0700, Stephen Boyd wrote: > > > Quoting Brian Masney (2019-10-06 18:45:08) > > > > diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi > > > > b/arch/arm/boot/dts/qcom-msm8974.dtsi > > > > index 7fc23e422cc5..af02eace14e2 100644 > > > > --- a/arch/arm/boot/dts/qcom-msm8974.dtsi > > > > +++ b/arch/arm/boot/dts/qcom-msm8974.dtsi > > > > @@ -1335,6 +1342,77 @@ > > > > clocks = <&mmcc MDSS_AHB_CLK>; > > > > clock-names = "iface"; > > > > }; > > > > + > > > > + hdmi: hdmi-tx@fd922100 { > > > > + status = "disabled"; > > > > + > > > > + compatible = "qcom,hdmi-tx-8974"; > > > > + reg = <0xfd922100 0x35c>, > > > > + <0xfc4b8000 0x60f0>; > > > > + reg-names = "core_physical", > > > > + "qfprom_physical"; > > > > > > Is this the qfprom "uncorrected" physical address? If so, why can't this > > > node use an nvmem to read whatever it needs out of the qfprom? > > > > The MSM HDMI code is configured to look for this reg-name here: > > > > https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/msm/hdmi/hdmi.c#L582 > > > > There is a qcom,qfprom configured for this board in DTS, however its at > > a different address range, so maybe there are multiple qfproms? > > > > https://elixir.bootlin.com/linux/latest/source/arch/arm/boot/dts/qcom-msm8974.dtsi#L424 > > > > msm8996.dtsi has the same style of configuration: > > > > https://elixir.bootlin.com/linux/latest/source/arch/arm64/boot/dts/qcom/msm8996.dtsi#L956 > > https://elixir.bootlin.com/linux/latest/source/arch/arm64/boot/dts/qcom/msm8996.dtsi#L1736 > > > > There's only one qfprom and there's the address space that's > "uncorrected" which is not supposed to be used and there's the space > that is "corrected" and is supposed to be used. It looks like this is > poking the uncorrected space and it should probably stop doing that and > use the nvmem provider instead. Maybe someone with docs for this chip > and 8996 can help confirm this. Do you know of any publicly-available documentation that describes the "uncorrected" and "corrected" addresses? I got that qfprom address for the HDMI from here: https://github.com/AICP/kernel_lge_hammerhead/blob/n7.1/arch/arm/boot/dts/msm8974-mdss.dtsi#L101 I assume the downstream kernel probably doesn't have the corrected address anywhere else? Brian ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
Re: [Freedreno] [PATCH RFC v2 4/5] ARM: dts: qcom: msm8974: add HDMI nodes
On Tue, Oct 08, 2019 at 07:21:30PM -0700, Stephen Boyd wrote: > Quoting Brian Masney (2019-10-06 18:45:08) > > diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi > > b/arch/arm/boot/dts/qcom-msm8974.dtsi > > index 7fc23e422cc5..af02eace14e2 100644 > > --- a/arch/arm/boot/dts/qcom-msm8974.dtsi > > +++ b/arch/arm/boot/dts/qcom-msm8974.dtsi > > @@ -1335,6 +1342,77 @@ > > clocks = <&mmcc MDSS_AHB_CLK>; > > clock-names = "iface"; > > }; > > + > > + hdmi: hdmi-tx@fd922100 { > > + status = "disabled"; > > + > > + compatible = "qcom,hdmi-tx-8974"; > > + reg = <0xfd922100 0x35c>, > > + <0xfc4b8000 0x60f0>; > > + reg-names = "core_physical", > > + "qfprom_physical"; > > Is this the qfprom "uncorrected" physical address? If so, why can't this > node use an nvmem to read whatever it needs out of the qfprom? The MSM HDMI code is configured to look for this reg-name here: https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/msm/hdmi/hdmi.c#L582 There is a qcom,qfprom configured for this board in DTS, however its at a different address range, so maybe there are multiple qfproms? https://elixir.bootlin.com/linux/latest/source/arch/arm/boot/dts/qcom-msm8974.dtsi#L424 msm8996.dtsi has the same style of configuration: https://elixir.bootlin.com/linux/latest/source/arch/arm64/boot/dts/qcom/msm8996.dtsi#L956 https://elixir.bootlin.com/linux/latest/source/arch/arm64/boot/dts/qcom/msm8996.dtsi#L1736 Brian ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH RFC v2 3/5] ARM: dts: qcom: pm8941: add 5vs2 regulator node
pm8941 is missing the 5vs2 regulator node so let's add it since its needed to get the external display working. This regulator was already configured in the interrupts property on the parent node. Note that this regulator is referred to as mvs2 in the downstream MSM kernel sources. Signed-off-by: Brian Masney Reviewed-by: Linus Walleij --- Changes since v1: - None arch/arm/boot/dts/qcom-pm8941.dtsi | 10 ++ 1 file changed, 10 insertions(+) diff --git a/arch/arm/boot/dts/qcom-pm8941.dtsi b/arch/arm/boot/dts/qcom-pm8941.dtsi index f198480c8ef4..c1f2012d1c8b 100644 --- a/arch/arm/boot/dts/qcom-pm8941.dtsi +++ b/arch/arm/boot/dts/qcom-pm8941.dtsi @@ -178,6 +178,16 @@ qcom,vs-soft-start-strength = <0>; regulator-initial-mode = <1>; }; + + pm8941_5vs2: 5vs2 { + regulator-enable-ramp-delay = <1000>; + regulator-pull-down; + regulator-over-current-protection; + qcom,ocp-max-retries = <10>; + qcom,ocp-retry-delay = <30>; + qcom,vs-soft-start-strength = <0>; + regulator-initial-mode = <1>; + }; }; }; }; -- 2.21.0 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH RFC v2 5/5] ARM: dts: qcom: msm8974-hammerhead: add support for external display
Add HDMI nodes and other supporting infrastructure in order to support the external display. This is based on work from Jonathan Marek. Signed-off-by: Brian Masney Reviewed-by: Linus Walleij --- Changes since v1: - Regulators always on as a temporary haack. - Hot plug detect pin for the HDMI bridge needs to be low. .../qcom-msm8974-lge-nexus5-hammerhead.dts| 142 ++ 1 file changed, 142 insertions(+) diff --git a/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts b/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts index b607c9ff9e12..380a805cd1f0 100644 --- a/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts +++ b/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts @@ -235,6 +235,36 @@ pinctrl-names = "default"; pinctrl-0 = <&wlan_regulator_pin>; }; + + anx_avdd33: avdd33 { + compatible = "regulator-fixed"; + + regulator-name = "avdd-3p3"; + regulator-min-microvolt = <330>; + regulator-max-microvolt = <330>; + regulator-always-on; // FIXME + + gpio = <&pm8941_gpios 26 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-names = "default"; + pinctrl-0 = <&anx_avdd33_pin>; + }; + + anx_vdd10: vdd10 { + compatible = "regulator-fixed"; + + regulator-name = "vdd-1p0"; + regulator-min-microvolt = <100>; + regulator-max-microvolt = <100>; + regulator-always-on; // FIXME + + gpio = <&pm8941_gpios 8 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-names = "default"; + pinctrl-0 = <&anx_vdd10_pin>; + }; }; &soc { @@ -371,6 +401,40 @@ function = "gpio"; }; }; + + hdmi_pin: hdmi { + cec { + pins = "gpio31"; + function = "hdmi_cec"; + }; + + ddc { + pins = "gpio32", "gpio33"; + function = "hdmi_ddc"; + }; + + hpd { + pins = "gpio34"; + function = "hdmi_hpd"; + }; + }; + + anx_msm_pin: anx { + irq { + pins = "gpio28"; + function = "gpio"; + drive-strength = <8>; + bias-pull-up; + input-enable; + }; + + reset { + pins = "gpio68"; + function = "gpio"; + drive-strength = <8>; + bias-pull-up; + }; + }; }; vibrator@fd8c3450 { @@ -471,6 +535,28 @@ default-brightness = <200>; }; }; + + anx7808@72 { + compatible = "analogix,anx7808"; + reg = <0x72>; + interrupts-extended = <&msmgpio 28 IRQ_TYPE_EDGE_RISING>; + + hpd-gpios = <&pm8941_gpios 13 GPIO_ACTIVE_LOW>; + pd-gpios = <&pm8941_gpios 14 GPIO_ACTIVE_HIGH>; + reset-gpios = <&msmgpio 68 GPIO_ACTIVE_LOW>; + + pinctrl-names = "default"; + pinctrl-0 = <&anx_msm_pin>, <&anx_pin>; + + dvdd10-supply = <&anx_vdd10>; + avdd33-supply = <&anx_avdd33>; + + port { + anx7808_in: endpoint { + remote-endpoint = <&hdmi_out>; + }; + }; + }; }; i2c@f9968000 { @@ -664,6 +750,29 @@ vddio-supply = <&pm8941_l12>; }; + + hdmi-tx@fd922100 { + status = "ok"; + + pinctrl-names = "default"; + pinctrl-0 = <&hdmi_pin>; + +
[Freedreno] [PATCH RFC v2 4/5] ARM: dts: qcom: msm8974: add HDMI nodes
Add HDMI tx and phy nodes to support an external display that can be connected over the SlimPort. This is based on work from Jonathan Marek. Signed-off-by: Brian Masney Reviewed-by: Linus Walleij --- Changes since v1: - Add hdmi_pll to hdmi-phy node - add power-domain to hdmi-phy per binding specification - Remove FIXME comment regarding the hpd-gdsc-supply. I saw a recent post on linux-arm-msm that this is present for running the upstream MSM display driver on the downstream kernel. arch/arm/boot/dts/qcom-msm8974.dtsi | 78 + 1 file changed, 78 insertions(+) diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi index 7fc23e422cc5..af02eace14e2 100644 --- a/arch/arm/boot/dts/qcom-msm8974.dtsi +++ b/arch/arm/boot/dts/qcom-msm8974.dtsi @@ -1258,6 +1258,13 @@ port@0 { reg = <0>; + mdp5_intf3_out: endpoint { + remote-endpoint = <&hdmi_in>; + }; + }; + + port@1 { + reg = <1>; mdp5_intf1_out: endpoint { remote-endpoint = <&dsi0_in>; }; @@ -1335,6 +1342,77 @@ clocks = <&mmcc MDSS_AHB_CLK>; clock-names = "iface"; }; + + hdmi: hdmi-tx@fd922100 { + status = "disabled"; + + compatible = "qcom,hdmi-tx-8974"; + reg = <0xfd922100 0x35c>, + <0xfc4b8000 0x60f0>; + reg-names = "core_physical", + "qfprom_physical"; + + interrupt-parent = <&mdss>; + interrupts = <8 IRQ_TYPE_LEVEL_HIGH>; + + power-domains = <&mmcc MDSS_GDSC>; + + clocks = <&mmcc MDSS_MDP_CLK>, +<&mmcc MDSS_AHB_CLK>, +<&mmcc MDSS_HDMI_CLK>, +<&mmcc MDSS_HDMI_AHB_CLK>, +<&mmcc MDSS_EXTPCLK_CLK>; + clock-names = "mdp_core", + "iface", + "core", + "alt_iface", + "extp"; + + hpd-5v-supply = <&pm8941_5vs2>; + core-vdda-supply = <&pm8941_l12>; + core-vcc-supply = <&pm8941_s3>; + + phys = <&hdmi_phy>; + phy-names = "hdmi_phy"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + hdmi_in: endpoint { + remote-endpoint = <&mdp5_intf3_out>; + }; + }; + + port@1 { + reg = <1>; + }; + }; + }; + + hdmi_phy: hdmi-phy@fd922500 { + status = "disabled"; + + compatible = "qcom,hdmi-phy-8974"; + reg = <0xfd922500 0x7c>, + <0xfd922700 0xd4>; + reg-names = "hdmi_phy", + "hdmi_pll"; + + clocks = <&mmcc MDSS_AHB_CLK>, +<&mmcc MDSS_HDMI_AHB_CLK>; + clock-names = "iface", +
[Freedreno] [PATCH RFC v2 1/5] drm/bridge: analogix-anx78xx: add support for avdd33 regulator
Add support for the avdd33 regulator to the analogix-anx78xx driver. Note that the regulator is currently enabled during driver probe and disabled when the driver is removed. This is currently how the downstream MSM kernel sources do this. Let's not merge this upstream for the mean time until I get the external display fully working on the Nexus 5 and then I can submit proper support then that powers down this regulator in the power off function. Signed-off-by: Brian Masney --- Changes since v1: - None drivers/gpu/drm/bridge/analogix-anx78xx.c | 33 +++ 1 file changed, 33 insertions(+) diff --git a/drivers/gpu/drm/bridge/analogix-anx78xx.c b/drivers/gpu/drm/bridge/analogix-anx78xx.c index dec3f7e66aa0..e25fae36dbe1 100644 --- a/drivers/gpu/drm/bridge/analogix-anx78xx.c +++ b/drivers/gpu/drm/bridge/analogix-anx78xx.c @@ -56,6 +56,7 @@ static const u8 anx781x_i2c_addresses[] = { struct anx78xx_platform_data { struct regulator *dvdd10; + struct regulator *avdd33; struct gpio_desc *gpiod_hpd; struct gpio_desc *gpiod_pd; struct gpio_desc *gpiod_reset; @@ -715,10 +716,42 @@ static int anx78xx_start(struct anx78xx *anx78xx) return err; } +static void anx78xx_disable_regulator_action(void *_data) +{ + struct anx78xx_platform_data *pdata = _data; + + regulator_disable(pdata->avdd33); +} + static int anx78xx_init_pdata(struct anx78xx *anx78xx) { struct anx78xx_platform_data *pdata = &anx78xx->pdata; struct device *dev = &anx78xx->client->dev; + int err; + + /* 3.3V digital core power regulator */ + pdata->avdd33 = devm_regulator_get(dev, "avdd33"); + if (IS_ERR(pdata->avdd33)) { + err = PTR_ERR(pdata->avdd33); + if (err != -EPROBE_DEFER) + DRM_ERROR("avdd33 regulator not found\n"); + + return err; + } + + err = regulator_enable(pdata->avdd33); + if (err) { + DRM_ERROR("Failed to enable avdd33 regulator: %d\n", err); + return err; + } + + err = devm_add_action(dev, anx78xx_disable_regulator_action, + pdata); + if (err < 0) { + dev_err(dev, "Failed to setup regulator cleanup action %d\n", + err); + return err; + } /* 1.0V digital core power regulator */ pdata->dvdd10 = devm_regulator_get(dev, "dvdd10"); -- 2.21.0 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH RFC v2 0/5] drm/msm: external HDMI support for Nexus 5 phone
I am using an Analogix SP6001 SlimPort Micro-USB to 4K HDMI Adapter to connect my Nexus 5 phone to an external display. The external display is not fully working yet however I think I'm close. When I plug the cable into the phone, the interrupt for the hot plug detect GPIO for the HDMI bridge (Analogix ANX7808) fires and anx78xx_handle_common_int_4() shows that the interrupt status bit is set to SP_HPD_ESYNC_ERR. The second hot plug detect pin (for qcom,hdmi-tx-8974 for the MSM KMS/DRM driver) does not fire, and the clocks are not configured via msm_hdmi_phy_pll_init(). I suspect that this is the issue that I need to solve next. I verified in the downstream MSM sources that IRQ 8 on the mdss is the correct IRQ number for hdmi-tx. Here's the relevant line from /proc/interrupts showing that no interrupts are triggered: 93: 0 0 0 0 mdss 8 Edge hdmi_isr. I'm going to continue digging through the code but I'd appreciate any suggestions for things to check. I assume that the IRQs for both hot plug detect pins should fire when I plug the cable in. Unfortunately, the display doesn't work for me with the downstream kernel and I only have access to a running downstream kernel over the serial console. High-level changes since v1: - Hot plug detect interrupt now working properly on HDMI bridge - Introduce msm8974 PLL support I've held back some cosmetic changes to the drivers and only included the necessary changes required to get this functional. This requires the following patch I sent out on 2019-09-22 to analogix-anx78xx that corrects an i2c address: https://lore.kernel.org/lkml/20190922175940.5311-1-masn...@onstation.org/ Brian Masney (5): drm/bridge: analogix-anx78xx: add support for avdd33 regulator drm/msm/hdmi: add msm8974 PLL support ARM: dts: qcom: pm8941: add 5vs2 regulator node ARM: dts: qcom: msm8974: add HDMI nodes ARM: dts: qcom: msm8974-hammerhead: add support for external display .../qcom-msm8974-lge-nexus5-hammerhead.dts| 142 arch/arm/boot/dts/qcom-msm8974.dtsi | 78 ++ arch/arm/boot/dts/qcom-pm8941.dtsi| 10 + drivers/gpu/drm/bridge/analogix-anx78xx.c | 33 + drivers/gpu/drm/msm/Makefile | 1 + drivers/gpu/drm/msm/hdmi/hdmi.h | 6 + drivers/gpu/drm/msm/hdmi/hdmi_phy.c | 4 +- drivers/gpu/drm/msm/hdmi/hdmi_pll_8974.c | 684 ++ 8 files changed, 957 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/msm/hdmi/hdmi_pll_8974.c -- 2.21.0 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH RFC v2 2/5] drm/msm/hdmi: add msm8974 PLL support
Add msm8974 Phase-Locked Loop (PLL) support to the MSM HDMI so that an external display can be used on this SoC. Signed-off-by: Brian Masney --- Changes since v1: - New patch introduced in v2 drivers/gpu/drm/msm/Makefile | 1 + drivers/gpu/drm/msm/hdmi/hdmi.h | 6 + drivers/gpu/drm/msm/hdmi/hdmi_phy.c | 4 +- drivers/gpu/drm/msm/hdmi/hdmi_pll_8974.c | 684 +++ 4 files changed, 694 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/msm/hdmi/hdmi_pll_8974.c diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 7a05cbf2f820..fa1c9cf86e38 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -100,6 +100,7 @@ msm-$(CONFIG_DRM_MSM_GPU_STATE) += adreno/a6xx_gpu_state.o msm-$(CONFIG_DRM_FBDEV_EMULATION) += msm_fbdev.o msm-$(CONFIG_COMMON_CLK) += disp/mdp4/mdp4_lvds_pll.o msm-$(CONFIG_COMMON_CLK) += hdmi/hdmi_pll_8960.o +msm-$(CONFIG_COMMON_CLK) += hdmi/hdmi_pll_8974.o msm-$(CONFIG_COMMON_CLK) += hdmi/hdmi_phy_8996.o msm-$(CONFIG_DRM_MSM_HDMI_HDCP) += hdmi/hdmi_hdcp.o diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h b/drivers/gpu/drm/msm/hdmi/hdmi.h index 982865866a29..59c3cf09cb0d 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.h +++ b/drivers/gpu/drm/msm/hdmi/hdmi.h @@ -184,6 +184,7 @@ void __exit msm_hdmi_phy_driver_unregister(void); #ifdef CONFIG_COMMON_CLK int msm_hdmi_pll_8960_init(struct platform_device *pdev); +int msm_hdmi_pll_8974_init(struct platform_device *pdev); int msm_hdmi_pll_8996_init(struct platform_device *pdev); #else static inline int msm_hdmi_pll_8960_init(struct platform_device *pdev) @@ -191,6 +192,11 @@ static inline int msm_hdmi_pll_8960_init(struct platform_device *pdev) return -ENODEV; } +static inline int msm_hdmi_pll_8974_init(struct platform_device *pdev) +{ + return -ENODEV; +} + static inline int msm_hdmi_pll_8996_init(struct platform_device *pdev) { return -ENODEV; diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_phy.c b/drivers/gpu/drm/msm/hdmi/hdmi_phy.c index 8a38d4b95102..29d01004ee3b 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_phy.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_phy.c @@ -123,6 +123,9 @@ static int msm_hdmi_phy_pll_init(struct platform_device *pdev, case MSM_HDMI_PHY_8960: ret = msm_hdmi_pll_8960_init(pdev); break; + case MSM_HDMI_PHY_8x74: + ret = msm_hdmi_pll_8974_init(pdev); + break; case MSM_HDMI_PHY_8996: ret = msm_hdmi_pll_8996_init(pdev); break; @@ -130,7 +133,6 @@ static int msm_hdmi_phy_pll_init(struct platform_device *pdev, * we don't have PLL support for these, don't report an error for now */ case MSM_HDMI_PHY_8x60: - case MSM_HDMI_PHY_8x74: default: ret = 0; break; diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_pll_8974.c b/drivers/gpu/drm/msm/hdmi/hdmi_pll_8974.c new file mode 100644 index ..6ce0648ae71d --- /dev/null +++ b/drivers/gpu/drm/msm/hdmi/hdmi_pll_8974.c @@ -0,0 +1,684 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2019 Brian Masney + * + * Based on clock-mdss-8974.c in downstream MSM sources. + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Based on hdmi_pll_8960.c + * Copyright (C) 2013 Red Hat + * Copyright (c) 2016 The Linux Foundation. All rights reserved. + */ + +#include +#include + +#include "hdmi.h" + +/* hdmi phy registers */ +#define HDMI_PHY_ANA_CFG0 0x +#define HDMI_PHY_ANA_CFG1 0x0004 +#define HDMI_PHY_ANA_CFG2 0x0008 +#define HDMI_PHY_ANA_CFG3 0x000c +#define HDMI_PHY_PD_CTRL0 0x0010 +#define HDMI_PHY_PD_CTRL1 0x0014 +#define HDMI_PHY_GLB_CFG 0x0018 +#define HDMI_PHY_DCC_CFG0 0x001c +#define HDMI_PHY_DCC_CFG1 0x0020 +#define HDMI_PHY_TXCAL_CFG00x0024 +#define HDMI_PHY_TXCAL_CFG10x0028 +#define HDMI_PHY_TXCAL_CFG20x002c +#define HDMI_PHY_TXCAL_CFG30x0030 +#define HDMI_PHY_BIST_CFG0 0x0034 +#define HDMI_PHY_BIST_CFG1 0x0038 +#define HDMI_PHY_BIST_PATN00x003c +#define HDMI_PHY_BIST_PATN10x0040 +#define HDMI_PHY_BIST_PATN20x0044 +#define HDMI_PHY_BIST_PATN30x0048 +#define HDMI_PHY_STATUS0x005c + +/* hdmi phy unified pll registers */ +#define HDMI_UNI_PLL_REFCLK_CFG0x +#define HDMI_UNI_PLL_POSTDIV1_CFG 0x0004 +#define HDMI_UNI_PLL_CHFPUMP_CFG 0x0008 +#define HDMI_UNI_PLL_VCOLPF_CFG0x000c +#define HDMI_UNI_PLL_VREG_CFG 0x0010 +#define HDMI_UNI_PLL_PWRGEN_CFG0x0014 +#define HDMI_UNI_PLL_GLB_CFG 0x0020 +#define HDMI_UNI_PLL_POSTDIV2_CFG 0x0024 +#define HDMI_UNI_PLL_POST
Re: [Freedreno] [PATCH 05/11] drm/bridge: analogix-anx78xx: correct value of TX_P0
On Mon, Sep 16, 2019 at 01:32:58PM +0200, Enric Balletbo i Serra wrote: > Hi, > > On 16/9/19 12:49, Laurent Pinchart wrote: > > Hi Brian, > > > > On Mon, Sep 16, 2019 at 06:36:14AM -0400, Brian Masney wrote: > >> On Mon, Sep 16, 2019 at 12:02:09PM +0200, Andrzej Hajda wrote: > >>> On 15.08.2019 02:48, Brian Masney wrote: > >>>> When attempting to configure this driver on a Nexus 5 phone (msm8974), > >>>> setting up the dummy i2c bus for TX_P0 would fail due to an -EBUSY > >>>> error. The downstream MSM kernel sources [1] shows that the proper value > >>>> for TX_P0 is 0x78, not 0x70, so correct the value to allow device > >>>> probing to succeed. > >>>> > >>>> [1] > >>>> https://github.com/AICP/kernel_lge_hammerhead/blob/n7.1/drivers/video/slimport/slimport_tx_reg.h > >>>> > >>>> Signed-off-by: Brian Masney > >>>> --- > >>>> drivers/gpu/drm/bridge/analogix-anx78xx.h | 2 +- > >>>> 1 file changed, 1 insertion(+), 1 deletion(-) > >>>> > >>>> diff --git a/drivers/gpu/drm/bridge/analogix-anx78xx.h > >>>> b/drivers/gpu/drm/bridge/analogix-anx78xx.h > >>>> index 25e063bcecbc..bc511fc605c9 100644 > >>>> --- a/drivers/gpu/drm/bridge/analogix-anx78xx.h > >>>> +++ b/drivers/gpu/drm/bridge/analogix-anx78xx.h > >>>> @@ -6,7 +6,7 @@ > >>>> #ifndef __ANX78xx_H > >>>> #define __ANX78xx_H > >>>> > >>>> -#define TX_P0 0x70 > >>>> +#define TX_P0 0x78 > >>> > >>> > >>> This bothers me little. There are no upstream users, grepping android > >>> sources suggests that both values can be used [1][2] (grep for "#define > >>> TX_P0"), moreover there is code suggesting both values can be valid [3]. > >>> > >>> Could you verify datasheet which i2c slave addresses are valid for this > >>> chip, if both I guess this patch should be reworked. > >>> > >>> > >>> [1]: > >>> https://android.googlesource.com/kernel/msm/+/android-msm-flo-3.4-jb-mr2/drivers/misc/slimport_anx7808/slimport_tx_reg.h > >>> > >>> [2]: > >>> https://github.com/AndroidGX/SimpleGX-MM-6.0_H815_20d/blob/master/drivers/video/slimport/anx7812/slimport7812_tx_reg.h > >>> > >>> [3]: > >>> https://github.com/commaai/android_kernel_leeco_msm8996/blob/master/drivers/video/msm/mdss/dp/slimport_custom_declare.h#L73 > >> > >> This address is 0x78 on my Nexus 5. Given [3] above it looks like we > >> need to support both addresses. What do you think about moving these > >> addresses into device tree? > > > > Assuming that the device supports different addresses (I can't validate > > that as I don't have access to the datasheet), and different addresses > > need to be used on different systems, then the address to be used needs > > to be provided by the firmware (DT in this case). Two options are > > possible, either specifying the address explicitly in the device's DT > > node, or specifying free addresses (in the form of a white list or black > > list) and allocating an address from that pool. The latter has been > > discussed in a BoF at the Linux Plumbers Conference last week, > > https://linuxplumbersconf.org/event/4/contributions/542/. > > > >> The downstream and upstream kernel sources divide these addresses by two > >> to get the i2c address. Here's the code in upstream: > >> > >> https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/bridge/analogix-anx78xx.c#L1353 > >> https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/bridge/analogix-anx78xx.c#L41 > >> > >> I'm not sure why the actual i2c address isn't used in this code. > > > > The ANX7802/12/14/16 has a slave I2C bus that provides the interface to access > or control the chip from the AP. The I2C slave addresses used to control the > ANX7802/12/14/16 are 70h, 72h, 7Ah, 7Eh and 80h. Every address allows you to > access to different registers of the chip and AFAICS is not configurable. > > I don't think these addresses should be configured via DT but for the driver > itself. > > My wild guess is that the ANX7808 has different addresses, but I don't have > the > datasheet of this version. I'm able to communicate with the 7808 on my Nexus 5 using the 0x78 address. Given that the addresses appear to be fixed per model, maybe it makes sense to drop the address #defines and add the addresses to the data pointer in the driver's of_match_table like so: static const struct of_device_id anx78xx_match_table[] = { { .compatible = "analogix,anx7808", .data = PTR_TO_7808_ADDRS }, { .compatible = "analogix,anx7812", .data = PTR_TO_781X_ADDRS }, { .compatible = "analogix,anx7814", .data = PTR_TO_781X_ADDRS }, { .compatible = "analogix,anx7818", .data = PTR_TO_781X_ADDRS }, { /* sentinel */ }, }; Brian ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
Re: [Freedreno] [PATCH 05/11] drm/bridge: analogix-anx78xx: correct value of TX_P0
On Mon, Sep 16, 2019 at 12:36:19PM +0200, Enric Balletbo i Serra wrote: > Hi Andrzej and Brian > > On 16/9/19 12:02, Andrzej Hajda wrote: > > On 15.08.2019 02:48, Brian Masney wrote: > >> When attempting to configure this driver on a Nexus 5 phone (msm8974), > >> setting up the dummy i2c bus for TX_P0 would fail due to an -EBUSY > >> error. The downstream MSM kernel sources [1] shows that the proper value > >> for TX_P0 is 0x78, not 0x70, so correct the value to allow device > >> probing to succeed. > >> > >> [1] > >> https://github.com/AICP/kernel_lge_hammerhead/blob/n7.1/drivers/video/slimport/slimport_tx_reg.h > >> > >> Signed-off-by: Brian Masney > >> --- > >> drivers/gpu/drm/bridge/analogix-anx78xx.h | 2 +- > >> 1 file changed, 1 insertion(+), 1 deletion(-) > >> > >> diff --git a/drivers/gpu/drm/bridge/analogix-anx78xx.h > >> b/drivers/gpu/drm/bridge/analogix-anx78xx.h > >> index 25e063bcecbc..bc511fc605c9 100644 > >> --- a/drivers/gpu/drm/bridge/analogix-anx78xx.h > >> +++ b/drivers/gpu/drm/bridge/analogix-anx78xx.h > >> @@ -6,7 +6,7 @@ > >> #ifndef __ANX78xx_H > >> #define __ANX78xx_H > >> > >> -#define TX_P0 0x70 > >> +#define TX_P0 0x78 > > > > > > This bothers me little. There are no upstream users, grepping android > > sources suggests that both values can be used [1][2] (grep for "#define > > TX_P0"), moreover there is code suggesting both values can be valid [3]. > > > > Could you verify datasheet which i2c slave addresses are valid for this > > chip, if both I guess this patch should be reworked. > > > > On my case the valid i2c slave address is 0x70 (from datasheet, very sorry I > can't share it) and the bridge used is an ANX7814, it could be that ANX7808 or > ANX7812 have different slave addresses? I haven't been able to find any of the datasheets for these devices online. Product briefs are online (such as https://www.analogix.com/en/system/files/ANX7808_product_brief.pdf), but they don't provide this type of information. Brian ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
Re: [Freedreno] [PATCH 05/11] drm/bridge: analogix-anx78xx: correct value of TX_P0
On Mon, Sep 16, 2019 at 12:02:09PM +0200, Andrzej Hajda wrote: > On 15.08.2019 02:48, Brian Masney wrote: > > When attempting to configure this driver on a Nexus 5 phone (msm8974), > > setting up the dummy i2c bus for TX_P0 would fail due to an -EBUSY > > error. The downstream MSM kernel sources [1] shows that the proper value > > for TX_P0 is 0x78, not 0x70, so correct the value to allow device > > probing to succeed. > > > > [1] > > https://github.com/AICP/kernel_lge_hammerhead/blob/n7.1/drivers/video/slimport/slimport_tx_reg.h > > > > Signed-off-by: Brian Masney > > --- > > drivers/gpu/drm/bridge/analogix-anx78xx.h | 2 +- > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > diff --git a/drivers/gpu/drm/bridge/analogix-anx78xx.h > > b/drivers/gpu/drm/bridge/analogix-anx78xx.h > > index 25e063bcecbc..bc511fc605c9 100644 > > --- a/drivers/gpu/drm/bridge/analogix-anx78xx.h > > +++ b/drivers/gpu/drm/bridge/analogix-anx78xx.h > > @@ -6,7 +6,7 @@ > > #ifndef __ANX78xx_H > > #define __ANX78xx_H > > > > -#define TX_P0 0x70 > > +#define TX_P0 0x78 > > > This bothers me little. There are no upstream users, grepping android > sources suggests that both values can be used [1][2] (grep for "#define > TX_P0"), moreover there is code suggesting both values can be valid [3]. > > Could you verify datasheet which i2c slave addresses are valid for this > chip, if both I guess this patch should be reworked. > > > [1]: > https://android.googlesource.com/kernel/msm/+/android-msm-flo-3.4-jb-mr2/drivers/misc/slimport_anx7808/slimport_tx_reg.h > > [2]: > https://github.com/AndroidGX/SimpleGX-MM-6.0_H815_20d/blob/master/drivers/video/slimport/anx7812/slimport7812_tx_reg.h > > [3]: > https://github.com/commaai/android_kernel_leeco_msm8996/blob/master/drivers/video/msm/mdss/dp/slimport_custom_declare.h#L73 This address is 0x78 on my Nexus 5. Given [3] above it looks like we need to support both addresses. What do you think about moving these addresses into device tree? The downstream and upstream kernel sources divide these addresses by two to get the i2c address. Here's the code in upstream: https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/bridge/analogix-anx78xx.c#L1353 https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/bridge/analogix-anx78xx.c#L41 I'm not sure why the actual i2c address isn't used in this code. Brian ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
Re: [Freedreno] [PATCH 00/11] ARM: dts: qcom: msm8974: add support for external display
Hi Andrzej, On Mon, Sep 16, 2019 at 10:13:58AM +0200, Andrzej Hajda wrote: > Hi Brian, > > On 15.08.2019 02:48, Brian Masney wrote: > > This patch series begins to add support for the external display over > > HDMI that is supported on msm8974 SoCs. I'm testing this series on the > > Nexus 5, and I'm able to communicate with the HDMI bridge via the > > analogix-anx78xx driver, however the external display is not working > > yet. > > > > When I plug in the HDMI cable, the monitor detects that a device is > > hooked up, but nothing is shown on the external monitor. The hot plug > > detect GPIO (hpd-gpios) on the analogix-anx78xx bridge and MSM HDMI > > drivers do not change state when the slimport adapter or HDMI cable is > > plugged in or removed. I wonder if a regulator is not enabled somewhere? > > I have a comment in patch 10 regarding 'hpd-gdsc-supply' that may > > potentially be an issue. > > > > I'm still digging in on this, however I'd appreciate any feedback if > > anyone has time. Most of these patches are ready now, so I marked the > > ones that aren't ready with 'PATCH RFC'. > > > > I'm using an Analogix Semiconductor SP6001 SlimPort Micro-USB to 4K HDMI > > Adapter to connect my phone to an external display via a standard HDMI > > cable. This works just fine with the downstream MSM kernel using > > Android. > > > This patchset risks to be forgotten. To avoid it, at least partially, I > can merge patches 1-5, is it OK for you? That would be great if you could do that. Thanks, Brian ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
Re: [Freedreno] [PATCH v7 0/7] qcom: add OCMEM support
Hi Rob C / Sean P, On Fri, Aug 23, 2019 at 05:16:30AM -0700, Brian Masney wrote: > This patch series adds support for Qualcomm's On Chip MEMory (OCMEM) > that is needed in order to support some a3xx and a4xx-based GPUs > upstream. This is based on Rob Clark's patch series that he submitted > in October 2015 and I am resubmitting updated patches with his > permission. See the individual patches for the changelog. I talked to Bjorn in person at the Embedded Linux Conference over a week ago about this series. He thinks that this series should go through your tree. I assume it's too late for the upcoming merge window, which is fine. I just want to make sure that this series gets picked up for the following merge window. I just sent out a fix for a compiler error on MIPS as a separate patch: https://lore.kernel.org/lkml/20190901213037.25889-1-masn...@onstation.org/ Brian ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v7 5/7] soc: qcom: add OCMEM driver
The OCMEM driver handles allocation and configuration of the On Chip MEMory that is present on some Snapdragon SoCs. Devices which have OCMEM do not have GMEM inside the GPU core, so the GPU must instead use OCMEM to be functional. Since the GPU is currently the only OCMEM user with an upstream driver, this is just a minimal implementation sufficient for statically allocating to the GPU it's chunk of OCMEM. This driver currently does not read the gmu-sram node that is described in the device tree bindings. The starting memory address of the GPU's reserved memory region is hardcoded to zero to match what the hardware expects. The driver can be updated to read the reserved memory regions from device tree once other users of OCMEM are added upstream. Signed-off-by: Brian Masney Co-developed-by: Rob Clark Signed-off-by: Rob Clark Reviewed-by: Bjorn Andersson --- Changes since v6: - Look up parent device node Changes since v5: - rename ocmem property to sram Changes since v4: - Change 'GPL' to 'GPL v2' in MODULE_LICENSE Changes since v3: - None Changes since v2 - Changed static inline stubs return -ENODEV when OCMEM is not configured into the kernel. Changes since v1: - ocmem_allocate(): check for alignment and minimum allocation size. The 64K values came from the downstream MSM kernel sources. - add locking to memory allocations based on the client - use clk_bulk_*() functions - rename qcom,ocmem-msm8974 to qcom,msm8974-ocmem - rename reg-names to ctrl and mem - remove ocmem.xml.h file; use FIELD_PREP() instead for some nice cleanups - add static inline noop versions of public-facing functions when ocmem is disabled to remove #ifdefs in adrenu_gpu.c - use unsigned long for memory addresses - move ocmem_dev_remove() below _probe() function - remove error check from platform_get_resource_byname for ctrl resource - add MODULE_DESCRIPTION() and MODULE_LICENSE() - add description to top of ocmem.[ch] - correct thin mode bit in update_ocmem() - add 'WARN_ON(client != OCMEM_GRAPHICS)' to device_address() - make of_get_ocmem return error codes via ERR_PTR instead of NULL - ocmem_{allocate,free} - WARN_ON() if client != OCMEM_GRAPHICS. Simplify if statements. - allow NULL to be passed into ocmem_free - remove unnecessary initialization of i in update_ocmem() - add dev_dbg to ocmem_allocate Changes since Rob's last version of this patch from 2015: https://patchwork.kernel.org/patch/7379801/ - reformatted driver to allow multiple instances - updated logging of error paths during device probing - remove unused psgsc_ctrl - remove _clk from clock names - propagate error code from devm_ioremap_resource() - use device_get_match_data() - SPDX license tags - remove QCOM_SMD in Kconfig - select ARCH_QCOM in Kconfig - select ARCH_QCOM in Kconfig - select QCOM_SCM in Kconfig - longer description in Kconfig drivers/soc/qcom/Kconfig | 10 + drivers/soc/qcom/Makefile | 1 + drivers/soc/qcom/ocmem.c | 433 ++ include/soc/qcom/ocmem.h | 62 ++ 4 files changed, 506 insertions(+) create mode 100644 drivers/soc/qcom/ocmem.c create mode 100644 include/soc/qcom/ocmem.h diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig index 661e47acc354..adbf3bfae805 100644 --- a/drivers/soc/qcom/Kconfig +++ b/drivers/soc/qcom/Kconfig @@ -74,6 +74,16 @@ config QCOM_MDT_LOADER tristate select QCOM_SCM +config QCOM_OCMEM + tristate "Qualcomm On Chip Memory (OCMEM) driver" + depends on ARCH_QCOM + select QCOM_SCM + help + The On Chip Memory (OCMEM) allocator allows various clients to + allocate memory from OCMEM based on performance, latency and power + requirements. This is typically used by the GPU, camera/video, and + audio components on some Snapdragon SoCs. + config QCOM_PM bool "Qualcomm Power Management" depends on ARCH_QCOM && !ARM64 diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile index 162788701a77..aab333720bfd 100644 --- a/drivers/soc/qcom/Makefile +++ b/drivers/soc/qcom/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_QCOM_COMMAND_DB) += cmd-db.o obj-$(CONFIG_QCOM_GLINK_SSR) +=glink_ssr.o obj-$(CONFIG_QCOM_GSBI)+= qcom_gsbi.o obj-$(CONFIG_QCOM_MDT_LOADER) += mdt_loader.o +obj-$(CONFIG_QCOM_OCMEM) += ocmem.o obj-$(CONFIG_QCOM_PM) += spm.o obj-$(CONFIG_QCOM_QMI_HELPERS) += qmi_helpers.o qmi_helpers-y += qmi_encdec.o qmi_interface.o diff --git a/drivers/soc/qcom/ocmem.c b/drivers/soc/qcom/ocmem.c new file mode 100644 index ..7f9e9944d1ea --- /dev/null +++ b/drivers/soc/qcom/ocmem.c @@ -0,0 +1,433 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * The On Chip Memory (OCMEM) allocator allows various clients to allocate + * memory from OCMEM based on performance, latency and power requirements. + * This is typically used b
[Freedreno] [PATCH v7 0/7] qcom: add OCMEM support
This patch series adds support for Qualcomm's On Chip MEMory (OCMEM) that is needed in order to support some a3xx and a4xx-based GPUs upstream. This is based on Rob Clark's patch series that he submitted in October 2015 and I am resubmitting updated patches with his permission. See the individual patches for the changelog. This was tested with the GPU on a LG Nexus 5 (hammerhead) phone and this will work on other msm8974-based systems. For a summary of what currently works upstream on the Nexus 5, see my status page at https://masneyb.github.io/nexus-5-upstream/. Changes since v6: - link to gmu-sram child node in device tree - add ranges property to ocmem example in adreno GMU example (patch 2) to match bindings in patch 1 See individual patches for changelogs for previous versions. Brian Masney (5): dt-bindings: soc: qcom: add On Chip MEMory (OCMEM) bindings dt-bindings: display: msm: gmu: add optional ocmem property soc: qcom: add OCMEM driver drm/msm/gpu: add ocmem init/cleanup functions ARM: qcom_defconfig: add ocmem support Rob Clark (2): firmware: qcom: scm: add OCMEM lock/unlock interface firmware: qcom: scm: add support to restore secure config to qcm_scm-32 .../devicetree/bindings/display/msm/gmu.txt | 51 +++ .../devicetree/bindings/sram/qcom,ocmem.yaml | 96 arch/arm/configs/qcom_defconfig | 1 + drivers/firmware/qcom_scm-32.c| 52 ++- drivers/firmware/qcom_scm-64.c| 12 + drivers/firmware/qcom_scm.c | 53 +++ drivers/firmware/qcom_scm.h | 9 + drivers/gpu/drm/msm/Kconfig | 1 + drivers/gpu/drm/msm/adreno/a3xx_gpu.c | 28 +- drivers/gpu/drm/msm/adreno/a3xx_gpu.h | 3 +- drivers/gpu/drm/msm/adreno/a4xx_gpu.c | 25 +- drivers/gpu/drm/msm/adreno/a4xx_gpu.h | 3 +- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 40 ++ drivers/gpu/drm/msm/adreno/adreno_gpu.h | 10 + drivers/soc/qcom/Kconfig | 10 + drivers/soc/qcom/Makefile | 1 + drivers/soc/qcom/ocmem.c | 433 ++ include/linux/qcom_scm.h | 26 ++ include/soc/qcom/ocmem.h | 62 +++ 19 files changed, 871 insertions(+), 45 deletions(-) create mode 100644 Documentation/devicetree/bindings/sram/qcom,ocmem.yaml create mode 100644 drivers/soc/qcom/ocmem.c create mode 100644 include/soc/qcom/ocmem.h -- 2.21.0 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v7 3/7] firmware: qcom: scm: add OCMEM lock/unlock interface
From: Rob Clark Add support for the OCMEM lock/unlock interface that is needed by the On Chip MEMory (OCMEM) that is present on some Snapdragon devices. Signed-off-by: Rob Clark [masn...@onstation.org: ported to latest kernel; minor reformatting.] Signed-off-by: Brian Masney Reviewed-by: Bjorn Andersson --- Changes since v6: - None Changes since v5: - None Changes since v4: - None Changes since v3: - None Changes since v2: - None Changes since v1: - None Rob's last version of this patch: https://patchwork.kernel.org/patch/7340711/ drivers/firmware/qcom_scm-32.c | 35 + drivers/firmware/qcom_scm-64.c | 12 ++ drivers/firmware/qcom_scm.c| 40 ++ drivers/firmware/qcom_scm.h| 9 include/linux/qcom_scm.h | 15 + 5 files changed, 111 insertions(+) diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c index 215061c581e1..4c2514e5e249 100644 --- a/drivers/firmware/qcom_scm-32.c +++ b/drivers/firmware/qcom_scm-32.c @@ -442,6 +442,41 @@ int __qcom_scm_hdcp_req(struct device *dev, struct qcom_scm_hdcp_req *req, req, req_cnt * sizeof(*req), resp, sizeof(*resp)); } +int __qcom_scm_ocmem_lock(struct device *dev, u32 id, u32 offset, u32 size, + u32 mode) +{ + struct ocmem_tz_lock { + __le32 id; + __le32 offset; + __le32 size; + __le32 mode; + } request; + + request.id = cpu_to_le32(id); + request.offset = cpu_to_le32(offset); + request.size = cpu_to_le32(size); + request.mode = cpu_to_le32(mode); + + return qcom_scm_call(dev, QCOM_SCM_OCMEM_SVC, QCOM_SCM_OCMEM_LOCK_CMD, +&request, sizeof(request), NULL, 0); +} + +int __qcom_scm_ocmem_unlock(struct device *dev, u32 id, u32 offset, u32 size) +{ + struct ocmem_tz_unlock { + __le32 id; + __le32 offset; + __le32 size; + } request; + + request.id = cpu_to_le32(id); + request.offset = cpu_to_le32(offset); + request.size = cpu_to_le32(size); + + return qcom_scm_call(dev, QCOM_SCM_OCMEM_SVC, QCOM_SCM_OCMEM_UNLOCK_CMD, +&request, sizeof(request), NULL, 0); +} + void __qcom_scm_init(void) { } diff --git a/drivers/firmware/qcom_scm-64.c b/drivers/firmware/qcom_scm-64.c index 91d5ad7cf58b..c3a3d9874def 100644 --- a/drivers/firmware/qcom_scm-64.c +++ b/drivers/firmware/qcom_scm-64.c @@ -241,6 +241,18 @@ int __qcom_scm_hdcp_req(struct device *dev, struct qcom_scm_hdcp_req *req, return ret; } +int __qcom_scm_ocmem_lock(struct device *dev, uint32_t id, uint32_t offset, + uint32_t size, uint32_t mode) +{ + return -ENOTSUPP; +} + +int __qcom_scm_ocmem_unlock(struct device *dev, uint32_t id, uint32_t offset, + uint32_t size) +{ + return -ENOTSUPP; +} + void __qcom_scm_init(void) { u64 cmd; diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index 4802ab170fe5..7e285ff3961d 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -191,6 +191,46 @@ bool qcom_scm_pas_supported(u32 peripheral) } EXPORT_SYMBOL(qcom_scm_pas_supported); +/** + * qcom_scm_ocmem_lock_available() - is OCMEM lock/unlock interface available + */ +bool qcom_scm_ocmem_lock_available(void) +{ + return __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_OCMEM_SVC, + QCOM_SCM_OCMEM_LOCK_CMD); +} +EXPORT_SYMBOL(qcom_scm_ocmem_lock_available); + +/** + * qcom_scm_ocmem_lock() - call OCMEM lock interface to assign an OCMEM + * region to the specified initiator + * + * @id: tz initiator id + * @offset: OCMEM offset + * @size: OCMEM size + * @mode: access mode (WIDE/NARROW) + */ +int qcom_scm_ocmem_lock(enum qcom_scm_ocmem_client id, u32 offset, u32 size, + u32 mode) +{ + return __qcom_scm_ocmem_lock(__scm->dev, id, offset, size, mode); +} +EXPORT_SYMBOL(qcom_scm_ocmem_lock); + +/** + * qcom_scm_ocmem_unlock() - call OCMEM unlock interface to release an OCMEM + * region from the specified initiator + * + * @id: tz initiator id + * @offset: OCMEM offset + * @size: OCMEM size + */ +int qcom_scm_ocmem_unlock(enum qcom_scm_ocmem_client id, u32 offset, u32 size) +{ + return __qcom_scm_ocmem_unlock(__scm->dev, id, offset, size); +} +EXPORT_SYMBOL(qcom_scm_ocmem_unlock); + /** * qcom_scm_pas_init_image() - Initialize peripheral authentication service *state machine for a given peripheral, using the diff --git a/drivers/firmware/qcom_scm.h b/drivers/firmware/qcom_scm.h index 99506bd873c0..ef293ee67ec1 100644 --- a/drivers/firmware/qcom_scm.h +++ b/drivers/firmware/qcom_scm.h @@ -42,6 +42,15 @@ extern int __qcom_scm_hdcp_req(struct devic
[Freedreno] [PATCH v7 6/7] drm/msm/gpu: add ocmem init/cleanup functions
The files a3xx_gpu.c and a4xx_gpu.c have ifdefs for the OCMEM support that was missing upstream. Add two new functions (adreno_gpu_ocmem_init and adreno_gpu_ocmem_cleanup) that removes some duplicated code. Signed-off-by: Brian Masney --- Changes since v6: - None Changes since v5: - None Changes since v4: - None Changes since v3: - None Changes since v2: - Check for -ENODEV error of_get_ocmem() - remove fail_cleanup_ocmem label in a[34]xx_gpu_init Changes since v1: - remove CONFIG_QCOM_OCMEM #ifdefs - use unsigned long for memory addresses instead of uint32_t - add 'depends on QCOM_OCMEM || QCOM_OCMEM=n' to Kconfig drivers/gpu/drm/msm/Kconfig | 1 + drivers/gpu/drm/msm/adreno/a3xx_gpu.c | 28 + drivers/gpu/drm/msm/adreno/a3xx_gpu.h | 3 +- drivers/gpu/drm/msm/adreno/a4xx_gpu.c | 25 drivers/gpu/drm/msm/adreno/a4xx_gpu.h | 3 +- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 40 + drivers/gpu/drm/msm/adreno/adreno_gpu.h | 10 +++ 7 files changed, 66 insertions(+), 44 deletions(-) diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig index 9c37e4de5896..b3d3b2172659 100644 --- a/drivers/gpu/drm/msm/Kconfig +++ b/drivers/gpu/drm/msm/Kconfig @@ -7,6 +7,7 @@ config DRM_MSM depends on OF && COMMON_CLK depends on MMU depends on INTERCONNECT || !INTERCONNECT + depends on QCOM_OCMEM || QCOM_OCMEM=n select QCOM_MDT_LOADER if ARCH_QCOM select REGULATOR select DRM_KMS_HELPER diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c index 5f7e98028eaf..7ad14937fcdf 100644 --- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c @@ -6,10 +6,6 @@ * Copyright (c) 2014 The Linux Foundation. All rights reserved. */ -#ifdef CONFIG_MSM_OCMEM -# include -#endif - #include "a3xx_gpu.h" #define A3XX_INT0_MASK \ @@ -195,9 +191,9 @@ static int a3xx_hw_init(struct msm_gpu *gpu) gpu_write(gpu, REG_A3XX_RBBM_GPR0_CTL, 0x); /* Set the OCMEM base address for A330, etc */ - if (a3xx_gpu->ocmem_hdl) { + if (a3xx_gpu->ocmem.hdl) { gpu_write(gpu, REG_A3XX_RB_GMEM_BASE_ADDR, - (unsigned int)(a3xx_gpu->ocmem_base >> 14)); + (unsigned int)(a3xx_gpu->ocmem.base >> 14)); } /* Turn on performance counters: */ @@ -318,10 +314,7 @@ static void a3xx_destroy(struct msm_gpu *gpu) adreno_gpu_cleanup(adreno_gpu); -#ifdef CONFIG_MSM_OCMEM - if (a3xx_gpu->ocmem_base) - ocmem_free(OCMEM_GRAPHICS, a3xx_gpu->ocmem_hdl); -#endif + adreno_gpu_ocmem_cleanup(&a3xx_gpu->ocmem); kfree(a3xx_gpu); } @@ -494,17 +487,10 @@ struct msm_gpu *a3xx_gpu_init(struct drm_device *dev) /* if needed, allocate gmem: */ if (adreno_is_a330(adreno_gpu)) { -#ifdef CONFIG_MSM_OCMEM - /* TODO this is different/missing upstream: */ - struct ocmem_buf *ocmem_hdl = - ocmem_allocate(OCMEM_GRAPHICS, adreno_gpu->gmem); - - a3xx_gpu->ocmem_hdl = ocmem_hdl; - a3xx_gpu->ocmem_base = ocmem_hdl->addr; - adreno_gpu->gmem = ocmem_hdl->len; - DBG("using %dK of OCMEM at 0x%08x", adreno_gpu->gmem / 1024, - a3xx_gpu->ocmem_base); -#endif + ret = adreno_gpu_ocmem_init(&adreno_gpu->base.pdev->dev, + adreno_gpu, &a3xx_gpu->ocmem); + if (ret) + goto fail; } if (!gpu->aspace) { diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.h b/drivers/gpu/drm/msm/adreno/a3xx_gpu.h index 5dc33e5ea53b..c555fb13e0d7 100644 --- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.h +++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.h @@ -19,8 +19,7 @@ struct a3xx_gpu { struct adreno_gpu base; /* if OCMEM is used for GMEM: */ - uint32_t ocmem_base; - void *ocmem_hdl; + struct adreno_ocmem ocmem; }; #define to_a3xx_gpu(x) container_of(x, struct a3xx_gpu, base) diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c index ab2b752566d8..b01388a9e89e 100644 --- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c @@ -2,9 +2,6 @@ /* Copyright (c) 2014 The Linux Foundation. All rights reserved. */ #include "a4xx_gpu.h" -#ifdef CONFIG_MSM_OCMEM -# include -#endif #define A4XX_INT0_MASK \ (A4XX_INT0_RBBM_AHB_ERROR |\ @@ -188,7 +185,7 @@ static int a4xx_hw_init(struct msm_gpu *gpu) (1 << 30) | 0x); gpu_write(gpu, REG_A4XX_RB_GMEM_BASE_ADDR, - (unsigned int)(a4xx_
[Freedreno] [PATCH v7 7/7] ARM: qcom_defconfig: add ocmem support
Add ocmem driver that's needed for some a3xx and a4xx based systems. Signed-off-by: Brian Masney --- Changes since v6: - None Changes since v5: - None This patch was introduced in v5. arch/arm/configs/qcom_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/configs/qcom_defconfig b/arch/arm/configs/qcom_defconfig index 34433bf5885d..595e1910ba78 100644 --- a/arch/arm/configs/qcom_defconfig +++ b/arch/arm/configs/qcom_defconfig @@ -225,6 +225,7 @@ CONFIG_QCOM_WCNSS_PIL=y CONFIG_RPMSG_CHAR=y CONFIG_RPMSG_QCOM_SMD=y CONFIG_QCOM_GSBI=y +CONFIG_QCOM_OCMEM=y CONFIG_QCOM_PM=y CONFIG_QCOM_SMEM=y CONFIG_QCOM_SMD_RPM=y -- 2.21.0 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v7 1/7] dt-bindings: soc: qcom: add On Chip MEMory (OCMEM) bindings
Add device tree bindings for the On Chip Memory (OCMEM) that is present on some Qualcomm Snapdragon SoCs. Signed-off-by: Brian Masney Reviewed-by: Rob Herring --- Changes since v6: - None Changes since v5: - None Changes since v4: - remove qcom from path in $id Changes since v3: - add ranges property - remove unnecessary literal block | - add #address-cells and #size-cells to binding - rename path devicetree/bindings/sram/qcom/ to devicetree/bindings/sram/ since this is the only qcom binding in the sram namespace. That was a holdover from when I originally put this in the soc namespace. Changes since v2: - Add *-sram node and gmu-sram to example. Changes since v1: - Rename qcom,ocmem-msm8974 to qcom,msm8974-ocmem - Renamed reg-names to ctrl and mem - update hardware description - moved from soc to sram namespace in the device tree bindings .../devicetree/bindings/sram/qcom,ocmem.yaml | 96 +++ 1 file changed, 96 insertions(+) create mode 100644 Documentation/devicetree/bindings/sram/qcom,ocmem.yaml diff --git a/Documentation/devicetree/bindings/sram/qcom,ocmem.yaml b/Documentation/devicetree/bindings/sram/qcom,ocmem.yaml new file mode 100644 index ..222990f9923c --- /dev/null +++ b/Documentation/devicetree/bindings/sram/qcom,ocmem.yaml @@ -0,0 +1,96 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sram/qcom,ocmem.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: On Chip Memory (OCMEM) that is present on some Qualcomm Snapdragon SoCs. + +maintainers: + - Brian Masney + +description: | + The On Chip Memory (OCMEM) is typically used by the GPU, camera/video, and + audio components on some Snapdragon SoCs. + +properties: + compatible: +const: qcom,msm8974-ocmem + + reg: +items: + - description: Control registers + - description: OCMEM address range + + reg-names: +items: + - const: ctrl + - const: mem + + clocks: +items: + - description: Core clock + - description: Interface clock + + clock-names: +items: + - const: core + - const: iface + + '#address-cells': +const: 1 + + '#size-cells': +const: 1 + +required: + - compatible + - reg + - reg-names + - clocks + - clock-names + - '#address-cells' + - '#size-cells' + +patternProperties: + "^.+-sram$": +type: object +description: A region of reserved memory. + +properties: + reg: +maxItems: 1 + + ranges: +maxItems: 1 + +required: + - reg + - ranges + +examples: + - | + #include + #include + + ocmem: ocmem@fdd0 { +compatible = "qcom,msm8974-ocmem"; + +reg = <0xfdd0 0x2000>, + <0xfec0 0x18>; +reg-names = "ctrl", +"mem"; + +clocks = <&rpmcc RPM_SMD_OCMEMGX_CLK>, + <&mmcc OCMEMCX_OCMEMNOC_CLK>; +clock-names = "core", + "iface"; + +#address-cells = <1>; +#size-cells = <1>; + +gmu-sram@0 { +reg = <0x0 0x10>; +ranges = <0 0 0xfec0 0x10>; +}; + }; -- 2.21.0 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v7 2/7] dt-bindings: display: msm: gmu: add optional ocmem property
Some A3xx and A4xx Adreno GPUs do not have GMEM inside the GPU core and must use the On Chip MEMory (OCMEM) in order to be functional. Add the optional ocmem property to the Adreno Graphics Management Unit bindings. Signed-off-by: Brian Masney --- Changes since v6: - link to gmu-sram in example - add ranges property to ocmem example to match bindings Changes since v5: - rename ocmem property to sram to match what TI currently has. Changes since v4: - None Changes since v3: - correct link to qcom,ocmem.yaml Changes since v2: - Add a3xx example with OCMEM Changes since v1: - None .../devicetree/bindings/display/msm/gmu.txt | 51 +++ 1 file changed, 51 insertions(+) diff --git a/Documentation/devicetree/bindings/display/msm/gmu.txt b/Documentation/devicetree/bindings/display/msm/gmu.txt index 90af5b0a56a9..bf9c7a2a495c 100644 --- a/Documentation/devicetree/bindings/display/msm/gmu.txt +++ b/Documentation/devicetree/bindings/display/msm/gmu.txt @@ -31,6 +31,10 @@ Required properties: - iommus: phandle to the adreno iommu - operating-points-v2: phandle to the OPP operating points +Optional properties: +- sram: phandle to the On Chip Memory (OCMEM) that's present on some Snapdragon +SoCs. See Documentation/devicetree/bindings/sram/qcom,ocmem.yaml. + Example: / { @@ -63,3 +67,50 @@ Example: operating-points-v2 = <&gmu_opp_table>; }; }; + +a3xx example with OCMEM support: + +/ { + ... + + gpu: adreno@fdb0 { + compatible = "qcom,adreno-330.2", +"qcom,adreno"; + reg = <0xfdb0 0x1>; + reg-names = "kgsl_3d0_reg_memory"; + interrupts = ; + interrupt-names = "kgsl_3d0_irq"; + clock-names = "core", + "iface", + "mem_iface"; + clocks = <&mmcc OXILI_GFX3D_CLK>, +<&mmcc OXILICX_AHB_CLK>, +<&mmcc OXILICX_AXI_CLK>; + sram = <&gmu_sram>; + power-domains = <&mmcc OXILICX_GDSC>; + operating-points-v2 = <&gpu_opp_table>; + iommus = <&gpu_iommu 0>; + }; + + ocmem@fdd0 { + compatible = "qcom,msm8974-ocmem"; + + reg = <0xfdd0 0x2000>, + <0xfec0 0x18>; + reg-names = "ctrl", +"mem"; + + clocks = <&rpmcc RPM_SMD_OCMEMGX_CLK>, +<&mmcc OCMEMCX_OCMEMNOC_CLK>; + clock-names = "core", + "iface"; + + #address-cells = <1>; + #size-cells = <1>; + + gmu_sram: gmu-sram@0 { + reg = <0x0 0x10>; + ranges = <0 0 0xfec0 0x10>; + }; + }; +}; -- 2.21.0 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v7 4/7] firmware: qcom: scm: add support to restore secure config to qcm_scm-32
From: Rob Clark Add support to restore the secure configuration for qcm_scm-32.c. This is needed by the On Chip MEMory (OCMEM) that is present on some Snapdragon devices. Signed-off-by: Rob Clark [masn...@onstation.org: ported to latest kernel; set ctx_bank_num to spare parameter.] Signed-off-by: Brian Masney Reviewed-by: Bjorn Andersson --- Changes since v6: - None Changes since v5: - None Changes since v4: - None Changes since v3: - None Changes since v2: - None Changes since v1: - Use existing __qcom_scm_restore_sec_cfg() function stub in qcom_scm-32.c that was unimplemented - Set the cfg.ctx_bank_num to the spare function parameter. It was previously set to the device_id. drivers/firmware/qcom_scm-32.c | 17 - drivers/firmware/qcom_scm.c| 13 + include/linux/qcom_scm.h | 11 +++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c index 4c2514e5e249..5d90b7f5ab5a 100644 --- a/drivers/firmware/qcom_scm-32.c +++ b/drivers/firmware/qcom_scm-32.c @@ -617,7 +617,22 @@ int __qcom_scm_assign_mem(struct device *dev, phys_addr_t mem_region, int __qcom_scm_restore_sec_cfg(struct device *dev, u32 device_id, u32 spare) { - return -ENODEV; + struct msm_scm_sec_cfg { + __le32 id; + __le32 ctx_bank_num; + } cfg; + int ret, scm_ret = 0; + + cfg.id = cpu_to_le32(device_id); + cfg.ctx_bank_num = cpu_to_le32(spare); + + ret = qcom_scm_call(dev, QCOM_SCM_SVC_MP, QCOM_SCM_RESTORE_SEC_CFG, + &cfg, sizeof(cfg), &scm_ret, sizeof(scm_ret)); + + if (ret || scm_ret) + return ret ? ret : -EINVAL; + + return 0; } int __qcom_scm_iommu_secure_ptbl_size(struct device *dev, u32 spare, diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index 7e285ff3961d..27c1d98a34e6 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -367,6 +367,19 @@ static const struct reset_control_ops qcom_scm_pas_reset_ops = { .deassert = qcom_scm_pas_reset_deassert, }; +/** + * qcom_scm_restore_sec_cfg_available() - Check if secure environment + * supports restore security config interface. + * + * Return true if restore-cfg interface is supported, false if not. + */ +bool qcom_scm_restore_sec_cfg_available(void) +{ + return __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_MP, + QCOM_SCM_RESTORE_SEC_CFG); +} +EXPORT_SYMBOL(qcom_scm_restore_sec_cfg_available); + int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare) { return __qcom_scm_restore_sec_cfg(__scm->dev, device_id, spare); diff --git a/include/linux/qcom_scm.h b/include/linux/qcom_scm.h index b49b734d662c..04382e1798e4 100644 --- a/include/linux/qcom_scm.h +++ b/include/linux/qcom_scm.h @@ -34,6 +34,16 @@ enum qcom_scm_ocmem_client { QCOM_SCM_OCMEM_DEBUG_ID, }; +enum qcom_scm_sec_dev_id { + QCOM_SCM_MDSS_DEV_ID= 1, + QCOM_SCM_OCMEM_DEV_ID = 5, + QCOM_SCM_PCIE0_DEV_ID = 11, + QCOM_SCM_PCIE1_DEV_ID = 12, + QCOM_SCM_GFX_DEV_ID = 18, + QCOM_SCM_UFS_DEV_ID = 19, + QCOM_SCM_ICE_DEV_ID = 20, +}; + #define QCOM_SCM_VMID_HLOS 0x3 #define QCOM_SCM_VMID_MSS_MSA0xF #define QCOM_SCM_VMID_WLAN 0x18 @@ -70,6 +80,7 @@ extern int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz, extern void qcom_scm_cpu_power_down(u32 flags); extern u32 qcom_scm_get_version(void); extern int qcom_scm_set_remote_state(u32 state, u32 id); +extern bool qcom_scm_restore_sec_cfg_available(void); extern int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare); extern int qcom_scm_iommu_secure_ptbl_size(u32 spare, size_t *size); extern int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare); -- 2.21.0 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v6 4/7] firmware: qcom: scm: add support to restore secure config to qcm_scm-32
From: Rob Clark Add support to restore the secure configuration for qcm_scm-32.c. This is needed by the On Chip MEMory (OCMEM) that is present on some Snapdragon devices. Signed-off-by: Rob Clark [masn...@onstation.org: ported to latest kernel; set ctx_bank_num to spare parameter.] Signed-off-by: Brian Masney --- Changes since v5: - None Changes since v4: - None Changes since v3: - None Changes since v2: - None Changes since v1: - Use existing __qcom_scm_restore_sec_cfg() function stub in qcom_scm-32.c that was unimplemented - Set the cfg.ctx_bank_num to the spare function parameter. It was previously set to the device_id. drivers/firmware/qcom_scm-32.c | 17 - drivers/firmware/qcom_scm.c| 13 + include/linux/qcom_scm.h | 11 +++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c index 4c2514e5e249..5d90b7f5ab5a 100644 --- a/drivers/firmware/qcom_scm-32.c +++ b/drivers/firmware/qcom_scm-32.c @@ -617,7 +617,22 @@ int __qcom_scm_assign_mem(struct device *dev, phys_addr_t mem_region, int __qcom_scm_restore_sec_cfg(struct device *dev, u32 device_id, u32 spare) { - return -ENODEV; + struct msm_scm_sec_cfg { + __le32 id; + __le32 ctx_bank_num; + } cfg; + int ret, scm_ret = 0; + + cfg.id = cpu_to_le32(device_id); + cfg.ctx_bank_num = cpu_to_le32(spare); + + ret = qcom_scm_call(dev, QCOM_SCM_SVC_MP, QCOM_SCM_RESTORE_SEC_CFG, + &cfg, sizeof(cfg), &scm_ret, sizeof(scm_ret)); + + if (ret || scm_ret) + return ret ? ret : -EINVAL; + + return 0; } int __qcom_scm_iommu_secure_ptbl_size(struct device *dev, u32 spare, diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index 7e285ff3961d..27c1d98a34e6 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -367,6 +367,19 @@ static const struct reset_control_ops qcom_scm_pas_reset_ops = { .deassert = qcom_scm_pas_reset_deassert, }; +/** + * qcom_scm_restore_sec_cfg_available() - Check if secure environment + * supports restore security config interface. + * + * Return true if restore-cfg interface is supported, false if not. + */ +bool qcom_scm_restore_sec_cfg_available(void) +{ + return __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_MP, + QCOM_SCM_RESTORE_SEC_CFG); +} +EXPORT_SYMBOL(qcom_scm_restore_sec_cfg_available); + int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare) { return __qcom_scm_restore_sec_cfg(__scm->dev, device_id, spare); diff --git a/include/linux/qcom_scm.h b/include/linux/qcom_scm.h index b49b734d662c..04382e1798e4 100644 --- a/include/linux/qcom_scm.h +++ b/include/linux/qcom_scm.h @@ -34,6 +34,16 @@ enum qcom_scm_ocmem_client { QCOM_SCM_OCMEM_DEBUG_ID, }; +enum qcom_scm_sec_dev_id { + QCOM_SCM_MDSS_DEV_ID= 1, + QCOM_SCM_OCMEM_DEV_ID = 5, + QCOM_SCM_PCIE0_DEV_ID = 11, + QCOM_SCM_PCIE1_DEV_ID = 12, + QCOM_SCM_GFX_DEV_ID = 18, + QCOM_SCM_UFS_DEV_ID = 19, + QCOM_SCM_ICE_DEV_ID = 20, +}; + #define QCOM_SCM_VMID_HLOS 0x3 #define QCOM_SCM_VMID_MSS_MSA0xF #define QCOM_SCM_VMID_WLAN 0x18 @@ -70,6 +80,7 @@ extern int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz, extern void qcom_scm_cpu_power_down(u32 flags); extern u32 qcom_scm_get_version(void); extern int qcom_scm_set_remote_state(u32 state, u32 id); +extern bool qcom_scm_restore_sec_cfg_available(void); extern int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare); extern int qcom_scm_iommu_secure_ptbl_size(u32 spare, size_t *size); extern int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare); -- 2.21.0 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v6 1/7] dt-bindings: soc: qcom: add On Chip MEMory (OCMEM) bindings
Add device tree bindings for the On Chip Memory (OCMEM) that is present on some Qualcomm Snapdragon SoCs. Signed-off-by: Brian Masney Reviewed-by: Rob Herring --- Changes since v5: - None Changes since v4: - remove qcom from path in $id Changes since v3: - add ranges property - remove unnecessary literal block | - add #address-cells and #size-cells to binding - rename path devicetree/bindings/sram/qcom/ to devicetree/bindings/sram/ since this is the only qcom binding in the sram namespace. That was a holdover from when I originally put this in the soc namespace. Changes since v2: - Add *-sram node and gmu-sram to example. Changes since v1: - Rename qcom,ocmem-msm8974 to qcom,msm8974-ocmem - Renamed reg-names to ctrl and mem - update hardware description - moved from soc to sram namespace in the device tree bindings .../devicetree/bindings/sram/qcom,ocmem.yaml | 96 +++ 1 file changed, 96 insertions(+) create mode 100644 Documentation/devicetree/bindings/sram/qcom,ocmem.yaml diff --git a/Documentation/devicetree/bindings/sram/qcom,ocmem.yaml b/Documentation/devicetree/bindings/sram/qcom,ocmem.yaml new file mode 100644 index ..222990f9923c --- /dev/null +++ b/Documentation/devicetree/bindings/sram/qcom,ocmem.yaml @@ -0,0 +1,96 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sram/qcom,ocmem.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: On Chip Memory (OCMEM) that is present on some Qualcomm Snapdragon SoCs. + +maintainers: + - Brian Masney + +description: | + The On Chip Memory (OCMEM) is typically used by the GPU, camera/video, and + audio components on some Snapdragon SoCs. + +properties: + compatible: +const: qcom,msm8974-ocmem + + reg: +items: + - description: Control registers + - description: OCMEM address range + + reg-names: +items: + - const: ctrl + - const: mem + + clocks: +items: + - description: Core clock + - description: Interface clock + + clock-names: +items: + - const: core + - const: iface + + '#address-cells': +const: 1 + + '#size-cells': +const: 1 + +required: + - compatible + - reg + - reg-names + - clocks + - clock-names + - '#address-cells' + - '#size-cells' + +patternProperties: + "^.+-sram$": +type: object +description: A region of reserved memory. + +properties: + reg: +maxItems: 1 + + ranges: +maxItems: 1 + +required: + - reg + - ranges + +examples: + - | + #include + #include + + ocmem: ocmem@fdd0 { +compatible = "qcom,msm8974-ocmem"; + +reg = <0xfdd0 0x2000>, + <0xfec0 0x18>; +reg-names = "ctrl", +"mem"; + +clocks = <&rpmcc RPM_SMD_OCMEMGX_CLK>, + <&mmcc OCMEMCX_OCMEMNOC_CLK>; +clock-names = "core", + "iface"; + +#address-cells = <1>; +#size-cells = <1>; + +gmu-sram@0 { +reg = <0x0 0x10>; +ranges = <0 0 0xfec0 0x10>; +}; + }; -- 2.21.0 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v6 5/7] soc: qcom: add OCMEM driver
The OCMEM driver handles allocation and configuration of the On Chip MEMory that is present on some Snapdragon SoCs. Devices which have OCMEM do not have GMEM inside the GPU core, so the GPU must instead use OCMEM to be functional. Since the GPU is currently the only OCMEM user with an upstream driver, this is just a minimal implementation sufficient for statically allocating to the GPU it's chunk of OCMEM. This driver currently does not read the gmu-sram node that is described in the device tree bindings. The starting memory address of the GPU's reserved memory region is hardcoded to zero to match what the hardware expects. The driver can be updated to read the reserved memory regions from device tree once other users of OCMEM are added upstream. Signed-off-by: Brian Masney Co-developed-by: Rob Clark Signed-off-by: Rob Clark Reviewed-by: Bjorn Andersson --- Changes since v5: - rename ocmem property to sram Changes since v4: - Change 'GPL' to 'GPL v2' in MODULE_LICENSE Changes since v3: - None Changes since v2 - Changed static inline stubs return -ENODEV when OCMEM is not configured into the kernel. Changes since v1: - ocmem_allocate(): check for alignment and minimum allocation size. The 64K values came from the downstream MSM kernel sources. - add locking to memory allocations based on the client - use clk_bulk_*() functions - rename qcom,ocmem-msm8974 to qcom,msm8974-ocmem - rename reg-names to ctrl and mem - remove ocmem.xml.h file; use FIELD_PREP() instead for some nice cleanups - add static inline noop versions of public-facing functions when ocmem is disabled to remove #ifdefs in adrenu_gpu.c - use unsigned long for memory addresses - move ocmem_dev_remove() below _probe() function - remove error check from platform_get_resource_byname for ctrl resource - add MODULE_DESCRIPTION() and MODULE_LICENSE() - add description to top of ocmem.[ch] - correct thin mode bit in update_ocmem() - add 'WARN_ON(client != OCMEM_GRAPHICS)' to device_address() - make of_get_ocmem return error codes via ERR_PTR instead of NULL - ocmem_{allocate,free} - WARN_ON() if client != OCMEM_GRAPHICS. Simplify if statements. - allow NULL to be passed into ocmem_free - remove unnecessary initialization of i in update_ocmem() - add dev_dbg to ocmem_allocate Changes since Rob's last version of this patch from 2015: https://patchwork.kernel.org/patch/7379801/ - reformatted driver to allow multiple instances - updated logging of error paths during device probing - remove unused psgsc_ctrl - remove _clk from clock names - propagate error code from devm_ioremap_resource() - use device_get_match_data() - SPDX license tags - remove QCOM_SMD in Kconfig - select ARCH_QCOM in Kconfig - select ARCH_QCOM in Kconfig - select QCOM_SCM in Kconfig - longer description in Kconfig drivers/soc/qcom/Kconfig | 10 + drivers/soc/qcom/Makefile | 1 + drivers/soc/qcom/ocmem.c | 433 ++ include/soc/qcom/ocmem.h | 62 ++ 4 files changed, 506 insertions(+) create mode 100644 drivers/soc/qcom/ocmem.c create mode 100644 include/soc/qcom/ocmem.h diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig index 661e47acc354..adbf3bfae805 100644 --- a/drivers/soc/qcom/Kconfig +++ b/drivers/soc/qcom/Kconfig @@ -74,6 +74,16 @@ config QCOM_MDT_LOADER tristate select QCOM_SCM +config QCOM_OCMEM + tristate "Qualcomm On Chip Memory (OCMEM) driver" + depends on ARCH_QCOM + select QCOM_SCM + help + The On Chip Memory (OCMEM) allocator allows various clients to + allocate memory from OCMEM based on performance, latency and power + requirements. This is typically used by the GPU, camera/video, and + audio components on some Snapdragon SoCs. + config QCOM_PM bool "Qualcomm Power Management" depends on ARCH_QCOM && !ARM64 diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile index 162788701a77..aab333720bfd 100644 --- a/drivers/soc/qcom/Makefile +++ b/drivers/soc/qcom/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_QCOM_COMMAND_DB) += cmd-db.o obj-$(CONFIG_QCOM_GLINK_SSR) +=glink_ssr.o obj-$(CONFIG_QCOM_GSBI)+= qcom_gsbi.o obj-$(CONFIG_QCOM_MDT_LOADER) += mdt_loader.o +obj-$(CONFIG_QCOM_OCMEM) += ocmem.o obj-$(CONFIG_QCOM_PM) += spm.o obj-$(CONFIG_QCOM_QMI_HELPERS) += qmi_helpers.o qmi_helpers-y += qmi_encdec.o qmi_interface.o diff --git a/drivers/soc/qcom/ocmem.c b/drivers/soc/qcom/ocmem.c new file mode 100644 index ..f9e31be5d844 --- /dev/null +++ b/drivers/soc/qcom/ocmem.c @@ -0,0 +1,433 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * The On Chip Memory (OCMEM) allocator allows various clients to allocate + * memory from OCMEM based on performance, latency and power requirements. + * This is typically used by the GPU, camera/video, and audio components on + * some Snapdra
[Freedreno] [PATCH v6 2/7] dt-bindings: display: msm: gmu: add optional ocmem property
Some A3xx and A4xx Adreno GPUs do not have GMEM inside the GPU core and must use the On Chip MEMory (OCMEM) in order to be functional. Add the optional ocmem property to the Adreno Graphics Management Unit bindings. Signed-off-by: Brian Masney --- Changes since v5: - rename ocmem property to sram to match what TI currently has. Changes since v4: - None Changes since v3: - correct link to qcom,ocmem.yaml Changes since v2: - Add a3xx example with OCMEM Changes since v1: - None .../devicetree/bindings/display/msm/gmu.txt | 50 +++ 1 file changed, 50 insertions(+) diff --git a/Documentation/devicetree/bindings/display/msm/gmu.txt b/Documentation/devicetree/bindings/display/msm/gmu.txt index 90af5b0a56a9..2305a2aede5a 100644 --- a/Documentation/devicetree/bindings/display/msm/gmu.txt +++ b/Documentation/devicetree/bindings/display/msm/gmu.txt @@ -31,6 +31,10 @@ Required properties: - iommus: phandle to the adreno iommu - operating-points-v2: phandle to the OPP operating points +Optional properties: +- sram: phandle to the On Chip Memory (OCMEM) that's present on some Snapdragon +SoCs. See Documentation/devicetree/bindings/sram/qcom,ocmem.yaml. + Example: / { @@ -63,3 +67,49 @@ Example: operating-points-v2 = <&gmu_opp_table>; }; }; + +a3xx example with OCMEM support: + +/ { + ... + + gpu: adreno@fdb0 { + compatible = "qcom,adreno-330.2", +"qcom,adreno"; + reg = <0xfdb0 0x1>; + reg-names = "kgsl_3d0_reg_memory"; + interrupts = ; + interrupt-names = "kgsl_3d0_irq"; + clock-names = "core", + "iface", + "mem_iface"; + clocks = <&mmcc OXILI_GFX3D_CLK>, +<&mmcc OXILICX_AHB_CLK>, +<&mmcc OXILICX_AXI_CLK>; + sram = <&ocmem>; + power-domains = <&mmcc OXILICX_GDSC>; + operating-points-v2 = <&gpu_opp_table>; + iommus = <&gpu_iommu 0>; + }; + + ocmem: ocmem@fdd0 { + compatible = "qcom,msm8974-ocmem"; + + reg = <0xfdd0 0x2000>, + <0xfec0 0x18>; + reg-names = "ctrl", +"mem"; + + clocks = <&rpmcc RPM_SMD_OCMEMGX_CLK>, +<&mmcc OCMEMCX_OCMEMNOC_CLK>; + clock-names = "core", + "iface"; + + #address-cells = <1>; + #size-cells = <1>; + + gmu-sram@0 { + reg = <0x0 0x10>; + }; + }; +}; -- 2.21.0 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v6 3/7] firmware: qcom: scm: add OCMEM lock/unlock interface
From: Rob Clark Add support for the OCMEM lock/unlock interface that is needed by the On Chip MEMory (OCMEM) that is present on some Snapdragon devices. Signed-off-by: Rob Clark [masn...@onstation.org: ported to latest kernel; minor reformatting.] Signed-off-by: Brian Masney Reviewed-by: Bjorn Andersson --- Changes since v5: - None Changes since v4: - None Changes since v3: - None Changes since v2: - None Changes since v1: - None Rob's last version of this patch: https://patchwork.kernel.org/patch/7340711/ drivers/firmware/qcom_scm-32.c | 35 + drivers/firmware/qcom_scm-64.c | 12 ++ drivers/firmware/qcom_scm.c| 40 ++ drivers/firmware/qcom_scm.h| 9 include/linux/qcom_scm.h | 15 + 5 files changed, 111 insertions(+) diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c index 215061c581e1..4c2514e5e249 100644 --- a/drivers/firmware/qcom_scm-32.c +++ b/drivers/firmware/qcom_scm-32.c @@ -442,6 +442,41 @@ int __qcom_scm_hdcp_req(struct device *dev, struct qcom_scm_hdcp_req *req, req, req_cnt * sizeof(*req), resp, sizeof(*resp)); } +int __qcom_scm_ocmem_lock(struct device *dev, u32 id, u32 offset, u32 size, + u32 mode) +{ + struct ocmem_tz_lock { + __le32 id; + __le32 offset; + __le32 size; + __le32 mode; + } request; + + request.id = cpu_to_le32(id); + request.offset = cpu_to_le32(offset); + request.size = cpu_to_le32(size); + request.mode = cpu_to_le32(mode); + + return qcom_scm_call(dev, QCOM_SCM_OCMEM_SVC, QCOM_SCM_OCMEM_LOCK_CMD, +&request, sizeof(request), NULL, 0); +} + +int __qcom_scm_ocmem_unlock(struct device *dev, u32 id, u32 offset, u32 size) +{ + struct ocmem_tz_unlock { + __le32 id; + __le32 offset; + __le32 size; + } request; + + request.id = cpu_to_le32(id); + request.offset = cpu_to_le32(offset); + request.size = cpu_to_le32(size); + + return qcom_scm_call(dev, QCOM_SCM_OCMEM_SVC, QCOM_SCM_OCMEM_UNLOCK_CMD, +&request, sizeof(request), NULL, 0); +} + void __qcom_scm_init(void) { } diff --git a/drivers/firmware/qcom_scm-64.c b/drivers/firmware/qcom_scm-64.c index 91d5ad7cf58b..c3a3d9874def 100644 --- a/drivers/firmware/qcom_scm-64.c +++ b/drivers/firmware/qcom_scm-64.c @@ -241,6 +241,18 @@ int __qcom_scm_hdcp_req(struct device *dev, struct qcom_scm_hdcp_req *req, return ret; } +int __qcom_scm_ocmem_lock(struct device *dev, uint32_t id, uint32_t offset, + uint32_t size, uint32_t mode) +{ + return -ENOTSUPP; +} + +int __qcom_scm_ocmem_unlock(struct device *dev, uint32_t id, uint32_t offset, + uint32_t size) +{ + return -ENOTSUPP; +} + void __qcom_scm_init(void) { u64 cmd; diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index 4802ab170fe5..7e285ff3961d 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -191,6 +191,46 @@ bool qcom_scm_pas_supported(u32 peripheral) } EXPORT_SYMBOL(qcom_scm_pas_supported); +/** + * qcom_scm_ocmem_lock_available() - is OCMEM lock/unlock interface available + */ +bool qcom_scm_ocmem_lock_available(void) +{ + return __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_OCMEM_SVC, + QCOM_SCM_OCMEM_LOCK_CMD); +} +EXPORT_SYMBOL(qcom_scm_ocmem_lock_available); + +/** + * qcom_scm_ocmem_lock() - call OCMEM lock interface to assign an OCMEM + * region to the specified initiator + * + * @id: tz initiator id + * @offset: OCMEM offset + * @size: OCMEM size + * @mode: access mode (WIDE/NARROW) + */ +int qcom_scm_ocmem_lock(enum qcom_scm_ocmem_client id, u32 offset, u32 size, + u32 mode) +{ + return __qcom_scm_ocmem_lock(__scm->dev, id, offset, size, mode); +} +EXPORT_SYMBOL(qcom_scm_ocmem_lock); + +/** + * qcom_scm_ocmem_unlock() - call OCMEM unlock interface to release an OCMEM + * region from the specified initiator + * + * @id: tz initiator id + * @offset: OCMEM offset + * @size: OCMEM size + */ +int qcom_scm_ocmem_unlock(enum qcom_scm_ocmem_client id, u32 offset, u32 size) +{ + return __qcom_scm_ocmem_unlock(__scm->dev, id, offset, size); +} +EXPORT_SYMBOL(qcom_scm_ocmem_unlock); + /** * qcom_scm_pas_init_image() - Initialize peripheral authentication service *state machine for a given peripheral, using the diff --git a/drivers/firmware/qcom_scm.h b/drivers/firmware/qcom_scm.h index 99506bd873c0..ef293ee67ec1 100644 --- a/drivers/firmware/qcom_scm.h +++ b/drivers/firmware/qcom_scm.h @@ -42,6 +42,15 @@ extern int __qcom_scm_hdcp_req(struct device *dev, extern void __qcom_scm_
[Freedreno] [PATCH v6 7/7] ARM: qcom_defconfig: add ocmem support
Add ocmem driver that's needed for some a3xx and a4xx based systems. Signed-off-by: Brian Masney --- Changes since v5: - None This patch was introduced in v5. arch/arm/configs/qcom_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/configs/qcom_defconfig b/arch/arm/configs/qcom_defconfig index 34433bf5885d..595e1910ba78 100644 --- a/arch/arm/configs/qcom_defconfig +++ b/arch/arm/configs/qcom_defconfig @@ -225,6 +225,7 @@ CONFIG_QCOM_WCNSS_PIL=y CONFIG_RPMSG_CHAR=y CONFIG_RPMSG_QCOM_SMD=y CONFIG_QCOM_GSBI=y +CONFIG_QCOM_OCMEM=y CONFIG_QCOM_PM=y CONFIG_QCOM_SMEM=y CONFIG_QCOM_SMD_RPM=y -- 2.21.0 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v6 6/7] drm/msm/gpu: add ocmem init/cleanup functions
The files a3xx_gpu.c and a4xx_gpu.c have ifdefs for the OCMEM support that was missing upstream. Add two new functions (adreno_gpu_ocmem_init and adreno_gpu_ocmem_cleanup) that removes some duplicated code. Signed-off-by: Brian Masney --- Changes since v5: - None Changes since v4: - None Changes since v3: - None Changes since v2: - Check for -ENODEV error of_get_ocmem() - remove fail_cleanup_ocmem label in a[34]xx_gpu_init Changes since v1: - remove CONFIG_QCOM_OCMEM #ifdefs - use unsigned long for memory addresses instead of uint32_t - add 'depends on QCOM_OCMEM || QCOM_OCMEM=n' to Kconfig drivers/gpu/drm/msm/Kconfig | 1 + drivers/gpu/drm/msm/adreno/a3xx_gpu.c | 28 + drivers/gpu/drm/msm/adreno/a3xx_gpu.h | 3 +- drivers/gpu/drm/msm/adreno/a4xx_gpu.c | 25 drivers/gpu/drm/msm/adreno/a4xx_gpu.h | 3 +- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 40 + drivers/gpu/drm/msm/adreno/adreno_gpu.h | 10 +++ 7 files changed, 66 insertions(+), 44 deletions(-) diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig index 9c37e4de5896..b3d3b2172659 100644 --- a/drivers/gpu/drm/msm/Kconfig +++ b/drivers/gpu/drm/msm/Kconfig @@ -7,6 +7,7 @@ config DRM_MSM depends on OF && COMMON_CLK depends on MMU depends on INTERCONNECT || !INTERCONNECT + depends on QCOM_OCMEM || QCOM_OCMEM=n select QCOM_MDT_LOADER if ARCH_QCOM select REGULATOR select DRM_KMS_HELPER diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c index 5f7e98028eaf..7ad14937fcdf 100644 --- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c @@ -6,10 +6,6 @@ * Copyright (c) 2014 The Linux Foundation. All rights reserved. */ -#ifdef CONFIG_MSM_OCMEM -# include -#endif - #include "a3xx_gpu.h" #define A3XX_INT0_MASK \ @@ -195,9 +191,9 @@ static int a3xx_hw_init(struct msm_gpu *gpu) gpu_write(gpu, REG_A3XX_RBBM_GPR0_CTL, 0x); /* Set the OCMEM base address for A330, etc */ - if (a3xx_gpu->ocmem_hdl) { + if (a3xx_gpu->ocmem.hdl) { gpu_write(gpu, REG_A3XX_RB_GMEM_BASE_ADDR, - (unsigned int)(a3xx_gpu->ocmem_base >> 14)); + (unsigned int)(a3xx_gpu->ocmem.base >> 14)); } /* Turn on performance counters: */ @@ -318,10 +314,7 @@ static void a3xx_destroy(struct msm_gpu *gpu) adreno_gpu_cleanup(adreno_gpu); -#ifdef CONFIG_MSM_OCMEM - if (a3xx_gpu->ocmem_base) - ocmem_free(OCMEM_GRAPHICS, a3xx_gpu->ocmem_hdl); -#endif + adreno_gpu_ocmem_cleanup(&a3xx_gpu->ocmem); kfree(a3xx_gpu); } @@ -494,17 +487,10 @@ struct msm_gpu *a3xx_gpu_init(struct drm_device *dev) /* if needed, allocate gmem: */ if (adreno_is_a330(adreno_gpu)) { -#ifdef CONFIG_MSM_OCMEM - /* TODO this is different/missing upstream: */ - struct ocmem_buf *ocmem_hdl = - ocmem_allocate(OCMEM_GRAPHICS, adreno_gpu->gmem); - - a3xx_gpu->ocmem_hdl = ocmem_hdl; - a3xx_gpu->ocmem_base = ocmem_hdl->addr; - adreno_gpu->gmem = ocmem_hdl->len; - DBG("using %dK of OCMEM at 0x%08x", adreno_gpu->gmem / 1024, - a3xx_gpu->ocmem_base); -#endif + ret = adreno_gpu_ocmem_init(&adreno_gpu->base.pdev->dev, + adreno_gpu, &a3xx_gpu->ocmem); + if (ret) + goto fail; } if (!gpu->aspace) { diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.h b/drivers/gpu/drm/msm/adreno/a3xx_gpu.h index 5dc33e5ea53b..c555fb13e0d7 100644 --- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.h +++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.h @@ -19,8 +19,7 @@ struct a3xx_gpu { struct adreno_gpu base; /* if OCMEM is used for GMEM: */ - uint32_t ocmem_base; - void *ocmem_hdl; + struct adreno_ocmem ocmem; }; #define to_a3xx_gpu(x) container_of(x, struct a3xx_gpu, base) diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c index ab2b752566d8..b01388a9e89e 100644 --- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c @@ -2,9 +2,6 @@ /* Copyright (c) 2014 The Linux Foundation. All rights reserved. */ #include "a4xx_gpu.h" -#ifdef CONFIG_MSM_OCMEM -# include -#endif #define A4XX_INT0_MASK \ (A4XX_INT0_RBBM_AHB_ERROR |\ @@ -188,7 +185,7 @@ static int a4xx_hw_init(struct msm_gpu *gpu) (1 << 30) | 0x); gpu_write(gpu, REG_A4XX_RB_GMEM_BASE_ADDR, - (unsigned int)(a4xx_gpu->ocmem_base >>
[Freedreno] [PATCH v6 0/7] qcom: add OCMEM support
This patch series adds support for Qualcomm's On Chip MEMory (OCMEM) that is needed in order to support some a3xx and a4xx-based GPUs upstream. This is based on Rob Clark's patch series that he submitted in October 2015 and I am resubmitting updated patches with his permission. See the individual patches for the changelog. This was tested with the GPU on a LG Nexus 5 (hammerhead) phone and this will work on other msm8974-based systems. For a summary of what currently works upstream on the Nexus 5, see my status page at https://masneyb.github.io/nexus-5-upstream/. Changes since v5: - Rename ocmem device tree property to sram See individual patches for changelogs for previous versions. Brian Masney (5): dt-bindings: soc: qcom: add On Chip MEMory (OCMEM) bindings dt-bindings: display: msm: gmu: add optional ocmem property soc: qcom: add OCMEM driver drm/msm/gpu: add ocmem init/cleanup functions ARM: qcom_defconfig: add ocmem support Rob Clark (2): firmware: qcom: scm: add OCMEM lock/unlock interface firmware: qcom: scm: add support to restore secure config to qcm_scm-32 .../devicetree/bindings/display/msm/gmu.txt | 50 ++ .../devicetree/bindings/sram/qcom,ocmem.yaml | 96 arch/arm/configs/qcom_defconfig | 1 + drivers/firmware/qcom_scm-32.c| 52 ++- drivers/firmware/qcom_scm-64.c| 12 + drivers/firmware/qcom_scm.c | 53 +++ drivers/firmware/qcom_scm.h | 9 + drivers/gpu/drm/msm/Kconfig | 1 + drivers/gpu/drm/msm/adreno/a3xx_gpu.c | 28 +- drivers/gpu/drm/msm/adreno/a3xx_gpu.h | 3 +- drivers/gpu/drm/msm/adreno/a4xx_gpu.c | 25 +- drivers/gpu/drm/msm/adreno/a4xx_gpu.h | 3 +- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 40 ++ drivers/gpu/drm/msm/adreno/adreno_gpu.h | 10 + drivers/soc/qcom/Kconfig | 10 + drivers/soc/qcom/Makefile | 1 + drivers/soc/qcom/ocmem.c | 433 ++ include/linux/qcom_scm.h | 26 ++ include/soc/qcom/ocmem.h | 62 +++ 19 files changed, 870 insertions(+), 45 deletions(-) create mode 100644 Documentation/devicetree/bindings/sram/qcom,ocmem.yaml create mode 100644 drivers/soc/qcom/ocmem.c create mode 100644 include/soc/qcom/ocmem.h -- 2.21.0 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
Re: [Freedreno] [PATCH v5 2/7] dt-bindings: display: msm: gmu: add optional ocmem property
On Wed, Aug 21, 2019 at 02:26:02PM -0500, Rob Herring wrote: > On Mon, Aug 05, 2019 at 08:22:24PM -0400, Brian Masney wrote: > > Some A3xx and A4xx Adreno GPUs do not have GMEM inside the GPU core and > > must use the On Chip MEMory (OCMEM) in order to be functional. Add the > > optional ocmem property to the Adreno Graphics Management Unit bindings. > > > > Signed-off-by: Brian Masney > > --- > > Changes since v4: > > - None > > > > Changes since v3: > > - correct link to qcom,ocmem.yaml > > > > Changes since v2: > > - Add a3xx example with OCMEM > > > > Changes since v1: > > - None > > > > .../devicetree/bindings/display/msm/gmu.txt | 50 +++ > > 1 file changed, 50 insertions(+) > > > > diff --git a/Documentation/devicetree/bindings/display/msm/gmu.txt > > b/Documentation/devicetree/bindings/display/msm/gmu.txt > > index 90af5b0a56a9..672d557caba4 100644 > > --- a/Documentation/devicetree/bindings/display/msm/gmu.txt > > +++ b/Documentation/devicetree/bindings/display/msm/gmu.txt > > @@ -31,6 +31,10 @@ Required properties: > > - iommus: phandle to the adreno iommu > > - operating-points-v2: phandle to the OPP operating points > > > > +Optional properties: > > +- ocmem: phandle to the On Chip Memory (OCMEM) that's present on some > > Snapdragon > > + SoCs. See Documentation/devicetree/bindings/sram/qcom,ocmem.yaml. > > Sigh, to repeat my comment on v1 and v3: > > We already have a couple of similar properties. Lets standardize on > 'sram' as that is what TI already uses. I also had the path wrong then in those older versions. It was previously in the soc namespace instead of the sram namespace. I didn't realize that you also wanted to change the name of the property as well. Sorry about the confusion on my part. Brian ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
Re: [Freedreno] [PATCH RFC 06/11] drm/bridge: analogix-anx78xx: add support for avdd33 regulator
On Thu, Aug 15, 2019 at 10:22:45AM +0200, Linus Walleij wrote: > On Thu, Aug 15, 2019 at 2:49 AM Brian Masney wrote: > > > Add support for the avdd33 regulator to the analogix-anx78xx driver. > > Note that the regulator is currently enabled during driver probe and > > disabled when the driver is removed. This is currently how the > > downstream MSM kernel sources do this. > > > > Let's not merge this upstream for the mean time until I get the external > > display fully working on the Nexus 5 and then I can submit proper > > support then that powers down this regulator in the power off function. > > > > Signed-off-by: Brian Masney > > > +static void anx78xx_disable_regulator_action(void *_data) > > +{ > > + struct anx78xx_platform_data *pdata = _data; > > + > > + regulator_disable(pdata->avdd33); > > +} > (...) > > + err = devm_add_action(dev, anx78xx_disable_regulator_action, > > + pdata); > > Clever idea. Good for initial support, probably later on it would > need to be reworked using runtime PM so it's not constantly > powered up. Yes, that's my plan. I suspect that I may have a regulator disabled somewhere so I was planning to leave this on all the time for the time being to match the downstream behavior until I get the hot plug detect GPIO working. > Reviewed-by: Linus Walleij Thanks, Brian ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
Re: [Freedreno] [PATCH 09/11] ARM: dts: qcom: pm8941: add 5vs2 regulator node
On Thu, Aug 15, 2019 at 10:34:17AM +0200, Linus Walleij wrote: > On Thu, Aug 15, 2019 at 2:49 AM Brian Masney wrote: > > > pm8941 is missing the 5vs2 regulator node so let's add it since its > > needed to get the external display working. This regulator was already > > configured in the interrupts property on the parent node. > > > > Note that this regulator is referred to as mvs2 in the downstream MSM > > kernel sources. > > When I looked at it it seemed like this convention is used for power > supplies that appear on both the main PMIC and the "extra (boot? basic? > low power?) PMIC that the main 80xx PMIC has mvs1 and the > other 89xx PMIC has mvs2. According to the downstream MSM sources, the 5vs1 and 5vs2 rails are both on the second pm8941 PMIC: https://github.com/AICP/kernel_lge_hammerhead/blob/n7.1/arch/arm/boot/dts/msm8974-regulator.dtsi#L18 > I suppose it is named "mvs" on both PMICs and this is just a rail > name so as not to confuse the schematic? That sounds reasonable. > > Signed-off-by: Brian Masney > > Reviewed-by: Linus Walleij Thank you! Brian ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH RFC 11/11] ARM: dts: qcom: msm8974-hammerhead: add support for external display
Add HDMI nodes and other supporting infrastructure in order to support the external display. This is based on work from Jonathan Marek. Signed-off-by: Brian Masney --- The hdmi-tx node in the downstream MSM sources: https://github.com/AICP/kernel_lge_hammerhead/blob/n7.1/arch/arm/boot/dts/msm8974-mdss.dtsi#L101 .../qcom-msm8974-lge-nexus5-hammerhead.dts| 140 ++ 1 file changed, 140 insertions(+) diff --git a/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts b/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts index 3487daf98e81..83416b6d6634 100644 --- a/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts +++ b/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts @@ -234,6 +234,34 @@ pinctrl-names = "default"; pinctrl-0 = <&wlan_regulator_pin>; }; + + anx_avdd33: avdd33 { + compatible = "regulator-fixed"; + + regulator-name = "avdd-3p3"; + regulator-min-microvolt = <330>; + regulator-max-microvolt = <330>; + + gpio = <&pm8941_gpios 26 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-names = "default"; + pinctrl-0 = <&anx_avdd33_pin>; + }; + + anx_vdd10: vdd10 { + compatible = "regulator-fixed"; + + regulator-name = "vdd-1p0"; + regulator-min-microvolt = <100>; + regulator-max-microvolt = <100>; + + gpio = <&pm8941_gpios 8 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-names = "default"; + pinctrl-0 = <&anx_vdd10_pin>; + }; }; &soc { @@ -355,6 +383,40 @@ bias-disable; }; }; + + hdmi_pin: hdmi { + cec { + pins = "gpio31"; + function = "hdmi_cec"; + }; + + ddc { + pins = "gpio32", "gpio33"; + function = "hdmi_ddc"; + }; + + hpd { + pins = "gpio34"; + function = "hdmi_hpd"; + }; + }; + + anx_msm_pin: anx { + irq { + pins = "gpio28"; + function = "gpio"; + drive-strength = <8>; + bias-pull-up; + input-enable; + }; + + reset { + pins = "gpio68"; + function = "gpio"; + drive-strength = <8>; + bias-pull-up; + }; + }; }; sdhci@f9824900 { @@ -440,6 +502,28 @@ default-brightness = <200>; }; }; + + anx7808@72 { + compatible = "analogix,anx7808"; + reg = <0x72>; + interrupts-extended = <&msmgpio 28 IRQ_TYPE_EDGE_RISING>; + + hpd-gpios = <&pm8941_gpios 13 GPIO_ACTIVE_HIGH>; + pd-gpios = <&pm8941_gpios 14 GPIO_ACTIVE_HIGH>; + reset-gpios = <&msmgpio 68 GPIO_ACTIVE_LOW>; + + pinctrl-names = "default"; + pinctrl-0 = <&anx_msm_pin>, <&anx_pin>; + + dvdd10-supply = <&anx_vdd10>; + avdd33-supply = <&anx_avdd33>; + + port { + anx7808_in: endpoint { + remote-endpoint = <&hdmi_out>; + }; + }; + }; }; i2c@f9968000 { @@ -621,6 +705,29 @@ vddio-supply = <&pm8941_l12>; }; + + hdmi-tx@fd922100 { + status = "ok"; + + pinctrl-names = "default"; + pinctrl-0 = <&hdmi_pin>; + + qcom,hdmi-tx-ddc-clk = <&msmgpio 32 GPIO_ACTIVE_HIGH>; + qcom,hdmi-tx-ddc-data = <&msmgpio 33 GPIO_ACTIVE_HIGH>;
[Freedreno] [PATCH 05/11] drm/bridge: analogix-anx78xx: correct value of TX_P0
When attempting to configure this driver on a Nexus 5 phone (msm8974), setting up the dummy i2c bus for TX_P0 would fail due to an -EBUSY error. The downstream MSM kernel sources [1] shows that the proper value for TX_P0 is 0x78, not 0x70, so correct the value to allow device probing to succeed. [1] https://github.com/AICP/kernel_lge_hammerhead/blob/n7.1/drivers/video/slimport/slimport_tx_reg.h Signed-off-by: Brian Masney --- drivers/gpu/drm/bridge/analogix-anx78xx.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/analogix-anx78xx.h b/drivers/gpu/drm/bridge/analogix-anx78xx.h index 25e063bcecbc..bc511fc605c9 100644 --- a/drivers/gpu/drm/bridge/analogix-anx78xx.h +++ b/drivers/gpu/drm/bridge/analogix-anx78xx.h @@ -6,7 +6,7 @@ #ifndef __ANX78xx_H #define __ANX78xx_H -#define TX_P0 0x70 +#define TX_P0 0x78 #define TX_P1 0x7a #define TX_P2 0x72 -- 2.21.0 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH 09/11] ARM: dts: qcom: pm8941: add 5vs2 regulator node
pm8941 is missing the 5vs2 regulator node so let's add it since its needed to get the external display working. This regulator was already configured in the interrupts property on the parent node. Note that this regulator is referred to as mvs2 in the downstream MSM kernel sources. Signed-off-by: Brian Masney --- arch/arm/boot/dts/qcom-pm8941.dtsi | 10 ++ 1 file changed, 10 insertions(+) diff --git a/arch/arm/boot/dts/qcom-pm8941.dtsi b/arch/arm/boot/dts/qcom-pm8941.dtsi index f198480c8ef4..c1f2012d1c8b 100644 --- a/arch/arm/boot/dts/qcom-pm8941.dtsi +++ b/arch/arm/boot/dts/qcom-pm8941.dtsi @@ -178,6 +178,16 @@ qcom,vs-soft-start-strength = <0>; regulator-initial-mode = <1>; }; + + pm8941_5vs2: 5vs2 { + regulator-enable-ramp-delay = <1000>; + regulator-pull-down; + regulator-over-current-protection; + qcom,ocp-max-retries = <10>; + qcom,ocp-retry-delay = <30>; + qcom,vs-soft-start-strength = <0>; + regulator-initial-mode = <1>; + }; }; }; }; -- 2.21.0 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH RFC 10/11] ARM: dts: qcom: msm8974: add HDMI nodes
Add HDMI tx and phy nodes to support an external display that can be connected over the SlimPort. This is based on work from Jonathan Marek. Signed-off-by: Brian Masney --- The hdmi-tx node in the downstream MSM sources: https://github.com/AICP/kernel_lge_hammerhead/blob/n7.1/arch/arm/boot/dts/msm8974-mdss.dtsi#L101 arch/arm/boot/dts/qcom-msm8974.dtsi | 80 + 1 file changed, 80 insertions(+) diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi index 369e58f64145..35c51336a9d4 100644 --- a/arch/arm/boot/dts/qcom-msm8974.dtsi +++ b/arch/arm/boot/dts/qcom-msm8974.dtsi @@ -1139,6 +1139,13 @@ port@0 { reg = <0>; + mdp5_intf3_out: endpoint { + remote-endpoint = <&hdmi_in>; + }; + }; + + port@1 { + reg = <1>; mdp5_intf1_out: endpoint { remote-endpoint = <&dsi0_in>; }; @@ -1216,6 +1223,79 @@ clocks = <&mmcc MDSS_AHB_CLK>; clock-names = "iface"; }; + + hdmi: hdmi-tx@fd922100 { + status = "disabled"; + + compatible = "qcom,hdmi-tx-8974"; + reg = <0xfd922100 0x35c>, + <0xfc4b8000 0x60f0>; + reg-names = "core_physical", + "qfprom_physical"; + + interrupt-parent = <&mdss>; + interrupts = <8 IRQ_TYPE_LEVEL_HIGH>; + + power-domains = <&mmcc MDSS_GDSC>; + + clocks = <&mmcc MDSS_MDP_CLK>, +<&mmcc MDSS_AHB_CLK>, +<&mmcc MDSS_HDMI_CLK>, +<&mmcc MDSS_HDMI_AHB_CLK>, +<&mmcc MDSS_EXTPCLK_CLK>; + clock-names = "mdp_core", + "iface", + "core", + "alt_iface", + "extp"; + + hpd-5v-supply = <&pm8941_5vs2>; + core-vdda-supply = <&pm8941_l12>; + core-vcc-supply = <&pm8941_s3>; + + /* +* FIXME - drivers/gpu/drm/msm/hdmi/hdmi.c via hpd_reg_names_8x74 +* looks for hpd-gdsc-supply. What should be used here? Shouldn't +* this functionality be provided by the power-domains above? +*/ + + phys = <&hdmi_phy>; + phy-names = "hdmi_phy"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + hdmi_in: endpoint { + remote-endpoint = <&mdp5_intf3_out>; + }; + }; + + port@1 { + reg = <1>; + }; + }; + }; + + hdmi_phy: hdmi-phy@fd922500 { + status = "disabled"; + + compatible = "qcom,hdmi-phy-8974"; + reg = <0xfd922500 0x7c>; + reg-names = "hdmi_phy"; + + clocks = <&mmcc MDSS_AHB_CLK>, +<&mmcc MDSS_HDMI_AH
[Freedreno] [PATCH 08/11] drm/msm/hdmi: silence -EPROBE_DEFER warning
Silence a warning message due to an -EPROBE_DEFER error to help cleanup the system boot log. Signed-off-by: Brian Masney --- drivers/gpu/drm/msm/hdmi/hdmi_phy.c | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_phy.c b/drivers/gpu/drm/msm/hdmi/hdmi_phy.c index 1697e61f9c2f..8a38d4b95102 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_phy.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_phy.c @@ -29,8 +29,12 @@ static int msm_hdmi_phy_resource_init(struct hdmi_phy *phy) reg = devm_regulator_get(dev, cfg->reg_names[i]); if (IS_ERR(reg)) { ret = PTR_ERR(reg); - DRM_DEV_ERROR(dev, "failed to get phy regulator: %s (%d)\n", - cfg->reg_names[i], ret); + if (ret != -EPROBE_DEFER) { + DRM_DEV_ERROR(dev, + "failed to get phy regulator: %s (%d)\n", + cfg->reg_names[i], ret); + } + return ret; } -- 2.21.0 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH 01/11] dt-bindings: drm/bridge: analogix-anx78xx: add new variants
Add support for the analogix,anx7808, analogix,anx7812, and analogix,anx7818 variants. Signed-off-by: Brian Masney --- .../devicetree/bindings/display/bridge/anx7814.txt | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/display/bridge/anx7814.txt b/Documentation/devicetree/bindings/display/bridge/anx7814.txt index dbd7c84ee584..17258747fff6 100644 --- a/Documentation/devicetree/bindings/display/bridge/anx7814.txt +++ b/Documentation/devicetree/bindings/display/bridge/anx7814.txt @@ -6,7 +6,11 @@ designed for portable devices. Required properties: - - compatible : "analogix,anx7814" + - compatible : Must be one of: + "analogix,anx7808" + "analogix,anx7812" + "analogix,anx7814" + "analogix,anx7818" - reg : I2C address of the device - interrupts : Should contain the INTP interrupt - hpd-gpios : Which GPIO to use for hpd -- 2.21.0 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH RFC 06/11] drm/bridge: analogix-anx78xx: add support for avdd33 regulator
Add support for the avdd33 regulator to the analogix-anx78xx driver. Note that the regulator is currently enabled during driver probe and disabled when the driver is removed. This is currently how the downstream MSM kernel sources do this. Let's not merge this upstream for the mean time until I get the external display fully working on the Nexus 5 and then I can submit proper support then that powers down this regulator in the power off function. Signed-off-by: Brian Masney --- drivers/gpu/drm/bridge/analogix-anx78xx.c | 33 +++ 1 file changed, 33 insertions(+) diff --git a/drivers/gpu/drm/bridge/analogix-anx78xx.c b/drivers/gpu/drm/bridge/analogix-anx78xx.c index 8daee6b1fa88..48adf010816c 100644 --- a/drivers/gpu/drm/bridge/analogix-anx78xx.c +++ b/drivers/gpu/drm/bridge/analogix-anx78xx.c @@ -48,6 +48,7 @@ static const u8 anx78xx_i2c_addresses[] = { struct anx78xx_platform_data { struct regulator *dvdd10; + struct regulator *avdd33; struct gpio_desc *gpiod_hpd; struct gpio_desc *gpiod_pd; struct gpio_desc *gpiod_reset; @@ -707,10 +708,42 @@ static int anx78xx_start(struct anx78xx *anx78xx) return err; } +static void anx78xx_disable_regulator_action(void *_data) +{ + struct anx78xx_platform_data *pdata = _data; + + regulator_disable(pdata->avdd33); +} + static int anx78xx_init_pdata(struct anx78xx *anx78xx) { struct anx78xx_platform_data *pdata = &anx78xx->pdata; struct device *dev = &anx78xx->client->dev; + int err; + + /* 3.3V digital core power regulator */ + pdata->avdd33 = devm_regulator_get(dev, "avdd33"); + if (IS_ERR(pdata->avdd33)) { + err = PTR_ERR(pdata->avdd33); + if (err != -EPROBE_DEFER) + DRM_ERROR("avdd33 regulator not found\n"); + + return err; + } + + err = regulator_enable(pdata->avdd33); + if (err) { + DRM_ERROR("Failed to enable avdd33 regulator: %d\n", err); + return err; + } + + err = devm_add_action(dev, anx78xx_disable_regulator_action, + pdata); + if (err < 0) { + dev_err(dev, "Failed to setup regulator cleanup action %d\n", + err); + return err; + } /* 1.0V digital core power regulator */ pdata->dvdd10 = devm_regulator_get(dev, "dvdd10"); -- 2.21.0 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH 00/11] ARM: dts: qcom: msm8974: add support for external display
This patch series begins to add support for the external display over HDMI that is supported on msm8974 SoCs. I'm testing this series on the Nexus 5, and I'm able to communicate with the HDMI bridge via the analogix-anx78xx driver, however the external display is not working yet. When I plug in the HDMI cable, the monitor detects that a device is hooked up, but nothing is shown on the external monitor. The hot plug detect GPIO (hpd-gpios) on the analogix-anx78xx bridge and MSM HDMI drivers do not change state when the slimport adapter or HDMI cable is plugged in or removed. I wonder if a regulator is not enabled somewhere? I have a comment in patch 10 regarding 'hpd-gdsc-supply' that may potentially be an issue. I'm still digging in on this, however I'd appreciate any feedback if anyone has time. Most of these patches are ready now, so I marked the ones that aren't ready with 'PATCH RFC'. I'm using an Analogix Semiconductor SP6001 SlimPort Micro-USB to 4K HDMI Adapter to connect my phone to an external display via a standard HDMI cable. This works just fine with the downstream MSM kernel using Android. Brian Masney (11): dt-bindings: drm/bridge: analogix-anx78xx: add new variants drm/bridge: analogix-anx78xx: add new variants drm/bridge: analogix-anx78xx: silence -EPROBE_DEFER warnings drm/bridge: analogix-anx78xx: convert to i2c_new_dummy_device drm/bridge: analogix-anx78xx: correct value of TX_P0 drm/bridge: analogix-anx78xx: add support for avdd33 regulator ARM: qcom_defconfig: add CONFIG_DRM_ANALOGIX_ANX78XX drm/msm/hdmi: silence -EPROBE_DEFER warning ARM: dts: qcom: pm8941: add 5vs2 regulator node ARM: dts: qcom: msm8974: add HDMI nodes ARM: dts: qcom: msm8974-hammerhead: add support for external display .../bindings/display/bridge/anx7814.txt | 6 +- .../qcom-msm8974-lge-nexus5-hammerhead.dts| 140 ++ arch/arm/boot/dts/qcom-msm8974.dtsi | 80 ++ arch/arm/boot/dts/qcom-pm8941.dtsi| 10 ++ arch/arm/configs/qcom_defconfig | 1 + drivers/gpu/drm/bridge/analogix-anx78xx.c | 60 +++- drivers/gpu/drm/bridge/analogix-anx78xx.h | 2 +- drivers/gpu/drm/msm/hdmi/hdmi_phy.c | 8 +- 8 files changed, 295 insertions(+), 12 deletions(-) -- 2.21.0 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH 04/11] drm/bridge: analogix-anx78xx: convert to i2c_new_dummy_device
The i2c_new_dummy() function is deprecated since it returns NULL on error. Change this to use the recommended replacement i2c_new_dummy_device() that returns an error code that can be read with PTR_ERR() and friends. Signed-off-by: Brian Masney --- drivers/gpu/drm/bridge/analogix-anx78xx.c | 15 +-- 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix-anx78xx.c b/drivers/gpu/drm/bridge/analogix-anx78xx.c index 62dfced91384..8daee6b1fa88 100644 --- a/drivers/gpu/drm/bridge/analogix-anx78xx.c +++ b/drivers/gpu/drm/bridge/analogix-anx78xx.c @@ -1355,15 +1355,18 @@ static int anx78xx_i2c_probe(struct i2c_client *client, /* Map slave addresses of ANX7814 */ for (i = 0; i < I2C_NUM_ADDRESSES; i++) { - anx78xx->i2c_dummy[i] = i2c_new_dummy(client->adapter, - anx78xx_i2c_addresses[i] >> 1); - if (!anx78xx->i2c_dummy[i]) { - err = -ENOMEM; - DRM_ERROR("Failed to reserve I2C bus %02x\n", - anx78xx_i2c_addresses[i]); + struct i2c_client *i2c_dummy; + + i2c_dummy = i2c_new_dummy_device(client->adapter, +anx78xx_i2c_addresses[i] >> 1); + if (IS_ERR(i2c_dummy)) { + err = PTR_ERR(i2c_dummy); + DRM_ERROR("Failed to reserve I2C bus %02x: %d\n", + anx78xx_i2c_addresses[i], err); goto err_unregister_i2c; } + anx78xx->i2c_dummy[i] = i2c_dummy; anx78xx->map[i] = devm_regmap_init_i2c(anx78xx->i2c_dummy[i], &anx78xx_regmap_config); if (IS_ERR(anx78xx->map[i])) { -- 2.21.0 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH 07/11] ARM: qcom_defconfig: add CONFIG_DRM_ANALOGIX_ANX78XX
Add CONFIG_DRM_ANALOGIX_ANX78XX as a module so that the external display can be used on the Nexus 5 phones. Signed-off-by: Brian Masney --- arch/arm/configs/qcom_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/configs/qcom_defconfig b/arch/arm/configs/qcom_defconfig index 34433bf5885d..139e6610f034 100644 --- a/arch/arm/configs/qcom_defconfig +++ b/arch/arm/configs/qcom_defconfig @@ -148,6 +148,7 @@ CONFIG_REGULATOR_QCOM_SPMI=y CONFIG_MEDIA_SUPPORT=y CONFIG_DRM=y CONFIG_DRM_PANEL_SIMPLE=y +CONFIG_DRM_ANALOGIX_ANX78XX=m CONFIG_FB=y CONFIG_FRAMEBUFFER_CONSOLE=y # CONFIG_LCD_CLASS_DEVICE is not set -- 2.21.0 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH 02/11] drm/bridge: analogix-anx78xx: add new variants
Add support for the 7808 variant. While we're here, the of match table was missing support for the 7812 and 7818 variants, so add them as well. Signed-off-by: Brian Masney --- drivers/gpu/drm/bridge/analogix-anx78xx.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/bridge/analogix-anx78xx.c b/drivers/gpu/drm/bridge/analogix-anx78xx.c index 3c7cc5af735c..9acdbedf1245 100644 --- a/drivers/gpu/drm/bridge/analogix-anx78xx.c +++ b/drivers/gpu/drm/bridge/analogix-anx78xx.c @@ -1301,6 +1301,7 @@ static const struct regmap_config anx78xx_regmap_config = { }; static const u16 anx78xx_chipid_list[] = { + 0x7808, 0x7812, 0x7814, 0x7818, @@ -1463,7 +1464,10 @@ MODULE_DEVICE_TABLE(i2c, anx78xx_id); #if IS_ENABLED(CONFIG_OF) static const struct of_device_id anx78xx_match_table[] = { + { .compatible = "analogix,anx7808", }, + { .compatible = "analogix,anx7812", }, { .compatible = "analogix,anx7814", }, + { .compatible = "analogix,anx7818", }, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(of, anx78xx_match_table); -- 2.21.0 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH 03/11] drm/bridge: analogix-anx78xx: silence -EPROBE_DEFER warnings
Silence two warning messages that occur due to -EPROBE_DEFER errors to help cleanup the system boot log. Signed-off-by: Brian Masney --- drivers/gpu/drm/bridge/analogix-anx78xx.c | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix-anx78xx.c b/drivers/gpu/drm/bridge/analogix-anx78xx.c index 9acdbedf1245..62dfced91384 100644 --- a/drivers/gpu/drm/bridge/analogix-anx78xx.c +++ b/drivers/gpu/drm/bridge/analogix-anx78xx.c @@ -715,7 +715,9 @@ static int anx78xx_init_pdata(struct anx78xx *anx78xx) /* 1.0V digital core power regulator */ pdata->dvdd10 = devm_regulator_get(dev, "dvdd10"); if (IS_ERR(pdata->dvdd10)) { - DRM_ERROR("DVDD10 regulator not found\n"); + if (PTR_ERR(pdata->dvdd10) != -EPROBE_DEFER) + DRM_ERROR("DVDD10 regulator not found\n"); + return PTR_ERR(pdata->dvdd10); } @@ -1333,7 +1335,9 @@ static int anx78xx_i2c_probe(struct i2c_client *client, err = anx78xx_init_pdata(anx78xx); if (err) { - DRM_ERROR("Failed to initialize pdata: %d\n", err); + if (err != -EPROBE_DEFER) + DRM_ERROR("Failed to initialize pdata: %d\n", err); + return err; } -- 2.21.0 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
Re: [Freedreno] [PATCH 1/7] drm/msm/mdp4: Drop unused GPIO include
On Sat, Jun 29, 2019 at 02:59:27PM +0200, Linus Walleij wrote: > This file is not using any symbols from so just > drop this include. > > Cc: Rob Clark > Cc: Sean Paul > Cc: linux-arm-...@vger.kernel.org > Cc: freedreno@lists.freedesktop.org > Signed-off-by: Linus Walleij For the series: Reviewed-by: Brian Masney ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v5 0/7] qcom: add OCMEM support
This patch series adds support for Qualcomm's On Chip MEMory (OCMEM) that is needed in order to support some a3xx and a4xx-based GPUs upstream. This is based on Rob Clark's patch series that he submitted in October 2015 and I am resubmitting updated patches with his permission. See the individual patches for the changelog. This was tested with the GPU on a LG Nexus 5 (hammerhead) phone and this will work on other msm8974-based systems. For a summary of what currently works upstream on the Nexus 5, see my status page at https://masneyb.github.io/nexus-5-upstream/. Brian Masney (5): dt-bindings: soc: qcom: add On Chip MEMory (OCMEM) bindings dt-bindings: display: msm: gmu: add optional ocmem property soc: qcom: add OCMEM driver drm/msm/gpu: add ocmem init/cleanup functions ARM: qcom_defconfig: add ocmem support Rob Clark (2): firmware: qcom: scm: add OCMEM lock/unlock interface firmware: qcom: scm: add support to restore secure config to qcm_scm-32 .../devicetree/bindings/display/msm/gmu.txt | 50 ++ .../devicetree/bindings/sram/qcom,ocmem.yaml | 96 arch/arm/configs/qcom_defconfig | 1 + drivers/firmware/qcom_scm-32.c| 52 ++- drivers/firmware/qcom_scm-64.c| 12 + drivers/firmware/qcom_scm.c | 53 +++ drivers/firmware/qcom_scm.h | 9 + drivers/gpu/drm/msm/Kconfig | 1 + drivers/gpu/drm/msm/adreno/a3xx_gpu.c | 28 +- drivers/gpu/drm/msm/adreno/a3xx_gpu.h | 3 +- drivers/gpu/drm/msm/adreno/a4xx_gpu.c | 25 +- drivers/gpu/drm/msm/adreno/a4xx_gpu.h | 3 +- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 40 ++ drivers/gpu/drm/msm/adreno/adreno_gpu.h | 10 + drivers/soc/qcom/Kconfig | 10 + drivers/soc/qcom/Makefile | 1 + drivers/soc/qcom/ocmem.c | 433 ++ include/linux/qcom_scm.h | 26 ++ include/soc/qcom/ocmem.h | 62 +++ 19 files changed, 870 insertions(+), 45 deletions(-) create mode 100644 Documentation/devicetree/bindings/sram/qcom,ocmem.yaml create mode 100644 drivers/soc/qcom/ocmem.c create mode 100644 include/soc/qcom/ocmem.h -- 2.21.0 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v5 7/7] ARM: qcom_defconfig: add ocmem support
Add ocmem driver that's needed for some a3xx and a4xx based systems. Signed-off-by: Brian Masney --- This is a new patch that was introduced in v5. arch/arm/configs/qcom_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/configs/qcom_defconfig b/arch/arm/configs/qcom_defconfig index 34433bf5885d..595e1910ba78 100644 --- a/arch/arm/configs/qcom_defconfig +++ b/arch/arm/configs/qcom_defconfig @@ -225,6 +225,7 @@ CONFIG_QCOM_WCNSS_PIL=y CONFIG_RPMSG_CHAR=y CONFIG_RPMSG_QCOM_SMD=y CONFIG_QCOM_GSBI=y +CONFIG_QCOM_OCMEM=y CONFIG_QCOM_PM=y CONFIG_QCOM_SMEM=y CONFIG_QCOM_SMD_RPM=y -- 2.21.0 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v5 5/7] soc: qcom: add OCMEM driver
The OCMEM driver handles allocation and configuration of the On Chip MEMory that is present on some Snapdragon SoCs. Devices which have OCMEM do not have GMEM inside the GPU core, so the GPU must instead use OCMEM to be functional. Since the GPU is currently the only OCMEM user with an upstream driver, this is just a minimal implementation sufficient for statically allocating to the GPU it's chunk of OCMEM. This driver currently does not read the gmu-sram node that is described in the device tree bindings. The starting memory address of the GPU's reserved memory region is hardcoded to zero to match what the hardware expects. The driver can be updated to read the reserved memory regions from device tree once other users of OCMEM are added upstream. Signed-off-by: Brian Masney Co-developed-by: Rob Clark Signed-off-by: Rob Clark Reviewed-by: Bjorn Andersson --- Changes since v4: - Change 'GPL' to 'GPL v2' in MODULE_LICENSE Changes since v3: - None Changes since v2 - Changed static inline stubs return -ENODEV when OCMEM is not configured into the kernel. Changes since v1: - ocmem_allocate(): check for alignment and minimum allocation size. The 64K values came from the downstream MSM kernel sources. - add locking to memory allocations based on the client - use clk_bulk_*() functions - rename qcom,ocmem-msm8974 to qcom,msm8974-ocmem - rename reg-names to ctrl and mem - remove ocmem.xml.h file; use FIELD_PREP() instead for some nice cleanups - add static inline noop versions of public-facing functions when ocmem is disabled to remove #ifdefs in adrenu_gpu.c - use unsigned long for memory addresses - move ocmem_dev_remove() below _probe() function - remove error check from platform_get_resource_byname for ctrl resource - add MODULE_DESCRIPTION() and MODULE_LICENSE() - add description to top of ocmem.[ch] - correct thin mode bit in update_ocmem() - add 'WARN_ON(client != OCMEM_GRAPHICS)' to device_address() - make of_get_ocmem return error codes via ERR_PTR instead of NULL - ocmem_{allocate,free} - WARN_ON() if client != OCMEM_GRAPHICS. Simplify if statements. - allow NULL to be passed into ocmem_free - remove unnecessary initialization of i in update_ocmem() - add dev_dbg to ocmem_allocate Changes since Rob's last version of this patch from 2015: https://patchwork.kernel.org/patch/7379801/ - reformatted driver to allow multiple instances - updated logging of error paths during device probing - remove unused psgsc_ctrl - remove _clk from clock names - propagate error code from devm_ioremap_resource() - use device_get_match_data() - SPDX license tags - remove QCOM_SMD in Kconfig - select ARCH_QCOM in Kconfig - select ARCH_QCOM in Kconfig - select QCOM_SCM in Kconfig - longer description in Kconfig drivers/soc/qcom/Kconfig | 10 + drivers/soc/qcom/Makefile | 1 + drivers/soc/qcom/ocmem.c | 433 ++ include/soc/qcom/ocmem.h | 62 ++ 4 files changed, 506 insertions(+) create mode 100644 drivers/soc/qcom/ocmem.c create mode 100644 include/soc/qcom/ocmem.h diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig index a6d1bfb17279..d18eb83b10da 100644 --- a/drivers/soc/qcom/Kconfig +++ b/drivers/soc/qcom/Kconfig @@ -74,6 +74,16 @@ config QCOM_MDT_LOADER tristate select QCOM_SCM +config QCOM_OCMEM + tristate "Qualcomm On Chip Memory (OCMEM) driver" + depends on ARCH_QCOM + select QCOM_SCM + help + The On Chip Memory (OCMEM) allocator allows various clients to + allocate memory from OCMEM based on performance, latency and power + requirements. This is typically used by the GPU, camera/video, and + audio components on some Snapdragon SoCs. + config QCOM_PM bool "Qualcomm Power Management" depends on ARCH_QCOM && !ARM64 diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile index eeb088beb15f..dfc378014a33 100644 --- a/drivers/soc/qcom/Makefile +++ b/drivers/soc/qcom/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_QCOM_COMMAND_DB) += cmd-db.o obj-$(CONFIG_QCOM_GLINK_SSR) +=glink_ssr.o obj-$(CONFIG_QCOM_GSBI)+= qcom_gsbi.o obj-$(CONFIG_QCOM_MDT_LOADER) += mdt_loader.o +obj-$(CONFIG_QCOM_OCMEM) += ocmem.o obj-$(CONFIG_QCOM_PM) += spm.o obj-$(CONFIG_QCOM_QMI_HELPERS) += qmi_helpers.o qmi_helpers-y += qmi_encdec.o qmi_interface.o diff --git a/drivers/soc/qcom/ocmem.c b/drivers/soc/qcom/ocmem.c new file mode 100644 index ..3a54044076a5 --- /dev/null +++ b/drivers/soc/qcom/ocmem.c @@ -0,0 +1,433 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * The On Chip Memory (OCMEM) allocator allows various clients to allocate + * memory from OCMEM based on performance, latency and power requirements. + * This is typically used by the GPU, camera/video, and audio components on + * some Snapdragon SoCs. + * + * Copyright (C) 2019 Brian Ma
[Freedreno] [PATCH v5 4/7] firmware: qcom: scm: add support to restore secure config to qcm_scm-32
From: Rob Clark Add support to restore the secure configuration for qcm_scm-32.c. This is needed by the On Chip MEMory (OCMEM) that is present on some Snapdragon devices. Signed-off-by: Rob Clark [masn...@onstation.org: ported to latest kernel; set ctx_bank_num to spare parameter.] Signed-off-by: Brian Masney --- Changes since v4: - None Changes since v3: - None Changes since v2: - None Changes since v1: - Use existing __qcom_scm_restore_sec_cfg() function stub in qcom_scm-32.c that was unimplemented - Set the cfg.ctx_bank_num to the spare function parameter. It was previously set to the device_id. drivers/firmware/qcom_scm-32.c | 17 - drivers/firmware/qcom_scm.c| 13 + include/linux/qcom_scm.h | 11 +++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c index 4c2514e5e249..5d90b7f5ab5a 100644 --- a/drivers/firmware/qcom_scm-32.c +++ b/drivers/firmware/qcom_scm-32.c @@ -617,7 +617,22 @@ int __qcom_scm_assign_mem(struct device *dev, phys_addr_t mem_region, int __qcom_scm_restore_sec_cfg(struct device *dev, u32 device_id, u32 spare) { - return -ENODEV; + struct msm_scm_sec_cfg { + __le32 id; + __le32 ctx_bank_num; + } cfg; + int ret, scm_ret = 0; + + cfg.id = cpu_to_le32(device_id); + cfg.ctx_bank_num = cpu_to_le32(spare); + + ret = qcom_scm_call(dev, QCOM_SCM_SVC_MP, QCOM_SCM_RESTORE_SEC_CFG, + &cfg, sizeof(cfg), &scm_ret, sizeof(scm_ret)); + + if (ret || scm_ret) + return ret ? ret : -EINVAL; + + return 0; } int __qcom_scm_iommu_secure_ptbl_size(struct device *dev, u32 spare, diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index 7e285ff3961d..27c1d98a34e6 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -367,6 +367,19 @@ static const struct reset_control_ops qcom_scm_pas_reset_ops = { .deassert = qcom_scm_pas_reset_deassert, }; +/** + * qcom_scm_restore_sec_cfg_available() - Check if secure environment + * supports restore security config interface. + * + * Return true if restore-cfg interface is supported, false if not. + */ +bool qcom_scm_restore_sec_cfg_available(void) +{ + return __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_MP, + QCOM_SCM_RESTORE_SEC_CFG); +} +EXPORT_SYMBOL(qcom_scm_restore_sec_cfg_available); + int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare) { return __qcom_scm_restore_sec_cfg(__scm->dev, device_id, spare); diff --git a/include/linux/qcom_scm.h b/include/linux/qcom_scm.h index b49b734d662c..04382e1798e4 100644 --- a/include/linux/qcom_scm.h +++ b/include/linux/qcom_scm.h @@ -34,6 +34,16 @@ enum qcom_scm_ocmem_client { QCOM_SCM_OCMEM_DEBUG_ID, }; +enum qcom_scm_sec_dev_id { + QCOM_SCM_MDSS_DEV_ID= 1, + QCOM_SCM_OCMEM_DEV_ID = 5, + QCOM_SCM_PCIE0_DEV_ID = 11, + QCOM_SCM_PCIE1_DEV_ID = 12, + QCOM_SCM_GFX_DEV_ID = 18, + QCOM_SCM_UFS_DEV_ID = 19, + QCOM_SCM_ICE_DEV_ID = 20, +}; + #define QCOM_SCM_VMID_HLOS 0x3 #define QCOM_SCM_VMID_MSS_MSA0xF #define QCOM_SCM_VMID_WLAN 0x18 @@ -70,6 +80,7 @@ extern int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz, extern void qcom_scm_cpu_power_down(u32 flags); extern u32 qcom_scm_get_version(void); extern int qcom_scm_set_remote_state(u32 state, u32 id); +extern bool qcom_scm_restore_sec_cfg_available(void); extern int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare); extern int qcom_scm_iommu_secure_ptbl_size(u32 spare, size_t *size); extern int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare); -- 2.21.0 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v5 2/7] dt-bindings: display: msm: gmu: add optional ocmem property
Some A3xx and A4xx Adreno GPUs do not have GMEM inside the GPU core and must use the On Chip MEMory (OCMEM) in order to be functional. Add the optional ocmem property to the Adreno Graphics Management Unit bindings. Signed-off-by: Brian Masney --- Changes since v4: - None Changes since v3: - correct link to qcom,ocmem.yaml Changes since v2: - Add a3xx example with OCMEM Changes since v1: - None .../devicetree/bindings/display/msm/gmu.txt | 50 +++ 1 file changed, 50 insertions(+) diff --git a/Documentation/devicetree/bindings/display/msm/gmu.txt b/Documentation/devicetree/bindings/display/msm/gmu.txt index 90af5b0a56a9..672d557caba4 100644 --- a/Documentation/devicetree/bindings/display/msm/gmu.txt +++ b/Documentation/devicetree/bindings/display/msm/gmu.txt @@ -31,6 +31,10 @@ Required properties: - iommus: phandle to the adreno iommu - operating-points-v2: phandle to the OPP operating points +Optional properties: +- ocmem: phandle to the On Chip Memory (OCMEM) that's present on some Snapdragon + SoCs. See Documentation/devicetree/bindings/sram/qcom,ocmem.yaml. + Example: / { @@ -63,3 +67,49 @@ Example: operating-points-v2 = <&gmu_opp_table>; }; }; + +a3xx example with OCMEM support: + +/ { + ... + + gpu: adreno@fdb0 { + compatible = "qcom,adreno-330.2", +"qcom,adreno"; + reg = <0xfdb0 0x1>; + reg-names = "kgsl_3d0_reg_memory"; + interrupts = ; + interrupt-names = "kgsl_3d0_irq"; + clock-names = "core", + "iface", + "mem_iface"; + clocks = <&mmcc OXILI_GFX3D_CLK>, +<&mmcc OXILICX_AHB_CLK>, +<&mmcc OXILICX_AXI_CLK>; + ocmem = <&ocmem>; + power-domains = <&mmcc OXILICX_GDSC>; + operating-points-v2 = <&gpu_opp_table>; + iommus = <&gpu_iommu 0>; + }; + + ocmem: ocmem@fdd0 { + compatible = "qcom,msm8974-ocmem"; + + reg = <0xfdd0 0x2000>, + <0xfec0 0x18>; + reg-names = "ctrl", +"mem"; + + clocks = <&rpmcc RPM_SMD_OCMEMGX_CLK>, +<&mmcc OCMEMCX_OCMEMNOC_CLK>; + clock-names = "core", + "iface"; + + #address-cells = <1>; + #size-cells = <1>; + + gmu-sram@0 { + reg = <0x0 0x10>; + }; + }; +}; -- 2.21.0 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v5 1/7] dt-bindings: soc: qcom: add On Chip MEMory (OCMEM) bindings
Add device tree bindings for the On Chip Memory (OCMEM) that is present on some Qualcomm Snapdragon SoCs. Signed-off-by: Brian Masney Reviewed-by: Rob Herring --- Changes since v4: - remove qcom from path in $id Changes since v3: - add ranges property - remove unnecessary literal block | - add #address-cells and #size-cells to binding - rename path devicetree/bindings/sram/qcom/ to devicetree/bindings/sram/ since this is the only qcom binding in the sram namespace. That was a holdover from when I originally put this in the soc namespace. Changes since v2: - Add *-sram node and gmu-sram to example. Changes since v1: - Rename qcom,ocmem-msm8974 to qcom,msm8974-ocmem - Renamed reg-names to ctrl and mem - update hardware description - moved from soc to sram namespace in the device tree bindings .../devicetree/bindings/sram/qcom,ocmem.yaml | 96 +++ 1 file changed, 96 insertions(+) create mode 100644 Documentation/devicetree/bindings/sram/qcom,ocmem.yaml diff --git a/Documentation/devicetree/bindings/sram/qcom,ocmem.yaml b/Documentation/devicetree/bindings/sram/qcom,ocmem.yaml new file mode 100644 index ..222990f9923c --- /dev/null +++ b/Documentation/devicetree/bindings/sram/qcom,ocmem.yaml @@ -0,0 +1,96 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sram/qcom,ocmem.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: On Chip Memory (OCMEM) that is present on some Qualcomm Snapdragon SoCs. + +maintainers: + - Brian Masney + +description: | + The On Chip Memory (OCMEM) is typically used by the GPU, camera/video, and + audio components on some Snapdragon SoCs. + +properties: + compatible: +const: qcom,msm8974-ocmem + + reg: +items: + - description: Control registers + - description: OCMEM address range + + reg-names: +items: + - const: ctrl + - const: mem + + clocks: +items: + - description: Core clock + - description: Interface clock + + clock-names: +items: + - const: core + - const: iface + + '#address-cells': +const: 1 + + '#size-cells': +const: 1 + +required: + - compatible + - reg + - reg-names + - clocks + - clock-names + - '#address-cells' + - '#size-cells' + +patternProperties: + "^.+-sram$": +type: object +description: A region of reserved memory. + +properties: + reg: +maxItems: 1 + + ranges: +maxItems: 1 + +required: + - reg + - ranges + +examples: + - | + #include + #include + + ocmem: ocmem@fdd0 { +compatible = "qcom,msm8974-ocmem"; + +reg = <0xfdd0 0x2000>, + <0xfec0 0x18>; +reg-names = "ctrl", +"mem"; + +clocks = <&rpmcc RPM_SMD_OCMEMGX_CLK>, + <&mmcc OCMEMCX_OCMEMNOC_CLK>; +clock-names = "core", + "iface"; + +#address-cells = <1>; +#size-cells = <1>; + +gmu-sram@0 { +reg = <0x0 0x10>; +ranges = <0 0 0xfec0 0x10>; +}; + }; -- 2.21.0 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v5 3/7] firmware: qcom: scm: add OCMEM lock/unlock interface
From: Rob Clark Add support for the OCMEM lock/unlock interface that is needed by the On Chip MEMory (OCMEM) that is present on some Snapdragon devices. Signed-off-by: Rob Clark [masn...@onstation.org: ported to latest kernel; minor reformatting.] Signed-off-by: Brian Masney Reviewed-by: Bjorn Andersson --- Rob's last version of this patch: https://patchwork.kernel.org/patch/7340711/ Changes since v4: - None Changes since v3: - None Changes since v2: - None Changes since v1: - None drivers/firmware/qcom_scm-32.c | 35 + drivers/firmware/qcom_scm-64.c | 12 ++ drivers/firmware/qcom_scm.c| 40 ++ drivers/firmware/qcom_scm.h| 9 include/linux/qcom_scm.h | 15 + 5 files changed, 111 insertions(+) diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c index 215061c581e1..4c2514e5e249 100644 --- a/drivers/firmware/qcom_scm-32.c +++ b/drivers/firmware/qcom_scm-32.c @@ -442,6 +442,41 @@ int __qcom_scm_hdcp_req(struct device *dev, struct qcom_scm_hdcp_req *req, req, req_cnt * sizeof(*req), resp, sizeof(*resp)); } +int __qcom_scm_ocmem_lock(struct device *dev, u32 id, u32 offset, u32 size, + u32 mode) +{ + struct ocmem_tz_lock { + __le32 id; + __le32 offset; + __le32 size; + __le32 mode; + } request; + + request.id = cpu_to_le32(id); + request.offset = cpu_to_le32(offset); + request.size = cpu_to_le32(size); + request.mode = cpu_to_le32(mode); + + return qcom_scm_call(dev, QCOM_SCM_OCMEM_SVC, QCOM_SCM_OCMEM_LOCK_CMD, +&request, sizeof(request), NULL, 0); +} + +int __qcom_scm_ocmem_unlock(struct device *dev, u32 id, u32 offset, u32 size) +{ + struct ocmem_tz_unlock { + __le32 id; + __le32 offset; + __le32 size; + } request; + + request.id = cpu_to_le32(id); + request.offset = cpu_to_le32(offset); + request.size = cpu_to_le32(size); + + return qcom_scm_call(dev, QCOM_SCM_OCMEM_SVC, QCOM_SCM_OCMEM_UNLOCK_CMD, +&request, sizeof(request), NULL, 0); +} + void __qcom_scm_init(void) { } diff --git a/drivers/firmware/qcom_scm-64.c b/drivers/firmware/qcom_scm-64.c index 91d5ad7cf58b..c3a3d9874def 100644 --- a/drivers/firmware/qcom_scm-64.c +++ b/drivers/firmware/qcom_scm-64.c @@ -241,6 +241,18 @@ int __qcom_scm_hdcp_req(struct device *dev, struct qcom_scm_hdcp_req *req, return ret; } +int __qcom_scm_ocmem_lock(struct device *dev, uint32_t id, uint32_t offset, + uint32_t size, uint32_t mode) +{ + return -ENOTSUPP; +} + +int __qcom_scm_ocmem_unlock(struct device *dev, uint32_t id, uint32_t offset, + uint32_t size) +{ + return -ENOTSUPP; +} + void __qcom_scm_init(void) { u64 cmd; diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index 4802ab170fe5..7e285ff3961d 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -191,6 +191,46 @@ bool qcom_scm_pas_supported(u32 peripheral) } EXPORT_SYMBOL(qcom_scm_pas_supported); +/** + * qcom_scm_ocmem_lock_available() - is OCMEM lock/unlock interface available + */ +bool qcom_scm_ocmem_lock_available(void) +{ + return __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_OCMEM_SVC, + QCOM_SCM_OCMEM_LOCK_CMD); +} +EXPORT_SYMBOL(qcom_scm_ocmem_lock_available); + +/** + * qcom_scm_ocmem_lock() - call OCMEM lock interface to assign an OCMEM + * region to the specified initiator + * + * @id: tz initiator id + * @offset: OCMEM offset + * @size: OCMEM size + * @mode: access mode (WIDE/NARROW) + */ +int qcom_scm_ocmem_lock(enum qcom_scm_ocmem_client id, u32 offset, u32 size, + u32 mode) +{ + return __qcom_scm_ocmem_lock(__scm->dev, id, offset, size, mode); +} +EXPORT_SYMBOL(qcom_scm_ocmem_lock); + +/** + * qcom_scm_ocmem_unlock() - call OCMEM unlock interface to release an OCMEM + * region from the specified initiator + * + * @id: tz initiator id + * @offset: OCMEM offset + * @size: OCMEM size + */ +int qcom_scm_ocmem_unlock(enum qcom_scm_ocmem_client id, u32 offset, u32 size) +{ + return __qcom_scm_ocmem_unlock(__scm->dev, id, offset, size); +} +EXPORT_SYMBOL(qcom_scm_ocmem_unlock); + /** * qcom_scm_pas_init_image() - Initialize peripheral authentication service *state machine for a given peripheral, using the diff --git a/drivers/firmware/qcom_scm.h b/drivers/firmware/qcom_scm.h index 99506bd873c0..ef293ee67ec1 100644 --- a/drivers/firmware/qcom_scm.h +++ b/drivers/firmware/qcom_scm.h @@ -42,6 +42,15 @@ extern int __qcom_scm_hdcp_req(struct device *dev, extern void __qcom_scm_init(void); +#def
[Freedreno] [PATCH v5 6/7] drm/msm/gpu: add ocmem init/cleanup functions
The files a3xx_gpu.c and a4xx_gpu.c have ifdefs for the OCMEM support that was missing upstream. Add two new functions (adreno_gpu_ocmem_init and adreno_gpu_ocmem_cleanup) that removes some duplicated code. Signed-off-by: Brian Masney --- Changes since v4: - None Changes since v3: - None Changes since v2: - Check for -ENODEV error of_get_ocmem() - remove fail_cleanup_ocmem label in a[34]xx_gpu_init Changes since v1: - remove CONFIG_QCOM_OCMEM #ifdefs - use unsigned long for memory addresses instead of uint32_t - add 'depends on QCOM_OCMEM || QCOM_OCMEM=n' to Kconfig drivers/gpu/drm/msm/Kconfig | 1 + drivers/gpu/drm/msm/adreno/a3xx_gpu.c | 28 + drivers/gpu/drm/msm/adreno/a3xx_gpu.h | 3 +- drivers/gpu/drm/msm/adreno/a4xx_gpu.c | 25 drivers/gpu/drm/msm/adreno/a4xx_gpu.h | 3 +- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 40 + drivers/gpu/drm/msm/adreno/adreno_gpu.h | 10 +++ 7 files changed, 66 insertions(+), 44 deletions(-) diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig index 9c37e4de5896..b3d3b2172659 100644 --- a/drivers/gpu/drm/msm/Kconfig +++ b/drivers/gpu/drm/msm/Kconfig @@ -7,6 +7,7 @@ config DRM_MSM depends on OF && COMMON_CLK depends on MMU depends on INTERCONNECT || !INTERCONNECT + depends on QCOM_OCMEM || QCOM_OCMEM=n select QCOM_MDT_LOADER if ARCH_QCOM select REGULATOR select DRM_KMS_HELPER diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c index ec82aaa21734..07ddcc529573 100644 --- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c @@ -6,10 +6,6 @@ * Copyright (c) 2014 The Linux Foundation. All rights reserved. */ -#ifdef CONFIG_MSM_OCMEM -# include -#endif - #include "a3xx_gpu.h" #define A3XX_INT0_MASK \ @@ -195,9 +191,9 @@ static int a3xx_hw_init(struct msm_gpu *gpu) gpu_write(gpu, REG_A3XX_RBBM_GPR0_CTL, 0x); /* Set the OCMEM base address for A330, etc */ - if (a3xx_gpu->ocmem_hdl) { + if (a3xx_gpu->ocmem.hdl) { gpu_write(gpu, REG_A3XX_RB_GMEM_BASE_ADDR, - (unsigned int)(a3xx_gpu->ocmem_base >> 14)); + (unsigned int)(a3xx_gpu->ocmem.base >> 14)); } /* Turn on performance counters: */ @@ -318,10 +314,7 @@ static void a3xx_destroy(struct msm_gpu *gpu) adreno_gpu_cleanup(adreno_gpu); -#ifdef CONFIG_MSM_OCMEM - if (a3xx_gpu->ocmem_base) - ocmem_free(OCMEM_GRAPHICS, a3xx_gpu->ocmem_hdl); -#endif + adreno_gpu_ocmem_cleanup(&a3xx_gpu->ocmem); kfree(a3xx_gpu); } @@ -494,17 +487,10 @@ struct msm_gpu *a3xx_gpu_init(struct drm_device *dev) /* if needed, allocate gmem: */ if (adreno_is_a330(adreno_gpu)) { -#ifdef CONFIG_MSM_OCMEM - /* TODO this is different/missing upstream: */ - struct ocmem_buf *ocmem_hdl = - ocmem_allocate(OCMEM_GRAPHICS, adreno_gpu->gmem); - - a3xx_gpu->ocmem_hdl = ocmem_hdl; - a3xx_gpu->ocmem_base = ocmem_hdl->addr; - adreno_gpu->gmem = ocmem_hdl->len; - DBG("using %dK of OCMEM at 0x%08x", adreno_gpu->gmem / 1024, - a3xx_gpu->ocmem_base); -#endif + ret = adreno_gpu_ocmem_init(&adreno_gpu->base.pdev->dev, + adreno_gpu, &a3xx_gpu->ocmem); + if (ret) + goto fail; } if (!gpu->aspace) { diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.h b/drivers/gpu/drm/msm/adreno/a3xx_gpu.h index 5dc33e5ea53b..c555fb13e0d7 100644 --- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.h +++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.h @@ -19,8 +19,7 @@ struct a3xx_gpu { struct adreno_gpu base; /* if OCMEM is used for GMEM: */ - uint32_t ocmem_base; - void *ocmem_hdl; + struct adreno_ocmem ocmem; }; #define to_a3xx_gpu(x) container_of(x, struct a3xx_gpu, base) diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c index ab2b752566d8..b01388a9e89e 100644 --- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c @@ -2,9 +2,6 @@ /* Copyright (c) 2014 The Linux Foundation. All rights reserved. */ #include "a4xx_gpu.h" -#ifdef CONFIG_MSM_OCMEM -# include -#endif #define A4XX_INT0_MASK \ (A4XX_INT0_RBBM_AHB_ERROR |\ @@ -188,7 +185,7 @@ static int a4xx_hw_init(struct msm_gpu *gpu) (1 << 30) | 0x); gpu_write(gpu, REG_A4XX_RB_GMEM_BASE_ADDR, - (unsigned int)(a4xx_gpu->ocmem_base >> 14)); +
[Freedreno] [PATCH v4 5/6] soc: qcom: add OCMEM driver
The OCMEM driver handles allocation and configuration of the On Chip MEMory that is present on some Snapdragon SoCs. Devices which have OCMEM do not have GMEM inside the GPU core, so the GPU must instead use OCMEM to be functional. Since the GPU is currently the only OCMEM user with an upstream driver, this is just a minimal implementation sufficient for statically allocating to the GPU it's chunk of OCMEM. This driver currently does not read the gmu-sram node that is described in the device tree bindings. The starting memory address of the GPU's reserved memory region is hardcoded to zero to match what the hardware expects. The driver can be updated to read the reserved memory regions from device tree once other users of OCMEM are added upstream. Signed-off-by: Brian Masney Co-developed-by: Rob Clark Signed-off-by: Rob Clark --- Changes since v3: - None Changes since v2 - Changed static inline stubs return -ENODEV when OCMEM is not configured into the kernel. Changes since v1: - ocmem_allocate(): check for alignment and minimum allocation size. The 64K values came from the downstream MSM kernel sources. - add locking to memory allocations based on the client - use clk_bulk_*() functions - rename qcom,ocmem-msm8974 to qcom,msm8974-ocmem - rename reg-names to ctrl and mem - remove ocmem.xml.h file; use FIELD_PREP() instead for some nice cleanups - add static inline noop versions of public-facing functions when ocmem is disabled to remove #ifdefs in adrenu_gpu.c - use unsigned long for memory addresses - move ocmem_dev_remove() below _probe() function - remove error check from platform_get_resource_byname for ctrl resource - add MODULE_DESCRIPTION() and MODULE_LICENSE() - add description to top of ocmem.[ch] - correct thin mode bit in update_ocmem() - add 'WARN_ON(client != OCMEM_GRAPHICS)' to device_address() - make of_get_ocmem return error codes via ERR_PTR instead of NULL - ocmem_{allocate,free} - WARN_ON() if client != OCMEM_GRAPHICS. Simplify if statements. - allow NULL to be passed into ocmem_free - remove unnecessary initialization of i in update_ocmem() - add dev_dbg to ocmem_allocate Changes since Rob's last version of this patch from 2015: https://patchwork.kernel.org/patch/7379801/ - reformatted driver to allow multiple instances - updated logging of error paths during device probing - remove unused psgsc_ctrl - remove _clk from clock names - propagate error code from devm_ioremap_resource() - use device_get_match_data() - SPDX license tags - remove QCOM_SMD in Kconfig - select ARCH_QCOM in Kconfig - select ARCH_QCOM in Kconfig - select QCOM_SCM in Kconfig - longer description in Kconfig drivers/soc/qcom/Kconfig | 10 + drivers/soc/qcom/Makefile | 1 + drivers/soc/qcom/ocmem.c | 433 ++ include/soc/qcom/ocmem.h | 62 ++ 4 files changed, 506 insertions(+) create mode 100644 drivers/soc/qcom/ocmem.c create mode 100644 include/soc/qcom/ocmem.h diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig index a6d1bfb17279..d18eb83b10da 100644 --- a/drivers/soc/qcom/Kconfig +++ b/drivers/soc/qcom/Kconfig @@ -74,6 +74,16 @@ config QCOM_MDT_LOADER tristate select QCOM_SCM +config QCOM_OCMEM + tristate "Qualcomm On Chip Memory (OCMEM) driver" + depends on ARCH_QCOM + select QCOM_SCM + help + The On Chip Memory (OCMEM) allocator allows various clients to + allocate memory from OCMEM based on performance, latency and power + requirements. This is typically used by the GPU, camera/video, and + audio components on some Snapdragon SoCs. + config QCOM_PM bool "Qualcomm Power Management" depends on ARCH_QCOM && !ARM64 diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile index eeb088beb15f..dfc378014a33 100644 --- a/drivers/soc/qcom/Makefile +++ b/drivers/soc/qcom/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_QCOM_COMMAND_DB) += cmd-db.o obj-$(CONFIG_QCOM_GLINK_SSR) +=glink_ssr.o obj-$(CONFIG_QCOM_GSBI)+= qcom_gsbi.o obj-$(CONFIG_QCOM_MDT_LOADER) += mdt_loader.o +obj-$(CONFIG_QCOM_OCMEM) += ocmem.o obj-$(CONFIG_QCOM_PM) += spm.o obj-$(CONFIG_QCOM_QMI_HELPERS) += qmi_helpers.o qmi_helpers-y += qmi_encdec.o qmi_interface.o diff --git a/drivers/soc/qcom/ocmem.c b/drivers/soc/qcom/ocmem.c new file mode 100644 index ..7c28ad3108a6 --- /dev/null +++ b/drivers/soc/qcom/ocmem.c @@ -0,0 +1,433 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * The On Chip Memory (OCMEM) allocator allows various clients to allocate + * memory from OCMEM based on performance, latency and power requirements. + * This is typically used by the GPU, camera/video, and audio components on + * some Snapdragon SoCs. + * + * Copyright (C) 2019 Brian Masney + * Copyright (C) 2015 Red Hat. Author: Rob Clark + */ + +#include +#include +#include +#include +#include
[Freedreno] [PATCH v4 1/6] dt-bindings: soc: qcom: add On Chip MEMory (OCMEM) bindings
Add device tree bindings for the On Chip Memory (OCMEM) that is present on some Qualcomm Snapdragon SoCs. Signed-off-by: Brian Masney --- Changes since v3 - add ranges property - remove unnecessary literal block | - add #address-cells and #size-cells to binding - rename path devicetree/bindings/sram/qcom/ to devicetree/bindings/sram/ since this is the only qcom binding in the sram namespace. That was a holdover from when I originally put this in the soc namespace. Changes since v2: - Add *-sram node and gmu-sram to example. Changes since v1: - Rename qcom,ocmem-msm8974 to qcom,msm8974-ocmem - Renamed reg-names to ctrl and mem - update hardware description - moved from soc to sram namespace in the device tree bindings .../devicetree/bindings/sram/qcom,ocmem.yaml | 96 +++ 1 file changed, 96 insertions(+) create mode 100644 Documentation/devicetree/bindings/sram/qcom,ocmem.yaml diff --git a/Documentation/devicetree/bindings/sram/qcom,ocmem.yaml b/Documentation/devicetree/bindings/sram/qcom,ocmem.yaml new file mode 100644 index ..1bb386fffa01 --- /dev/null +++ b/Documentation/devicetree/bindings/sram/qcom,ocmem.yaml @@ -0,0 +1,96 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sram/qcom/qcom,ocmem.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: On Chip Memory (OCMEM) that is present on some Qualcomm Snapdragon SoCs. + +maintainers: + - Brian Masney + +description: | + The On Chip Memory (OCMEM) is typically used by the GPU, camera/video, and + audio components on some Snapdragon SoCs. + +properties: + compatible: +const: qcom,msm8974-ocmem + + reg: +items: + - description: Control registers + - description: OCMEM address range + + reg-names: +items: + - const: ctrl + - const: mem + + clocks: +items: + - description: Core clock + - description: Interface clock + + clock-names: +items: + - const: core + - const: iface + + '#address-cells': +const: 1 + + '#size-cells': +const: 1 + +required: + - compatible + - reg + - reg-names + - clocks + - clock-names + - '#address-cells' + - '#size-cells' + +patternProperties: + "^.+-sram$": +type: object +description: A region of reserved memory. + +properties: + reg: +maxItems: 1 + + ranges: +maxItems: 1 + +required: + - reg + - ranges + +examples: + - | + #include + #include + + ocmem: ocmem@fdd0 { +compatible = "qcom,msm8974-ocmem"; + +reg = <0xfdd0 0x2000>, + <0xfec0 0x18>; +reg-names = "ctrl", +"mem"; + +clocks = <&rpmcc RPM_SMD_OCMEMGX_CLK>, + <&mmcc OCMEMCX_OCMEMNOC_CLK>; +clock-names = "core", + "iface"; + +#address-cells = <1>; +#size-cells = <1>; + +gmu-sram@0 { +reg = <0x0 0x10>; +ranges = <0 0 0xfec0 0x10>; +}; + }; -- 2.21.0 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v4 2/6] dt-bindings: display: msm: gmu: add optional ocmem property
Some A3xx and A4xx Adreno GPUs do not have GMEM inside the GPU core and must use the On Chip MEMory (OCMEM) in order to be functional. Add the optional ocmem property to the Adreno Graphics Management Unit bindings. Signed-off-by: Brian Masney --- Changes since v3: - correct link to qcom,ocmem.yaml Changes since v2: - Add a3xx example with OCMEM Changes since v1: - None .../devicetree/bindings/display/msm/gmu.txt | 50 +++ 1 file changed, 50 insertions(+) diff --git a/Documentation/devicetree/bindings/display/msm/gmu.txt b/Documentation/devicetree/bindings/display/msm/gmu.txt index 90af5b0a56a9..672d557caba4 100644 --- a/Documentation/devicetree/bindings/display/msm/gmu.txt +++ b/Documentation/devicetree/bindings/display/msm/gmu.txt @@ -31,6 +31,10 @@ Required properties: - iommus: phandle to the adreno iommu - operating-points-v2: phandle to the OPP operating points +Optional properties: +- ocmem: phandle to the On Chip Memory (OCMEM) that's present on some Snapdragon + SoCs. See Documentation/devicetree/bindings/sram/qcom,ocmem.yaml. + Example: / { @@ -63,3 +67,49 @@ Example: operating-points-v2 = <&gmu_opp_table>; }; }; + +a3xx example with OCMEM support: + +/ { + ... + + gpu: adreno@fdb0 { + compatible = "qcom,adreno-330.2", +"qcom,adreno"; + reg = <0xfdb0 0x1>; + reg-names = "kgsl_3d0_reg_memory"; + interrupts = ; + interrupt-names = "kgsl_3d0_irq"; + clock-names = "core", + "iface", + "mem_iface"; + clocks = <&mmcc OXILI_GFX3D_CLK>, +<&mmcc OXILICX_AHB_CLK>, +<&mmcc OXILICX_AXI_CLK>; + ocmem = <&ocmem>; + power-domains = <&mmcc OXILICX_GDSC>; + operating-points-v2 = <&gpu_opp_table>; + iommus = <&gpu_iommu 0>; + }; + + ocmem: ocmem@fdd0 { + compatible = "qcom,msm8974-ocmem"; + + reg = <0xfdd0 0x2000>, + <0xfec0 0x18>; + reg-names = "ctrl", +"mem"; + + clocks = <&rpmcc RPM_SMD_OCMEMGX_CLK>, +<&mmcc OCMEMCX_OCMEMNOC_CLK>; + clock-names = "core", + "iface"; + + #address-cells = <1>; + #size-cells = <1>; + + gmu-sram@0 { + reg = <0x0 0x10>; + }; + }; +}; -- 2.21.0 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v4 3/6] firmware: qcom: scm: add OCMEM lock/unlock interface
From: Rob Clark Add support for the OCMEM lock/unlock interface that is needed by the On Chip MEMory (OCMEM) that is present on some Snapdragon devices. Signed-off-by: Rob Clark [masn...@onstation.org: ported to latest kernel; minor reformatting.] Signed-off-by: Brian Masney Reviewed-by: Bjorn Andersson --- Rob's last version of this patch: https://patchwork.kernel.org/patch/7340711/ Changes since v3: - None Changes since v2: - None Changes since v1: - None drivers/firmware/qcom_scm-32.c | 35 + drivers/firmware/qcom_scm-64.c | 12 ++ drivers/firmware/qcom_scm.c| 40 ++ drivers/firmware/qcom_scm.h| 9 include/linux/qcom_scm.h | 15 + 5 files changed, 111 insertions(+) diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c index 215061c581e1..4c2514e5e249 100644 --- a/drivers/firmware/qcom_scm-32.c +++ b/drivers/firmware/qcom_scm-32.c @@ -442,6 +442,41 @@ int __qcom_scm_hdcp_req(struct device *dev, struct qcom_scm_hdcp_req *req, req, req_cnt * sizeof(*req), resp, sizeof(*resp)); } +int __qcom_scm_ocmem_lock(struct device *dev, u32 id, u32 offset, u32 size, + u32 mode) +{ + struct ocmem_tz_lock { + __le32 id; + __le32 offset; + __le32 size; + __le32 mode; + } request; + + request.id = cpu_to_le32(id); + request.offset = cpu_to_le32(offset); + request.size = cpu_to_le32(size); + request.mode = cpu_to_le32(mode); + + return qcom_scm_call(dev, QCOM_SCM_OCMEM_SVC, QCOM_SCM_OCMEM_LOCK_CMD, +&request, sizeof(request), NULL, 0); +} + +int __qcom_scm_ocmem_unlock(struct device *dev, u32 id, u32 offset, u32 size) +{ + struct ocmem_tz_unlock { + __le32 id; + __le32 offset; + __le32 size; + } request; + + request.id = cpu_to_le32(id); + request.offset = cpu_to_le32(offset); + request.size = cpu_to_le32(size); + + return qcom_scm_call(dev, QCOM_SCM_OCMEM_SVC, QCOM_SCM_OCMEM_UNLOCK_CMD, +&request, sizeof(request), NULL, 0); +} + void __qcom_scm_init(void) { } diff --git a/drivers/firmware/qcom_scm-64.c b/drivers/firmware/qcom_scm-64.c index 91d5ad7cf58b..c3a3d9874def 100644 --- a/drivers/firmware/qcom_scm-64.c +++ b/drivers/firmware/qcom_scm-64.c @@ -241,6 +241,18 @@ int __qcom_scm_hdcp_req(struct device *dev, struct qcom_scm_hdcp_req *req, return ret; } +int __qcom_scm_ocmem_lock(struct device *dev, uint32_t id, uint32_t offset, + uint32_t size, uint32_t mode) +{ + return -ENOTSUPP; +} + +int __qcom_scm_ocmem_unlock(struct device *dev, uint32_t id, uint32_t offset, + uint32_t size) +{ + return -ENOTSUPP; +} + void __qcom_scm_init(void) { u64 cmd; diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index 4802ab170fe5..7e285ff3961d 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -191,6 +191,46 @@ bool qcom_scm_pas_supported(u32 peripheral) } EXPORT_SYMBOL(qcom_scm_pas_supported); +/** + * qcom_scm_ocmem_lock_available() - is OCMEM lock/unlock interface available + */ +bool qcom_scm_ocmem_lock_available(void) +{ + return __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_OCMEM_SVC, + QCOM_SCM_OCMEM_LOCK_CMD); +} +EXPORT_SYMBOL(qcom_scm_ocmem_lock_available); + +/** + * qcom_scm_ocmem_lock() - call OCMEM lock interface to assign an OCMEM + * region to the specified initiator + * + * @id: tz initiator id + * @offset: OCMEM offset + * @size: OCMEM size + * @mode: access mode (WIDE/NARROW) + */ +int qcom_scm_ocmem_lock(enum qcom_scm_ocmem_client id, u32 offset, u32 size, + u32 mode) +{ + return __qcom_scm_ocmem_lock(__scm->dev, id, offset, size, mode); +} +EXPORT_SYMBOL(qcom_scm_ocmem_lock); + +/** + * qcom_scm_ocmem_unlock() - call OCMEM unlock interface to release an OCMEM + * region from the specified initiator + * + * @id: tz initiator id + * @offset: OCMEM offset + * @size: OCMEM size + */ +int qcom_scm_ocmem_unlock(enum qcom_scm_ocmem_client id, u32 offset, u32 size) +{ + return __qcom_scm_ocmem_unlock(__scm->dev, id, offset, size); +} +EXPORT_SYMBOL(qcom_scm_ocmem_unlock); + /** * qcom_scm_pas_init_image() - Initialize peripheral authentication service *state machine for a given peripheral, using the diff --git a/drivers/firmware/qcom_scm.h b/drivers/firmware/qcom_scm.h index 99506bd873c0..ef293ee67ec1 100644 --- a/drivers/firmware/qcom_scm.h +++ b/drivers/firmware/qcom_scm.h @@ -42,6 +42,15 @@ extern int __qcom_scm_hdcp_req(struct device *dev, extern void __qcom_scm_init(void); +#define QCOM_SCM_OCMEM_SVC
[Freedreno] [PATCH v4 0/6] qcom: add OCMEM support
This patch series adds support for Qualcomm's On Chip MEMory (OCMEM) that is needed in order to support some a3xx and a4xx-based GPUs upstream. This is based on Rob Clark's patch series that he submitted in October 2015 and I am resubmitting updated patches with his permission. See the individual patches for the changelog. This was tested with the GPU on a LG Nexus 5 (hammerhead) phone and this will work on other msm8974-based systems. For a summary of what currently works upstream on the Nexus 5, see my status page at https://masneyb.github.io/nexus-5-upstream/. Brian Masney (4): dt-bindings: soc: qcom: add On Chip MEMory (OCMEM) bindings dt-bindings: display: msm: gmu: add optional ocmem property soc: qcom: add OCMEM driver drm/msm/gpu: add ocmem init/cleanup functions Rob Clark (2): firmware: qcom: scm: add OCMEM lock/unlock interface firmware: qcom: scm: add support to restore secure config to qcm_scm-32 .../devicetree/bindings/display/msm/gmu.txt | 50 ++ .../devicetree/bindings/sram/qcom,ocmem.yaml | 96 drivers/firmware/qcom_scm-32.c| 52 ++- drivers/firmware/qcom_scm-64.c| 12 + drivers/firmware/qcom_scm.c | 53 +++ drivers/firmware/qcom_scm.h | 9 + drivers/gpu/drm/msm/Kconfig | 1 + drivers/gpu/drm/msm/adreno/a3xx_gpu.c | 28 +- drivers/gpu/drm/msm/adreno/a3xx_gpu.h | 3 +- drivers/gpu/drm/msm/adreno/a4xx_gpu.c | 25 +- drivers/gpu/drm/msm/adreno/a4xx_gpu.h | 3 +- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 40 ++ drivers/gpu/drm/msm/adreno/adreno_gpu.h | 10 + drivers/soc/qcom/Kconfig | 10 + drivers/soc/qcom/Makefile | 1 + drivers/soc/qcom/ocmem.c | 433 ++ include/linux/qcom_scm.h | 26 ++ include/soc/qcom/ocmem.h | 62 +++ 18 files changed, 869 insertions(+), 45 deletions(-) create mode 100644 Documentation/devicetree/bindings/sram/qcom,ocmem.yaml create mode 100644 drivers/soc/qcom/ocmem.c create mode 100644 include/soc/qcom/ocmem.h -- 2.21.0 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v4 6/6] drm/msm/gpu: add ocmem init/cleanup functions
The files a3xx_gpu.c and a4xx_gpu.c have ifdefs for the OCMEM support that was missing upstream. Add two new functions (adreno_gpu_ocmem_init and adreno_gpu_ocmem_cleanup) that removes some duplicated code. Signed-off-by: Brian Masney --- Changes since v3: - None Changes since v2: - Check for -ENODEV error of_get_ocmem() - remove fail_cleanup_ocmem label in a[34]xx_gpu_init Changes since v1: - remove CONFIG_QCOM_OCMEM #ifdefs - use unsigned long for memory addresses instead of uint32_t - add 'depends on QCOM_OCMEM || QCOM_OCMEM=n' to Kconfig drivers/gpu/drm/msm/Kconfig | 1 + drivers/gpu/drm/msm/adreno/a3xx_gpu.c | 28 + drivers/gpu/drm/msm/adreno/a3xx_gpu.h | 3 +- drivers/gpu/drm/msm/adreno/a4xx_gpu.c | 25 drivers/gpu/drm/msm/adreno/a4xx_gpu.h | 3 +- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 40 + drivers/gpu/drm/msm/adreno/adreno_gpu.h | 10 +++ 7 files changed, 66 insertions(+), 44 deletions(-) diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig index 9c37e4de5896..b3d3b2172659 100644 --- a/drivers/gpu/drm/msm/Kconfig +++ b/drivers/gpu/drm/msm/Kconfig @@ -7,6 +7,7 @@ config DRM_MSM depends on OF && COMMON_CLK depends on MMU depends on INTERCONNECT || !INTERCONNECT + depends on QCOM_OCMEM || QCOM_OCMEM=n select QCOM_MDT_LOADER if ARCH_QCOM select REGULATOR select DRM_KMS_HELPER diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c index ec82aaa21734..07ddcc529573 100644 --- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c @@ -6,10 +6,6 @@ * Copyright (c) 2014 The Linux Foundation. All rights reserved. */ -#ifdef CONFIG_MSM_OCMEM -# include -#endif - #include "a3xx_gpu.h" #define A3XX_INT0_MASK \ @@ -195,9 +191,9 @@ static int a3xx_hw_init(struct msm_gpu *gpu) gpu_write(gpu, REG_A3XX_RBBM_GPR0_CTL, 0x); /* Set the OCMEM base address for A330, etc */ - if (a3xx_gpu->ocmem_hdl) { + if (a3xx_gpu->ocmem.hdl) { gpu_write(gpu, REG_A3XX_RB_GMEM_BASE_ADDR, - (unsigned int)(a3xx_gpu->ocmem_base >> 14)); + (unsigned int)(a3xx_gpu->ocmem.base >> 14)); } /* Turn on performance counters: */ @@ -318,10 +314,7 @@ static void a3xx_destroy(struct msm_gpu *gpu) adreno_gpu_cleanup(adreno_gpu); -#ifdef CONFIG_MSM_OCMEM - if (a3xx_gpu->ocmem_base) - ocmem_free(OCMEM_GRAPHICS, a3xx_gpu->ocmem_hdl); -#endif + adreno_gpu_ocmem_cleanup(&a3xx_gpu->ocmem); kfree(a3xx_gpu); } @@ -494,17 +487,10 @@ struct msm_gpu *a3xx_gpu_init(struct drm_device *dev) /* if needed, allocate gmem: */ if (adreno_is_a330(adreno_gpu)) { -#ifdef CONFIG_MSM_OCMEM - /* TODO this is different/missing upstream: */ - struct ocmem_buf *ocmem_hdl = - ocmem_allocate(OCMEM_GRAPHICS, adreno_gpu->gmem); - - a3xx_gpu->ocmem_hdl = ocmem_hdl; - a3xx_gpu->ocmem_base = ocmem_hdl->addr; - adreno_gpu->gmem = ocmem_hdl->len; - DBG("using %dK of OCMEM at 0x%08x", adreno_gpu->gmem / 1024, - a3xx_gpu->ocmem_base); -#endif + ret = adreno_gpu_ocmem_init(&adreno_gpu->base.pdev->dev, + adreno_gpu, &a3xx_gpu->ocmem); + if (ret) + goto fail; } if (!gpu->aspace) { diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.h b/drivers/gpu/drm/msm/adreno/a3xx_gpu.h index 5dc33e5ea53b..c555fb13e0d7 100644 --- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.h +++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.h @@ -19,8 +19,7 @@ struct a3xx_gpu { struct adreno_gpu base; /* if OCMEM is used for GMEM: */ - uint32_t ocmem_base; - void *ocmem_hdl; + struct adreno_ocmem ocmem; }; #define to_a3xx_gpu(x) container_of(x, struct a3xx_gpu, base) diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c index ab2b752566d8..b01388a9e89e 100644 --- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c @@ -2,9 +2,6 @@ /* Copyright (c) 2014 The Linux Foundation. All rights reserved. */ #include "a4xx_gpu.h" -#ifdef CONFIG_MSM_OCMEM -# include -#endif #define A4XX_INT0_MASK \ (A4XX_INT0_RBBM_AHB_ERROR |\ @@ -188,7 +185,7 @@ static int a4xx_hw_init(struct msm_gpu *gpu) (1 << 30) | 0x); gpu_write(gpu, REG_A4XX_RB_GMEM_BASE_ADDR, - (unsigned int)(a4xx_gpu->ocmem_base >> 14)); + (unsigned int)(a4xx_g
[Freedreno] [PATCH v4 4/6] firmware: qcom: scm: add support to restore secure config to qcm_scm-32
From: Rob Clark Add support to restore the secure configuration for qcm_scm-32.c. This is needed by the On Chip MEMory (OCMEM) that is present on some Snapdragon devices. Signed-off-by: Rob Clark [masn...@onstation.org: ported to latest kernel; set ctx_bank_num to spare parameter.] Signed-off-by: Brian Masney --- Changes since v3: - None Changes since v2: - None Changes since v1: - Use existing __qcom_scm_restore_sec_cfg() function stub in qcom_scm-32.c that was unimplemented - Set the cfg.ctx_bank_num to the spare function parameter. It was previously set to the device_id. drivers/firmware/qcom_scm-32.c | 17 - drivers/firmware/qcom_scm.c| 13 + include/linux/qcom_scm.h | 11 +++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c index 4c2514e5e249..5d90b7f5ab5a 100644 --- a/drivers/firmware/qcom_scm-32.c +++ b/drivers/firmware/qcom_scm-32.c @@ -617,7 +617,22 @@ int __qcom_scm_assign_mem(struct device *dev, phys_addr_t mem_region, int __qcom_scm_restore_sec_cfg(struct device *dev, u32 device_id, u32 spare) { - return -ENODEV; + struct msm_scm_sec_cfg { + __le32 id; + __le32 ctx_bank_num; + } cfg; + int ret, scm_ret = 0; + + cfg.id = cpu_to_le32(device_id); + cfg.ctx_bank_num = cpu_to_le32(spare); + + ret = qcom_scm_call(dev, QCOM_SCM_SVC_MP, QCOM_SCM_RESTORE_SEC_CFG, + &cfg, sizeof(cfg), &scm_ret, sizeof(scm_ret)); + + if (ret || scm_ret) + return ret ? ret : -EINVAL; + + return 0; } int __qcom_scm_iommu_secure_ptbl_size(struct device *dev, u32 spare, diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index 7e285ff3961d..27c1d98a34e6 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -367,6 +367,19 @@ static const struct reset_control_ops qcom_scm_pas_reset_ops = { .deassert = qcom_scm_pas_reset_deassert, }; +/** + * qcom_scm_restore_sec_cfg_available() - Check if secure environment + * supports restore security config interface. + * + * Return true if restore-cfg interface is supported, false if not. + */ +bool qcom_scm_restore_sec_cfg_available(void) +{ + return __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_MP, + QCOM_SCM_RESTORE_SEC_CFG); +} +EXPORT_SYMBOL(qcom_scm_restore_sec_cfg_available); + int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare) { return __qcom_scm_restore_sec_cfg(__scm->dev, device_id, spare); diff --git a/include/linux/qcom_scm.h b/include/linux/qcom_scm.h index b49b734d662c..04382e1798e4 100644 --- a/include/linux/qcom_scm.h +++ b/include/linux/qcom_scm.h @@ -34,6 +34,16 @@ enum qcom_scm_ocmem_client { QCOM_SCM_OCMEM_DEBUG_ID, }; +enum qcom_scm_sec_dev_id { + QCOM_SCM_MDSS_DEV_ID= 1, + QCOM_SCM_OCMEM_DEV_ID = 5, + QCOM_SCM_PCIE0_DEV_ID = 11, + QCOM_SCM_PCIE1_DEV_ID = 12, + QCOM_SCM_GFX_DEV_ID = 18, + QCOM_SCM_UFS_DEV_ID = 19, + QCOM_SCM_ICE_DEV_ID = 20, +}; + #define QCOM_SCM_VMID_HLOS 0x3 #define QCOM_SCM_VMID_MSS_MSA0xF #define QCOM_SCM_VMID_WLAN 0x18 @@ -70,6 +80,7 @@ extern int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz, extern void qcom_scm_cpu_power_down(u32 flags); extern u32 qcom_scm_get_version(void); extern int qcom_scm_set_remote_state(u32 state, u32 id); +extern bool qcom_scm_restore_sec_cfg_available(void); extern int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare); extern int qcom_scm_iommu_secure_ptbl_size(u32 spare, size_t *size); extern int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare); -- 2.21.0 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH] drm/msm/phy/dsi_phy: silence -EPROBE_DEFER warnings
The following errors show up when booting the Nexus 5: msm_dsi_phy fd922a00.dsi-phy: [drm:dsi_phy_driver_probe] *ERROR* dsi_phy_regulator_init: failed to init regulator, ret=-517 msm_dsi_phy fd922a00.dsi-phy: [drm:dsi_phy_driver_probe] *ERROR* dsi_phy_driver_probe: failed to init regulator dsi_phy_regulator_init() already logs the error, so no need to log the same error a second time in dsi_phy_driver_probe(). This patch also changes dsi_phy_regulator_init() to not log the error if the error code is -EPROBE_DEFER to reduce noise in dmesg. Signed-off-by: Brian Masney --- drivers/gpu/drm/msm/dsi/phy/dsi_phy.c | 11 ++- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c index 4097eca1b3ef..d0e1cc6728dc 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c @@ -396,8 +396,11 @@ static int dsi_phy_regulator_init(struct msm_dsi_phy *phy) ret = devm_regulator_bulk_get(dev, num, s); if (ret < 0) { - DRM_DEV_ERROR(dev, "%s: failed to init regulator, ret=%d\n", - __func__, ret); + if (ret != -EPROBE_DEFER) + DRM_DEV_ERROR(dev, + "%s: failed to init regulator, ret=%d\n", + __func__, ret); + return ret; } @@ -584,10 +587,8 @@ static int dsi_phy_driver_probe(struct platform_device *pdev) } ret = dsi_phy_regulator_init(phy); - if (ret) { - DRM_DEV_ERROR(dev, "%s: failed to init regulator\n", __func__); + if (ret) goto fail; - } phy->ahb_clk = msm_clk_get(pdev, "iface"); if (IS_ERR(phy->ahb_clk)) { -- 2.20.1 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH] drm/msm: correct NULL pointer dereference in context_init
Correct attempted NULL pointer dereference in context_init() when running without an IOMMU. Signed-off-by: Brian Masney Fixes: 295b22ae596c ("drm/msm: Pass the MMU domain index in struct msm_file_private") --- The no IOMMU case seems like functionality that we may want to keep based on this comment: https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/msm/adreno/a3xx_gpu.c#L523 Once I get the msm8974 interconnect driver done, I'm going to look into what needs to be done to get the IOMMU working on the Nexus 5. Alternatively, for development purposes, maybe we could have a NOOP IOMMU driver that would allow us to remove these NULL checks that are sprinkled throughout the code. I haven't looked into this in detail. Thoughts? drivers/gpu/drm/msm/msm_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 451bd4508793..83047cb2c735 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -619,7 +619,7 @@ static int context_init(struct drm_device *dev, struct drm_file *file) msm_submitqueue_init(dev, ctx); - ctx->aspace = priv->gpu->aspace; + ctx->aspace = priv->gpu ? priv->gpu->aspace : NULL; file->driver_priv = ctx; return 0; -- 2.20.1 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v3 4/6] firmware: qcom: scm: add support to restore secure config to qcm_scm-32
From: Rob Clark Add support to restore the secure configuration for qcm_scm-32.c. This is needed by the On Chip MEMory (OCMEM) that is present on some Snapdragon devices. Signed-off-by: Rob Clark [masn...@onstation.org: ported to latest kernel; set ctx_bank_num to spare parameter.] Signed-off-by: Brian Masney --- Changes since v2: - None Changes since v1: - Use existing __qcom_scm_restore_sec_cfg() function stub in qcom_scm-32.c that was unimplemented - Set the cfg.ctx_bank_num to the spare function parameter. It was previously set to the device_id. drivers/firmware/qcom_scm-32.c | 17 - drivers/firmware/qcom_scm.c| 13 + include/linux/qcom_scm.h | 11 +++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c index 4c2514e5e249..5d90b7f5ab5a 100644 --- a/drivers/firmware/qcom_scm-32.c +++ b/drivers/firmware/qcom_scm-32.c @@ -617,7 +617,22 @@ int __qcom_scm_assign_mem(struct device *dev, phys_addr_t mem_region, int __qcom_scm_restore_sec_cfg(struct device *dev, u32 device_id, u32 spare) { - return -ENODEV; + struct msm_scm_sec_cfg { + __le32 id; + __le32 ctx_bank_num; + } cfg; + int ret, scm_ret = 0; + + cfg.id = cpu_to_le32(device_id); + cfg.ctx_bank_num = cpu_to_le32(spare); + + ret = qcom_scm_call(dev, QCOM_SCM_SVC_MP, QCOM_SCM_RESTORE_SEC_CFG, + &cfg, sizeof(cfg), &scm_ret, sizeof(scm_ret)); + + if (ret || scm_ret) + return ret ? ret : -EINVAL; + + return 0; } int __qcom_scm_iommu_secure_ptbl_size(struct device *dev, u32 spare, diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index 2e12ea56c34c..54532331ddc1 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -366,6 +366,19 @@ static const struct reset_control_ops qcom_scm_pas_reset_ops = { .deassert = qcom_scm_pas_reset_deassert, }; +/** + * qcom_scm_restore_sec_cfg_available() - Check if secure environment + * supports restore security config interface. + * + * Return true if restore-cfg interface is supported, false if not. + */ +bool qcom_scm_restore_sec_cfg_available(void) +{ + return __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_MP, + QCOM_SCM_RESTORE_SEC_CFG); +} +EXPORT_SYMBOL(qcom_scm_restore_sec_cfg_available); + int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare) { return __qcom_scm_restore_sec_cfg(__scm->dev, device_id, spare); diff --git a/include/linux/qcom_scm.h b/include/linux/qcom_scm.h index 521b089be1c9..8a24f7eb2588 100644 --- a/include/linux/qcom_scm.h +++ b/include/linux/qcom_scm.h @@ -34,6 +34,16 @@ enum qcom_scm_ocmem_client { QCOM_SCM_OCMEM_DEBUG_ID, }; +enum qcom_scm_sec_dev_id { + QCOM_SCM_MDSS_DEV_ID= 1, + QCOM_SCM_OCMEM_DEV_ID = 5, + QCOM_SCM_PCIE0_DEV_ID = 11, + QCOM_SCM_PCIE1_DEV_ID = 12, + QCOM_SCM_GFX_DEV_ID = 18, + QCOM_SCM_UFS_DEV_ID = 19, + QCOM_SCM_ICE_DEV_ID = 20, +}; + #define QCOM_SCM_VMID_HLOS 0x3 #define QCOM_SCM_VMID_MSS_MSA0xF #define QCOM_SCM_VMID_WLAN 0x18 @@ -69,6 +79,7 @@ extern int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz, extern void qcom_scm_cpu_power_down(u32 flags); extern u32 qcom_scm_get_version(void); extern int qcom_scm_set_remote_state(u32 state, u32 id); +extern bool qcom_scm_restore_sec_cfg_available(void); extern int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare); extern int qcom_scm_iommu_secure_ptbl_size(u32 spare, size_t *size); extern int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare); -- 2.20.1 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v3 1/6] dt-bindings: soc: qcom: add On Chip MEMory (OCMEM) bindings
Add device tree bindings for the On Chip Memory (OCMEM) that is present on some Qualcomm Snapdragon SoCs. Signed-off-by: Brian Masney --- Changes since v2: - Add *-sram node and gmu-sram to example. Changes since v1: - Rename qcom,ocmem-msm8974 to qcom,msm8974-ocmem - Renamed reg-names to ctrl and mem - update hardware description - moved from soc to sram namespace in the device tree bindings .../bindings/sram/qcom/qcom,ocmem.yaml| 84 +++ 1 file changed, 84 insertions(+) create mode 100644 Documentation/devicetree/bindings/sram/qcom/qcom,ocmem.yaml diff --git a/Documentation/devicetree/bindings/sram/qcom/qcom,ocmem.yaml b/Documentation/devicetree/bindings/sram/qcom/qcom,ocmem.yaml new file mode 100644 index ..a0bf0af4860a --- /dev/null +++ b/Documentation/devicetree/bindings/sram/qcom/qcom,ocmem.yaml @@ -0,0 +1,84 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sram/qcom/qcom,ocmem.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: On Chip Memory (OCMEM) that is present on some Qualcomm Snapdragon SoCs. + +maintainers: + - Brian Masney + +description: | + The On Chip Memory (OCMEM) is typically used by the GPU, camera/video, and + audio components on some Snapdragon SoCs. + +properties: + compatible: +const: qcom,msm8974-ocmem + + reg: +items: + - description: Control registers + - description: OCMEM address range + + reg-names: +items: + - const: ctrl + - const: mem + + clocks: +items: + - description: Core clock + - description: Interface clock + + clock-names: +items: + - const: core + - const: iface + +required: + - compatible + - reg + - reg-names + - clocks + - clock-names + +patternProperties: + "^.+-sram$": +type: object +description: | + A region of reserved memory. + +properties: + reg: +maxItems: 1 + +required: + - reg + +examples: + - | + #include + #include + + ocmem: ocmem@fdd0 { +compatible = "qcom,msm8974-ocmem"; + +reg = <0xfdd0 0x2000>, + <0xfec0 0x18>; +reg-names = "ctrl", +"mem"; + +clocks = <&rpmcc RPM_SMD_OCMEMGX_CLK>, + <&mmcc OCMEMCX_OCMEMNOC_CLK>; +clock-names = "core", + "iface"; + +#address-cells = <1>; +#size-cells = <1>; + +gmu-sram@0 { +reg = <0x0 0x10>; +}; + }; -- 2.20.1 ___ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno
[Freedreno] [PATCH v3 5/6] soc: qcom: add OCMEM driver
The OCMEM driver handles allocation and configuration of the On Chip MEMory that is present on some Snapdragon SoCs. Devices which have OCMEM do not have GMEM inside the GPU core, so the GPU must instead use OCMEM to be functional. Since the GPU is currently the only OCMEM user with an upstream driver, this is just a minimal implementation sufficient for statically allocating to the GPU it's chunk of OCMEM. This driver currently does not read the gmu-sram node that is described in the device tree bindings. The starting memory address of the GPU's reserved memory region is hardcoded to zero to match what the hardware expects. The driver can be updated to read the reserved memory regions from device tree once other users of OCMEM are added upstream. Signed-off-by: Brian Masney Co-developed-by: Rob Clark Signed-off-by: Rob Clark --- Changes since v2 - Changed static inline stubs return -ENODEV when OCMEM is not configured into the kernel. Changes since v1: - ocmem_allocate(): check for alignment and minimum allocation size. The 64K values came from the downstream MSM kernel sources. - add locking to memory allocations based on the client - use clk_bulk_*() functions - rename qcom,ocmem-msm8974 to qcom,msm8974-ocmem - rename reg-names to ctrl and mem - remove ocmem.xml.h file; use FIELD_PREP() instead for some nice cleanups - add static inline noop versions of public-facing functions when ocmem is disabled to remove #ifdefs in adrenu_gpu.c - use unsigned long for memory addresses - move ocmem_dev_remove() below _probe() function - remove error check from platform_get_resource_byname for ctrl resource - add MODULE_DESCRIPTION() and MODULE_LICENSE() - add description to top of ocmem.[ch] - correct thin mode bit in update_ocmem() - add 'WARN_ON(client != OCMEM_GRAPHICS)' to device_address() - make of_get_ocmem return error codes via ERR_PTR instead of NULL - ocmem_{allocate,free} - WARN_ON() if client != OCMEM_GRAPHICS. Simplify if statements. - allow NULL to be passed into ocmem_free - remove unnecessary initialization of i in update_ocmem() - add dev_dbg to ocmem_allocate Changes since Rob's last version of this patch from 2015: https://patchwork.kernel.org/patch/7379801/ - reformatted driver to allow multiple instances - updated logging of error paths during device probing - remove unused psgsc_ctrl - remove _clk from clock names - propagate error code from devm_ioremap_resource() - use device_get_match_data() - SPDX license tags - remove QCOM_SMD in Kconfig - select ARCH_QCOM in Kconfig - select ARCH_QCOM in Kconfig - select QCOM_SCM in Kconfig - longer description in Kconfig drivers/soc/qcom/Kconfig | 10 + drivers/soc/qcom/Makefile | 1 + drivers/soc/qcom/ocmem.c | 433 ++ include/soc/qcom/ocmem.h | 62 ++ 4 files changed, 506 insertions(+) create mode 100644 drivers/soc/qcom/ocmem.c create mode 100644 include/soc/qcom/ocmem.h diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig index a6d1bfb17279..d18eb83b10da 100644 --- a/drivers/soc/qcom/Kconfig +++ b/drivers/soc/qcom/Kconfig @@ -74,6 +74,16 @@ config QCOM_MDT_LOADER tristate select QCOM_SCM +config QCOM_OCMEM + tristate "Qualcomm On Chip Memory (OCMEM) driver" + depends on ARCH_QCOM + select QCOM_SCM + help + The On Chip Memory (OCMEM) allocator allows various clients to + allocate memory from OCMEM based on performance, latency and power + requirements. This is typically used by the GPU, camera/video, and + audio components on some Snapdragon SoCs. + config QCOM_PM bool "Qualcomm Power Management" depends on ARCH_QCOM && !ARM64 diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile index eeb088beb15f..dfc378014a33 100644 --- a/drivers/soc/qcom/Makefile +++ b/drivers/soc/qcom/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_QCOM_COMMAND_DB) += cmd-db.o obj-$(CONFIG_QCOM_GLINK_SSR) +=glink_ssr.o obj-$(CONFIG_QCOM_GSBI)+= qcom_gsbi.o obj-$(CONFIG_QCOM_MDT_LOADER) += mdt_loader.o +obj-$(CONFIG_QCOM_OCMEM) += ocmem.o obj-$(CONFIG_QCOM_PM) += spm.o obj-$(CONFIG_QCOM_QMI_HELPERS) += qmi_helpers.o qmi_helpers-y += qmi_encdec.o qmi_interface.o diff --git a/drivers/soc/qcom/ocmem.c b/drivers/soc/qcom/ocmem.c new file mode 100644 index ..7c28ad3108a6 --- /dev/null +++ b/drivers/soc/qcom/ocmem.c @@ -0,0 +1,433 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * The On Chip Memory (OCMEM) allocator allows various clients to allocate + * memory from OCMEM based on performance, latency and power requirements. + * This is typically used by the GPU, camera/video, and audio components on + * some Snapdragon SoCs. + * + * Copyright (C) 2019 Brian Masney + * Copyright (C) 2015 Red Hat. Author: Rob Clark + */ + +#include +#include +#include +#include +#include +#include +#include
[Freedreno] [PATCH v3 3/6] firmware: qcom: scm: add OCMEM lock/unlock interface
From: Rob Clark Add support for the OCMEM lock/unlock interface that is needed by the On Chip MEMory (OCMEM) that is present on some Snapdragon devices. Signed-off-by: Rob Clark [masn...@onstation.org: ported to latest kernel; minor reformatting.] Signed-off-by: Brian Masney Reviewed-by: Bjorn Andersson --- Rob's last version of this patch: https://patchwork.kernel.org/patch/7340711/ Changes since v2: - None Changes since v1: - None drivers/firmware/qcom_scm-32.c | 35 + drivers/firmware/qcom_scm-64.c | 12 ++ drivers/firmware/qcom_scm.c| 40 ++ drivers/firmware/qcom_scm.h| 9 include/linux/qcom_scm.h | 15 + 5 files changed, 111 insertions(+) diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c index 215061c581e1..4c2514e5e249 100644 --- a/drivers/firmware/qcom_scm-32.c +++ b/drivers/firmware/qcom_scm-32.c @@ -442,6 +442,41 @@ int __qcom_scm_hdcp_req(struct device *dev, struct qcom_scm_hdcp_req *req, req, req_cnt * sizeof(*req), resp, sizeof(*resp)); } +int __qcom_scm_ocmem_lock(struct device *dev, u32 id, u32 offset, u32 size, + u32 mode) +{ + struct ocmem_tz_lock { + __le32 id; + __le32 offset; + __le32 size; + __le32 mode; + } request; + + request.id = cpu_to_le32(id); + request.offset = cpu_to_le32(offset); + request.size = cpu_to_le32(size); + request.mode = cpu_to_le32(mode); + + return qcom_scm_call(dev, QCOM_SCM_OCMEM_SVC, QCOM_SCM_OCMEM_LOCK_CMD, +&request, sizeof(request), NULL, 0); +} + +int __qcom_scm_ocmem_unlock(struct device *dev, u32 id, u32 offset, u32 size) +{ + struct ocmem_tz_unlock { + __le32 id; + __le32 offset; + __le32 size; + } request; + + request.id = cpu_to_le32(id); + request.offset = cpu_to_le32(offset); + request.size = cpu_to_le32(size); + + return qcom_scm_call(dev, QCOM_SCM_OCMEM_SVC, QCOM_SCM_OCMEM_UNLOCK_CMD, +&request, sizeof(request), NULL, 0); +} + void __qcom_scm_init(void) { } diff --git a/drivers/firmware/qcom_scm-64.c b/drivers/firmware/qcom_scm-64.c index 91d5ad7cf58b..c3a3d9874def 100644 --- a/drivers/firmware/qcom_scm-64.c +++ b/drivers/firmware/qcom_scm-64.c @@ -241,6 +241,18 @@ int __qcom_scm_hdcp_req(struct device *dev, struct qcom_scm_hdcp_req *req, return ret; } +int __qcom_scm_ocmem_lock(struct device *dev, uint32_t id, uint32_t offset, + uint32_t size, uint32_t mode) +{ + return -ENOTSUPP; +} + +int __qcom_scm_ocmem_unlock(struct device *dev, uint32_t id, uint32_t offset, + uint32_t size) +{ + return -ENOTSUPP; +} + void __qcom_scm_init(void) { u64 cmd; diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index 2ddc118dba1b..2e12ea56c34c 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -190,6 +190,46 @@ bool qcom_scm_pas_supported(u32 peripheral) } EXPORT_SYMBOL(qcom_scm_pas_supported); +/** + * qcom_scm_ocmem_lock_available() - is OCMEM lock/unlock interface available + */ +bool qcom_scm_ocmem_lock_available(void) +{ + return __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_OCMEM_SVC, + QCOM_SCM_OCMEM_LOCK_CMD); +} +EXPORT_SYMBOL(qcom_scm_ocmem_lock_available); + +/** + * qcom_scm_ocmem_lock() - call OCMEM lock interface to assign an OCMEM + * region to the specified initiator + * + * @id: tz initiator id + * @offset: OCMEM offset + * @size: OCMEM size + * @mode: access mode (WIDE/NARROW) + */ +int qcom_scm_ocmem_lock(enum qcom_scm_ocmem_client id, u32 offset, u32 size, + u32 mode) +{ + return __qcom_scm_ocmem_lock(__scm->dev, id, offset, size, mode); +} +EXPORT_SYMBOL(qcom_scm_ocmem_lock); + +/** + * qcom_scm_ocmem_unlock() - call OCMEM unlock interface to release an OCMEM + * region from the specified initiator + * + * @id: tz initiator id + * @offset: OCMEM offset + * @size: OCMEM size + */ +int qcom_scm_ocmem_unlock(enum qcom_scm_ocmem_client id, u32 offset, u32 size) +{ + return __qcom_scm_ocmem_unlock(__scm->dev, id, offset, size); +} +EXPORT_SYMBOL(qcom_scm_ocmem_unlock); + /** * qcom_scm_pas_init_image() - Initialize peripheral authentication service *state machine for a given peripheral, using the diff --git a/drivers/firmware/qcom_scm.h b/drivers/firmware/qcom_scm.h index 99506bd873c0..ef293ee67ec1 100644 --- a/drivers/firmware/qcom_scm.h +++ b/drivers/firmware/qcom_scm.h @@ -42,6 +42,15 @@ extern int __qcom_scm_hdcp_req(struct device *dev, extern void __qcom_scm_init(void); +#define QCOM_SCM_OCMEM_SVC 0xf +#define Q