* Re: [PATCH v2] net: dsa: tag_mtk: add padding for tx packets
From: Vladimir Oltean @ 2022-05-10 22:21 UTC (permalink / raw)
To: Felix Fietkau
Cc: Sean Wang, Landen Chao, DENG Qingfang, Andrew Lunn,
Vivien Didelot, Florian Fainelli, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Matthias Brugger, netdev,
linux-arm-kernel, linux-mediatek, linux-kernel
In-Reply-To: <bc4bde22-c2d6-1ded-884a-69465b9d1dc7@nbd.name>
On Wed, May 11, 2022 at 12:06:25AM +0200, Felix Fietkau wrote:
>
> On 10.05.22 18:52, Vladimir Oltean wrote:
> > On Tue, May 10, 2022 at 04:52:16PM +0200, Felix Fietkau wrote:
> > >
> > > On 10.05.22 14:37, Vladimir Oltean wrote:
> > > > On Tue, May 10, 2022 at 11:40:13AM +0200, Felix Fietkau wrote:
> > > > > Padding for transmitted packets needs to account for the special tag.
> > > > > With not enough padding, garbage bytes are inserted by the switch at the
> > > > > end of small packets.
> > > > > I don't think padding bytes are guaranteed to be zeroes. Aren't
> > > they
> > > > discarded? What is the issue?
> > > With the broken padding, ARP requests are silently discarded on the receiver
> > > side in my test. Adding the padding explicitly fixes the issue.
> > >
> > > - Felix
> >
> > Ok, I'm not going to complain too much about the patch, but I'm still
> > curious where are the so-called "broken" packets discarded.
> > I think the receiving MAC should be passing up to software a buffer
> > without the extra padding beyond the L2 payload length (at least that's
> > the behavior I'm familiar with).
>
> I don't know where exactly these packets are discarded.
> After digging through the devices I used during the tests, I just found some
> leftover pcap files that show the differences in the received packets. Since
> the packets are bigger after my patch, I can't rule out that packet size
> instead of the padding may have made a difference here in getting the ARP
> requests accepted by the receiver.
>
> I've extracted the ARP requests and you can find them here:
> http://nbd.name/arp-broken.pcap
arp-broken.pcap was collected at the receiver MAC, right? So the packets
actually exited the switch?
> http://nbd.name/arp-working.pcap
>
> - Felix
It sounds as if this is masking a problem on the receiver end, because
not only does my enetc port receive the packet, it also replies to the
ARP request.
pc # sudo tcpreplay -i eth1 arp-broken.pcap
root@debian:~# ip addr add 192.168.42.1/24 dev eno0
root@debian:~# tcpdump -i eno0 -e -n --no-promiscuous-mode arp
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eno0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
22:18:58.846753 f4:d4:88:5e:6f:d2 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 60: Request who-has 192.168.42.1 tell 192.168.42.173, length 46
22:18:58.846806 00:04:9f:05:f4:ab > f4:d4:88:5e:6f:d2, ethertype ARP (0x0806), length 42: Reply 192.168.42.1 is-at 00:04:9f:05:f4:ab, length 28
^C
2 packets captured
2 packets received by filter
0 packets dropped by kernel
What MAC/driver has trouble with these packets? Is there anything wrong
in ethtool stats? Do they even reach software? You can also use
"dropwatch -l kas" for some hints if they do.
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply
* Re: [PATCH v2 1/3] dt-bindings: mediatek: add vdosys1 RDMA definition for mt8195
From: Rex-BC Chen @ 2022-05-11 2:26 UTC (permalink / raw)
To: Krzysztof Kozlowski, Chen-Yu Tsai
Cc: robh+dt@kernel.org, krzysztof.kozlowski+dt@linaro.org,
chunkuang.hu@kernel.org, p.zabel@pengutronix.de,
devicetree@vger.kernel.org, airlied@linux.ie,
Jason-JH Lin (林睿祥),
linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org,
Project_Global_Chrome_Upstream_Group,
Nancy Lin (林欣螢),
linux-mediatek@lists.infradead.org, matthias.bgg@gmail.com,
linux-arm-kernel@lists.infradead.org,
angelogioacchino.delregno@collabora.com
In-Reply-To: <0686125d-4984-5dcd-32ca-4eeece09d7c3@linaro.org>
On Tue, 2022-05-10 at 18:57 +0800, Krzysztof Kozlowski wrote:
> On 10/05/2022 12:37, Chen-Yu Tsai wrote:
> > > Use a generic node name, as Devicetree spec asks:
> > > "The name of a node should be somewhat generic, reflecting the
> > > function
> > > of the device and not its precise programming
> > >
> > > model. If appropriate, the name should be one of the following
> > > choices:"
> > >
> > > I proposed dma-controller, but feel free to find better generic
> > > node name.
> >
> > dma-controller is covered by dma-controller.yaml, which references
> > dma-common.yaml in its entirety, so I don't think that would work.
> >
> > What about "blitter"? I think that is a generic term that is/was
> > commonly
> > used with display hardware and sort of describes the function of
> > the RDMA
> > & WDMA blocks, and if only one side is memory and the other is the
> > display
> > pipeline.
>
> Sure, sounds fine!
>
>
> Best regards,
> Krzysztof
Hello Krzysztof and Chen-Yu,
Nancy thinks our IP is more like rdma.
Blitter may be somthing for reading memory and writing to another
memory, but we don't have the function of writing memory.
If we use rdma, is it ok?
BRs,
Rex
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply
* Re: [PATCH v2 3/3] dt-bindings: mediatek: add ethdr definition for mt8195
From: Rex-BC Chen @ 2022-05-11 2:29 UTC (permalink / raw)
To: Krzysztof Kozlowski, AngeloGioacchino Del Regno,
robh+dt@kernel.org, krzysztof.kozlowski+dt@linaro.org,
chunkuang.hu@kernel.org, p.zabel@pengutronix.de
Cc: airlied@linux.ie, matthias.bgg@gmail.com,
Jason-JH Lin (林睿祥),
Nancy Lin (林欣螢), devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org,
linux-mediatek@lists.infradead.org,
linux-arm-kernel@lists.infradead.org,
Project_Global_Chrome_Upstream_Group
In-Reply-To: <f1d477d2-13c4-2914-e520-4b2778e52e35@linaro.org>
On Tue, 2022-05-10 at 19:19 +0800, Krzysztof Kozlowski wrote:
> On 10/05/2022 03:46, Rex-BC Chen wrote:
> > >
> > >
> > > That's mediatek-drm, and this refers to the HDR block in the
> > > display
> > > IP...
> > >
> > > Though, I have no idea of what "ET" stands for in "ETHDR", so, it
> > > would be
> > > definitely nice if MediaTek can write the meaning in the
> > > description,
> > > like
> > >
> > > description:
> > > ETHDR (E??? T??? High Dynamic Range) is designed for HDR video
> > > and
> > > ...blah
> > >
> > > Cheers,
> > > Angelo
> >
> > Hello Krzysztof and Angelo,
> >
> > "ET" is actually meaningless.
> > ET is one of mediatek departments and it's where the engine from.
> > Therefore, I think we will add description like this:
> > > ETHDR (ET High Dynamic Range) is a MediaTek internal HDR engine
> > > and
> > > designed for HDR video...
>
> Sure, sounds good, but then the node name should not have it. Please
> try
> to find some more generic name (DT spec gives examples). Could be
> display-controller, "hdr-engine", "isp".
>
>
> Best regards,
> Krzysztof
Hello Krzysztof,
Thanks for your suggestion.
We will use hdr-engine to name this node.
Thanks!
BRs,
Rex
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply
* Re: [PATCH next v3 2/2] arm64: dts: mediatek: mt8195: enable usb remote wakeup
From: Macpaul Lin @ 2022-05-11 2:31 UTC (permalink / raw)
To: Chunfeng Yun, Matthias Brugger
Cc: Rob Herring, Krzysztof Kozlowski, devicetree, linux-arm-kernel,
linux-mediatek, linux-kernel, Greg Kroah-Hartman,
AngeloGioacchino Del Regno, Fabien Parent, Pablo Sun, Bear Wang
In-Reply-To: <20220510121027.19041-2-chunfeng.yun@mediatek.com>
On Tue, 2022-05-10 at 20:10 +0800, Chunfeng Yun wrote:
> Enable USB remote wakeup of all four xHCI controller
>
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno@collabora.com>
> Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
> ---
> v3: add reviewed-by AngeloGioacchino;
>
> NOTE:
> based on v5.18-next/dts64 of matthias.bgg's branch
>
> v2: no changes, based on new version of mt8195.dtsi
> ---
> arch/arm64/boot/dts/mediatek/mt8195.dtsi | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
> b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
> index d5bc4cf5f4ac..3ad14e0e0956 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
> @@ -573,6 +573,8 @@
> <&apmixedsys CLK_APMIXED_USB1PLL>,
> <&infracfg_ao
> CLK_INFRA_AO_SSUSB_XHCI>;
> clock-names = "sys_ck", "ref_ck", "mcu_ck",
> "xhci_ck";
> + mediatek,syscon-wakeup = <&pericfg 0x400 103>;
> + wakeup-source;
> status = "disabled";
> };
>
> @@ -636,6 +638,8 @@
> <&apmixedsys CLK_APMIXED_USB1PLL>,
> <&pericfg_ao
> CLK_PERI_AO_SSUSB_1P_XHCI>;
> clock-names = "sys_ck", "ref_ck",
> "mcu_ck","xhci_ck";
> + mediatek,syscon-wakeup = <&pericfg 0x400 104>;
> + wakeup-source;
> status = "disabled";
> };
>
> @@ -655,6 +659,8 @@
> <&topckgen CLK_TOP_SSUSB_P2_REF>,
> <&pericfg_ao
> CLK_PERI_AO_SSUSB_2P_XHCI>;
> clock-names = "sys_ck", "ref_ck", "xhci_ck";
> + mediatek,syscon-wakeup = <&pericfg 0x400 105>;
> + wakeup-source;
> status = "disabled";
> };
>
> @@ -674,6 +680,8 @@
> <&topckgen CLK_TOP_SSUSB_P3_REF>,
> <&pericfg_ao
> CLK_PERI_AO_SSUSB_3P_XHCI>;
> clock-names = "sys_ck", "ref_ck", "xhci_ck";
> + mediatek,syscon-wakeup = <&pericfg 0x400 106>;
> + wakeup-source;
> status = "disabled";
> };
>
Tested-by: Macpaul Lin <macpaul.lin@mediatek.com>
Test method: test build pass and boot pass based on 'for-next' branch.
N
ote:
System suspend and resume of MT8195 has not been ready or enabled
on mainline. We cannot verify USB Host remote wake-up on mainline code,
but the settings and function works when applied to MediaTek's internal
working tree.
Regards,
Macpaul Lin
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply
* [PATCH v5,2/5] drm/mediatek: Modify dsi funcs to atomic operations
From: xinlei.lee @ 2022-05-11 2:36 UTC (permalink / raw)
To: chunkuang.hu, p.zabel, airlied, daniel, matthias.bgg
Cc: dri-devel, linux-mediatek, linux-arm-kernel, linux-kernel,
Project_Global_Chrome_Upstream_Group, rex-bc.chen, jitao.shi,
Xinlei Lee
In-Reply-To: <1652236596-21648-1-git-send-email-xinlei.lee@mediatek.com>
From: Xinlei Lee <xinlei.lee@mediatek.com>
Modify dsi_enable & dsi_disable to dsi_atomic_enable & dsi_atomic_disable funcs.
Signed-off-by: Jitao Shi <jitao.shi@mediatek.com>
Signed-off-by: Xinlei Lee <xinlei.lee@mediatek.com>
---
drivers/gpu/drm/mediatek/mtk_dsi.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 02e31a7d9257..82a811801c9f 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -763,14 +763,16 @@ static void mtk_dsi_bridge_mode_set(struct drm_bridge *bridge,
drm_display_mode_to_videomode(adjusted, &dsi->vm);
}
-static void mtk_dsi_bridge_disable(struct drm_bridge *bridge)
+static void mtk_dsi_bridge_atomic_disable(struct drm_bridge *bridge,
+ struct drm_bridge_state *old_bridge_state)
{
struct mtk_dsi *dsi = bridge_to_dsi(bridge);
mtk_output_dsi_disable(dsi);
}
-static void mtk_dsi_bridge_enable(struct drm_bridge *bridge)
+static void mtk_dsi_bridge_atomic_enable(struct drm_bridge *bridge,
+ struct drm_bridge_state *old_bridge_state)
{
struct mtk_dsi *dsi = bridge_to_dsi(bridge);
@@ -779,8 +781,8 @@ static void mtk_dsi_bridge_enable(struct drm_bridge *bridge)
static const struct drm_bridge_funcs mtk_dsi_bridge_funcs = {
.attach = mtk_dsi_bridge_attach,
- .disable = mtk_dsi_bridge_disable,
- .enable = mtk_dsi_bridge_enable,
+ .atomic_disable = mtk_dsi_bridge_atomic_disable,
+ .atomic_enable = mtk_dsi_bridge_atomic_enable,
.mode_set = mtk_dsi_bridge_mode_set,
};
--
2.18.0
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply related
* [PATCH v5, 5/5] drm/mediatek: Add pull-down MIPI operation in mtk_dsi_poweroff function
From: xinlei.lee @ 2022-05-11 2:36 UTC (permalink / raw)
To: chunkuang.hu, p.zabel, airlied, daniel, matthias.bgg
Cc: dri-devel, linux-mediatek, linux-arm-kernel, linux-kernel,
Project_Global_Chrome_Upstream_Group, rex-bc.chen, jitao.shi,
Xinlei Lee
In-Reply-To: <1652236596-21648-1-git-send-email-xinlei.lee@mediatek.com>
From: Xinlei Lee <xinlei.lee@mediatek.com>
In the dsi_enable function, mtk_dsi_rxtx_control is to
pull up the MIPI signal operation. Before dsi_disable,
MIPI should also be pulled down by writing a register
instead of disabling dsi.
If disable dsi without pulling the mipi signal low, the value of
the register will still maintain the setting of the mipi signal being
pulled high.
After resume, even if the mipi signal is not pulled high, it will still
be in the high state.
Fixes: 2e54c14e310f ("drm/mediatek: Add DSI sub driver")
Signed-off-by: Jitao Shi <jitao.shi@mediatek.com>
Signed-off-by: Xinlei Lee <xinlei.lee@mediatek.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
Reviewed-by: CK Hu <ck.hu@mediatek.com>
---
drivers/gpu/drm/mediatek/mtk_dsi.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 98b7811502e7..1035fafdbf7c 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -688,6 +688,8 @@ static void mtk_dsi_poweroff(struct mtk_dsi *dsi)
mtk_dsi_reset_engine(dsi);
mtk_dsi_lane0_ulp_mode_enter(dsi);
mtk_dsi_clk_ulp_mode_enter(dsi);
+ /* set the lane number as 0 to pull down mipi */
+ writel(0, dsi->regs + DSI_TXRX_CTRL);
mtk_dsi_disable(dsi);
--
2.18.0
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply related
* [PATCH v5, 0/5] Cooperate with DSI RX devices to modify dsi funcs and delay mipi high to cooperate with panel sequence
From: xinlei.lee @ 2022-05-11 2:36 UTC (permalink / raw)
To: chunkuang.hu, p.zabel, airlied, daniel, matthias.bgg
Cc: dri-devel, linux-mediatek, linux-arm-kernel, linux-kernel,
Project_Global_Chrome_Upstream_Group, rex-bc.chen, jitao.shi,
Xinlei Lee
From: Xinlei Lee <xinlei.lee@mediatek.com>
In upstream-v5.8, dsi_enable will operate panel_enable, but this
modification has been moved in v5.9. In order to ensure the timing of
dsi_power_on/off and the timing of pulling up/down the MIPI signal,
the modification of v5.9 is synchronized in this series of patches.
Changes since v4:
1. Dsi func modified to atomic operation.
2. Added fix tag.
3. Removed lane_ready print statement.
Changes since v3:
1. Rebase kernel-5.18-rc1.
2. Added dsi_enable protection.
3. Encapsulates the dsi_lane_ready function.
Changes since v2:
1. Rebase linux-next.
Changes since v1:
1. Dsi sequence marked with patch adjustment.
2. Fixes: mtk_dsi: Use the drm_panel_bridge.
Jitao Shi (3):
drm/mediatek: Adjust the timing of mipi signal from LP00 to LP11
drm/mediatek: Separate poweron/poweroff from enable/disable and define
new funcs
drm/mediatek: keep dsi as LP00 before dcs cmds transfer
Xinlei Lee (2):
drm/mediatek: Modify dsi funcs to atomic operations
drm/mediatek: Add pull-down MIPI operation in mtk_dsi_poweroff
function
drivers/gpu/drm/mediatek/mtk_dsi.c | 94 ++++++++++++++++++++----------
1 file changed, 64 insertions(+), 30 deletions(-)
--
2.18.0
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply
* [PATCH v5, 1/5] drm/mediatek: Adjust the timing of mipi signal from LP00 to LP11
From: xinlei.lee @ 2022-05-11 2:36 UTC (permalink / raw)
To: chunkuang.hu, p.zabel, airlied, daniel, matthias.bgg
Cc: dri-devel, linux-mediatek, linux-arm-kernel, linux-kernel,
Project_Global_Chrome_Upstream_Group, rex-bc.chen, jitao.shi,
Xinlei Lee
In-Reply-To: <1652236596-21648-1-git-send-email-xinlei.lee@mediatek.com>
From: Jitao Shi <jitao.shi@mediatek.com>
Old sequence:
1. Pull the MIPI signal high
2. Delay & Dsi_reset
3. Set the dsi timing register
4. dsi clk & lanes leave ulp mode and enter hs mode
The sequence after patching is:
1. Set the dsi timing register
2. Pull the MIPI signal high
3. Delay & Dsi_reset
4. dsi clk & lanes leave ulp mode and enter hs mode
Fixes: 75374fc2c152 ("drm/mediatek: add dphy reset after setting lanes number")
Signed-off-by: Jitao Shi <jitao.shi@mediatek.com>
Signed-off-by: Xinlei Lee <xinlei.lee@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
---
drivers/gpu/drm/mediatek/mtk_dsi.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index bd3f5b485085..02e31a7d9257 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -661,14 +661,14 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
mtk_dsi_reset_engine(dsi);
mtk_dsi_phy_timconfig(dsi);
- mtk_dsi_rxtx_control(dsi);
- usleep_range(30, 100);
- mtk_dsi_reset_dphy(dsi);
mtk_dsi_ps_control_vact(dsi);
mtk_dsi_set_vm_cmd(dsi);
mtk_dsi_config_vdo_timing(dsi);
mtk_dsi_set_interrupt_enable(dsi);
+ mtk_dsi_rxtx_control(dsi);
+ usleep_range(30, 100);
+ mtk_dsi_reset_dphy(dsi);
mtk_dsi_clk_ulp_mode_leave(dsi);
mtk_dsi_lane0_ulp_mode_leave(dsi);
mtk_dsi_clk_hs_mode(dsi, 0);
--
2.18.0
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply related
* Re: [PATCH v4 0/3] dt-bindings: nvmem: mediatek: Convert efuse binding to YAML
From: allen-kh.cheng @ 2022-05-11 2:43 UTC (permalink / raw)
To: Srinivas Kandagatla, Matthias Brugger, Rob Herring,
Krzysztof Kozlowski
Cc: Lala Lin, Project_Global_Chrome_Upstream_Group, devicetree,
linux-arm-kernel, linux-kernel, linux-mediatek, Chen-Yu Tsai,
Allen-kh Cheng, Chunfeng Yun
In-Reply-To: <20220510132637.5864-1-allen-kh.cheng@mediatek.com>
Hi the reviewers,
Please ignore this PATCH series.
There is anther series for efuse yaml (
20220509014521.10248-1-chunfeng.yun@mediatek.com) by chunfeng.
We will integrate together and resend again.
I apologize for any inconvenience caused.
Best regard,
Allen
On Tue, 2022-05-10 at 21:26 +0800, Allen-KH Cheng wrote:
> From: Allen-kh Cheng <allen-kh.cheng@mediatek.corp-partner.google.com
> >
>
> Convert MediaTek eFuse devicetree binding to YAML.
>
> Based on tag: next-20220510, linux-next/master
>
> Run cmds as following:
> make DT_CHECKER_FLAGS=-m dt_binding_check
> DT_SCHEMA_FILES=Documentation/devicetree/bindings/nvmem/mediatek,efus
> e.yaml
>
> make ARCH=arm64
> dtbs_check
> DT_SCHEMA_FILES=Documentation/devicetree/bindings/nvmem/mediatek,efus
> e.yaml
>
> We mark the mediatek,mt8173-efuse and mediatek,efuse as deprecated to
> indicate
> not use a signle compatible and should always use mediatek,efuse as
> generic
> fallback.
>
> change since v3:
> - use mediatek as vendor name instead of mtk
>
> changes since v2:
> - document deprecated efuse property
> - update efuse compatible fallbacks
> - add two PATCHs into series
>
> changes since v1:
> - change file name from mtk,efuse-yaml to mtk,efuse.yaml
> - add efuse in commit title
> - change compatible entries from const to enum
>
> Allen-KH Cheng (2):
> dt-bindings: nvmem: mediatek: Convert efuse binding to YAML
> arm64: dts: mediatek: update efuse compatible fallbacks
>
> Allen-kh Cheng (1):
> dt-bindings: nvmem: mediatek: document deprecated efuse property
>
> .../bindings/nvmem/mediatek,efuse.yaml | 60
> +++++++++++++++++++
> .../devicetree/bindings/nvmem/mtk-efuse.txt | 43 -------------
> arch/arm64/boot/dts/mediatek/mt8173.dtsi | 3 +-
> arch/arm64/boot/dts/mediatek/mt8192.dtsi | 3 +-
> 4 files changed, 64 insertions(+), 45 deletions(-)
> create mode 100644
> Documentation/devicetree/bindings/nvmem/mediatek,efuse.yaml
> delete mode 100644 Documentation/devicetree/bindings/nvmem/mtk-
> efuse.txt
>
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply
* [PATCH v5, 4/5] drm/mediatek: keep dsi as LP00 before dcs cmds transfer
From: xinlei.lee @ 2022-05-11 2:36 UTC (permalink / raw)
To: chunkuang.hu, p.zabel, airlied, daniel, matthias.bgg
Cc: dri-devel, linux-mediatek, linux-arm-kernel, linux-kernel,
Project_Global_Chrome_Upstream_Group, rex-bc.chen, jitao.shi,
Xinlei Lee
In-Reply-To: <1652236596-21648-1-git-send-email-xinlei.lee@mediatek.com>
From: Jitao Shi <jitao.shi@mediatek.com>
To comply with the panel sequence, hold the mipi signal to LP00 before the dcs cmds transmission,
and pull the mipi signal high from LP00 to LP11 until the start of the dcs cmds transmission.
The normal panel timing is :
(1) pp1800 DC pull up
(2) avdd & avee AC pull high
(3) lcm_reset pull high -> pull low -> pull high
(4) Pull MIPI signal high (LP11) -> initial code -> send video data(HS mode)
The power-off sequence is reversed.
If dsi is not in cmd mode, then dsi will pull the mipi signal high in the mtk_output_dsi_enable function.
The delay in lane_ready func is the reaction time of dsi_rx after pulling up the mipi signal.
Fixes: 2dd8075d2185 ("drm/mediatek: mtk_dsi: Use the drm_panel_bridge API")
Signed-off-by: Jitao Shi <jitao.shi@mediatek.com>
Signed-off-by: Xinlei Lee <xinlei.lee@mediatek.com>
---
drivers/gpu/drm/mediatek/mtk_dsi.c | 29 ++++++++++++++++++++++-------
1 file changed, 22 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 2dee6632a541..98b7811502e7 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -203,6 +203,7 @@ struct mtk_dsi {
struct mtk_phy_timing phy_timing;
int refcount;
bool enabled;
+ bool lanes_ready;
u32 irq_data;
wait_queue_head_t irq_wait_queue;
const struct mtk_dsi_driver_data *driver_data;
@@ -666,13 +667,6 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
mtk_dsi_config_vdo_timing(dsi);
mtk_dsi_set_interrupt_enable(dsi);
- mtk_dsi_rxtx_control(dsi);
- usleep_range(30, 100);
- mtk_dsi_reset_dphy(dsi);
- mtk_dsi_clk_ulp_mode_leave(dsi);
- mtk_dsi_lane0_ulp_mode_leave(dsi);
- mtk_dsi_clk_hs_mode(dsi, 0);
-
return 0;
err_disable_engine_clk:
clk_disable_unprepare(dsi->engine_clk);
@@ -701,6 +695,24 @@ static void mtk_dsi_poweroff(struct mtk_dsi *dsi)
clk_disable_unprepare(dsi->digital_clk);
phy_power_off(dsi->phy);
+
+ dsi->lanes_ready = false;
+
+}
+
+static void mtk_dsi_lane_ready(struct mtk_dsi *dsi)
+{
+ if (!dsi->lanes_ready) {
+ dsi->lanes_ready = true;
+ mtk_dsi_rxtx_control(dsi);
+ usleep_range(30, 100);
+ mtk_dsi_reset_dphy(dsi);
+ mtk_dsi_clk_ulp_mode_leave(dsi);
+ mtk_dsi_lane0_ulp_mode_leave(dsi);
+ mtk_dsi_clk_hs_mode(dsi, 0);
+ msleep(20);
+ /* The reaction time after pulling up the mipi signal for dsi_rx */
+ }
}
static void mtk_output_dsi_enable(struct mtk_dsi *dsi)
@@ -708,6 +720,7 @@ static void mtk_output_dsi_enable(struct mtk_dsi *dsi)
if (dsi->enabled)
return;
+ mtk_dsi_lane_ready(dsi);
mtk_dsi_set_mode(dsi);
mtk_dsi_clk_hs_mode(dsi, 1);
@@ -1017,6 +1030,8 @@ static ssize_t mtk_dsi_host_transfer(struct mipi_dsi_host *host,
if (MTK_DSI_HOST_IS_READ(msg->type))
irq_flag |= LPRX_RD_RDY_INT_FLAG;
+ mtk_dsi_lane_ready(dsi);
+
ret = mtk_dsi_host_send_cmd(dsi, msg, irq_flag);
if (ret)
goto restore_dsi_mode;
--
2.18.0
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply related
* [PATCH v5, 3/5] drm/mediatek: Separate poweron/poweroff from enable/disable and define new funcs
From: xinlei.lee @ 2022-05-11 2:36 UTC (permalink / raw)
To: chunkuang.hu, p.zabel, airlied, daniel, matthias.bgg
Cc: dri-devel, linux-mediatek, linux-arm-kernel, linux-kernel,
Project_Global_Chrome_Upstream_Group, rex-bc.chen, jitao.shi,
Xinlei Lee
In-Reply-To: <1652236596-21648-1-git-send-email-xinlei.lee@mediatek.com>
From: Jitao Shi <jitao.shi@mediatek.com>
In order to match the changes of "Use the drm_panel_bridge API",
the poweron/poweroff of dsi is extracted from enable/disable and
defined as new funcs (atomic_pre_enable/atomic_post_disable).
Fixes: 2dd8075d2185 ("drm/mediatek: mtk_dsi: Use the drm_panel_bridge API")
Signed-off-by: Jitao Shi <jitao.shi@mediatek.com>
Signed-off-by: Xinlei Lee <xinlei.lee@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
---
drivers/gpu/drm/mediatek/mtk_dsi.c | 53 +++++++++++++++++++-----------
1 file changed, 34 insertions(+), 19 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 82a811801c9f..2dee6632a541 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -691,16 +691,6 @@ static void mtk_dsi_poweroff(struct mtk_dsi *dsi)
if (--dsi->refcount != 0)
return;
- /*
- * mtk_dsi_stop() and mtk_dsi_start() is asymmetric, since
- * mtk_dsi_stop() should be called after mtk_drm_crtc_atomic_disable(),
- * which needs irq for vblank, and mtk_dsi_stop() will disable irq.
- * mtk_dsi_start() needs to be called in mtk_output_dsi_enable(),
- * after dsi is fully set.
- */
- mtk_dsi_stop(dsi);
-
- mtk_dsi_switch_to_cmd_mode(dsi, VM_DONE_INT_FLAG, 500);
mtk_dsi_reset_engine(dsi);
mtk_dsi_lane0_ulp_mode_enter(dsi);
mtk_dsi_clk_ulp_mode_enter(dsi);
@@ -715,17 +705,9 @@ static void mtk_dsi_poweroff(struct mtk_dsi *dsi)
static void mtk_output_dsi_enable(struct mtk_dsi *dsi)
{
- int ret;
-
if (dsi->enabled)
return;
- ret = mtk_dsi_poweron(dsi);
- if (ret < 0) {
- DRM_ERROR("failed to power on dsi\n");
- return;
- }
-
mtk_dsi_set_mode(dsi);
mtk_dsi_clk_hs_mode(dsi, 1);
@@ -739,7 +721,16 @@ static void mtk_output_dsi_disable(struct mtk_dsi *dsi)
if (!dsi->enabled)
return;
- mtk_dsi_poweroff(dsi);
+ /*
+ * mtk_dsi_stop() and mtk_dsi_start() is asymmetric, since
+ * mtk_dsi_stop() should be called after mtk_drm_crtc_atomic_disable(),
+ * which needs irq for vblank, and mtk_dsi_stop() will disable irq.
+ * mtk_dsi_start() needs to be called in mtk_output_dsi_enable(),
+ * after dsi is fully set.
+ */
+ mtk_dsi_stop(dsi);
+
+ mtk_dsi_switch_to_cmd_mode(dsi, VM_DONE_INT_FLAG, 500);
dsi->enabled = false;
}
@@ -776,13 +767,37 @@ static void mtk_dsi_bridge_atomic_enable(struct drm_bridge *bridge,
{
struct mtk_dsi *dsi = bridge_to_dsi(bridge);
+ if (dsi->refcount == 0)
+ return;
+
mtk_output_dsi_enable(dsi);
}
+static void mtk_dsi_bridge_atomic_pre_enable(struct drm_bridge *bridge,
+ struct drm_bridge_state *old_bridge_state)
+{
+ struct mtk_dsi *dsi = bridge_to_dsi(bridge);
+ int ret;
+
+ ret = mtk_dsi_poweron(dsi);
+ if (ret < 0)
+ DRM_ERROR("failed to power on dsi\n");
+}
+
+static void mtk_dsi_bridge_atomic_post_disable(struct drm_bridge *bridge,
+ struct drm_bridge_state *old_bridge_state)
+{
+ struct mtk_dsi *dsi = bridge_to_dsi(bridge);
+
+ mtk_dsi_poweroff(dsi);
+}
+
static const struct drm_bridge_funcs mtk_dsi_bridge_funcs = {
.attach = mtk_dsi_bridge_attach,
.atomic_disable = mtk_dsi_bridge_atomic_disable,
.atomic_enable = mtk_dsi_bridge_atomic_enable,
+ .atomic_pre_enable = mtk_dsi_bridge_atomic_pre_enable,
+ .atomic_post_disable = mtk_dsi_bridge_atomic_post_disable,
.mode_set = mtk_dsi_bridge_mode_set,
};
--
2.18.0
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply related
* [PATCH] net: ethernet: mediatek: ppe: fix wrong size passed to memset()
From: Yang Yingliang @ 2022-05-11 3:08 UTC (permalink / raw)
To: linux-kernel, linux-mediatek, linux-arm-kernel, netdev; +Cc: nbd, davem, kuba
'foe_table' is a pointer, the real size of struct mtk_foe_entry
should be pass to memset().
Fixes: ba37b7caf1ed ("net: ethernet: mtk_eth_soc: add support for initializing the PPE")
Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
---
drivers/net/ethernet/mediatek/mtk_ppe.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.c b/drivers/net/ethernet/mediatek/mtk_ppe.c
index 3ad10c793308..66298e2235c9 100644
--- a/drivers/net/ethernet/mediatek/mtk_ppe.c
+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
@@ -395,7 +395,7 @@ static void mtk_ppe_init_foe_table(struct mtk_ppe *ppe)
static const u8 skip[] = { 12, 25, 38, 51, 76, 89, 102 };
int i, k;
- memset(ppe->foe_table, 0, MTK_PPE_ENTRIES * sizeof(ppe->foe_table));
+ memset(ppe->foe_table, 0, MTK_PPE_ENTRIES * sizeof(*ppe->foe_table));
if (!IS_ENABLED(CONFIG_SOC_MT7621))
return;
--
2.25.1
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply related
* Re: [PATCH v2] cpufreq: mediatek: Fix potential deadlock problem in mtk_cpufreq_set_target
From: Viresh Kumar @ 2022-05-11 3:11 UTC (permalink / raw)
To: Rex-BC Chen
Cc: Jiabing Wan, Rafael J. Wysocki, Matthias Brugger,
AngeloGioacchino Del Regno, Jia-Wei Chang, Andrew-sh.Cheng,
linux-pm, linux-kernel, linux-arm-kernel, linux-mediatek
In-Reply-To: <0181c505dd94c599b270f159ca93442a4afe1760.camel@mediatek.com>
On 10-05-22, 19:23, Rex-BC Chen wrote:
> I am not sure what's the problem.
> But I subscribed the linux-arm-kernel mailing list and linux-mediatek.
>
> As for LKML, do you mean subscribe "List: linux-kernel;" in [1]?
Yes, this is one of the most useful email lists and mostly gets cc'd anyway, you
can disable mail delivery if you don't want to get emails.
I asked because I couldn't find your email in https://lore.kernel.org/lkml, but
its fine either way.
--
viresh
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply
* Re: [PATCH v2] cpufreq: mediatek: Fix potential deadlock problem in mtk_cpufreq_set_target
From: Rex-BC Chen @ 2022-05-11 3:23 UTC (permalink / raw)
To: Viresh Kumar
Cc: Jiabing Wan, Rafael J. Wysocki, Matthias Brugger,
AngeloGioacchino Del Regno, Jia-Wei Chang, Andrew-sh.Cheng,
linux-pm, linux-kernel, linux-arm-kernel, linux-mediatek
In-Reply-To: <20220511031122.kkotwq7co2vx5zqp@vireshk-i7>
On Wed, 2022-05-11 at 08:41 +0530, Viresh Kumar wrote:
> On 10-05-22, 19:23, Rex-BC Chen wrote:
> > I am not sure what's the problem.
> > But I subscribed the linux-arm-kernel mailing list and linux-
> > mediatek.
> >
> > As for LKML, do you mean subscribe "List: linux-kernel;" in [1]?
>
> Yes, this is one of the most useful email lists and mostly gets cc'd
> anyway, you
> can disable mail delivery if you don't want to get emails.
>
> I asked because I couldn't find your email in
> https://lore.kernel.org/lkml, but
> its fine either way.
>
Hello Viresh,
thanks for your suggestion.
I will try to subscribe this.
BRs,
Rex
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply
* Re: [PATCH v8 2/2] phy: mediatek: Add PCIe PHY driver
From: Rex-BC Chen @ 2022-05-11 3:22 UTC (permalink / raw)
To: Jianjun Wang, Chunfeng Yun, Kishon Vijay Abraham I, Vinod Koul,
Rob Herring, Matthias Brugger, Chen-Yu Tsai,
AngeloGioacchino Del Regno, Krzysztof Kozlowski
Cc: Wei-Shun Chang, linux-arm-kernel, linux-mediatek, linux-phy,
devicetree, linux-kernel, randy.wu, jieyy.yang, chuanjia.liu,
qizhong.cheng, jian.yang
In-Reply-To: <20220507060621.32252-3-jianjun.wang@mediatek.com>
On Sat, 2022-05-07 at 14:06 +0800, Jianjun Wang wrote:
> Add PCIe GEN3 PHY driver support on MediaTek chipsets.
>
> Signed-off-by: Jianjun Wang <jianjun.wang@mediatek.com>
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno@collabora.com>
> ---
> drivers/phy/mediatek/Kconfig | 11 ++
> drivers/phy/mediatek/Makefile | 1 +
> drivers/phy/mediatek/phy-mtk-pcie.c | 267
> ++++++++++++++++++++++++++++
> 3 files changed, 279 insertions(+)
> create mode 100644 drivers/phy/mediatek/phy-mtk-pcie.c
>
> diff --git a/drivers/phy/mediatek/Kconfig
> b/drivers/phy/mediatek/Kconfig
> index 55f8e6c048ab..387ed1b3f2cc 100644
> --- a/drivers/phy/mediatek/Kconfig
> +++ b/drivers/phy/mediatek/Kconfig
> @@ -55,3 +55,14 @@ config PHY_MTK_MIPI_DSI
> select GENERIC_PHY
> help
> Support MIPI DSI for Mediatek SoCs.
> +
> +config PHY_MTK_PCIE
> + tristate "MediaTek PCIe-PHY Driver"
> + depends on ARCH_MEDIATEK || COMPILE_TEST
> + depends on OF
> + select GENERIC_PHY
> + help
> + Say 'Y' here to add support for MediaTek PCIe PHY driver.
> + This driver create the basic PHY instance and provides
> initialize
> + callback for PCIe GEN3 port, it supports software efuse
> + initialization.
> diff --git a/drivers/phy/mediatek/Makefile
> b/drivers/phy/mediatek/Makefile
> index ace660fbed3a..788c13147f63 100644
> --- a/drivers/phy/mediatek/Makefile
> +++ b/drivers/phy/mediatek/Makefile
> @@ -6,6 +6,7 @@
> obj-$(CONFIG_PHY_MTK_TPHY) += phy-mtk-tphy.o
> obj-$(CONFIG_PHY_MTK_UFS) += phy-mtk-ufs.o
> obj-$(CONFIG_PHY_MTK_XSPHY) += phy-mtk-xsphy.o
> +obj-$(CONFIG_PHY_MTK_PCIE) += phy-mtk-pcie.o
>
> phy-mtk-hdmi-drv-y := phy-mtk-hdmi.o
> phy-mtk-hdmi-drv-y += phy-mtk-hdmi-mt2701.o
> diff --git a/drivers/phy/mediatek/phy-mtk-pcie.c
> b/drivers/phy/mediatek/phy-mtk-pcie.c
> new file mode 100644
> index 000000000000..e4bcf1e9941c
> --- /dev/null
> +++ b/drivers/phy/mediatek/phy-mtk-pcie.c
> @@ -0,0 +1,267 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2022 MediaTek Inc.
> + * Author: Jianjun Wang <jianjun.wang@mediatek.com>
> + */
> +
> +#include <linux/bitfield.h>
> +#include <linux/module.h>
> +#include <linux/nvmem-consumer.h>
> +#include <linux/of_device.h>
> +#include <linux/phy/phy.h>
> +#include <linux/platform_device.h>
> +#include <linux/slab.h>
> +
> +#include "phy-mtk-io.h"
> +
> +#define PEXTP_ANA_GLB_00_REG 0x9000
> +/* Internal Resistor Selection of TX Bias Current */
> +#define EFUSE_GLB_INTR_SEL GENMASK(28, 24)
> +
> +#define PEXTP_ANA_LN0_TRX_REG 0xa000
> +
> +#define PEXTP_ANA_TX_REG 0x04
> +/* TX PMOS impedance selection */
> +#define EFUSE_LN_TX_PMOS_SEL GENMASK(5, 2)
> +/* TX NMOS impedance selection */
> +#define EFUSE_LN_TX_NMOS_SEL GENMASK(11, 8)
> +
> +#define PEXTP_ANA_RX_REG 0x3c
> +/* RX impedance selection */
> +#define EFUSE_LN_RX_SEL GENMASK(3, 0)
> +
> +#define PEXTP_ANA_LANE_OFFSET 0x100
> +
> +/**
> + * struct mtk_pcie_lane_efuse - eFuse data for each lane
> + * @tx_pmos: TX PMOS impedance selection data
> + * @tx_nmos: TX NMOS impedance selection data
> + * @rx_data: RX impedance selection data
> + * @lane_efuse_supported: software eFuse data is supported for this
> lane
> + */
> +struct mtk_pcie_lane_efuse {
> + u32 tx_pmos;
> + u32 tx_nmos;
> + u32 rx_data;
> + bool lane_efuse_supported;
> +};
> +
> +/**
> + * struct mtk_pcie_phy_data - phy data for each SoC
> + * @num_lanes: supported lane numbers
> + * @sw_efuse_supported: support software to load eFuse data
> + */
> +struct mtk_pcie_phy_data {
> + int num_lanes;
> + bool sw_efuse_supported;
> +};
> +
> +/**
> + * struct mtk_pcie_phy - PCIe phy driver main structure
> + * @dev: pointer to device
> + * @phy: pointer to generic phy
> + * @sif_base: IO mapped register base address of system interface
> + * @data: pointer to SoC dependent data
> + * @sw_efuse_en: software eFuse enable status
> + * @efuse_glb_intr: internal resistor selection of TX bias current
> data
> + * @efuse: pointer to eFuse data for each lane
> + */
> +struct mtk_pcie_phy {
> + struct device *dev;
> + struct phy *phy;
> + void __iomem *sif_base;
> + const struct mtk_pcie_phy_data *data;
> +
> + bool sw_efuse_en;
> + u32 efuse_glb_intr;
> + struct mtk_pcie_lane_efuse *efuse;
> +};
> +
> +static void mtk_pcie_efuse_set_lane(struct mtk_pcie_phy *pcie_phy,
> + unsigned int lane)
> +{
> + struct mtk_pcie_lane_efuse *data = &pcie_phy->efuse[lane];
> + void __iomem *addr;
> +
> + if (!data->lane_efuse_supported)
> + return;
> +
> + addr = pcie_phy->sif_base + PEXTP_ANA_LN0_TRX_REG +
> + lane * PEXTP_ANA_LANE_OFFSET;
> +
> + mtk_phy_update_bits(addr + PEXTP_ANA_TX_REG,
> EFUSE_LN_TX_PMOS_SEL,
> + FIELD_PREP(EFUSE_LN_TX_PMOS_SEL, data-
> >tx_pmos));
> +
> + mtk_phy_update_bits(addr + PEXTP_ANA_TX_REG,
> EFUSE_LN_TX_NMOS_SEL,
> + FIELD_PREP(EFUSE_LN_TX_NMOS_SEL, data-
> >tx_nmos));
> +
> + mtk_phy_update_bits(addr + PEXTP_ANA_RX_REG, EFUSE_LN_RX_SEL,
> + FIELD_PREP(EFUSE_LN_RX_SEL, data-
> >rx_data));
> +}
> +
> +/**
> + * mtk_pcie_phy_init() - Initialize the phy
> + * @phy: the phy to be initialized
> + *
> + * Initialize the phy by setting the efuse data.
> + * The hardware settings will be reset during suspend, it should be
> + * reinitialized when the consumer calls phy_init() again on resume.
> + */
> +static int mtk_pcie_phy_init(struct phy *phy)
> +{
> + struct mtk_pcie_phy *pcie_phy = phy_get_drvdata(phy);
> + int i;
> +
> + if (!pcie_phy->sw_efuse_en)
> + return 0;
> +
> + /* Set global data */
> + mtk_phy_update_bits(pcie_phy->sif_base + PEXTP_ANA_GLB_00_REG,
> + EFUSE_GLB_INTR_SEL,
> + FIELD_PREP(EFUSE_GLB_INTR_SEL, pcie_phy-
> >efuse_glb_intr));
> +
> + for (i = 0; i < pcie_phy->data->num_lanes; i++)
> + mtk_pcie_efuse_set_lane(pcie_phy, i);
> +
> + return 0;
> +}
> +
> +static const struct phy_ops mtk_pcie_phy_ops = {
> + .init = mtk_pcie_phy_init,
> + .owner = THIS_MODULE,
> +};
> +
> +static int mtk_pcie_efuse_read_for_lane(struct mtk_pcie_phy
> *pcie_phy,
> + unsigned int lane)
> +{
> + struct mtk_pcie_lane_efuse *efuse = &pcie_phy->efuse[lane];
> + struct device *dev = pcie_phy->dev;
> + char efuse_id[16];
> + int ret;
> +
> + snprintf(efuse_id, sizeof(efuse_id), "tx_ln%d_pmos", lane);
> + ret = nvmem_cell_read_variable_le_u32(dev, efuse_id, &efuse-
> >tx_pmos);
> + if (ret)
> + return dev_err_probe(dev, ret, "Failed to read %s\n",
> efuse_id);
> +
> + snprintf(efuse_id, sizeof(efuse_id), "tx_ln%d_nmos", lane);
> + ret = nvmem_cell_read_variable_le_u32(dev, efuse_id, &efuse-
> >tx_nmos);
> + if (ret)
> + return dev_err_probe(dev, ret, "Failed to read %s\n",
> efuse_id);
> +
> + snprintf(efuse_id, sizeof(efuse_id), "rx_ln%d", lane);
> + ret = nvmem_cell_read_variable_le_u32(dev, efuse_id, &efuse-
> >rx_data);
> + if (ret)
> + return dev_err_probe(dev, ret, "Failed to read %s\n",
> efuse_id);
> +
> + if (!(efuse->tx_pmos || efuse->tx_nmos || efuse->rx_data))
> + return dev_err_probe(dev, -EINVAL,
> + "No eFuse data found for lane%d,
> but dts enable it\n",
> + lane);
> +
> + efuse->lane_efuse_supported = true;
> +
> + return 0;
> +}
> +
> +static int mtk_pcie_read_efuse(struct mtk_pcie_phy *pcie_phy)
> +{
> + struct device *dev = pcie_phy->dev;
> + bool nvmem_enabled;
> + int ret, i;
> +
> + /* nvmem data is optional */
> + nvmem_enabled = device_property_present(dev, "nvmem-cells");
> + if (!nvmem_enabled)
> + return 0;
> +
> + ret = nvmem_cell_read_variable_le_u32(dev, "glb_intr",
> + &pcie_phy-
> >efuse_glb_intr);
> + if (ret)
> + return dev_err_probe(dev, ret, "Failed to read
> glb_intr\n");
> +
> + pcie_phy->sw_efuse_en = true;
> +
> + pcie_phy->efuse = devm_kzalloc(dev, pcie_phy->data->num_lanes *
> + sizeof(*pcie_phy->efuse),
> GFP_KERNEL);
> + if (!pcie_phy->efuse)
> + return -ENOMEM;
> +
> + for (i = 0; i < pcie_phy->data->num_lanes; i++) {
> + ret = mtk_pcie_efuse_read_for_lane(pcie_phy, i);
> + if (ret)
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +static int mtk_pcie_phy_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct phy_provider *provider;
> + struct mtk_pcie_phy *pcie_phy;
> + int ret;
> +
> + pcie_phy = devm_kzalloc(dev, sizeof(*pcie_phy), GFP_KERNEL);
> + if (!pcie_phy)
> + return -ENOMEM;
> +
> + pcie_phy->sif_base =
> devm_platform_ioremap_resource_byname(pdev, "sif");
> + if (IS_ERR(pcie_phy->sif_base))
> + return dev_err_probe(dev, PTR_ERR(pcie_phy->sif_base),
> + "Failed to map phy-sif base\n");
> +
> + pcie_phy->phy = devm_phy_create(dev, dev->of_node,
> &mtk_pcie_phy_ops);
> + if (IS_ERR(pcie_phy->phy))
> + return dev_err_probe(dev, PTR_ERR(pcie_phy->phy),
> + "Failed to create PCIe phy\n");
> +
> + pcie_phy->dev = dev;
> + pcie_phy->data = of_device_get_match_data(dev);
> + if (!pcie_phy->data)
> + return dev_err_probe(dev, -EINVAL, "Failed to get phy
> data\n");
> +
> + if (pcie_phy->data->sw_efuse_supported) {
> + /*
> + * Failed to read the efuse data is not a fatal
> problem,
> + * ignore the failure and keep going.
> + */
> + ret = mtk_pcie_read_efuse(pcie_phy);
> + if (ret == -EPROBE_DEFER)
> + return ret;
Hello Jianjun,
even though it's not a fatal problem if we can not read efuse, but I
tink "ret = -ENOMEM" does not mean we can't read it?
Do we need to handle this?
BRs,
Rex
> + }
> +
> + phy_set_drvdata(pcie_phy->phy, pcie_phy);
> +
> + provider = devm_of_phy_provider_register(dev,
> of_phy_simple_xlate);
> + if (IS_ERR(provider))
> + return dev_err_probe(dev, PTR_ERR(provider),
> + "PCIe phy probe failed\n");
> +
> + return 0;
> +}
> +
> +static const struct mtk_pcie_phy_data mt8195_data = {
> + .num_lanes = 2,
> + .sw_efuse_supported = true,
> +};
> +
> +static const struct of_device_id mtk_pcie_phy_of_match[] = {
> + { .compatible = "mediatek,mt8195-pcie-phy", .data =
> &mt8195_data },
> + { },
> +};
> +MODULE_DEVICE_TABLE(of, mtk_pcie_phy_of_match);
> +
> +static struct platform_driver mtk_pcie_phy_driver = {
> + .probe = mtk_pcie_phy_probe,
> + .driver = {
> + .name = "mtk-pcie-phy",
> + .of_match_table = mtk_pcie_phy_of_match,
> + },
> +};
> +module_platform_driver(mtk_pcie_phy_driver);
> +
> +MODULE_DESCRIPTION("MediaTek PCIe PHY driver");
> +MODULE_AUTHOR("Jianjun Wang <jianjun.wang@mediatek.com>");
> +MODULE_LICENSE("GPL");
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply
* [PATCH v8 0/3] firmware: mtk: add adsp ipc protocol for SOF
From: Tinghan Shen @ 2022-05-11 4:27 UTC (permalink / raw)
To: Matthias Brugger, Pierre-Louis Bossart, Liam Girdwood,
Ranjani Sridharan, Kai Vehmanen, Daniel Baluta, Mark Brown,
Jaroslav Kysela, Takashi Iwai, Javier Martinez Canillas,
Thomas Zimmermann, Daniel Vetter, Bjorn Andersson, Sudeep Holla,
Michal Suchanek, Shuai Xue, Simon Trimmer, Cristian Marussi,
TingHan Shen, Arnd Bergmann, Borislav Petkov, Greg Kroah-Hartman,
John Stultz, Curtis Malainey, AngeloGioacchino Del Regno,
Allen-KH Cheng, YC Hung, Tzung-Bi Shih, Yang Yingliang,
Geert Uytterhoeven, Péter Ujfalusi
Cc: linux-kernel, linux-arm-kernel, linux-mediatek,
sound-open-firmware, alsa-devel,
Project_Global_Chrome_Upstream_Group
This patch provides mediatek adsp ipc support for SOF.
ADSP IPC protocol offers (send/recv) interfaces using
mediatek-mailbox APIs.
This patch was tested and confirmed to work with SOF fw on
MT8195 cherry board and MT8186 krabby board.
changes since v7:
- rebase to linux-next/next-22020504
- use EXPORT_SYMBOL_GPL instead of EXPORT_SYMBOL in mtk-adsp-ipc.c
- move mtk-adsp-ipc.c out from driver/firmware/mediatek
- add user of mtk-adsp-ipc.h in patchset 2 and 3.
changes since v6:
- rebase to matthias.bgg/linux.git, v5.18-next/soc
- Prefer "GPL" over "GPL v2" for MODULE_LICENSE
changes since v5:
- fix WARNING: modpost: missing MODULE_LICENSE() in drivers/mailbox
/mtk-adsp-mailbox.o. Add MODULE_LICENSE in the last line.
- Due to WARNING: Missing or malformed SPDX-License-Identifier tag
in line 1 in checkpatch, we don't remove SPDX-License in line 1.
changes since v4:
- add error message for wrong mbox chan
changes since v3:
- rebase on v5.16-rc8
- update reviewers
changes since v2:
- add out tag for two memory free phases
changes since v1:
- add comments for mtk_adsp_ipc_send and mtk_adsp_ipc_recv
- remove useless MODULE_LICENSE
- change label name to out_free
Allen-KH Cheng (1):
ASoC: SOF: mediatek: Add ipc support for mt8195
TingHan Shen (1):
firmware: mediatek: add adsp ipc protocol interface
Tinghan Shen (1):
ASoC: SOF: mediatek: Add mt8186 ipc support
drivers/firmware/Kconfig | 9 +
drivers/firmware/Makefile | 1 +
drivers/firmware/mtk-adsp-ipc.c | 157 ++++++++++++++++++
.../linux/firmware/mediatek/mtk-adsp-ipc.h | 65 ++++++++
sound/soc/sof/mediatek/Kconfig | 1 +
sound/soc/sof/mediatek/adsp_helper.h | 12 +-
sound/soc/sof/mediatek/mt8186/mt8186-loader.c | 5 +
sound/soc/sof/mediatek/mt8186/mt8186.c | 141 ++++++++++++++++
sound/soc/sof/mediatek/mt8195/mt8195.c | 138 ++++++++++++++-
9 files changed, 518 insertions(+), 11 deletions(-)
create mode 100644 drivers/firmware/mtk-adsp-ipc.c
create mode 100644 include/linux/firmware/mediatek/mtk-adsp-ipc.h
--
2.18.0
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply
* [PATCH v8 1/3] firmware: mediatek: add adsp ipc protocol interface
From: Tinghan Shen @ 2022-05-11 4:27 UTC (permalink / raw)
To: Matthias Brugger, Pierre-Louis Bossart, Liam Girdwood,
Ranjani Sridharan, Kai Vehmanen, Daniel Baluta, Mark Brown,
Jaroslav Kysela, Takashi Iwai, Javier Martinez Canillas,
Thomas Zimmermann, Daniel Vetter, Bjorn Andersson, Sudeep Holla,
Michal Suchanek, Shuai Xue, Simon Trimmer, Cristian Marussi,
TingHan Shen, Arnd Bergmann, Borislav Petkov, Greg Kroah-Hartman,
John Stultz, Curtis Malainey, AngeloGioacchino Del Regno,
Allen-KH Cheng, YC Hung, Tzung-Bi Shih, Yang Yingliang,
Geert Uytterhoeven, Péter Ujfalusi
Cc: linux-kernel, linux-arm-kernel, linux-mediatek,
sound-open-firmware, alsa-devel,
Project_Global_Chrome_Upstream_Group
In-Reply-To: <20220511042718.4305-1-tinghan.shen@mediatek.com>
From: TingHan Shen <tinghan.shen@mediatek.com>
Some of mediatek processors contain
the Tensilica HiFix DSP for audio processing.
The communication between Host CPU and DSP firmware is
taking place using a shared memory area for message passing.
ADSP IPC protocol offers (send/recv) interfaces using
mediatek-mailbox APIs.
We use two mbox channels to implement a request-reply protocol.
Signed-off-by: Allen-KH Cheng <allen-kh.cheng@mediatek.com>
Signed-off-by: TingHan Shen <tinghan.shen@mediatek.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Curtis Malainey <cujomalainey@chromium.org>
Reviewed-by: Tzung-Bi Shih <tzungbi@google.com>
Reviewed-by: YC Hung <yc.hung@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
drivers/firmware/Kconfig | 9 +
drivers/firmware/Makefile | 1 +
drivers/firmware/mtk-adsp-ipc.c | 157 ++++++++++++++++++
.../linux/firmware/mediatek/mtk-adsp-ipc.h | 65 ++++++++
4 files changed, 232 insertions(+)
create mode 100644 drivers/firmware/mtk-adsp-ipc.c
create mode 100644 include/linux/firmware/mediatek/mtk-adsp-ipc.h
diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index d65964996e8d..b59e3041fd62 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -203,6 +203,15 @@ config INTEL_STRATIX10_RSU
Say Y here if you want Intel RSU support.
+config MTK_ADSP_IPC
+ tristate "MTK ADSP IPC Protocol driver"
+ depends on MTK_ADSP_MBOX
+ help
+ Say yes here to add support for the MediaTek ADSP IPC
+ between host AP (Linux) and the firmware running on ADSP.
+ ADSP exists on some mtk processors.
+ Client might use shared memory to exchange information with ADSP.
+
config QCOM_SCM
tristate
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index 4e58cb474a68..1be0e8295222 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_INTEL_STRATIX10_RSU) += stratix10-rsu.o
obj-$(CONFIG_ISCSI_IBFT_FIND) += iscsi_ibft_find.o
obj-$(CONFIG_ISCSI_IBFT) += iscsi_ibft.o
obj-$(CONFIG_FIRMWARE_MEMMAP) += memmap.o
+obj-$(CONFIG_MTK_ADSP_IPC) += mtk-adsp-ipc.o
obj-$(CONFIG_RASPBERRYPI_FIRMWARE) += raspberrypi.o
obj-$(CONFIG_FW_CFG_SYSFS) += qemu_fw_cfg.o
obj-$(CONFIG_QCOM_SCM) += qcom-scm.o
diff --git a/drivers/firmware/mtk-adsp-ipc.c b/drivers/firmware/mtk-adsp-ipc.c
new file mode 100644
index 000000000000..cb255a99170c
--- /dev/null
+++ b/drivers/firmware/mtk-adsp-ipc.c
@@ -0,0 +1,157 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Corporation. All rights reserved.
+ * Author: Allen-KH Cheng <allen-kh.cheng@mediatek.com>
+ */
+
+#include <linux/firmware/mediatek/mtk-adsp-ipc.h>
+#include <linux/kernel.h>
+#include <linux/mailbox_client.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+/*
+ * mtk_adsp_ipc_send - send ipc cmd to MTK ADSP
+ *
+ * @ipc: ADSP IPC handle
+ * @idx: index of the mailbox channel
+ * @msg: IPC cmd (reply or request)
+ *
+ * Returns zero for success from mbox_send_message
+ * negative value for error
+ */
+int mtk_adsp_ipc_send(struct mtk_adsp_ipc *ipc, unsigned int idx, uint32_t msg)
+{
+ struct mtk_adsp_chan *adsp_chan;
+ int ret;
+
+ if (idx >= MTK_ADSP_MBOX_NUM)
+ return -EINVAL;
+
+ adsp_chan = &ipc->chans[idx];
+ ret = mbox_send_message(adsp_chan->ch, &msg);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(mtk_adsp_ipc_send);
+
+/*
+ * mtk_adsp_ipc_recv - recv callback used by MTK ADSP mailbox
+ *
+ * @c: mbox client
+ * @msg: message received
+ *
+ * Users of ADSP IPC will need to privde handle_reply and handle_request
+ * callbacks.
+ */
+static void mtk_adsp_ipc_recv(struct mbox_client *c, void *msg)
+{
+ struct mtk_adsp_chan *chan = container_of(c, struct mtk_adsp_chan, cl);
+ struct device *dev = c->dev;
+
+ switch (chan->idx) {
+ case MTK_ADSP_MBOX_REPLY:
+ chan->ipc->ops->handle_reply(chan->ipc);
+ break;
+ case MTK_ADSP_MBOX_REQUEST:
+ chan->ipc->ops->handle_request(chan->ipc);
+ break;
+ default:
+ dev_err(dev, "wrong mbox chan %d\n", chan->idx);
+ break;
+ }
+}
+
+static int mtk_adsp_ipc_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct mtk_adsp_ipc *adsp_ipc;
+ struct mtk_adsp_chan *adsp_chan;
+ struct mbox_client *cl;
+ char *chan_name;
+ int ret;
+ int i, j;
+
+ device_set_of_node_from_dev(&pdev->dev, pdev->dev.parent);
+
+ adsp_ipc = devm_kzalloc(dev, sizeof(*adsp_ipc), GFP_KERNEL);
+ if (!adsp_ipc)
+ return -ENOMEM;
+
+ for (i = 0; i < MTK_ADSP_MBOX_NUM; i++) {
+ chan_name = kasprintf(GFP_KERNEL, "mbox%d", i);
+ if (!chan_name) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ adsp_chan = &adsp_ipc->chans[i];
+ cl = &adsp_chan->cl;
+ cl->dev = dev->parent;
+ cl->tx_block = false;
+ cl->knows_txdone = false;
+ cl->tx_prepare = NULL;
+ cl->rx_callback = mtk_adsp_ipc_recv;
+
+ adsp_chan->ipc = adsp_ipc;
+ adsp_chan->idx = i;
+ adsp_chan->ch = mbox_request_channel_byname(cl, chan_name);
+ if (IS_ERR(adsp_chan->ch)) {
+ ret = PTR_ERR(adsp_chan->ch);
+ if (ret != -EPROBE_DEFER)
+ dev_err(dev, "Failed to request mbox chan %d ret %d\n",
+ i, ret);
+ goto out_free;
+ }
+
+ dev_dbg(dev, "request mbox chan %s\n", chan_name);
+ kfree(chan_name);
+ }
+
+ adsp_ipc->dev = dev;
+ dev_set_drvdata(dev, adsp_ipc);
+ dev_dbg(dev, "MTK ADSP IPC initialized\n");
+
+ return 0;
+
+out_free:
+ kfree(chan_name);
+out:
+ for (j = 0; j < i; j++) {
+ adsp_chan = &adsp_ipc->chans[j];
+ mbox_free_channel(adsp_chan->ch);
+ }
+
+ return ret;
+}
+
+static int mtk_adsp_ipc_remove(struct platform_device *pdev)
+{
+ struct mtk_adsp_ipc *adsp_ipc = dev_get_drvdata(&pdev->dev);
+ struct mtk_adsp_chan *adsp_chan;
+ int i;
+
+ for (i = 0; i < MTK_ADSP_MBOX_NUM; i++) {
+ adsp_chan = &adsp_ipc->chans[i];
+ mbox_free_channel(adsp_chan->ch);
+ }
+
+ return 0;
+}
+
+static struct platform_driver mtk_adsp_ipc_driver = {
+ .driver = {
+ .name = "mtk-adsp-ipc",
+ },
+ .probe = mtk_adsp_ipc_probe,
+ .remove = mtk_adsp_ipc_remove,
+};
+builtin_platform_driver(mtk_adsp_ipc_driver);
+
+MODULE_AUTHOR("Allen-KH Cheng <allen-kh.cheng@mediatek.com>");
+MODULE_DESCRIPTION("MTK ADSP IPC Driver");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/firmware/mediatek/mtk-adsp-ipc.h b/include/linux/firmware/mediatek/mtk-adsp-ipc.h
new file mode 100644
index 000000000000..28fd313340b8
--- /dev/null
+++ b/include/linux/firmware/mediatek/mtk-adsp-ipc.h
@@ -0,0 +1,65 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ */
+
+#ifndef MTK_ADSP_IPC_H
+#define MTK_ADSP_IPC_H
+
+#include <linux/device.h>
+#include <linux/types.h>
+#include <linux/mailbox_controller.h>
+#include <linux/mailbox_client.h>
+
+#define MTK_ADSP_IPC_REQ 0
+#define MTK_ADSP_IPC_RSP 1
+#define MTK_ADSP_IPC_OP_REQ 0x1
+#define MTK_ADSP_IPC_OP_RSP 0x2
+
+enum {
+ MTK_ADSP_MBOX_REPLY,
+ MTK_ADSP_MBOX_REQUEST,
+ MTK_ADSP_MBOX_NUM,
+};
+
+struct mtk_adsp_ipc;
+
+struct mtk_adsp_ipc_ops {
+ void (*handle_reply)(struct mtk_adsp_ipc *ipc);
+ void (*handle_request)(struct mtk_adsp_ipc *ipc);
+};
+
+struct mtk_adsp_chan {
+ struct mtk_adsp_ipc *ipc;
+ struct mbox_client cl;
+ struct mbox_chan *ch;
+ char *name;
+ int idx;
+};
+
+struct mtk_adsp_ipc {
+ struct mtk_adsp_chan chans[MTK_ADSP_MBOX_NUM];
+ struct device *dev;
+ struct mtk_adsp_ipc_ops *ops;
+ void *private_data;
+};
+
+static inline void mtk_adsp_ipc_set_data(struct mtk_adsp_ipc *ipc, void *data)
+{
+ if (!ipc)
+ return;
+
+ ipc->private_data = data;
+}
+
+static inline void *mtk_adsp_ipc_get_data(struct mtk_adsp_ipc *ipc)
+{
+ if (!ipc)
+ return NULL;
+
+ return ipc->private_data;
+}
+
+int mtk_adsp_ipc_send(struct mtk_adsp_ipc *ipc, unsigned int idx, uint32_t op);
+
+#endif /* MTK_ADSP_IPC_H */
--
2.18.0
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply related
* [PATCH v8 3/3] ASoC: SOF: mediatek: Add mt8186 ipc support
From: Tinghan Shen @ 2022-05-11 4:27 UTC (permalink / raw)
To: Matthias Brugger, Pierre-Louis Bossart, Liam Girdwood,
Ranjani Sridharan, Kai Vehmanen, Daniel Baluta, Mark Brown,
Jaroslav Kysela, Takashi Iwai, Javier Martinez Canillas,
Thomas Zimmermann, Daniel Vetter, Bjorn Andersson, Sudeep Holla,
Michal Suchanek, Shuai Xue, Simon Trimmer, Cristian Marussi,
TingHan Shen, Arnd Bergmann, Borislav Petkov, Greg Kroah-Hartman,
John Stultz, Curtis Malainey, AngeloGioacchino Del Regno,
Allen-KH Cheng, YC Hung, Tzung-Bi Shih, Yang Yingliang,
Geert Uytterhoeven, Péter Ujfalusi
Cc: linux-kernel, linux-arm-kernel, linux-mediatek,
sound-open-firmware, alsa-devel,
Project_Global_Chrome_Upstream_Group, Allen-KH Cheng
In-Reply-To: <20220511042718.4305-1-tinghan.shen@mediatek.com>
mt8186 DSP uses two hardware mailbox IP to communicate with AP.
One mailbox is used for requests coming from AP, and the other
one is for requests from DSP.
Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng@mediatek.com>
Signed-off-by: Tinghan Shen <tinghan.shen@mediatek.com>
---
sound/soc/sof/mediatek/mt8186/mt8186-loader.c | 5 +
sound/soc/sof/mediatek/mt8186/mt8186.c | 141 ++++++++++++++++++
2 files changed, 146 insertions(+)
diff --git a/sound/soc/sof/mediatek/mt8186/mt8186-loader.c b/sound/soc/sof/mediatek/mt8186/mt8186-loader.c
index 548b12c33d8a..946e6c43204f 100644
--- a/sound/soc/sof/mediatek/mt8186/mt8186-loader.c
+++ b/sound/soc/sof/mediatek/mt8186/mt8186-loader.c
@@ -17,6 +17,11 @@ void mt8186_sof_hifixdsp_boot_sequence(struct snd_sof_dev *sdev, u32 boot_addr)
snd_sof_dsp_update_bits(sdev, DSP_REG_BAR, ADSP_HIFI_IO_CONFIG,
RUNSTALL, RUNSTALL);
+ /* enable mbox 0 & 1 IRQ */
+ snd_sof_dsp_update_bits(sdev, DSP_REG_BAR, ADSP_MBOX_IRQ_EN,
+ DSP_MBOX0_IRQ_EN | DSP_MBOX1_IRQ_EN,
+ DSP_MBOX0_IRQ_EN | DSP_MBOX1_IRQ_EN);
+
/* set core boot address */
snd_sof_dsp_write(sdev, DSP_SECREG_BAR, ADSP_ALTVEC_C0, boot_addr);
snd_sof_dsp_write(sdev, DSP_SECREG_BAR, ADSP_ALTVECSEL, ADSP_ALTVECSEL_C0);
diff --git a/sound/soc/sof/mediatek/mt8186/mt8186.c b/sound/soc/sof/mediatek/mt8186/mt8186.c
index 6d574fd4492e..3333a0634e29 100644
--- a/sound/soc/sof/mediatek/mt8186/mt8186.c
+++ b/sound/soc/sof/mediatek/mt8186/mt8186.c
@@ -27,6 +27,99 @@
#include "mt8186.h"
#include "mt8186-clk.h"
+static int mt8186_get_mailbox_offset(struct snd_sof_dev *sdev)
+{
+ return MBOX_OFFSET;
+}
+
+static int mt8186_get_window_offset(struct snd_sof_dev *sdev, u32 id)
+{
+ return MBOX_OFFSET;
+}
+
+static int mt8186_send_msg(struct snd_sof_dev *sdev,
+ struct snd_sof_ipc_msg *msg)
+{
+ struct adsp_priv *priv = sdev->pdata->hw_pdata;
+
+ sof_mailbox_write(sdev, sdev->host_box.offset, msg->msg_data,
+ msg->msg_size);
+
+ return mtk_adsp_ipc_send(priv->dsp_ipc, MTK_ADSP_IPC_REQ, MTK_ADSP_IPC_OP_REQ);
+}
+
+static void mt8186_get_reply(struct snd_sof_dev *sdev)
+{
+ struct snd_sof_ipc_msg *msg = sdev->msg;
+ struct sof_ipc_reply reply;
+ int ret = 0;
+
+ if (!msg) {
+ dev_warn(sdev->dev, "unexpected ipc interrupt\n");
+ return;
+ }
+
+ /* get reply */
+ sof_mailbox_read(sdev, sdev->host_box.offset, &reply, sizeof(reply));
+ if (reply.error < 0) {
+ memcpy(msg->reply_data, &reply, sizeof(reply));
+ ret = reply.error;
+ } else {
+ /* reply has correct size? */
+ if (reply.hdr.size != msg->reply_size) {
+ dev_err(sdev->dev, "error: reply expected %zu got %u bytes\n",
+ msg->reply_size, reply.hdr.size);
+ ret = -EINVAL;
+ }
+
+ /* read the message */
+ if (msg->reply_size > 0)
+ sof_mailbox_read(sdev, sdev->host_box.offset,
+ msg->reply_data, msg->reply_size);
+ }
+
+ msg->reply_error = ret;
+}
+
+static void mt8186_dsp_handle_reply(struct mtk_adsp_ipc *ipc)
+{
+ struct adsp_priv *priv = mtk_adsp_ipc_get_data(ipc);
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->sdev->ipc_lock, flags);
+ mt8186_get_reply(priv->sdev);
+ snd_sof_ipc_reply(priv->sdev, 0);
+ spin_unlock_irqrestore(&priv->sdev->ipc_lock, flags);
+}
+
+static void mt8186_dsp_handle_request(struct mtk_adsp_ipc *ipc)
+{
+ struct adsp_priv *priv = mtk_adsp_ipc_get_data(ipc);
+ u32 p; /* panic code */
+ int ret;
+
+ /* Read the message from the debug box. */
+ sof_mailbox_read(priv->sdev, priv->sdev->debug_box.offset + 4,
+ &p, sizeof(p));
+
+ /* Check to see if the message is a panic code 0x0dead*** */
+ if ((p & SOF_IPC_PANIC_MAGIC_MASK) == SOF_IPC_PANIC_MAGIC) {
+ snd_sof_dsp_panic(priv->sdev, p, true);
+ } else {
+ snd_sof_ipc_msgs_rx(priv->sdev);
+
+ /* tell DSP cmd is done */
+ ret = mtk_adsp_ipc_send(priv->dsp_ipc, MTK_ADSP_IPC_RSP, MTK_ADSP_IPC_OP_RSP);
+ if (ret)
+ dev_err(priv->dev, "request send ipc failed");
+ }
+}
+
+static struct mtk_adsp_ipc_ops dsp_ops = {
+ .handle_reply = mt8186_dsp_handle_reply,
+ .handle_request = mt8186_dsp_handle_request,
+};
+
static int platform_parse_resource(struct platform_device *pdev, void *data)
{
struct resource *mmio;
@@ -271,6 +364,9 @@ static int mt8186_dsp_probe(struct snd_sof_dev *sdev)
sdev->mmio_bar = SOF_FW_BLK_TYPE_SRAM;
sdev->mailbox_bar = SOF_FW_BLK_TYPE_SRAM;
+ /* set default mailbox offset for FW ready message */
+ sdev->dsp_box.offset = mt8186_get_mailbox_offset(sdev);
+
ret = adsp_memory_remap_init(sdev, priv->adsp);
if (ret) {
dev_err(sdev->dev, "adsp_memory_remap_init fail!\n");
@@ -292,11 +388,41 @@ static int mt8186_dsp_probe(struct snd_sof_dev *sdev)
adsp_sram_power_on(sdev);
+ priv->ipc_dev = platform_device_register_data(&pdev->dev, "mtk-adsp-ipc",
+ PLATFORM_DEVID_NONE,
+ pdev, sizeof(*pdev));
+ if (IS_ERR(priv->ipc_dev)) {
+ ret = IS_ERR(priv->ipc_dev);
+ dev_err(sdev->dev, "failed to create mtk-adsp-ipc device\n");
+ goto err_adsp_off;
+ }
+
+ priv->dsp_ipc = dev_get_drvdata(&priv->ipc_dev->dev);
+ if (!priv->dsp_ipc) {
+ ret = -EPROBE_DEFER;
+ dev_err(sdev->dev, "failed to get drvdata\n");
+ goto exit_pdev_unregister;
+ }
+
+ mtk_adsp_ipc_set_data(priv->dsp_ipc, priv);
+ priv->dsp_ipc->ops = &dsp_ops;
+
return 0;
+
+exit_pdev_unregister:
+ platform_device_unregister(priv->ipc_dev);
+err_adsp_off:
+ adsp_sram_power_off(sdev);
+ mt8186_adsp_clock_off(sdev);
+
+ return ret;
}
static int mt8186_dsp_remove(struct snd_sof_dev *sdev)
{
+ struct adsp_priv *priv = sdev->pdata->hw_pdata;
+
+ platform_device_unregister(priv->ipc_dev);
mt8186_sof_hifixdsp_shutdown(sdev);
adsp_sram_power_off(sdev);
mt8186_adsp_clock_off(sdev);
@@ -334,6 +460,14 @@ static int mt8186_get_bar_index(struct snd_sof_dev *sdev, u32 type)
return type;
}
+static int mt8186_ipc_msg_data(struct snd_sof_dev *sdev,
+ struct snd_pcm_substream *substream,
+ void *p, size_t sz)
+{
+ sof_mailbox_read(sdev, sdev->dsp_box.offset, p, sz);
+ return 0;
+}
+
/* mt8186 ops */
static struct snd_sof_dsp_ops sof_mt8186_ops = {
/* probe and remove */
@@ -353,6 +487,13 @@ static struct snd_sof_dsp_ops sof_mt8186_ops = {
.write64 = sof_io_write64,
.read64 = sof_io_read64,
+ /* ipc */
+ .send_msg = mt8186_send_msg,
+ .get_mailbox_offset = mt8186_get_mailbox_offset,
+ .get_window_offset = mt8186_get_window_offset,
+ .ipc_msg_data = mt8186_ipc_msg_data,
+ .set_stream_data_offset = sof_set_stream_data_offset,
+
/* misc */
.get_bar_index = mt8186_get_bar_index,
--
2.18.0
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply related
* [PATCH v8 2/3] ASoC: SOF: mediatek: Add ipc support for mt8195
From: Tinghan Shen @ 2022-05-11 4:27 UTC (permalink / raw)
To: Matthias Brugger, Pierre-Louis Bossart, Liam Girdwood,
Ranjani Sridharan, Kai Vehmanen, Daniel Baluta, Mark Brown,
Jaroslav Kysela, Takashi Iwai, Javier Martinez Canillas,
Thomas Zimmermann, Daniel Vetter, Bjorn Andersson, Sudeep Holla,
Michal Suchanek, Shuai Xue, Simon Trimmer, Cristian Marussi,
TingHan Shen, Arnd Bergmann, Borislav Petkov, Greg Kroah-Hartman,
John Stultz, Curtis Malainey, AngeloGioacchino Del Regno,
Allen-KH Cheng, YC Hung, Tzung-Bi Shih, Yang Yingliang,
Geert Uytterhoeven, Péter Ujfalusi
Cc: linux-kernel, linux-arm-kernel, linux-mediatek,
sound-open-firmware, alsa-devel,
Project_Global_Chrome_Upstream_Group, Allen-KH Cheng
In-Reply-To: <20220511042718.4305-1-tinghan.shen@mediatek.com>
From: Allen-KH Cheng <Allen-KH.Cheng@mediatek.com>
This patch adds mt8195 IPC support by using mailbox.
On mt8195 resource, there are two mboxes used to handle ipc request
and reply. We create a mtk-adsp-ipc client device to request mbox
controllers.
Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng@mediatek.com>
---
sound/soc/sof/mediatek/Kconfig | 1 +
sound/soc/sof/mediatek/adsp_helper.h | 12 +--
sound/soc/sof/mediatek/mt8195/mt8195.c | 138 ++++++++++++++++++++++++-
3 files changed, 140 insertions(+), 11 deletions(-)
diff --git a/sound/soc/sof/mediatek/Kconfig b/sound/soc/sof/mediatek/Kconfig
index f79e76a6f3c6..c3c99a248302 100644
--- a/sound/soc/sof/mediatek/Kconfig
+++ b/sound/soc/sof/mediatek/Kconfig
@@ -17,6 +17,7 @@ config SND_SOC_SOF_MTK_COMMON
select SND_SOC_SOF
select SND_SOC_SOF_XTENSA
select SND_SOC_SOF_COMPRESS
+ depends on MTK_ADSP_IPC
help
This option is not user-selectable but automagically handled by
'select' statements at a higher level
diff --git a/sound/soc/sof/mediatek/adsp_helper.h b/sound/soc/sof/mediatek/adsp_helper.h
index f269a2b6c26a..4ab998756bbc 100644
--- a/sound/soc/sof/mediatek/adsp_helper.h
+++ b/sound/soc/sof/mediatek/adsp_helper.h
@@ -7,24 +7,22 @@
#ifndef __MTK_ADSP_HELPER_H__
#define __MTK_ADSP_HELPER_H__
+#include <linux/firmware/mediatek/mtk-adsp-ipc.h>
+
/*
* Global important adsp data structure.
*/
-#define DSP_MBOX_NUM 3
-
struct mtk_adsp_chip_info {
phys_addr_t pa_sram;
phys_addr_t pa_dram; /* adsp dram physical base */
phys_addr_t pa_shared_dram; /* adsp dram physical base */
phys_addr_t pa_cfgreg;
- phys_addr_t pa_mboxreg[DSP_MBOX_NUM];
u32 sramsize;
u32 dramsize;
u32 cfgregsize;
void __iomem *va_sram; /* corresponding to pa_sram */
void __iomem *va_dram; /* corresponding to pa_dram */
void __iomem *va_cfgreg;
- void __iomem *va_mboxreg[DSP_MBOX_NUM];
void __iomem *shared_sram; /* part of va_sram */
void __iomem *shared_dram; /* part of va_dram */
phys_addr_t adsp_bootup_addr;
@@ -42,10 +40,8 @@ struct mtk_adsp_chip_info {
struct adsp_priv {
struct device *dev;
struct snd_sof_dev *sdev;
-
- /* DSP IPC handler */
- struct mbox_controller *adsp_mbox;
-
+ struct mtk_adsp_ipc *dsp_ipc;
+ struct platform_device *ipc_dev;
struct mtk_adsp_chip_info *adsp;
struct clk **clk;
u32 (*ap2adsp_addr)(u32 addr, void *data);
diff --git a/sound/soc/sof/mediatek/mt8195/mt8195.c b/sound/soc/sof/mediatek/mt8195/mt8195.c
index ba13e4540f7a..f4b24afb6f75 100644
--- a/sound/soc/sof/mediatek/mt8195/mt8195.c
+++ b/sound/soc/sof/mediatek/mt8195/mt8195.c
@@ -12,6 +12,7 @@
#include <linux/delay.h>
#include <linux/firmware.h>
#include <linux/io.h>
+#include <linux/of_platform.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
@@ -27,6 +28,99 @@
#include "mt8195.h"
#include "mt8195-clk.h"
+static int mt8195_get_mailbox_offset(struct snd_sof_dev *sdev)
+{
+ return MBOX_OFFSET;
+}
+
+static int mt8195_get_window_offset(struct snd_sof_dev *sdev, u32 id)
+{
+ return MBOX_OFFSET;
+}
+
+static int mt8195_send_msg(struct snd_sof_dev *sdev,
+ struct snd_sof_ipc_msg *msg)
+{
+ struct adsp_priv *priv = sdev->pdata->hw_pdata;
+
+ sof_mailbox_write(sdev, sdev->host_box.offset, msg->msg_data,
+ msg->msg_size);
+
+ return mtk_adsp_ipc_send(priv->dsp_ipc, MTK_ADSP_IPC_REQ, MTK_ADSP_IPC_OP_REQ);
+}
+
+static void mt8195_get_reply(struct snd_sof_dev *sdev)
+{
+ struct snd_sof_ipc_msg *msg = sdev->msg;
+ struct sof_ipc_reply reply;
+ int ret = 0;
+
+ if (!msg) {
+ dev_warn(sdev->dev, "unexpected ipc interrupt\n");
+ return;
+ }
+
+ /* get reply */
+ sof_mailbox_read(sdev, sdev->host_box.offset, &reply, sizeof(reply));
+ if (reply.error < 0) {
+ memcpy(msg->reply_data, &reply, sizeof(reply));
+ ret = reply.error;
+ } else {
+ /* reply has correct size? */
+ if (reply.hdr.size != msg->reply_size) {
+ dev_err(sdev->dev, "error: reply expected %zu got %u bytes\n",
+ msg->reply_size, reply.hdr.size);
+ ret = -EINVAL;
+ }
+
+ /* read the message */
+ if (msg->reply_size > 0)
+ sof_mailbox_read(sdev, sdev->host_box.offset,
+ msg->reply_data, msg->reply_size);
+ }
+
+ msg->reply_error = ret;
+}
+
+static void mt8195_dsp_handle_reply(struct mtk_adsp_ipc *ipc)
+{
+ struct adsp_priv *priv = mtk_adsp_ipc_get_data(ipc);
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->sdev->ipc_lock, flags);
+ mt8195_get_reply(priv->sdev);
+ snd_sof_ipc_reply(priv->sdev, 0);
+ spin_unlock_irqrestore(&priv->sdev->ipc_lock, flags);
+}
+
+static void mt8195_dsp_handle_request(struct mtk_adsp_ipc *ipc)
+{
+ struct adsp_priv *priv = mtk_adsp_ipc_get_data(ipc);
+ u32 p; /* panic code */
+ int ret;
+
+ /* Read the message from the debug box. */
+ sof_mailbox_read(priv->sdev, priv->sdev->debug_box.offset + 4,
+ &p, sizeof(p));
+
+ /* Check to see if the message is a panic code 0x0dead*** */
+ if ((p & SOF_IPC_PANIC_MAGIC_MASK) == SOF_IPC_PANIC_MAGIC) {
+ snd_sof_dsp_panic(priv->sdev, p, true);
+ } else {
+ snd_sof_ipc_msgs_rx(priv->sdev);
+
+ /* tell DSP cmd is done */
+ ret = mtk_adsp_ipc_send(priv->dsp_ipc, MTK_ADSP_IPC_RSP, MTK_ADSP_IPC_OP_RSP);
+ if (ret)
+ dev_err(priv->dev, "request send ipc failed");
+ }
+}
+
+static struct mtk_adsp_ipc_ops dsp_ops = {
+ .handle_reply = mt8195_dsp_handle_reply,
+ .handle_request = mt8195_dsp_handle_request,
+};
+
static int platform_parse_resource(struct platform_device *pdev, void *data)
{
struct resource *mmio;
@@ -285,15 +379,36 @@ static int mt8195_dsp_probe(struct snd_sof_dev *sdev)
}
sdev->bar[DSP_REG_BAR] = priv->adsp->va_cfgreg;
- sdev->bar[DSP_MBOX0_BAR] = priv->adsp->va_mboxreg[0];
- sdev->bar[DSP_MBOX1_BAR] = priv->adsp->va_mboxreg[1];
- sdev->bar[DSP_MBOX2_BAR] = priv->adsp->va_mboxreg[2];
sdev->mmio_bar = SOF_FW_BLK_TYPE_SRAM;
sdev->mailbox_bar = SOF_FW_BLK_TYPE_SRAM;
+ /* set default mailbox offset for FW ready message */
+ sdev->dsp_box.offset = mt8195_get_mailbox_offset(sdev);
+
+ priv->ipc_dev = platform_device_register_data(&pdev->dev, "mtk-adsp-ipc",
+ PLATFORM_DEVID_NONE,
+ pdev, sizeof(*pdev));
+ if (IS_ERR(priv->ipc_dev)) {
+ ret = PTR_ERR(priv->ipc_dev);
+ dev_err(sdev->dev, "failed to register mtk-adsp-ipc device\n");
+ goto err_adsp_sram_power_off;
+ }
+
+ priv->dsp_ipc = dev_get_drvdata(&priv->ipc_dev->dev);
+ if (!priv->dsp_ipc) {
+ ret = -EPROBE_DEFER;
+ dev_err(sdev->dev, "failed to get drvdata\n");
+ goto exit_pdev_unregister;
+ }
+
+ mtk_adsp_ipc_set_data(priv->dsp_ipc, priv);
+ priv->dsp_ipc->ops = &dsp_ops;
+
return 0;
+exit_pdev_unregister:
+ platform_device_unregister(priv->ipc_dev);
err_adsp_sram_power_off:
adsp_sram_power_on(&pdev->dev, false);
exit_clk_disable:
@@ -310,7 +425,9 @@ static int mt8195_dsp_shutdown(struct snd_sof_dev *sdev)
static int mt8195_dsp_remove(struct snd_sof_dev *sdev)
{
struct platform_device *pdev = container_of(sdev->dev, struct platform_device, dev);
+ struct adsp_priv *priv = sdev->pdata->hw_pdata;
+ platform_device_unregister(priv->ipc_dev);
adsp_sram_power_on(&pdev->dev, false);
adsp_clock_off(sdev);
@@ -361,6 +478,14 @@ static int mt8195_get_bar_index(struct snd_sof_dev *sdev, u32 type)
return type;
}
+static int mt8195_ipc_msg_data(struct snd_sof_dev *sdev,
+ struct snd_pcm_substream *substream,
+ void *p, size_t sz)
+{
+ sof_mailbox_read(sdev, sdev->dsp_box.offset, p, sz);
+ return 0;
+}
+
static struct snd_soc_dai_driver mt8195_dai[] = {
{
.name = "SOF_DL2",
@@ -412,6 +537,13 @@ static struct snd_sof_dsp_ops sof_mt8195_ops = {
.write64 = sof_io_write64,
.read64 = sof_io_read64,
+ /* ipc */
+ .send_msg = mt8195_send_msg,
+ .get_mailbox_offset = mt8195_get_mailbox_offset,
+ .get_window_offset = mt8195_get_window_offset,
+ .ipc_msg_data = mt8195_ipc_msg_data,
+ .set_stream_data_offset = sof_set_stream_data_offset,
+
/* misc */
.get_bar_index = mt8195_get_bar_index,
--
2.18.0
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply related
* Re: [PATCH] net: ethernet: mediatek: ppe: fix wrong size passed to memset()
From: Felix Fietkau @ 2022-05-11 5:05 UTC (permalink / raw)
To: Yang Yingliang, linux-kernel, linux-mediatek, linux-arm-kernel,
netdev
Cc: davem, kuba
In-Reply-To: <20220511030829.3308094-1-yangyingliang@huawei.com>
On 11.05.22 05:08, Yang Yingliang wrote:
> 'foe_table' is a pointer, the real size of struct mtk_foe_entry
> should be pass to memset().
>
> Fixes: ba37b7caf1ed ("net: ethernet: mtk_eth_soc: add support for initializing the PPE")
> Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
Acked-by: Felix Fietkau <nbd@nbd.name>
Thanks,
- Felix
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply
* Re: [PATCH v3 2/2] PM / devfreq: mediatek: Introduce MediaTek CCI devfreq driver
From: Johnson Wang @ 2022-05-11 5:14 UTC (permalink / raw)
To: Chanwoo Choi, cw00.choi, krzk+dt, robh+dt, kyungmin.park
Cc: khilman, linux-pm, linux-kernel, devicetree, linux-arm-kernel,
linux-mediatek, jia-wei.chang,
Project_Global_Chrome_Upstream_Group
In-Reply-To: <72396dec-d418-e732-11a8-a92e89692dd1@gmail.com>
On Mon, 2022-05-09 at 20:51 +0900, Chanwoo Choi wrote:
> On 22. 5. 9. 14:57, Johnson Wang wrote:
> > On Sat, 2022-05-07 at 22:53 +0900, Chanwoo Choi wrote:
> > > On 22. 5. 6. 20:38, Johnson Wang wrote:
> > > > On Mon, 2022-04-25 at 20:55 +0800, Johnson Wang wrote:
> > > > > We introduce a devfreq driver for the MediaTek Cache Coherent
> > > > > Interconnect
> > > > > (CCI) used by some MediaTek SoCs.
> > > > >
> > > > > In this driver, we use the passive devfreq driver to get
> > > > > target
> > > > > frequencies
> > > > > and adjust voltages accordingly. In MT8183 and MT8186, the
> > > > > MediaTek
> > > > > CCI
> > > > > is supplied by the same regulators with the little core CPUs.
> > > > >
> > > > > Signed-off-by: Johnson Wang <johnson.wang@mediatek.com>
> > > > > Signed-off-by: Jia-Wei Chang <jia-wei.chang@mediatek.com>
> > > > > ---
> > > > > This patch depends on "devfreq-testing"[1].
> > > > > [1]
> > > > >
> >
> >
https://urldefense.com/v3/__https://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/linux.git/log/?h=devfreq-testing__;!!CTRNKA9wMg0ARbw!wnTkI_sh3TsliBPFP70DFwtSZGtKyPinFu9h2BwULWX-xrWF0C21rLV-n1HhstfmLw42$
> > > > >
> > > > > ---
> > > > > drivers/devfreq/Kconfig | 10 +
> > > > > drivers/devfreq/Makefile | 1 +
> > > > > drivers/devfreq/mtk-cci-devfreq.c | 474
> > > > > ++++++++++++++++++++++++++++++
> > > > > 3 files changed, 485 insertions(+)
> > > > > create mode 100644 drivers/devfreq/mtk-cci-devfreq.c
> > > > >
> > > > > diff --git a/drivers/devfreq/Kconfig
> > > > > b/drivers/devfreq/Kconfig
> > > > > index 87eb2b837e68..9754d8b31621 100644
> > > > > --- a/drivers/devfreq/Kconfig
> > > > > +++ b/drivers/devfreq/Kconfig
> > > > > @@ -120,6 +120,16 @@ config ARM_TEGRA_DEVFREQ
> > > > > It reads ACTMON counters of memory controllers and
> > > > > adjusts
> > > > > the
> > > > > operating frequencies and voltages with OPP support.
> > > > >
> > > > > +config ARM_MEDIATEK_CCI_DEVFREQ
> > > > > + tristate "MEDIATEK CCI DEVFREQ Driver"
> > > > > + depends on ARM_MEDIATEK_CPUFREQ || COMPILE_TEST
> > > > > + select DEVFREQ_GOV_PASSIVE
> > > > > + help
> > > > > + This adds a devfreq driver for MediaTek Cache
> > > > > Coherent
> > > > > Interconnect
> > > > > + which is shared the same regulators with the cpu
> > > > > cluster. It
> > > > > can track
> > > > > + buck voltages and update a proper CCI frequency. Use
> > > > > the
> > > > > notification
> > > > > + to get the regulator status.
> > > > > +
> > > > > config ARM_RK3399_DMC_DEVFREQ
> > > > > tristate "ARM RK3399 DMC DEVFREQ Driver"
> > > > > depends on (ARCH_ROCKCHIP && HAVE_ARM_SMCCC) || \
> > > > > diff --git a/drivers/devfreq/Makefile
> > > > > b/drivers/devfreq/Makefile
> > > > > index 0b6be92a25d9..bf40d04928d0 100644
> > > > > --- a/drivers/devfreq/Makefile
> > > > > +++ b/drivers/devfreq/Makefile
> > > > > @@ -11,6 +11,7 @@ obj-$(CONFIG_DEVFREQ_GOV_PASSIVE) +=
> > > > > governor_passive.o
> > > > > obj-$(CONFIG_ARM_EXYNOS_BUS_DEVFREQ) += exynos-bus.o
> > > > > obj-$(CONFIG_ARM_IMX_BUS_DEVFREQ) += imx-bus.o
> > > > > obj-$(CONFIG_ARM_IMX8M_DDRC_DEVFREQ) += imx8m-ddrc.o
> > > > > +obj-$(CONFIG_ARM_MEDIATEK_CCI_DEVFREQ) += mtk-cci-
> > > > > devfreq.o
> > > > > obj-$(CONFIG_ARM_RK3399_DMC_DEVFREQ) += rk3399_dmc.o
> > > > > obj-$(CONFIG_ARM_SUN8I_A33_MBUS_DEVFREQ) += sun8i-a33-
> > > > > mbus.o
> > > > > obj-$(CONFIG_ARM_TEGRA_DEVFREQ) += tegra30-
> > > > > devfreq.o
> > > > > diff --git a/drivers/devfreq/mtk-cci-devfreq.c
> > > > > b/drivers/devfreq/mtk-
> > > > > cci-devfreq.c
> > > > > new file mode 100644
> > > > > index 000000000000..b3e31c45a57c
> > > > > --- /dev/null
> > > > > +++ b/drivers/devfreq/mtk-cci-devfreq.c
> > > > > @@ -0,0 +1,474 @@
> > > > > +// SPDX-License-Identifier: GPL-2.0-only
> > > > > +/*
> > > > > + * Copyright (C) 2022 MediaTek Inc.
> > > > > + */
> > > > > +
> > > > > +#include <linux/clk.h>
> > > > > +#include <linux/devfreq.h>
> > > > > +#include <linux/minmax.h>
> > > > > +#include <linux/module.h>
> > > > > +#include <linux/of.h>
> > > > > +#include <linux/of_device.h>
> > > > > +#include <linux/platform_device.h>
> > > > > +#include <linux/pm_opp.h>
> > > > > +#include <linux/regulator/consumer.h>
> > > > > +
> > > > > +struct mtk_ccifreq_platform_data {
> > > > > + int min_volt_shift;
> > > > > + int max_volt_shift;
> > > > > + int proc_max_volt;
> > > > > + int sram_min_volt;
> > > > > + int sram_max_volt;
> > > > > +};
> > > > > +
> > > > > +struct mtk_ccifreq_drv {
> > > > > + struct device *dev;
> > > > > + struct devfreq *devfreq;
> > > > > + struct regulator *proc_reg;
> > > > > + struct regulator *sram_reg;
> > > > > + struct clk *cci_clk;
> > > > > + struct clk *inter_clk;
> > > > > + int inter_voltage;
> > > > > + int pre_voltage;
> > > > > + unsigned long pre_freq;
> > > > > + /* Avoid race condition for regulators between notify
> > > > > and
> > > > > policy */
> > > > > + struct mutex reg_lock;
> > > > > + struct notifier_block opp_nb;
> > > > > + const struct mtk_ccifreq_platform_data *soc_data;
> > > > > + int vtrack_max;
> > > > > +};
> > > > > +
> > > > > +static int mtk_ccifreq_set_voltage(struct mtk_ccifreq_drv
> > > > > *drv,
> > > > > int
> > > > > new_voltage)
> > > > > +{
> > > > > + const struct mtk_ccifreq_platform_data *soc_data = drv-
> > > > > > soc_data;
> > > > >
> > > > > + struct device *dev = drv->dev;
> > > > > + int pre_voltage, pre_vsram, new_vsram, vsram, voltage,
> > > > > ret;
> > > > > + int retry_max = drv->vtrack_max;
> > > > > +
> > > > > + if (!drv->sram_reg) {
> > > > > + ret = regulator_set_voltage(drv->proc_reg,
> > > > > new_voltage,
> > > > > + drv->soc_data-
> > > > > > proc_max_volt);
> > > > >
> > > > > + goto out_set_voltage;
> > > > > + }
> > > > > +
> > > > > + pre_voltage = regulator_get_voltage(drv->proc_reg);
> > > > > + if (pre_voltage < 0) {
> > > > > + dev_err(dev, "invalid vproc value: %d\n",
> > > > > pre_voltage);
> > > > > + return pre_voltage;
> > > > > + }
> > > > > +
> > > > > + pre_vsram = regulator_get_voltage(drv->sram_reg);
> > > > > + if (pre_vsram < 0) {
> > > > > + dev_err(dev, "invalid vsram value: %d\n",
> > > > > pre_vsram);
> > > > > + return pre_vsram;
> > > > > + }
> > > > > +
> > > > > + new_vsram = clamp(new_voltage + soc_data-
> > > > > >min_volt_shift,
> > > > > + soc_data->sram_min_volt, soc_data-
> > > > > > sram_max_volt);
> > > > >
> > > > > +
> > > > > + do {
> > > > > + if (pre_voltage <= new_voltage) {
> > > > > + vsram = clamp(pre_voltage + soc_data-
> > > > > > max_volt_shift,
> > > > >
> > > > > + soc_data->sram_min_volt,
> > > > > new_vsram);
> > > > > + ret = regulator_set_voltage(drv-
> > > > > >sram_reg,
> > > > > vsram,
> > > > > + soc_data-
> > > > > > sram_max_volt);
> > > > >
> > > > > + if (ret)
> > > > > + return ret;
> > > > > +
> > > > > + if (vsram == soc_data->sram_max_volt ||
> > > > > + new_vsram == soc_data-
> > > > > >sram_min_volt)
> > > > > + voltage = new_voltage;
> > > > > + else
> > > > > + voltage = vsram - soc_data-
> > > > > > min_volt_shift;
> > > > >
> > > > > +
> > > > > + ret = regulator_set_voltage(drv-
> > > > > >proc_reg,
> > > > > voltage,
> > > > > + soc_data-
> > > > > > proc_max_volt);
> > > > >
> > > > > + if (ret) {
> > > > > + regulator_set_voltage(drv-
> > > > > >sram_reg,
> > > > > pre_vsram,
> > > > > + soc_data-
> > > > > > sram_max_volt);
> > > > >
> > > > > + return ret;
> > > > > + }
> > > > > + } else if (pre_voltage > new_voltage) {
> > > > > + voltage = max(new_voltage,
> > > > > + pre_vsram - soc_data-
> > > > > > max_volt_shift);
> > > > >
> > > > > + ret = regulator_set_voltage(drv-
> > > > > >proc_reg,
> > > > > voltage,
> > > > > + soc_data-
> > > > > > proc_max_volt);
> > > > >
> > > > > + if (ret)
> > > > > + return ret;
> > > > > +
> > > > > + if (voltage == new_voltage)
> > > > > + vsram = new_vsram;
> > > > > + else
> > > > > + vsram = max(new_vsram,
> > > > > + voltage + soc_data-
> > > > > > min_volt_shift);
> > > > >
> > > > > +
> > > > > + ret = regulator_set_voltage(drv-
> > > > > >sram_reg,
> > > > > vsram,
> > > > > + soc_data-
> > > > > > sram_max_volt);
> > > > >
> > > > > + if (ret) {
> > > > > + regulator_set_voltage(drv-
> > > > > >proc_reg,
> > > > > pre_voltage,
> > > > > + soc_data-
> > > > > > proc_max_volt);
> > > > >
> > > > > + return ret;
> > > > > + }
> > > > > + }
> > > > > +
> > > > > + pre_voltage = voltage;
> > > > > + pre_vsram = vsram;
> > > > > +
> > > > > + if (--retry_max < 0) {
> > > > > + dev_err(dev,
> > > > > + "over loop count, failed to set
> > > > > voltage\n");
> > > > > + return -EINVAL;
> > > > > + }
> > > > > + } while (voltage != new_voltage || vsram != new_vsram);
> > > > > +
> > > > > +out_set_voltage:
> > > > > + if (!ret)
> > > > > + drv->pre_voltage = new_voltage;
> > > > > +
> > > > > + return ret;
> > > > > +}
> > > > > +
> > > > > +static int mtk_ccifreq_target(struct device *dev, unsigned
> > > > > long
> > > > > *freq,
> > > > > + u32 flags)
> > > > > +{
> > > > > + struct mtk_ccifreq_drv *drv = dev_get_drvdata(dev);
> > > > > + struct clk *cci_pll = clk_get_parent(drv->cci_clk);
> > > > > + struct dev_pm_opp *opp;
> > > > > + unsigned long opp_rate;
> > > > > + int voltage, pre_voltage, inter_voltage,
> > > > > target_voltage, ret;
> > > > > +
> > > > > + if (!drv)
> > > > > + return -EINVAL;
> > > > > +
> > > > > + if (drv->pre_freq == *freq)
> > > > > + return 0;
> > > > > +
> > > > > + inter_voltage = drv->inter_voltage;
> > > > > +
> > > > > + opp_rate = *freq;
> > > > > + opp = devfreq_recommended_opp(dev, &opp_rate, 1);
> > > > > + if (IS_ERR(opp)) {
> > > > > + dev_err(dev, "failed to find opp for freq:
> > > > > %ld\n",
> > > > > opp_rate);
> > > > > + return PTR_ERR(opp);
> > > > > + }
> > > > > +
> > > > > + mutex_lock(&drv->reg_lock);
> > > > > +
> > > > > + voltage = dev_pm_opp_get_voltage(opp);
> > > > > + dev_pm_opp_put(opp);
> > > > > +
> > > > > + if (unlikely(drv->pre_voltage <= 0))
> > > > > + pre_voltage = regulator_get_voltage(drv-
> > > > > >proc_reg);
> > > > > + else
> > > > > + pre_voltage = drv->pre_voltage;
> > > > > +
> > > > > + if (pre_voltage < 0) {
> > > > > + dev_err(dev, "invalid vproc value: %d\n",
> > > > > pre_voltage);
> > > > > + return pre_voltage;
> > > > > + }
> > > > > +
> > > > > + /* scale up: set voltage first then freq. */
> > > > > + target_voltage = max(inter_voltage, voltage);
> > > > > + if (pre_voltage <= target_voltage) {
> > > > > + ret = mtk_ccifreq_set_voltage(drv,
> > > > > target_voltage);
> > > > > + if (ret) {
> > > > > + dev_err(dev, "failed to scale up
> > > > > voltage\n");
> > > > > + goto out_restore_voltage;
> > > > > + }
> > > > > + }
> > > > > +
> > > > > + /* switch the cci clock to intermediate clock source.
> > > > > */
> > > > > + ret = clk_set_parent(drv->cci_clk, drv->inter_clk);
> > > > > + if (ret) {
> > > > > + dev_err(dev, "failed to re-parent cci
> > > > > clock\n");
> > > > > + goto out_restore_voltage;
> > > > > + }
> > > > > +
> > > > > + /* set the original clock to target rate. */
> > > > > + ret = clk_set_rate(cci_pll, *freq);
> > > > > + if (ret) {
> > > > > + dev_err(dev, "failed to set cci pll rate:
> > > > > %d\n", ret);
> > > > > + clk_set_parent(drv->cci_clk, cci_pll);
> > > > > + goto out_restore_voltage;
> > > > > + }
> > > > > +
> > > > > + /* switch the cci clock back to the original clock
> > > > > source. */
> > > > > + ret = clk_set_parent(drv->cci_clk, cci_pll);
> > > > > + if (ret) {
> > > > > + dev_err(dev, "failed to re-parent cci
> > > > > clock\n");
> > > > > + mtk_ccifreq_set_voltage(drv, inter_voltage);
> > > > > + goto out_unlock;
> > > > > + }
> > > > > +
> > > > > + /*
> > > > > + * If the new voltage is lower than the intermediate
> > > > > voltage or
> > > > > the
> > > > > + * original voltage, scale down to the new voltage.
> > > > > + */
> > > > > + if (voltage < inter_voltage || voltage < pre_voltage) {
> > > > > + ret = mtk_ccifreq_set_voltage(drv, voltage);
> > > > > + if (ret) {
> > > > > + dev_err(dev, "failed to scale down
> > > > > voltage\n");
> > > > > + goto out_unlock;
> > > > > + }
> > > > > + }
> > > > > +
> > > > > + drv->pre_freq = *freq;
> > > > > + mutex_unlock(&drv->reg_lock);
> > > > > +
> > > > > + return 0;
> > > > > +
> > > > > +out_restore_voltage:
> > > > > + mtk_ccifreq_set_voltage(drv, pre_voltage);
> > > > > +
> > > > > +out_unlock:
> > > > > + mutex_unlock(&drv->reg_lock);
> > > > > + return ret;
> > > > > +}
> > > > > +
> > > > > +static int mtk_ccifreq_opp_notifier(struct notifier_block
> > > > > *nb,
> > > > > + unsigned long event, void
> > > > > *data)
> > > > > +{
> > > > > + struct dev_pm_opp *opp = data;
> > > > > + struct mtk_ccifreq_drv *drv;
> > > > > + unsigned long freq, volt;
> > > > > +
> > > > > + drv = container_of(nb, struct mtk_ccifreq_drv, opp_nb);
> > > > > +
> > > > > + if (event == OPP_EVENT_ADJUST_VOLTAGE) {
> > > > > + freq = dev_pm_opp_get_freq(opp);
> > > > > +
> > > > > + mutex_lock(&drv->reg_lock);
> > > > > + /* current opp item is changed */
> > > > > + if (freq == drv->pre_freq) {
> > > > > + volt = dev_pm_opp_get_voltage(opp);
> > > > > + mtk_ccifreq_set_voltage(drv, volt);
> > > > > + }
> > > > > + mutex_unlock(&drv->reg_lock);
> > > > > + }
> > > > > +
> > > > > + return 0;
> > > > > +}
> > > > > +
> > > > > +static struct devfreq_dev_profile mtk_ccifreq_profile = {
> > > > > + .target = mtk_ccifreq_target,
> > > > > +};
> > > > > +
> > > > > +static int mtk_ccifreq_probe(struct platform_device *pdev)
> > > > > +{
> > > > > + struct device *dev = &pdev->dev;
> > > > > + struct mtk_ccifreq_drv *drv;
> > > > > + struct devfreq_passive_data *passive_data;
> > > > > + struct dev_pm_opp *opp;
> > > > > + unsigned long rate, opp_volt;
> > > > > + int ret;
> > > > > +
> > > > > + drv = devm_kzalloc(dev, sizeof(*drv), GFP_KERNEL);
> > > > > + if (!drv)
> > > > > + return -ENOMEM;
> > > > > +
> > > > > + drv->dev = dev;
> > > > > + drv->soc_data = (const struct mtk_ccifreq_platform_data
> > > > > *)
> > > > > + of_device_get_match_data(&pdev-
> > > > > >dev);
> > > > > + mutex_init(&drv->reg_lock);
> > > > > + platform_set_drvdata(pdev, drv);
> > > > > +
> > > > > + drv->cci_clk = devm_clk_get(dev, "cci");
> > > > > + if (IS_ERR(drv->cci_clk)) {
> > > > > + ret = PTR_ERR(drv->cci_clk);
> > > > > + return dev_err_probe(dev, ret,
> > > > > + "failed to get cci clk:
> > > > > %d\n",
> > > > > ret);
> > > > > + }
> > > > > +
> > > > > + drv->inter_clk = devm_clk_get(dev, "intermediate");
> > > > > + if (IS_ERR(drv->inter_clk)) {
> > > > > + ret = PTR_ERR(drv->inter_clk);
> > > > > + dev_err_probe(dev, ret,
> > > > > + "failed to get intermediate clk:
> > > > > %d\n",
> > > > > ret);
> > > > > + goto out_free_resources;
> > > > > + }
> > > > > +
> > > > > + drv->proc_reg = devm_regulator_get_optional(dev,
> > > > > "proc");
> > > > > + if (IS_ERR(drv->proc_reg)) {
> > > > > + ret = PTR_ERR(drv->proc_reg);
> > > > > + dev_err_probe(dev, ret,
> > > > > + "failed to get proc regulator:
> > > > > %d\n",
> > > > > ret);
> > > > > + goto out_free_resources;
> > > > > + }
> > > > > +
> > > > > + ret = regulator_enable(drv->proc_reg);
> > > > > + if (ret) {
> > > > > + dev_err(dev, "failed to enable proc
> > > > > regulator\n");
> > > > > + goto out_free_resources;
> > > > > + }
> > > > > +
> > > > > + drv->sram_reg = regulator_get_optional(dev, "sram");
> > > > > + if (IS_ERR(drv->sram_reg))
> > > > > + drv->sram_reg = NULL;
> > > > > + else {
> > > > > + ret = regulator_enable(drv->sram_reg);
> > > > > + if (ret) {
> > > > > + dev_err(dev, "failed to enable sram
> > > > > regulator\n");
> > > > > + goto out_free_resources;
> > > > > + }
> > > > > + }
> > > > > +
> > > > > + /*
> > > > > + * We assume min voltage is 0 and tracking target
> > > > > voltage using
> > > > > + * min_volt_shift for each iteration.
> > > > > + * The retry_max is 3 times of expeted iteration count.
> > > > > + */
> > > > > + drv->vtrack_max = 3 * DIV_ROUND_UP(max(drv->soc_data-
> > > > > > sram_max_volt,
> > > > >
> > > > > + drv->soc_data-
> > > > > > proc_max_volt),
> > > > >
> > > > > + drv->soc_data-
> > > > > > min_volt_shift);
> > > > >
> > > > > +
> > > > > + ret = clk_prepare_enable(drv->cci_clk);
> > > > > + if (ret)
> > > > > + goto out_free_resources;
> > > > > +
> > > > > + ret = clk_prepare_enable(drv->inter_clk);
> > > > > + if (ret)
> > > > > + goto out_disable_cci_clk;
> > > > > +
> > > > > + ret = dev_pm_opp_of_add_table(dev);
> > > > > + if (ret) {
> > > > > + dev_err(dev, "failed to add opp table: %d\n",
> > > > > ret);
> > > > > + goto out_disable_inter_clk;
> > > > > + }
> > > > > +
> > > > > + rate = clk_get_rate(drv->inter_clk);
> > > > > + opp = dev_pm_opp_find_freq_ceil(dev, &rate);
> > > > > + if (IS_ERR(opp)) {
> > > > > + ret = PTR_ERR(opp);
> > > > > + dev_err(dev, "failed to get intermediate opp:
> > > > > %d\n",
> > > > > ret);
> > > > > + goto out_remove_opp_table;
> > > > > + }
> > > > > + drv->inter_voltage = dev_pm_opp_get_voltage(opp);
> > > > > + dev_pm_opp_put(opp);
> > > > > +
> > > > > + rate = U32_MAX;
> > > > > + opp = dev_pm_opp_find_freq_floor(drv->dev, &rate);
> > > > > + if (IS_ERR(opp)) {
> > > > > + dev_err(dev, "failed to get opp\n");
> > > > > + ret = PTR_ERR(opp);
> > > > > + goto out_remove_opp_table;
> > > > > + }
> > > > > +
> > > > > + opp_volt = dev_pm_opp_get_voltage(opp);
> > > > > + dev_pm_opp_put(opp);
> > > > > + ret = mtk_ccifreq_set_voltage(drv, opp_volt);
> > > > > + if (ret) {
> > > > > + dev_err(dev, "failed to scale to highest
> > > > > voltage %lu in
> > > > > proc_reg\n",
> > > > > + opp_volt);
> > > > > + goto out_remove_opp_table;
> > > > > + }
> > > > > +
> > > > > + passive_data = devm_kzalloc(dev, sizeof(struct
> > > > > devfreq_passive_data),
> > > > > + GFP_KERNEL);
> > > > > + if (!passive_data) {
> > > > > + ret = -ENOMEM;
> > > > > + goto out_remove_opp_table;
> > > > > + }
> > > > > +
> > > > > + passive_data->parent_type = CPUFREQ_PARENT_DEV;
> > > > > + drv->devfreq = devm_devfreq_add_device(dev,
> > > > > &mtk_ccifreq_profile,
> > > > > + DEVFREQ_GOV_PASS
> > > > > IVE,
> > > > > + passive_data);
> > > > > + if (IS_ERR(drv->devfreq)) {
> > > > > + ret = -EPROBE_DEFER;
> > > > > + dev_err(dev, "failed to add devfreq device:
> > > > > %d\n",
> > > > > + PTR_ERR(drv->devfreq));
> > > > > + goto out_remove_opp_table;
> > > > > + }
> > > > > +
> > > > > + drv->opp_nb.notifier_call = mtk_ccifreq_opp_notifier;
> > > > > + ret = dev_pm_opp_register_notifier(dev, &drv->opp_nb);
> > > > > + if (ret) {
> > > > > + dev_err(dev, "failed to register opp notifier:
> > > > > %d\n",
> > > > > ret);
> > > > > + goto out_remove_devfreq_device;
> > > > > + }
> > > > > + return 0;
> > > > > +
> > > > > +out_remove_devfreq_device:
> > > > > + devm_devfreq_remove_device(dev, drv->devfreq);
> > > > > +
> > > > > +out_remove_opp_table:
> > > > > + dev_pm_opp_of_remove_table(dev);
> > > > > +
> > > > > +out_disable_inter_clk:
> > > > > + clk_disable_unprepare(drv->inter_clk);
> > > > > +
> > > > > +out_disable_cci_clk:
> > > > > + clk_disable_unprepare(drv->cci_clk);
> > > > > +
> > > > > +out_free_resources:
> > > > > + if (regulator_is_enabled(drv->proc_reg))
> > > > > + regulator_disable(drv->proc_reg);
> > > > > + if (drv->sram_reg && regulator_is_enabled(drv-
> > > > > >sram_reg))
> > > > > + regulator_disable(drv->sram_reg);
> > > > > +
> > > > > + if (!IS_ERR(drv->proc_reg))
> > > > > + regulator_put(drv->proc_reg);
> > > > > + if (!IS_ERR(drv->sram_reg))
> > > > > + regulator_put(drv->sram_reg);
> > > > > + if (!IS_ERR(drv->cci_clk))
> > > > > + clk_put(drv->cci_clk);
> > > > > + if (!IS_ERR(drv->inter_clk))
> > > > > + clk_put(drv->inter_clk);
> > > > > +
> > > > > + return ret;
> > > > > +}
> > > > > +
> > > > > +static int mtk_ccifreq_remove(struct platform_device *pdev)
> > > > > +{
> > > > > + struct device *dev = &pdev->dev;
> > > > > + struct mtk_ccifreq_drv *drv;
> > > > > +
> > > > > + drv = platform_get_drvdata(pdev);
> > > > > +
> > > > > + dev_pm_opp_unregister_notifier(dev, &drv->opp_nb);
> > > > > + dev_pm_opp_of_remove_table(dev);
> > > > > + clk_disable_unprepare(drv->inter_clk);
> > > > > + clk_disable_unprepare(drv->cci_clk);
> > > > > + regulator_disable(drv->proc_reg);
> > > > > + if (drv->sram_reg)
> > > > > + regulator_disable(drv->sram_reg);
> > > > > +
> > > > > + return 0;
> > > > > +}
> > > > > +
> > > > > +static const struct mtk_ccifreq_platform_data
> > > > > mt8183_platform_data =
> > > > > {
> > > > > + .min_volt_shift = 100000,
> > > > > + .max_volt_shift = 200000,
> > > > > + .proc_max_volt = 1150000,
> > > > > + .sram_min_volt = 0,
> > > > > + .sram_max_volt = 1150000,
> > > > > +};
> > > > > +
> > > > > +static const struct mtk_ccifreq_platform_data
> > > > > mt8186_platform_data =
> > > > > {
> > > > > + .min_volt_shift = 100000,
> > > > > + .max_volt_shift = 250000,
> > > > > + .proc_max_volt = 1118750,
> > > > > + .sram_min_volt = 850000,
> > > > > + .sram_max_volt = 1118750,
> > > > > +};
> > > > > +
> > > > > +static const struct of_device_id mtk_ccifreq_machines[] = {
> > > > > + { .compatible = "mediatek,mt8183-cci", .data =
> > > > > &mt8183_platform_data },
> > > > > + { .compatible = "mediatek,mt8186-cci", .data =
> > > > > &mt8186_platform_data },
> > > > > + { },
> > > > > +};
> > > > > +MODULE_DEVICE_TABLE(of, mtk_ccifreq_machines);
> > > > > +
> > > > > +static struct platform_driver mtk_ccifreq_platdrv = {
> > > > > + .probe = mtk_ccifreq_probe,
> > > > > + .remove = mtk_ccifreq_remove,
> > > > > + .driver = {
> > > > > + .name = "mtk-ccifreq",
> > > > > + .of_match_table = mtk_ccifreq_machines,
> > > > > + },
> > > > > +};
> > > > > +module_platform_driver(mtk_ccifreq_platdrv);
> > > > > +
> > > > > +MODULE_DESCRIPTION("MediaTek CCI devfreq driver");
> > > > > +MODULE_AUTHOR("Jia-Wei Chang <jia-wei.chang@mediatek.com>");
> > > > > +MODULE_LICENSE("GPL v2");
> > > >
> > > > Hi Chanwoo,
> > > >
> > > > Just a kindly ping.
> > > > Could you please give me some suggestion on this patch?
> > > > Thanks!
> > > >
> > > > BRs,
> > > > Johnson Wang
> > > >
> > >
> > > Hi Johnson,
> > >
> > > Sorry for late reply.But I replied it yesterday as following:
> > > Maybe, this reply[1] has not yet arrrived at your mail box.
> > > [1]
> > >
> >
> >
https://lore.kernel.org/lkml/0846a062-2ea2-e6d4-03c8-992c2f2e24a0@gmail.com/T/#m3bc609d805d6e74ec7a105be0511926b4afbbaef
> > >
> > > As I described on reply[1], I updated the patches on devfreq-
> > > testing
> > > branch. Could you please test your patches based on devfreq-
> > > testing
> > > branch?
> > >
> >
> > Hi Chanwoo,
> >
> > Thanks for your information.
> > I've tested this patch based on the latest devfreq-testing branch.
> > It encounters the same crash as Chen-Yu mentioned[1].
> >
> > [1]
> > https://lore.kernel.org/linux-pm/YniX1w+oI1eOCmCx@google.com/T/#u
>
> Hi Johnson,
>
> Thanks for the test. I'll drop the last patch caused of crash.
> And I'll send v3 patchset right now.
>
>
Hi Chanwoo,
With your v3 patchset, this CCI devfreq driver works properly on the
target.
Thanks!
BRs,
Johnson Wang
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply
* Re: [PATCH v2] usb: typec: tcpci_mt6360: Update for BMC PHY setting
From: Heikki Krogerus @ 2022-05-11 6:31 UTC (permalink / raw)
To: cy_huang
Cc: linux, gregkh, matthias.bgg, cy_huang, bryan_huang, linux-usb,
linux-arm-kernel, linux-mediatek, linux-kernel, Fabien Parent,
stable
In-Reply-To: <1652159580-30959-1-git-send-email-u0084500@gmail.com>
On Tue, May 10, 2022 at 01:13:00PM +0800, cy_huang wrote:
> From: ChiYuan Huang <cy_huang@richtek.com>
>
> Update MT6360 BMC PHY Tx/Rx setting for the compatibility.
>
> Macpaul reported this CtoDP cable attention message cannot be received from
> MT6360 TCPC. But actually, attention message really sent from UFP_D
> device.
>
> After RD's comment, there may be BMC PHY Tx/Rx setting causes this issue.
>
> Below's the detailed TCPM log and DP attention message didn't received from 6360
> TCPCI.
> [ 1206.367775] Identity: 0000:0000.0000
> [ 1206.416570] Alternate mode 0: SVID 0xff01, VDO 1: 0x00000405
> [ 1206.447378] AMS DFP_TO_UFP_ENTER_MODE start
> [ 1206.447383] PD TX, header: 0x1d6f
> [ 1206.449393] PD TX complete, status: 0
> [ 1206.454110] PD RX, header: 0x184f [1]
> [ 1206.456867] Rx VDM cmd 0xff018144 type 1 cmd 4 len 1
> [ 1206.456872] AMS DFP_TO_UFP_ENTER_MODE finished
> [ 1206.456873] cc:=4
> [ 1206.473100] AMS STRUCTURED_VDMS start
> [ 1206.473103] PD TX, header: 0x2f6f
> [ 1206.475397] PD TX complete, status: 0
> [ 1206.480442] PD RX, header: 0x2a4f [1]
> [ 1206.483145] Rx VDM cmd 0xff018150 type 1 cmd 16 len 2
> [ 1206.483150] AMS STRUCTURED_VDMS finished
> [ 1206.483151] cc:=4
> [ 1206.505643] AMS STRUCTURED_VDMS start
> [ 1206.505646] PD TX, header: 0x216f
> [ 1206.507933] PD TX complete, status: 0
> [ 1206.512664] PD RX, header: 0x1c4f [1]
> [ 1206.515456] Rx VDM cmd 0xff018151 type 1 cmd 17 len 1
> [ 1206.515460] AMS STRUCTURED_VDMS finished
> [ 1206.515461] cc:=4
>
> Fixes: e1aefcdd394fd ("usb typec: mt6360: Add support for mt6360 Type-C driver")
> Reported-by: Macpaul Lin <macpaul.lin@mediatek.com>
> Signed-off-by: ChiYuan Huang <cy_huang@richtek.com>
> Signed-off-by: Fabien Parent <fparent@baylibre.com>
> Cc: stable <stable@vger.kernel.org>
Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> ---
> drivers/usb/typec/tcpm/tcpci_mt6360.c | 26 ++++++++++++++++++++++++++
> 1 file changed, 26 insertions(+)
>
> diff --git a/drivers/usb/typec/tcpm/tcpci_mt6360.c b/drivers/usb/typec/tcpm/tcpci_mt6360.c
> index f1bd9e0..8a952ea 100644
> --- a/drivers/usb/typec/tcpm/tcpci_mt6360.c
> +++ b/drivers/usb/typec/tcpm/tcpci_mt6360.c
> @@ -15,6 +15,9 @@
>
> #include "tcpci.h"
>
> +#define MT6360_REG_PHYCTRL1 0x80
> +#define MT6360_REG_PHYCTRL3 0x82
> +#define MT6360_REG_PHYCTRL7 0x86
> #define MT6360_REG_VCONNCTRL1 0x8C
> #define MT6360_REG_MODECTRL2 0x8F
> #define MT6360_REG_SWRESET 0xA0
> @@ -22,6 +25,8 @@
> #define MT6360_REG_DRPCTRL1 0xA2
> #define MT6360_REG_DRPCTRL2 0xA3
> #define MT6360_REG_I2CTORST 0xBF
> +#define MT6360_REG_PHYCTRL11 0xCA
> +#define MT6360_REG_RXCTRL1 0xCE
> #define MT6360_REG_RXCTRL2 0xCF
> #define MT6360_REG_CTDCTRL2 0xEC
>
> @@ -106,6 +111,27 @@ static int mt6360_tcpc_init(struct tcpci *tcpci, struct tcpci_data *tdata)
> if (ret)
> return ret;
>
> + /* BMC PHY */
> + ret = mt6360_tcpc_write16(regmap, MT6360_REG_PHYCTRL1, 0x3A70);
> + if (ret)
> + return ret;
> +
> + ret = regmap_write(regmap, MT6360_REG_PHYCTRL3, 0x82);
> + if (ret)
> + return ret;
> +
> + ret = regmap_write(regmap, MT6360_REG_PHYCTRL7, 0x36);
> + if (ret)
> + return ret;
> +
> + ret = mt6360_tcpc_write16(regmap, MT6360_REG_PHYCTRL11, 0x3C60);
> + if (ret)
> + return ret;
> +
> + ret = regmap_write(regmap, MT6360_REG_RXCTRL1, 0xE8);
> + if (ret)
> + return ret;
> +
> /* Set shipping mode off, AUTOIDLE on */
> return regmap_write(regmap, MT6360_REG_MODECTRL2, 0x7A);
> }
> --
> 2.7.4
--
heikki
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply
* [PATCH 0/4] iommu/mediatek: Improve safety from dts
From: Yong Wu @ 2022-05-11 6:49 UTC (permalink / raw)
To: Joerg Roedel, Will Deacon, Matthias Brugger
Cc: iommu, linux-mediatek, linux-arm-kernel, linux-kernel, Yong Wu,
AngeloGioacchino Del Regno, mingyuan.ma, yf.wang, libo.kang,
chengci.xu, youlin.pei, anan.sun, xueqi.zhang, Guenter Roeck,
Dan Carpenter
This patchset contains several improved patches:
[1/4] When mt8195 v7, I added a error log for dts parse fail, but it
doesn't ignore probe_defer case.(v6 doesn't have this err log.)
[2/4] Add a error path for MM dts parse.
[3/4][4/4] To improve safety from dts. Base on this:
https://lore.kernel.org/linux-mediatek/20211210205704.1664928-1-linux@roeck-us.net/
Base on linux-next-20220510.
Guenter Roeck (1):
iommu/mediatek: Validate number of phandles associated with
"mediatek,larbs"
Yong Wu (3):
iommu/mediatek: Use dev_err_probe to mute probe_defer err log
iommu/mediatek: Add error path for loop of mm_dts_parse
iommu/mediatek: Improve safety for mediatek,smi property in larb nodes
drivers/iommu/mtk_iommu.c | 83 ++++++++++++++++++++++++++++-----------
1 file changed, 61 insertions(+), 22 deletions(-)
--
2.18.0
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply
* [PATCH 1/4] iommu/mediatek: Use dev_err_probe to mute probe_defer err log
From: Yong Wu @ 2022-05-11 6:49 UTC (permalink / raw)
To: Joerg Roedel, Will Deacon, Matthias Brugger
Cc: iommu, linux-mediatek, linux-arm-kernel, linux-kernel, Yong Wu,
AngeloGioacchino Del Regno, mingyuan.ma, yf.wang, libo.kang,
chengci.xu, youlin.pei, anan.sun, xueqi.zhang, Guenter Roeck,
Dan Carpenter
In-Reply-To: <20220511064920.18455-1-yong.wu@mediatek.com>
Mute the probe defer log:
[ 2.654806] mtk-iommu 14018000.iommu: mm dts parse fail(-517).
[ 2.656168] mtk-iommu 1c01f000.iommu: mm dts parse fail(-517).
Fixes: d2e9a1102cfc ("iommu/mediatek: Contain MM IOMMU flow with the MM TYPE")
Signed-off-by: Yong Wu <yong.wu@mediatek.com>
---
The Fixes tag commit-id is from linux-next.
---
drivers/iommu/mtk_iommu.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 71b2ace74cd6..0f6ec4a4d9d4 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -1198,7 +1198,7 @@ static int mtk_iommu_probe(struct platform_device *pdev)
if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM)) {
ret = mtk_iommu_mm_dts_parse(dev, &match, data);
if (ret) {
- dev_err(dev, "mm dts parse fail(%d).", ret);
+ dev_err_probe(dev, ret, "mm dts parse fail.");
goto out_runtime_disable;
}
} else if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_INFRA) &&
--
2.18.0
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply related
* [PATCH 2/4] iommu/mediatek: Add error path for loop of mm_dts_parse
From: Yong Wu @ 2022-05-11 6:49 UTC (permalink / raw)
To: Joerg Roedel, Will Deacon, Matthias Brugger
Cc: iommu, linux-mediatek, linux-arm-kernel, linux-kernel, Yong Wu,
AngeloGioacchino Del Regno, mingyuan.ma, yf.wang, libo.kang,
chengci.xu, youlin.pei, anan.sun, xueqi.zhang, Guenter Roeck,
Dan Carpenter
In-Reply-To: <20220511064920.18455-1-yong.wu@mediatek.com>
The mtk_iommu_mm_dts_parse will parse the smi larbs nodes. if the i+1
larb is parsed fail(return -EINVAL), we should of_node_put for the 0..i
larbs.
Fixes: d2e9a1102cfc ("iommu/mediatek: Contain MM IOMMU flow with the MM TYPE")
Signed-off-by: Yong Wu <yong.wu@mediatek.com>
---
drivers/iommu/mtk_iommu.c | 21 ++++++++++++++++-----
1 file changed, 16 insertions(+), 5 deletions(-)
diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 0f6ec4a4d9d4..523bf59264e1 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -1065,12 +1065,12 @@ static int mtk_iommu_mm_dts_parse(struct device *dev, struct component_match **m
plarbdev = of_find_device_by_node(larbnode);
if (!plarbdev) {
- of_node_put(larbnode);
- return -ENODEV;
+ ret = -ENODEV;
+ goto err_larbnode_put;
}
if (!plarbdev->dev.driver) {
- of_node_put(larbnode);
- return -EPROBE_DEFER;
+ ret = -EPROBE_DEFER;
+ goto err_larbnode_put;
}
data->larb_imu[id].dev = &plarbdev->dev;
@@ -1101,9 +1101,20 @@ static int mtk_iommu_mm_dts_parse(struct device *dev, struct component_match **m
DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME);
if (!link) {
dev_err(dev, "Unable to link %s.\n", dev_name(data->smicomm_dev));
- return -EINVAL;
+ ret = -EINVAL;
+ goto err_larbnode_put;
}
return 0;
+
+err_larbnode_put:
+ while (i--) {
+ larbnode = of_parse_phandle(dev->of_node, "mediatek,larbs", i);
+ if (larbnode && of_device_is_available(larbnode)) {
+ of_node_put(larbnode);
+ of_node_put(larbnode);
+ }
+ }
+ return ret;
}
static int mtk_iommu_probe(struct platform_device *pdev)
--
2.18.0
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox