* [PATCH v2 0/3] Add Mediatek JPEG Decoder
From: Rick Chang @ 2016-10-31 7:16 UTC (permalink / raw)
To: Hans Verkuil, Laurent Pinchart, Mauro Carvalho Chehab,
Matthias Brugger
Cc: linux-kernel, linux-media, srv_heupstream, linux-mediatek,
Minghsiu Tsai, Rick Chang
This series of patches provide a v4l2 driver to control Mediatek JPEG hw
for decoding JPEG image and Motion JPEG bitstream.
changes since v1:
- Rebase for v4.9-rc1.
- Update Compliance test version and result
- Remove redundant path in Makefile
- Fix potential build error without CONFIG_PM_RUNTIME and CONFIG_PM_SLEEP
- Fix warnings from patch check and smatch check
* Dependency
The patch "arm: dts: mt2701: Add node for JPEG decoder" depends on:
CCF "Add clock support for Mediatek MT2701"[1]
iommu and smi "Add the dtsi node of iommu and smi for mt2701"[2]
[1] http://lists.infradead.org/pipermail/linux-mediatek/2016-October/007271.html
[2] https://patchwork.kernel.org/patch/9164013/
* Compliance test
v4l2-compliance SHA : 4ad7174b908a36c4f315e3fe2efa7e2f8a6f375a
Driver Info:
Driver name : mtk-jpeg decode
Card type : mtk-jpeg decoder
Bus info : platform:15004000.jpegdec
Driver version: 4.9.0
Capabilities : 0x84204000
Video Memory-to-Memory Multiplanar
Streaming
Extended Pix Format
Device Capabilities
Device Caps : 0x04204000
Video Memory-to-Memory Multiplanar
Streaming
Extended Pix Format
Compliance test for device /dev/video3 (not using libv4l2):
Required ioctls:
test VIDIOC_QUERYCAP: OK
Allow for multiple opens:
test second video open: OK
test VIDIOC_QUERYCAP: OK
test VIDIOC_G/S_PRIORITY: OK
test for unlimited opens: OK
Debug ioctls:
test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported)
test VIDIOC_LOG_STATUS: OK (Not Supported)
Input ioctls:
test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
test VIDIOC_ENUMAUDIO: OK (Not Supported)
test VIDIOC_G/S/ENUMINPUT: OK (Not Supported)
test VIDIOC_G/S_AUDIO: OK (Not Supported)
Inputs: 0 Audio Inputs: 0 Tuners: 0
Output ioctls:
test VIDIOC_G/S_MODULATOR: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_ENUMAUDOUT: OK (Not Supported)
test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
test VIDIOC_G/S_AUDOUT: OK (Not Supported)
Outputs: 0 Audio Outputs: 0 Modulators: 0
Input/Output configuration ioctls:
test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
test VIDIOC_G/S_EDID: OK (Not Supported)
Control ioctls:
test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK (Not Supported)
test VIDIOC_QUERYCTRL: OK (Not Supported)
test VIDIOC_G/S_CTRL: OK (Not Supported)
test VIDIOC_G/S/TRY_EXT_CTRLS: OK (Not Supported)
test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK (Not Supported)
test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
Standard Controls: 0 Private Controls: 0
Format ioctls:
test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
test VIDIOC_G/S_PARM: OK (Not Supported)
test VIDIOC_G_FBUF: OK (Not Supported)
test VIDIOC_G_FMT: OK
test VIDIOC_TRY_FMT: OK
test VIDIOC_S_FMT: OK
test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
test Cropping: OK (Not Supported)
test Composing: OK
test Scaling: OK
Codec ioctls:
test VIDIOC_(TRY_)ENCODER_CMD: OK (Not Supported)
test VIDIOC_G_ENC_INDEX: OK (Not Supported)
test VIDIOC_(TRY_)DECODER_CMD: OK (Not Supported)
Buffer ioctls:
test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
test VIDIOC_EXPBUF: OK
Test input 0:
Total: 43, Succeeded: 43, Failed: 0, Warnings: 0
Rick Chang (3):
dt-bindings: mediatek: Add a binding for Mediatek JPEG Decoder
vcodec: mediatek: Add Mediatek JPEG Decoder Driver
arm: dts: mt2701: Add node for Mediatek JPEG Decoder
.../bindings/media/mediatek-jpeg-codec.txt | 35 +
arch/arm/boot/dts/mt2701.dtsi | 14 +
drivers/media/platform/Kconfig | 15 +
drivers/media/platform/Makefile | 2 +
drivers/media/platform/mtk-jpeg/Makefile | 2 +
drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c | 1271 ++++++++++++++++++++
drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h | 141 +++
drivers/media/platform/mtk-jpeg/mtk_jpeg_hw.c | 417 +++++++
drivers/media/platform/mtk-jpeg/mtk_jpeg_hw.h | 91 ++
drivers/media/platform/mtk-jpeg/mtk_jpeg_parse.c | 160 +++
drivers/media/platform/mtk-jpeg/mtk_jpeg_parse.h | 25 +
drivers/media/platform/mtk-jpeg/mtk_jpeg_reg.h | 58 +
12 files changed, 2231 insertions(+)
create mode 100644 Documentation/devicetree/bindings/media/mediatek-jpeg-codec.txt
create mode 100644 drivers/media/platform/mtk-jpeg/Makefile
create mode 100644 drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
create mode 100644 drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h
create mode 100644 drivers/media/platform/mtk-jpeg/mtk_jpeg_hw.c
create mode 100644 drivers/media/platform/mtk-jpeg/mtk_jpeg_hw.h
create mode 100644 drivers/media/platform/mtk-jpeg/mtk_jpeg_parse.c
create mode 100644 drivers/media/platform/mtk-jpeg/mtk_jpeg_parse.h
create mode 100644 drivers/media/platform/mtk-jpeg/mtk_jpeg_reg.h
--
1.9.1
^ permalink raw reply
* Re: [PATCH v14 1/4] clk: mediatek: Add MT2701 clock support
From: James Liao @ 2016-10-31 6:49 UTC (permalink / raw)
To: Stephen Boyd
Cc: Erin Lo, Matthias Brugger, Mike Turquette, Rob Herring,
Arnd Bergmann, Sascha Hauer, Daniel Kurtz, Philipp Zabel,
devicetree, linux-arm-kernel, linux-kernel, linux-mediatek,
linux-clk, srv_heupstream, ms.chen, robert.chou, Shunli Wang
In-Reply-To: <20161028011753.GS26139@codeaurora.org>
Hi Stephen,
On Thu, 2016-10-27 at 18:17 -0700, Stephen Boyd wrote:
> On 10/21, Erin Lo wrote:
> > diff --git a/drivers/clk/mediatek/clk-mt2701-bdp.c b/drivers/clk/mediatek/clk-mt2701-bdp.c
> > new file mode 100644
> > index 0000000..dbf6ab2
> > --- /dev/null
> > +++ b/drivers/clk/mediatek/clk-mt2701-bdp.c
> > @@ -0,0 +1,148 @@
> > +
> > +static int mtk_bdpsys_init(struct platform_device *pdev)
> > +{
> > + struct clk_onecell_data *clk_data;
> > + int r;
> > + struct device_node *node = pdev->dev.of_node;
> > +
> > + clk_data = mtk_alloc_clk_data(CLK_BDP_NR);
> > +
> > + mtk_clk_register_gates(node, bdp_clks, ARRAY_SIZE(bdp_clks),
> > + clk_data);
> > +
> > + r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> > +
> > + return r;
> > +}
> > +
> > +static const struct of_device_id of_match_clk_mt2701_bdp[] = {
> > + { .compatible = "mediatek,mt2701-bdpsys", },
> > + {}
> > +};
> > +
> > +static int clk_mt2701_bdp_probe(struct platform_device *pdev)
> > +{
> > + int r;
> > +
> > + r = mtk_bdpsys_init(pdev);
>
> Why not just put the contents of that function here? I don't see
> the point of this.
Because of some historical reasons, we keep mtk_bdpsys_init() for
changing init points between CLK_OF_DECLARE() and probe() more easily. I
can move all contents from mtk_bdpsys_init() here in next patch.
> > + if (r) {
> > + dev_err(&pdev->dev,
> > + "could not register clock provider: %s: %d\n",
> > + pdev->name, r);
> > + }
> > +
> > + return r;
> > +}
> > +
> > +static struct platform_driver clk_mt2701_bdp_drv = {
> > + .probe = clk_mt2701_bdp_probe,
> > + .driver = {
> > + .name = "clk-mt2701-bdp",
> > + .of_match_table = of_match_clk_mt2701_bdp,
> > + },
> > +};
> > +
> > +builtin_platform_driver(clk_mt2701_bdp_drv);
> > diff --git a/drivers/clk/mediatek/clk-mt2701-eth.c b/drivers/clk/mediatek/clk-mt2701-eth.c
> > new file mode 100644
> > index 0000000..b2a71a4
> > --- /dev/null
> > +++ b/drivers/clk/mediatek/clk-mt2701-eth.c
> > @@ -0,0 +1,90 @@
> > +/*
> > + * Copyright (c) 2014 MediaTek Inc.
> > + * Author: Shunli Wang <shunli.wang@mediatek.com>
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> > + * GNU General Public License for more details.
> > + */
> > +
> > +#include <linux/clk-provider.h>
> > +#include <linux/platform_device.h>
> > +
> > +#include "clk-mtk.h"
> > +#include "clk-gate.h"
> > +
> > +#include <dt-bindings/clock/mt2701-clk.h>
> > +
> > +static const struct mtk_gate_regs eth_cg_regs = {
> > + .sta_ofs = 0x0030,
> > +};
> > +
> > +#define GATE_ETH(_id, _name, _parent, _shift) { \
> > + .id = _id, \
> > + .name = _name, \
> > + .parent_name = _parent, \
> > + .regs = ð_cg_regs, \
> > + .shift = _shift, \
> > + .ops = &mtk_clk_gate_ops_no_setclr_inv, \
> > + }
> > +
> > +static const struct mtk_gate eth_clks[] = {
> > + GATE_ETH(CLK_ETHSYS_HSDMA, "hsdma_clk", "ethif_sel", 5),
> > + GATE_ETH(CLK_ETHSYS_ESW, "esw_clk", "ethpll_500m_ck", 6),
> > + GATE_ETH(CLK_ETHSYS_GP2, "gp2_clk", "trgpll", 7),
> > + GATE_ETH(CLK_ETHSYS_GP1, "gp1_clk", "ethpll_500m_ck", 8),
> > + GATE_ETH(CLK_ETHSYS_PCM, "pcm_clk", "ethif_sel", 11),
> > + GATE_ETH(CLK_ETHSYS_GDMA, "gdma_clk", "ethif_sel", 14),
> > + GATE_ETH(CLK_ETHSYS_I2S, "i2s_clk", "ethif_sel", 17),
> > + GATE_ETH(CLK_ETHSYS_CRYPTO, "crypto_clk", "ethif_sel", 29),
> > +};
> > +
> > +static int mtk_ethsys_init(struct platform_device *pdev)
> > +{
> > + struct clk_onecell_data *clk_data;
> > + int r;
> > + struct device_node *node = pdev->dev.of_node;
> > +
> > + clk_data = mtk_alloc_clk_data(CLK_ETHSYS_NR);
> > +
> > + mtk_clk_register_gates(node, eth_clks, ARRAY_SIZE(eth_clks),
> > + clk_data);
> > +
> > + r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> > +
> > + return r;
>
> Just return of_clk_add_provider() please.
I'll change it in next patch.
> > +}
> > +
> > +static const struct of_device_id of_match_clk_mt2701_eth[] = {
> > + { .compatible = "mediatek,mt2701-ethsys", },
> > + {}
> > +};
> > +
> > +static int clk_mt2701_eth_probe(struct platform_device *pdev)
> > +{
> > + int r;
> > +
> > + r = mtk_ethsys_init(pdev);
>
> Same comment.
Okay.
> > + if (r) {
> > + dev_err(&pdev->dev,
> > + "could not register clock provider: %s: %d\n",
> > + pdev->name, r);
> > + }
> > +
> > + return r;
> > +}
> > +
> > +static struct platform_driver clk_mt2701_eth_drv = {
> > + .probe = clk_mt2701_eth_probe,
> > + .driver = {
> > + .name = "clk-mt2701-eth",
> > + .of_match_table = of_match_clk_mt2701_eth,
> > + },
> > +};
> > +
> > +builtin_platform_driver(clk_mt2701_eth_drv);
> > diff --git a/drivers/clk/mediatek/clk-mt2701-hif.c b/drivers/clk/mediatek/clk-mt2701-hif.c
> > new file mode 100644
> > index 0000000..e2b0039
> > --- /dev/null
> > +++ b/drivers/clk/mediatek/clk-mt2701-hif.c
> > @@ -0,0 +1,87 @@
> > +/*
> > + * Copyright (c) 2014 MediaTek Inc.
> > + * Author: Shunli Wang <shunli.wang@mediatek.com>
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> > + * GNU General Public License for more details.
> > + */
> > +
> > +#include <linux/clk-provider.h>
> > +#include <linux/platform_device.h>
> > +
> > +#include "clk-mtk.h"
> > +#include "clk-gate.h"
> > +
> > +#include <dt-bindings/clock/mt2701-clk.h>
> > +
> > +static const struct mtk_gate_regs hif_cg_regs = {
> > + .sta_ofs = 0x0030,
> > +};
> > +
> > +#define GATE_HIF(_id, _name, _parent, _shift) { \
> > + .id = _id, \
> > + .name = _name, \
> > + .parent_name = _parent, \
> > + .regs = &hif_cg_regs, \
> > + .shift = _shift, \
> > + .ops = &mtk_clk_gate_ops_no_setclr_inv, \
> > + }
> > +
> > +static const struct mtk_gate hif_clks[] = {
> > + GATE_HIF(CLK_HIFSYS_USB0PHY, "usb0_phy_clk", "ethpll_500m_ck", 21),
> > + GATE_HIF(CLK_HIFSYS_USB1PHY, "usb1_phy_clk", "ethpll_500m_ck", 22),
> > + GATE_HIF(CLK_HIFSYS_PCIE0, "pcie0_clk", "ethpll_500m_ck", 24),
> > + GATE_HIF(CLK_HIFSYS_PCIE1, "pcie1_clk", "ethpll_500m_ck", 25),
> > + GATE_HIF(CLK_HIFSYS_PCIE2, "pcie2_clk", "ethpll_500m_ck", 26),
> > +};
> > +
> > +static int mtk_hifsys_init(struct platform_device *pdev)
> > +{
> > + struct clk_onecell_data *clk_data;
> > + int r;
> > + struct device_node *node = pdev->dev.of_node;
> > +
> > + clk_data = mtk_alloc_clk_data(CLK_HIFSYS_NR);
> > +
> > + mtk_clk_register_gates(node, hif_clks, ARRAY_SIZE(hif_clks),
> > + clk_data);
> > +
> > + r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> > +
> > + return r;
>
> Just return of_clk_add_provider() please.
Okay.
> > +}
> > +
> > +static const struct of_device_id of_match_clk_mt2701_hif[] = {
> > + { .compatible = "mediatek,mt2701-hifsys", },
> > + {}
> > +};
> > +
> > +static int clk_mt2701_hif_probe(struct platform_device *pdev)
> > +{
> > + int r;
> > +
> > + r = mtk_hifsys_init(pdev);
>
> There's a pattern. Same comments apply for everything that uses
> this style.
I'll change them in next patch.
> > + if (r) {
> > + dev_err(&pdev->dev,
> > + "could not register clock provider: %s: %d\n",
> > + pdev->name, r);
> > + }
> > +
> > + return r;
> > +}
> > +
> > +static struct platform_driver clk_mt2701_hif_drv = {
> > + .probe = clk_mt2701_hif_probe,
> > + .driver = {
> > + .name = "clk-mt2701-hif",
> > + .of_match_table = of_match_clk_mt2701_hif,
> > + },
> > +};
> > +
> > +builtin_platform_driver(clk_mt2701_hif_drv);
> [cut a bunch of same drivers]
> > diff --git a/drivers/clk/mediatek/clk-mt2701.c b/drivers/clk/mediatek/clk-mt2701.c
> > new file mode 100644
> > index 0000000..c225256
> > --- /dev/null
> > +++ b/drivers/clk/mediatek/clk-mt2701.c
> > @@ -0,0 +1,1046 @@
> > +/*
> > + * Copyright (c) 2014 MediaTek Inc.
> > + * Author: Shunli Wang <shunli.wang@mediatek.com>
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> > + * GNU General Public License for more details.
> > + */
> > +
> > +#include <linux/clk-provider.h>
> > +#include <linux/of.h>
> > +#include <linux/of_address.h>
> > +#include <linux/of_device.h>
> > +#include <linux/platform_device.h>
> > +
> > +#include "clk-mtk.h"
> > +#include "clk-gate.h"
> > +
> > +#include <dt-bindings/clock/mt2701-clk.h>
> > +
> > +/*
> > + * For some clocks, we don't care what their actual rates are. And these
> > + * clocks may change their rate on different products or different scenarios.
> > + * So we model these clocks' rate as 0, to denote it's not an actual rate.
> > + */
> > +#define DUMMY_RATE 0
> > +
> > +static DEFINE_SPINLOCK(lock);
>
> Please name this something more mtk specific. mt2701_clk_lock?
Okay.
> > +
> > +static const struct mtk_fixed_clk top_fixed_clks[] = {
> > + FIXED_CLK(CLK_TOP_DPI, "dpi_ck", "clk26m",
> > + 108 * MHZ),
> > + FIXED_CLK(CLK_TOP_DMPLL, "dmpll_ck", "clk26m",
> > + 400 * MHZ),
> > + FIXED_CLK(CLK_TOP_VENCPLL, "vencpll_ck", "clk26m",
> > + 295750000),
> > + FIXED_CLK(CLK_TOP_HDMI_0_PIX340M, "hdmi_0_pix340m", "clk26m",
> > + 340 * MHZ),
> > + FIXED_CLK(CLK_TOP_HDMI_0_DEEP340M, "hdmi_0_deep340m", "clk26m",
> > + 340 * MHZ),
> > + FIXED_CLK(CLK_TOP_HDMI_0_PLL340M, "hdmi_0_pll340m", "clk26m",
> > + 340 * MHZ),
> > + FIXED_CLK(CLK_TOP_HDMITX_CLKDIG_CTS, "hdmitx_dig_cts", "clk26m",
> > + 300 * MHZ),
> > + FIXED_CLK(CLK_TOP_HADDS2_FB, "hadds2_fbclk", "clk26m",
> > + 27 * MHZ),
> > + FIXED_CLK(CLK_TOP_WBG_DIG_416M, "wbg_dig_ck_416m", "clk26m",
> > + 416 * MHZ),
> > + FIXED_CLK(CLK_TOP_DSI0_LNTC_DSI, "dsi0_lntc_dsi", "clk26m",
> > + 143 * MHZ),
> > + FIXED_CLK(CLK_TOP_HDMI_SCL_RX, "hdmi_scl_rx", "clk26m",
> > + 27 * MHZ),
> > + FIXED_CLK(CLK_TOP_AUD_EXT1, "aud_ext1", "clk26m",
> > + DUMMY_RATE),
> > + FIXED_CLK(CLK_TOP_AUD_EXT2, "aud_ext2", "clk26m",
> > + DUMMY_RATE),
> > + FIXED_CLK(CLK_TOP_NFI1X_PAD, "nfi1x_pad", "clk26m",
> > + DUMMY_RATE),
> > +};
> > +
> > +static const struct mtk_fixed_factor top_fixed_divs[] = {
> > + FACTOR(CLK_TOP_SYSPLL, "syspll_ck", "mainpll", 1, 1),
> > + FACTOR(CLK_TOP_SYSPLL_D2, "syspll_d2", "mainpll", 1, 2),
> > + FACTOR(CLK_TOP_SYSPLL_D3, "syspll_d3", "mainpll", 1, 3),
> > + FACTOR(CLK_TOP_SYSPLL_D5, "syspll_d5", "mainpll", 1, 5),
> > + FACTOR(CLK_TOP_SYSPLL_D7, "syspll_d7", "mainpll", 1, 7),
> > + FACTOR(CLK_TOP_SYSPLL1_D2, "syspll1_d2", "syspll_d2", 1, 2),
> > + FACTOR(CLK_TOP_SYSPLL1_D4, "syspll1_d4", "syspll_d2", 1, 4),
> > + FACTOR(CLK_TOP_SYSPLL1_D8, "syspll1_d8", "syspll_d2", 1, 8),
> > + FACTOR(CLK_TOP_SYSPLL1_D16, "syspll1_d16", "syspll_d2", 1, 16),
> > + FACTOR(CLK_TOP_SYSPLL2_D2, "syspll2_d2", "syspll_d3", 1, 2),
> > + FACTOR(CLK_TOP_SYSPLL2_D4, "syspll2_d4", "syspll_d3", 1, 4),
> > + FACTOR(CLK_TOP_SYSPLL2_D8, "syspll2_d8", "syspll_d3", 1, 8),
> > + FACTOR(CLK_TOP_SYSPLL3_D2, "syspll3_d2", "syspll_d5", 1, 2),
> > + FACTOR(CLK_TOP_SYSPLL3_D4, "syspll3_d4", "syspll_d5", 1, 4),
> > + FACTOR(CLK_TOP_SYSPLL4_D2, "syspll4_d2", "syspll_d7", 1, 2),
> > + FACTOR(CLK_TOP_SYSPLL4_D4, "syspll4_d4", "syspll_d7", 1, 4),
> > +
> > + FACTOR(CLK_TOP_UNIVPLL, "univpll_ck", "univpll", 1, 1),
> > + FACTOR(CLK_TOP_UNIVPLL_D2, "univpll_d2", "univpll", 1, 2),
> > + FACTOR(CLK_TOP_UNIVPLL_D3, "univpll_d3", "univpll", 1, 3),
> > + FACTOR(CLK_TOP_UNIVPLL_D5, "univpll_d5", "univpll", 1, 5),
> > + FACTOR(CLK_TOP_UNIVPLL_D7, "univpll_d7", "univpll", 1, 7),
> > + FACTOR(CLK_TOP_UNIVPLL_D26, "univpll_d26", "univpll", 1, 26),
> > + FACTOR(CLK_TOP_UNIVPLL_D52, "univpll_d52", "univpll", 1, 52),
> > + FACTOR(CLK_TOP_UNIVPLL_D108, "univpll_d108", "univpll", 1, 108),
> > + FACTOR(CLK_TOP_USB_PHY48M, "usb_phy48m_ck", "univpll", 1, 26),
> > + FACTOR(CLK_TOP_UNIVPLL1_D2, "univpll1_d2", "univpll_d2", 1, 2),
> > + FACTOR(CLK_TOP_UNIVPLL1_D4, "univpll1_d4", "univpll_d2", 1, 4),
> > + FACTOR(CLK_TOP_UNIVPLL1_D8, "univpll1_d8", "univpll_d2", 1, 8),
> > + FACTOR(CLK_TOP_8BDAC, "8bdac_ck", "univpll_d2", 1, 1),
> > + FACTOR(CLK_TOP_UNIVPLL2_D2, "univpll2_d2", "univpll_d3", 1, 2),
> > + FACTOR(CLK_TOP_UNIVPLL2_D4, "univpll2_d4", "univpll_d3", 1, 4),
> > + FACTOR(CLK_TOP_UNIVPLL2_D8, "univpll2_d8", "univpll_d3", 1, 8),
> > + FACTOR(CLK_TOP_UNIVPLL2_D16, "univpll2_d16", "univpll_d3", 1, 16),
> > + FACTOR(CLK_TOP_UNIVPLL2_D32, "univpll2_d32", "univpll_d3", 1, 32),
> > + FACTOR(CLK_TOP_UNIVPLL3_D2, "univpll3_d2", "univpll_d5", 1, 2),
> > + FACTOR(CLK_TOP_UNIVPLL3_D4, "univpll3_d4", "univpll_d5", 1, 4),
> > + FACTOR(CLK_TOP_UNIVPLL3_D8, "univpll3_d8", "univpll_d5", 1, 8),
> > +
> > + FACTOR(CLK_TOP_MSDCPLL, "msdcpll_ck", "msdcpll", 1, 1),
> > + FACTOR(CLK_TOP_MSDCPLL_D2, "msdcpll_d2", "msdcpll", 1, 2),
> > + FACTOR(CLK_TOP_MSDCPLL_D4, "msdcpll_d4", "msdcpll", 1, 4),
> > + FACTOR(CLK_TOP_MSDCPLL_D8, "msdcpll_d8", "msdcpll", 1, 8),
> > +
> > + FACTOR(CLK_TOP_MMPLL, "mmpll_ck", "mmpll", 1, 1),
> > + FACTOR(CLK_TOP_MMPLL_D2, "mmpll_d2", "mmpll", 1, 2),
> > +
> > + FACTOR(CLK_TOP_DMPLL_D2, "dmpll_d2", "dmpll_ck", 1, 2),
> > + FACTOR(CLK_TOP_DMPLL_D4, "dmpll_d4", "dmpll_ck", 1, 4),
> > + FACTOR(CLK_TOP_DMPLL_X2, "dmpll_x2", "dmpll_ck", 1, 1),
> > +
> > + FACTOR(CLK_TOP_TVDPLL, "tvdpll_ck", "tvdpll", 1, 1),
> > + FACTOR(CLK_TOP_TVDPLL_D2, "tvdpll_d2", "tvdpll", 1, 2),
> > + FACTOR(CLK_TOP_TVDPLL_D4, "tvdpll_d4", "tvdpll", 1, 4),
> > +
> > + FACTOR(CLK_TOP_VDECPLL, "vdecpll_ck", "vdecpll", 1, 1),
> > + FACTOR(CLK_TOP_TVD2PLL, "tvd2pll_ck", "tvd2pll", 1, 1),
> > + FACTOR(CLK_TOP_TVD2PLL_D2, "tvd2pll_d2", "tvd2pll", 1, 2),
> > +
> > + FACTOR(CLK_TOP_MIPIPLL, "mipipll", "dpi_ck", 1, 1),
> > + FACTOR(CLK_TOP_MIPIPLL_D2, "mipipll_d2", "dpi_ck", 1, 2),
> > + FACTOR(CLK_TOP_MIPIPLL_D4, "mipipll_d4", "dpi_ck", 1, 4),
> > +
> > + FACTOR(CLK_TOP_HDMIPLL, "hdmipll_ck", "hdmitx_dig_cts", 1, 1),
> > + FACTOR(CLK_TOP_HDMIPLL_D2, "hdmipll_d2", "hdmitx_dig_cts", 1, 2),
> > + FACTOR(CLK_TOP_HDMIPLL_D3, "hdmipll_d3", "hdmitx_dig_cts", 1, 3),
> > +
> > + FACTOR(CLK_TOP_ARMPLL_1P3G, "armpll_1p3g_ck", "armpll", 1, 1),
> > +
> > + FACTOR(CLK_TOP_AUDPLL, "audpll", "audpll_sel", 1, 1),
> > + FACTOR(CLK_TOP_AUDPLL_D4, "audpll_d4", "audpll_sel", 1, 4),
> > + FACTOR(CLK_TOP_AUDPLL_D8, "audpll_d8", "audpll_sel", 1, 8),
> > + FACTOR(CLK_TOP_AUDPLL_D16, "audpll_d16", "audpll_sel", 1, 16),
> > + FACTOR(CLK_TOP_AUDPLL_D24, "audpll_d24", "audpll_sel", 1, 24),
> > +
> > + FACTOR(CLK_TOP_AUD1PLL_98M, "aud1pll_98m_ck", "aud1pll", 1, 3),
> > + FACTOR(CLK_TOP_AUD2PLL_90M, "aud2pll_90m_ck", "aud2pll", 1, 3),
> > + FACTOR(CLK_TOP_HADDS2PLL_98M, "hadds2pll_98m", "hadds2pll", 1, 3),
> > + FACTOR(CLK_TOP_HADDS2PLL_294M, "hadds2pll_294m", "hadds2pll", 1, 1),
> > + FACTOR(CLK_TOP_ETHPLL_500M, "ethpll_500m_ck", "ethpll", 1, 1),
> > + FACTOR(CLK_TOP_CLK26M_D8, "clk26m_d8", "clk26m", 1, 8),
> > + FACTOR(CLK_TOP_32K_INTERNAL, "32k_internal", "clk26m", 1, 793),
> > + FACTOR(CLK_TOP_32K_EXTERNAL, "32k_external", "rtc32k", 1, 1),
> > +};
> > +
> > +static const char * const axi_parents[] = {
> > + "clk26m",
> > + "syspll1_d2",
> > + "syspll_d5",
> > + "syspll1_d4",
> > + "univpll_d5",
> > + "univpll2_d2",
> > + "mmpll_d2",
> > + "dmpll_d2"
> > +};
> > +
> > +static const char * const mem_parents[] = {
> > + "clk26m",
> > + "dmpll_ck"
> > +};
> > +
> > +static const char * const ddrphycfg_parents[] = {
> > + "clk26m",
> > + "syspll1_d8"
> > +};
> > +
> > +static const char * const mm_parents[] = {
> > + "clk26m",
> > + "vencpll_ck",
> > + "syspll1_d2",
> > + "syspll1_d4",
> > + "univpll_d5",
> > + "univpll1_d2",
> > + "univpll2_d2",
> > + "dmpll_ck"
> > +};
> > +
> > +static const char * const pwm_parents[] = {
> > + "clk26m",
> > + "univpll2_d4",
> > + "univpll3_d2",
> > + "univpll1_d4",
> > +};
> > +
> > +static const char * const vdec_parents[] = {
> > + "clk26m",
> > + "vdecpll_ck",
> > + "syspll_d5",
> > + "syspll1_d4",
> > + "univpll_d5",
> > + "univpll2_d2",
> > + "vencpll_ck",
> > + "msdcpll_d2",
> > + "mmpll_d2"
> > +};
> > +
> > +static const char * const mfg_parents[] = {
> > + "clk26m",
> > + "mmpll_ck",
> > + "dmpll_x2_ck",
> > + "msdcpll_ck",
> > + "clk26m",
> > + "syspll_d3",
> > + "univpll_d3",
> > + "univpll1_d2"
> > +};
> > +
> > +static const char * const camtg_parents[] = {
> > + "clk26m",
> > + "univpll_d26",
> > + "univpll2_d2",
> > + "syspll3_d2",
> > + "syspll3_d4",
> > + "msdcpll_d2",
> > + "mmpll_d2"
> > +};
> > +
> > +static const char * const uart_parents[] = {
> > + "clk26m",
> > + "univpll2_d8"
> > +};
> > +
> > +static const char * const spi_parents[] = {
> > + "clk26m",
> > + "syspll3_d2",
> > + "syspll4_d2",
> > + "univpll2_d4",
> > + "univpll1_d8"
> > +};
> > +
> > +static const char * const usb20_parents[] = {
> > + "clk26m",
> > + "univpll1_d8",
> > + "univpll3_d4"
> > +};
> > +
> > +static const char * const msdc30_parents[] = {
> > + "clk26m",
> > + "msdcpll_d2",
> > + "syspll2_d2",
> > + "syspll1_d4",
> > + "univpll1_d4",
> > + "univpll2_d4"
> > +};
> > +
> > +static const char * const audio_parents[] = {
> > + "clk26m",
> > + "syspll1_d16"
> > +};
> > +
> > +static const char * const aud_intbus_parents[] = {
> > + "clk26m",
> > + "syspll1_d4",
> > + "syspll3_d2",
> > + "syspll4_d2",
> > + "univpll3_d2",
> > + "univpll2_d4"
> > +};
> > +
> > +static const char * const pmicspi_parents[] = {
> > + "clk26m",
> > + "syspll1_d8",
> > + "syspll2_d4",
> > + "syspll4_d2",
> > + "syspll3_d4",
> > + "syspll2_d8",
> > + "syspll1_d16",
> > + "univpll3_d4",
> > + "univpll_d26",
> > + "dmpll_d2",
> > + "dmpll_d4"
> > +};
> > +
> > +static const char * const scp_parents[] = {
> > + "clk26m",
> > + "syspll1_d8",
> > + "dmpll_d2",
> > + "dmpll_d4"
> > +};
> > +
> > +static const char * const dpi0_parents[] = {
> > + "clk26m",
> > + "mipipll",
> > + "mipipll_d2",
> > + "mipipll_d4",
> > + "clk26m",
> > + "tvdpll_ck",
> > + "tvdpll_d2",
> > + "tvdpll_d4"
> > +};
> > +
> > +static const char * const dpi1_parents[] = {
> > + "clk26m",
> > + "tvdpll_ck",
> > + "tvdpll_d2",
> > + "tvdpll_d4"
> > +};
> > +
> > +static const char * const tve_parents[] = {
> > + "clk26m",
> > + "mipipll",
> > + "mipipll_d2",
> > + "mipipll_d4",
> > + "clk26m",
> > + "tvdpll_ck",
> > + "tvdpll_d2",
> > + "tvdpll_d4"
> > +};
> > +
> > +static const char * const hdmi_parents[] = {
> > + "clk26m",
> > + "hdmipll_ck",
> > + "hdmipll_d2",
> > + "hdmipll_d3"
> > +};
> > +
> > +static const char * const apll_parents[] = {
> > + "clk26m",
> > + "audpll",
> > + "audpll_d4",
> > + "audpll_d8",
> > + "audpll_d16",
> > + "audpll_d24",
> > + "clk26m",
> > + "clk26m"
> > +};
> > +
> > +static const char * const rtc_parents[] = {
> > + "32k_internal",
> > + "32k_external",
> > + "clk26m",
> > + "univpll3_d8"
> > +};
> > +
> > +static const char * const nfi2x_parents[] = {
> > + "clk26m",
> > + "syspll2_d2",
> > + "syspll_d7",
> > + "univpll3_d2",
> > + "syspll2_d4",
> > + "univpll3_d4",
> > + "syspll4_d4",
> > + "clk26m"
> > +};
> > +
> > +static const char * const emmc_hclk_parents[] = {
> > + "clk26m",
> > + "syspll1_d2",
> > + "syspll1_d4",
> > + "syspll2_d2"
> > +};
> > +
> > +static const char * const flash_parents[] = {
> > + "clk26m_d8",
> > + "clk26m",
> > + "syspll2_d8",
> > + "syspll3_d4",
> > + "univpll3_d4",
> > + "syspll4_d2",
> > + "syspll2_d4",
> > + "univpll2_d4"
> > +};
> > +
> > +static const char * const di_parents[] = {
> > + "clk26m",
> > + "tvd2pll_ck",
> > + "tvd2pll_d2",
> > + "clk26m"
> > +};
> > +
> > +static const char * const nr_osd_parents[] = {
> > + "clk26m",
> > + "vencpll_ck",
> > + "syspll1_d2",
> > + "syspll1_d4",
> > + "univpll_d5",
> > + "univpll1_d2",
> > + "univpll2_d2",
> > + "dmpll_ck"
> > +};
> > +
> > +static const char * const hdmirx_bist_parents[] = {
> > + "clk26m",
> > + "syspll_d3",
> > + "clk26m",
> > + "syspll1_d16",
> > + "syspll4_d2",
> > + "syspll1_d4",
> > + "vencpll_ck",
> > + "clk26m"
> > +};
> > +
> > +static const char * const intdir_parents[] = {
> > + "clk26m",
> > + "mmpll_ck",
> > + "syspll_d2",
> > + "univpll_d2"
> > +};
> > +
> > +static const char * const asm_parents[] = {
> > + "clk26m",
> > + "univpll2_d4",
> > + "univpll2_d2",
> > + "syspll_d5"
> > +};
> > +
> > +static const char * const ms_card_parents[] = {
> > + "clk26m",
> > + "univpll3_d8",
> > + "syspll4_d4"
> > +};
> > +
> > +static const char * const ethif_parents[] = {
> > + "clk26m",
> > + "syspll1_d2",
> > + "syspll_d5",
> > + "syspll1_d4",
> > + "univpll_d5",
> > + "univpll1_d2",
> > + "dmpll_ck",
> > + "dmpll_d2"
> > +};
> > +
> > +static const char * const hdmirx_parents[] = {
> > + "clk26m",
> > + "univpll_d52"
> > +};
> > +
> > +static const char * const cmsys_parents[] = {
> > + "clk26m",
> > + "syspll1_d2",
> > + "univpll1_d2",
> > + "univpll_d5",
> > + "syspll_d5",
> > + "syspll2_d2",
> > + "syspll1_d4",
> > + "syspll3_d2",
> > + "syspll2_d4",
> > + "syspll1_d8",
> > + "clk26m",
> > + "clk26m",
> > + "clk26m",
> > + "clk26m",
> > + "clk26m"
> > +};
> > +
> > +static const char * const clk_8bdac_parents[] = {
> > + "32k_internal",
> > + "8bdac_ck",
> > + "clk26m",
> > + "clk26m"
> > +};
> > +
> > +static const char * const aud2dvd_parents[] = {
> > + "a1sys_hp_ck",
> > + "a2sys_hp_ck"
> > +};
> > +
> > +static const char * const padmclk_parents[] = {
> > + "clk26m",
> > + "univpll_d26",
> > + "univpll_d52",
> > + "univpll_d108",
> > + "univpll2_d8",
> > + "univpll2_d16",
> > + "univpll2_d32"
> > +};
> > +
> > +static const char * const aud_mux_parents[] = {
> > + "clk26m",
> > + "aud1pll_98m_ck",
> > + "aud2pll_90m_ck",
> > + "hadds2pll_98m",
> > + "audio_ext1_ck",
> > + "audio_ext2_ck"
> > +};
> > +
> > +static const char * const aud_src_parents[] = {
> > + "aud_mux1_sel",
> > + "aud_mux2_sel"
> > +};
> > +
> > +static const char * const cpu_parents[] = {
> > + "clk26m",
> > + "armpll",
> > + "mainpll",
> > + "mmpll"
> > +};
> > +
> > +static const struct mtk_composite top_muxes[] = {
> > + MUX_GATE_FLAGS(CLK_TOP_AXI_SEL, "axi_sel", axi_parents,
> > + 0x0040, 0, 3, 7, CLK_IS_CRITICAL),
> > + MUX_GATE_FLAGS(CLK_TOP_MEM_SEL, "mem_sel", mem_parents,
> > + 0x0040, 8, 1, 15, CLK_IS_CRITICAL),
> > + MUX_GATE_FLAGS(CLK_TOP_DDRPHYCFG_SEL, "ddrphycfg_sel",
> > + ddrphycfg_parents, 0x0040, 16, 1, 23, CLK_IS_CRITICAL),
> > + MUX_GATE(CLK_TOP_MM_SEL, "mm_sel", mm_parents,
> > + 0x0040, 24, 3, 31),
> > +
> > + MUX_GATE(CLK_TOP_PWM_SEL, "pwm_sel", pwm_parents,
> > + 0x0050, 0, 2, 7),
> > + MUX_GATE(CLK_TOP_VDEC_SEL, "vdec_sel", vdec_parents,
> > + 0x0050, 8, 4, 15),
> > + MUX_GATE(CLK_TOP_MFG_SEL, "mfg_sel", mfg_parents,
> > + 0x0050, 16, 3, 23),
> > + MUX_GATE(CLK_TOP_CAMTG_SEL, "camtg_sel", camtg_parents,
> > + 0x0050, 24, 3, 31),
> > + MUX_GATE(CLK_TOP_UART_SEL, "uart_sel", uart_parents,
> > + 0x0060, 0, 1, 7),
> > +
> > + MUX_GATE(CLK_TOP_SPI0_SEL, "spi0_sel", spi_parents,
> > + 0x0060, 8, 3, 15),
> > + MUX_GATE(CLK_TOP_USB20_SEL, "usb20_sel", usb20_parents,
> > + 0x0060, 16, 2, 23),
> > + MUX_GATE(CLK_TOP_MSDC30_0_SEL, "msdc30_0_sel", msdc30_parents,
> > + 0x0060, 24, 3, 31),
> > +
> > + MUX_GATE(CLK_TOP_MSDC30_1_SEL, "msdc30_1_sel", msdc30_parents,
> > + 0x0070, 0, 3, 7),
> > + MUX_GATE(CLK_TOP_MSDC30_2_SEL, "msdc30_2_sel", msdc30_parents,
> > + 0x0070, 8, 3, 15),
> > + MUX_GATE(CLK_TOP_AUDIO_SEL, "audio_sel", msdc30_parents,
> > + 0x0070, 16, 1, 23),
> > + MUX_GATE(CLK_TOP_AUDINTBUS_SEL, "aud_intbus_sel", aud_intbus_parents,
> > + 0x0070, 24, 3, 31),
> > +
> > + MUX_GATE(CLK_TOP_PMICSPI_SEL, "pmicspi_sel", pmicspi_parents,
> > + 0x0080, 0, 4, 7),
> > + MUX_GATE(CLK_TOP_SCP_SEL, "scp_sel", scp_parents,
> > + 0x0080, 8, 2, 15),
> > + MUX_GATE(CLK_TOP_DPI0_SEL, "dpi0_sel", dpi0_parents,
> > + 0x0080, 16, 3, 23),
> > + MUX_GATE(CLK_TOP_DPI1_SEL, "dpi1_sel", dpi1_parents,
> > + 0x0080, 24, 2, 31),
> > +
> > + MUX_GATE(CLK_TOP_TVE_SEL, "tve_sel", tve_parents,
> > + 0x0090, 0, 3, 7),
> > + MUX_GATE(CLK_TOP_HDMI_SEL, "hdmi_sel", hdmi_parents,
> > + 0x0090, 8, 2, 15),
> > + MUX_GATE(CLK_TOP_APLL_SEL, "apll_sel", apll_parents,
> > + 0x0090, 16, 3, 23),
> > +
> > + MUX_GATE_FLAGS(CLK_TOP_RTC_SEL, "rtc_sel", rtc_parents,
> > + 0x00A0, 0, 2, 7, CLK_IS_CRITICAL),
> > + MUX_GATE(CLK_TOP_NFI2X_SEL, "nfi2x_sel", nfi2x_parents,
> > + 0x00A0, 8, 3, 15),
> > + MUX_GATE(CLK_TOP_EMMC_HCLK_SEL, "emmc_hclk_sel", emmc_hclk_parents,
> > + 0x00A0, 24, 2, 31),
> > +
> > + MUX_GATE(CLK_TOP_FLASH_SEL, "flash_sel", flash_parents,
> > + 0x00B0, 0, 3, 7),
> > + MUX_GATE(CLK_TOP_DI_SEL, "di_sel", di_parents,
> > + 0x00B0, 8, 2, 15),
> > + MUX_GATE(CLK_TOP_NR_SEL, "nr_sel", nr_osd_parents,
> > + 0x00B0, 16, 3, 23),
> > + MUX_GATE(CLK_TOP_OSD_SEL, "osd_sel", nr_osd_parents,
> > + 0x00B0, 24, 3, 31),
> > +
> > + MUX_GATE(CLK_TOP_HDMIRX_BIST_SEL, "hdmirx_bist_sel",
> > + hdmirx_bist_parents, 0x00C0, 0, 3, 7),
> > + MUX_GATE(CLK_TOP_INTDIR_SEL, "intdir_sel", intdir_parents,
> > + 0x00C0, 8, 2, 15),
> > + MUX_GATE(CLK_TOP_ASM_I_SEL, "asm_i_sel", asm_parents,
> > + 0x00C0, 16, 2, 23),
> > + MUX_GATE(CLK_TOP_ASM_M_SEL, "asm_m_sel", asm_parents,
> > + 0x00C0, 24, 3, 31),
> > +
> > + MUX_GATE(CLK_TOP_ASM_H_SEL, "asm_h_sel", asm_parents,
> > + 0x00D0, 0, 2, 7),
> > + MUX_GATE(CLK_TOP_MS_CARD_SEL, "ms_card_sel", ms_card_parents,
> > + 0x00D0, 16, 2, 23),
> > + MUX_GATE(CLK_TOP_ETHIF_SEL, "ethif_sel", ethif_parents,
> > + 0x00D0, 24, 3, 31),
> > +
> > + MUX_GATE(CLK_TOP_HDMIRX26_24_SEL, "hdmirx26_24_sel", hdmirx_parents,
> > + 0x00E0, 0, 1, 7),
> > + MUX_GATE(CLK_TOP_MSDC30_3_SEL, "msdc30_3_sel", msdc30_parents,
> > + 0x00E0, 8, 3, 15),
> > + MUX_GATE(CLK_TOP_CMSYS_SEL, "cmsys_sel", cmsys_parents,
> > + 0x00E0, 16, 4, 23),
> > +
> > + MUX_GATE(CLK_TOP_SPI1_SEL, "spi2_sel", spi_parents,
> > + 0x00E0, 24, 3, 31),
> > + MUX_GATE(CLK_TOP_SPI2_SEL, "spi1_sel", spi_parents,
> > + 0x00F0, 0, 3, 7),
> > + MUX_GATE(CLK_TOP_8BDAC_SEL, "8bdac_sel", clk_8bdac_parents,
> > + 0x00F0, 8, 2, 15),
> > + MUX_GATE(CLK_TOP_AUD2DVD_SEL, "aud2dvd_sel", aud2dvd_parents,
> > + 0x00F0, 16, 1, 23),
> > +
> > + MUX(CLK_TOP_PADMCLK_SEL, "padmclk_sel", padmclk_parents,
> > + 0x0100, 0, 3),
> > +
> > + MUX(CLK_TOP_AUD_MUX1_SEL, "aud_mux1_sel", aud_mux_parents,
> > + 0x012c, 0, 3),
> > + MUX(CLK_TOP_AUD_MUX2_SEL, "aud_mux2_sel", aud_mux_parents,
> > + 0x012c, 3, 3),
> > + MUX(CLK_TOP_AUDPLL_MUX_SEL, "audpll_sel", aud_mux_parents,
> > + 0x012c, 6, 3),
> > + MUX_GATE(CLK_TOP_AUD_K1_SRC_SEL, "aud_k1_src_sel", aud_src_parents,
> > + 0x012c, 15, 1, 23),
> > + MUX_GATE(CLK_TOP_AUD_K2_SRC_SEL, "aud_k2_src_sel", aud_src_parents,
> > + 0x012c, 16, 1, 24),
> > + MUX_GATE(CLK_TOP_AUD_K3_SRC_SEL, "aud_k3_src_sel", aud_src_parents,
> > + 0x012c, 17, 1, 25),
> > + MUX_GATE(CLK_TOP_AUD_K4_SRC_SEL, "aud_k4_src_sel", aud_src_parents,
> > + 0x012c, 18, 1, 26),
> > + MUX_GATE(CLK_TOP_AUD_K5_SRC_SEL, "aud_k5_src_sel", aud_src_parents,
> > + 0x012c, 19, 1, 27),
> > + MUX_GATE(CLK_TOP_AUD_K6_SRC_SEL, "aud_k6_src_sel", aud_src_parents,
> > + 0x012c, 20, 1, 28),
> > +};
> > +
> > +static const struct mtk_clk_divider top_adj_divs[] = {
> > + DIV_ADJ(CLK_TOP_AUD_EXTCK1_DIV, "audio_ext1_ck", "aud_ext1",
> > + 0x0120, 0, 8),
> > + DIV_ADJ(CLK_TOP_AUD_EXTCK2_DIV, "audio_ext2_ck", "aud_ext2",
> > + 0x0120, 8, 8),
> > + DIV_ADJ(CLK_TOP_AUD_MUX1_DIV, "aud_mux1_div", "aud_mux1_sel",
> > + 0x0120, 16, 8),
> > + DIV_ADJ(CLK_TOP_AUD_MUX2_DIV, "aud_mux2_div", "aud_mux2_sel",
> > + 0x0120, 24, 8),
> > + DIV_ADJ(CLK_TOP_AUD_K1_SRC_DIV, "aud_k1_src_div", "aud_k1_src_sel",
> > + 0x0124, 0, 8),
> > + DIV_ADJ(CLK_TOP_AUD_K2_SRC_DIV, "aud_k2_src_div", "aud_k2_src_sel",
> > + 0x0124, 8, 8),
> > + DIV_ADJ(CLK_TOP_AUD_K3_SRC_DIV, "aud_k3_src_div", "aud_k3_src_sel",
> > + 0x0124, 16, 8),
> > + DIV_ADJ(CLK_TOP_AUD_K4_SRC_DIV, "aud_k4_src_div", "aud_k4_src_sel",
> > + 0x0124, 24, 8),
> > + DIV_ADJ(CLK_TOP_AUD_K5_SRC_DIV, "aud_k5_src_div", "aud_k5_src_sel",
> > + 0x0128, 0, 8),
> > + DIV_ADJ(CLK_TOP_AUD_K6_SRC_DIV, "aud_k6_src_div", "aud_k6_src_sel",
> > + 0x0128, 8, 8),
> > +};
> > +
> > +static const struct mtk_gate_regs top_aud_cg_regs = {
> > + .sta_ofs = 0x012C,
> > +};
> > +
> > +#define GATE_TOP_AUD(_id, _name, _parent, _shift) { \
> > + .id = _id, \
> > + .name = _name, \
> > + .parent_name = _parent, \
> > + .regs = &top_aud_cg_regs, \
> > + .shift = _shift, \
> > + .ops = &mtk_clk_gate_ops_no_setclr, \
> > + }
> > +
> > +static const struct mtk_gate top_clks[] = {
> > + GATE_TOP_AUD(CLK_TOP_AUD_48K_TIMING, "a1sys_hp_ck", "aud_mux1_div",
> > + 21),
> > + GATE_TOP_AUD(CLK_TOP_AUD_44K_TIMING, "a2sys_hp_ck", "aud_mux2_div",
> > + 22),
> > + GATE_TOP_AUD(CLK_TOP_AUD_I2S1_MCLK, "aud_i2s1_mclk", "aud_k1_src_div",
> > + 23),
> > + GATE_TOP_AUD(CLK_TOP_AUD_I2S2_MCLK, "aud_i2s2_mclk", "aud_k2_src_div",
> > + 24),
> > + GATE_TOP_AUD(CLK_TOP_AUD_I2S3_MCLK, "aud_i2s3_mclk", "aud_k3_src_div",
> > + 25),
> > + GATE_TOP_AUD(CLK_TOP_AUD_I2S4_MCLK, "aud_i2s4_mclk", "aud_k4_src_div",
> > + 26),
> > + GATE_TOP_AUD(CLK_TOP_AUD_I2S5_MCLK, "aud_i2s5_mclk", "aud_k5_src_div",
> > + 27),
> > + GATE_TOP_AUD(CLK_TOP_AUD_I2S6_MCLK, "aud_i2s6_mclk", "aud_k6_src_div",
> > + 28),
> > +};
> > +
> > +void __iomem *devm_of_iomap(struct device *dev, int index)
>
> Sorry what is this?
To reduce duplicated code of looking up base address.
> > +{
> > + struct resource res;
> > +
> > + if (!dev)
> > + return NULL;
> > +
> > + if (of_address_to_resource(dev->of_node, index, &res))
> > + return NULL;
> > +
> > + return devm_ioremap(dev, res.start, resource_size(&res));
>
> Can't we just use platform_get_resouce() and
> devm_ioremap_resource() here? It looks like we always have a
> platform device.
I'll change it with these 2 functions.
> > +}
> > +
> > +static int mtk_topckgen_init(struct platform_device *pdev)
> > +{
> > + struct clk_onecell_data *clk_data;
> > + void __iomem *base;
> > + int r;
> > + struct device_node *node = pdev->dev.of_node;
> > +
> > + base = devm_of_iomap(&pdev->dev, 0);
> > + if (!base)
> > + return -ENOMEM;
> > +
> > + clk_data = mtk_alloc_clk_data(CLK_TOP_NR);
> > +
> > + mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks),
> > + clk_data);
> > +
> > + mtk_clk_register_factors(top_fixed_divs, ARRAY_SIZE(top_fixed_divs),
> > + clk_data);
> > +
> > + mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes),
> > + base, &lock, clk_data);
> > +
> > + mtk_clk_register_dividers(top_adj_divs, ARRAY_SIZE(top_adj_divs),
> > + base, &lock, clk_data);
> > +
> > + mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks),
> > + clk_data);
> > +
> > + r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> > +
> > + return r;
> > +}
> > +
> > +static const struct mtk_gate_regs infra_cg_regs = {
> > + .set_ofs = 0x0040,
> > + .clr_ofs = 0x0044,
> > + .sta_ofs = 0x0048,
> > +};
> > +
> > +#define GATE_ICG(_id, _name, _parent, _shift) { \
> > + .id = _id, \
> > + .name = _name, \
> > + .parent_name = _parent, \
> > + .regs = &infra_cg_regs, \
> > + .shift = _shift, \
> > + .ops = &mtk_clk_gate_ops_setclr, \
> > + }
> > +
> > +static const struct mtk_gate infra_clks[] = {
> > + GATE_ICG(CLK_INFRA_DBG, "dbgclk", "axi_sel", 0),
> > + GATE_ICG(CLK_INFRA_SMI, "smi_ck", "mm_sel", 1),
> > + GATE_ICG(CLK_INFRA_QAXI_CM4, "cm4_ck", "axi_sel", 2),
> > + GATE_ICG(CLK_INFRA_AUD_SPLIN_B, "audio_splin_bck", "hadds2pll_294m", 4),
> > + GATE_ICG(CLK_INFRA_AUDIO, "audio_ck", "clk26m", 5),
> > + GATE_ICG(CLK_INFRA_EFUSE, "efuse_ck", "clk26m", 6),
> > + GATE_ICG(CLK_INFRA_L2C_SRAM, "l2c_sram_ck", "mm_sel", 7),
> > + GATE_ICG(CLK_INFRA_M4U, "m4u_ck", "mem_sel", 8),
> > + GATE_ICG(CLK_INFRA_CONNMCU, "connsys_bus", "wbg_dig_ck_416m", 12),
> > + GATE_ICG(CLK_INFRA_TRNG, "trng_ck", "axi_sel", 13),
> > + GATE_ICG(CLK_INFRA_RAMBUFIF, "rambufif_ck", "mem_sel", 14),
> > + GATE_ICG(CLK_INFRA_CPUM, "cpum_ck", "mem_sel", 15),
> > + GATE_ICG(CLK_INFRA_KP, "kp_ck", "axi_sel", 16),
> > + GATE_ICG(CLK_INFRA_CEC, "cec_ck", "rtc_sel", 18),
> > + GATE_ICG(CLK_INFRA_IRRX, "irrx_ck", "axi_sel", 19),
> > + GATE_ICG(CLK_INFRA_PMICSPI, "pmicspi_ck", "pmicspi_sel", 22),
> > + GATE_ICG(CLK_INFRA_PMICWRAP, "pmicwrap_ck", "axi_sel", 23),
> > + GATE_ICG(CLK_INFRA_DDCCI, "ddcci_ck", "axi_sel", 24),
> > +};
> > +
> > +static const struct mtk_fixed_factor infra_fixed_divs[] = {
> > + FACTOR(CLK_INFRA_CLK_13M, "clk13m", "clk26m", 1, 2),
> > +};
> > +
> > +static struct clk_onecell_data *infra_clk_data;
> > +
> > +static void mtk_infrasys_init_early(struct device_node *node)
> > +{
> > + int r, i;
> > +
> > + if (!infra_clk_data) {
> > + infra_clk_data = mtk_alloc_clk_data(CLK_INFRA_NR);
> > +
> > + for (i = 0; i < CLK_INFRA_NR; i++)
> > + infra_clk_data->clks[i] = ERR_PTR(-EPROBE_DEFER);
> > + }
> > +
> > + mtk_clk_register_factors(infra_fixed_divs, ARRAY_SIZE(infra_fixed_divs),
> > + infra_clk_data);
> > +
> > + r = of_clk_add_provider(node, of_clk_src_onecell_get, infra_clk_data);
> > + if (r)
> > + pr_err("%s(): could not register clock provider: %d\n",
> > + __func__, r);
> > +}
> > +CLK_OF_DECLARE_DRIVER(mtk_infra, "mediatek,mt2701-infracfg",
> > + mtk_infrasys_init_early);
> > +
> > +static int mtk_infrasys_init(struct platform_device *pdev)
> > +{
> > + int r, i;
> > + struct device_node *node = pdev->dev.of_node;
> > +
> > + if (!infra_clk_data) {
> > + infra_clk_data = mtk_alloc_clk_data(CLK_INFRA_NR);
> > + } else {
> > + for (i = 0; i < CLK_INFRA_NR; i++) {
> > + if (infra_clk_data->clks[i] == ERR_PTR(-EPROBE_DEFER))
> > + infra_clk_data->clks[i] = ERR_PTR(-ENOENT);
> > + }
> > + }
> > +
> > + mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
> > + infra_clk_data);
> > + mtk_clk_register_factors(infra_fixed_divs, ARRAY_SIZE(infra_fixed_divs),
> > + infra_clk_data);
> > +
> > + r = of_clk_add_provider(node, of_clk_src_onecell_get, infra_clk_data);
> > +
> > + return r;
> > +}
> > +
> > +static const struct mtk_gate_regs peri0_cg_regs = {
> > + .set_ofs = 0x0008,
> > + .clr_ofs = 0x0010,
> > + .sta_ofs = 0x0018,
> > +};
> > +
> > +static const struct mtk_gate_regs peri1_cg_regs = {
> > + .set_ofs = 0x000c,
> > + .clr_ofs = 0x0014,
> > + .sta_ofs = 0x001c,
> > +};
> > +
> > +#define GATE_PERI0(_id, _name, _parent, _shift) { \
> > + .id = _id, \
> > + .name = _name, \
> > + .parent_name = _parent, \
> > + .regs = &peri0_cg_regs, \
> > + .shift = _shift, \
> > + .ops = &mtk_clk_gate_ops_setclr, \
> > + }
> > +
> > +#define GATE_PERI1(_id, _name, _parent, _shift) { \
> > + .id = _id, \
> > + .name = _name, \
> > + .parent_name = _parent, \
> > + .regs = &peri1_cg_regs, \
> > + .shift = _shift, \
> > + .ops = &mtk_clk_gate_ops_setclr, \
> > + }
> > +
> > +static const struct mtk_gate peri_clks[] = {
> > + GATE_PERI0(CLK_PERI_USB0_MCU, "usb0_mcu_ck", "axi_sel", 31),
> > + GATE_PERI0(CLK_PERI_ETH, "eth_ck", "clk26m", 30),
> > + GATE_PERI0(CLK_PERI_SPI0, "spi0_ck", "spi0_sel", 29),
> > + GATE_PERI0(CLK_PERI_AUXADC, "auxadc_ck", "clk26m", 28),
> > + GATE_PERI0(CLK_PERI_I2C3, "i2c3_ck", "clk26m", 27),
> > + GATE_PERI0(CLK_PERI_I2C2, "i2c2_ck", "axi_sel", 26),
> > + GATE_PERI0(CLK_PERI_I2C1, "i2c1_ck", "axi_sel", 25),
> > + GATE_PERI0(CLK_PERI_I2C0, "i2c0_ck", "axi_sel", 24),
> > + GATE_PERI0(CLK_PERI_BTIF, "bitif_ck", "axi_sel", 23),
> > + GATE_PERI0(CLK_PERI_UART3, "uart3_ck", "axi_sel", 22),
> > + GATE_PERI0(CLK_PERI_UART2, "uart2_ck", "axi_sel", 21),
> > + GATE_PERI0(CLK_PERI_UART1, "uart1_ck", "axi_sel", 20),
> > + GATE_PERI0(CLK_PERI_UART0, "uart0_ck", "axi_sel", 19),
> > + GATE_PERI0(CLK_PERI_NLI, "nli_ck", "axi_sel", 18),
> > + GATE_PERI0(CLK_PERI_MSDC50_3, "msdc50_3_ck", "emmc_hclk_sel", 17),
> > + GATE_PERI0(CLK_PERI_MSDC30_3, "msdc30_3_ck", "msdc30_3_sel", 16),
> > + GATE_PERI0(CLK_PERI_MSDC30_2, "msdc30_2_ck", "msdc30_2_sel", 15),
> > + GATE_PERI0(CLK_PERI_MSDC30_1, "msdc30_1_ck", "msdc30_1_sel", 14),
> > + GATE_PERI0(CLK_PERI_MSDC30_0, "msdc30_0_ck", "msdc30_0_sel", 13),
> > + GATE_PERI0(CLK_PERI_AP_DMA, "ap_dma_ck", "axi_sel", 12),
> > + GATE_PERI0(CLK_PERI_USB1, "usb1_ck", "usb20_sel", 11),
> > + GATE_PERI0(CLK_PERI_USB0, "usb0_ck", "usb20_sel", 10),
> > + GATE_PERI0(CLK_PERI_PWM, "pwm_ck", "axi_sel", 9),
> > + GATE_PERI0(CLK_PERI_PWM7, "pwm7_ck", "axi_sel", 8),
> > + GATE_PERI0(CLK_PERI_PWM6, "pwm6_ck", "axi_sel", 7),
> > + GATE_PERI0(CLK_PERI_PWM5, "pwm5_ck", "axi_sel", 6),
> > + GATE_PERI0(CLK_PERI_PWM4, "pwm4_ck", "axi_sel", 5),
> > + GATE_PERI0(CLK_PERI_PWM3, "pwm3_ck", "axi_sel", 4),
> > + GATE_PERI0(CLK_PERI_PWM2, "pwm2_ck", "axi_sel", 3),
> > + GATE_PERI0(CLK_PERI_PWM1, "pwm1_ck", "axi_sel", 2),
> > + GATE_PERI0(CLK_PERI_THERM, "therm_ck", "axi_sel", 1),
> > + GATE_PERI0(CLK_PERI_NFI, "nfi_ck", "nfi2x_sel", 0),
> > +
> > + GATE_PERI1(CLK_PERI_FCI, "fci_ck", "ms_card_sel", 11),
> > + GATE_PERI1(CLK_PERI_SPI2, "spi2_ck", "spi2_sel", 10),
> > + GATE_PERI1(CLK_PERI_SPI1, "spi1_ck", "spi1_sel", 9),
> > + GATE_PERI1(CLK_PERI_HOST89_DVD, "host89_dvd_ck", "aud2dvd_sel", 8),
> > + GATE_PERI1(CLK_PERI_HOST89_SPI, "host89_spi_ck", "spi0_sel", 7),
> > + GATE_PERI1(CLK_PERI_HOST89_INT, "host89_int_ck", "axi_sel", 6),
> > + GATE_PERI1(CLK_PERI_FLASH, "flash_ck", "nfi2x_sel", 5),
> > + GATE_PERI1(CLK_PERI_NFI_PAD, "nfi_pad_ck", "nfi1x_pad", 4),
> > + GATE_PERI1(CLK_PERI_NFI_ECC, "nfi_ecc_ck", "nfi1x_pad", 3),
> > + GATE_PERI1(CLK_PERI_GCPU, "gcpu_ck", "axi_sel", 2),
> > + GATE_PERI1(CLK_PERI_USB_SLV, "usbslv_ck", "axi_sel", 1),
> > + GATE_PERI1(CLK_PERI_USB1_MCU, "usb1_mcu_ck", "axi_sel", 0),
> > +};
> > +
> > +static const char * const uart_ck_sel_parents[] = {
> > + "clk26m",
> > + "uart_sel",
> > +};
> > +
> > +static const struct mtk_composite peri_muxs[] = {
> > + MUX(CLK_PERI_UART0_SEL, "uart0_ck_sel", uart_ck_sel_parents,
> > + 0x40c, 0, 1),
> > + MUX(CLK_PERI_UART1_SEL, "uart1_ck_sel", uart_ck_sel_parents,
> > + 0x40c, 1, 1),
> > + MUX(CLK_PERI_UART2_SEL, "uart2_ck_sel", uart_ck_sel_parents,
> > + 0x40c, 2, 1),
> > + MUX(CLK_PERI_UART3_SEL, "uart3_ck_sel", uart_ck_sel_parents,
> > + 0x40c, 3, 1),
> > +};
> > +
> > +static int mtk_pericfg_init(struct platform_device *pdev)
> > +{
> > + struct clk_onecell_data *clk_data;
> > + void __iomem *base;
> > + int r;
> > + struct device_node *node = pdev->dev.of_node;
> > +
> > + base = devm_of_iomap(&pdev->dev, 0);
> > + if (!base)
> > + return -ENOMEM;
> > +
> > + clk_data = mtk_alloc_clk_data(CLK_PERI_NR);
> > +
> > + mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks),
> > + clk_data);
> > +
> > + mtk_clk_register_composites(peri_muxs, ARRAY_SIZE(peri_muxs), base,
> > + &lock, clk_data);
> > +
> > + r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> > +
> > + return r;
>
> Just return of_clk_add_provider()?
Okay.
> > +}
> [...]
> > +
> > +static int clk_mt2701_probe(struct platform_device *pdev)
> > +{
> > + int (*clk_init)(struct platform_device *);
> > + int r;
> > +
> > + clk_init = of_device_get_match_data(&pdev->dev);
> > + if (!clk_init)
> > + return -EINVAL;
> > +
> > + r = clk_init(pdev);
> > + if (r) {
> > + dev_err(&pdev->dev,
> > + "could not register clock provider: %s: %d\n",
> > + pdev->name, r);
> > + }
>
> Braces are unnecessary.
I'll remove it.
> > +
> > + return r;
> > +}
> > +
> > +static struct platform_driver clk_mt2701_drv = {
> > + .probe = clk_mt2701_probe,
> > + .driver = {
> > + .name = "clk-mt2701",
> > + .owner = THIS_MODULE,
>
> This is unnecessary because platform_driver_register() already
> does it.
Okay, I'll remove it.
> > + .of_match_table = of_match_clk_mt2701,
> > + },
> > +};
> > +
> > +static int __init clk_mt2701_init(void)
> > +{
> > + return platform_driver_register(&clk_mt2701_drv);
> > +}
> > +
> > +arch_initcall(clk_mt2701_init);
> > diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
> > index bb30f70..0541df7 100644
> > --- a/drivers/clk/mediatek/clk-mtk.c
> > +++ b/drivers/clk/mediatek/clk-mtk.c
> > @@ -58,6 +58,9 @@ void mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks,
> > for (i = 0; i < num; i++) {
> > const struct mtk_fixed_clk *rc = &clks[i];
> >
> > + if (clk_data && !IS_ERR_OR_NULL(clk_data->clks[rc->id]))
> > + continue;
> > +
> > clk = clk_register_fixed_rate(NULL, rc->name, rc->parent, 0,
> > rc->rate);
> >
> > @@ -81,6 +84,9 @@ void mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
> > for (i = 0; i < num; i++) {
> > const struct mtk_fixed_factor *ff = &clks[i];
> >
> > + if (clk_data && !IS_ERR_OR_NULL(clk_data->clks[ff->id]))
> > + continue;
> > +
> > clk = clk_register_fixed_factor(NULL, ff->name, ff->parent_name,
> > CLK_SET_RATE_PARENT, ff->mult, ff->div);
> >
> > @@ -116,6 +122,9 @@ int mtk_clk_register_gates(struct device_node *node,
> > for (i = 0; i < num; i++) {
> > const struct mtk_gate *gate = &clks[i];
> >
> > + if (!IS_ERR_OR_NULL(clk_data->clks[gate->id]))
> > + continue;
> > +
> > clk = mtk_clk_register_gate(gate->name, gate->parent_name,
> > regmap,
> > gate->regs->set_ofs,
> > @@ -232,6 +241,9 @@ void mtk_clk_register_composites(const struct mtk_composite *mcs,
> > for (i = 0; i < num; i++) {
> > const struct mtk_composite *mc = &mcs[i];
> >
> > + if (clk_data && !IS_ERR_OR_NULL(clk_data->clks[mc->id]))
> > + continue;
> > +
> > clk = mtk_clk_register_composite(mc, base, lock);
> >
> > if (IS_ERR(clk)) {
> > @@ -244,3 +256,31 @@ void mtk_clk_register_composites(const struct mtk_composite *mcs,
> > clk_data->clks[mc->id] = clk;
> > }
> > }
> > +
> > +void mtk_clk_register_dividers(const struct mtk_clk_divider *mcds,
> > + int num, void __iomem *base, spinlock_t *lock,
> > + struct clk_onecell_data *clk_data)
> > +{
> > + struct clk *clk;
> > + int i;
> > +
> > + for (i = 0; i < num; i++) {
> > + const struct mtk_clk_divider *mcd = &mcds[i];
> > +
> > + if (clk_data && !IS_ERR_OR_NULL(clk_data->clks[mcd->id]))
>
> NULL is a valid clk. IS_ERR_OR_NULL is usually wrong.
Why NULL is a valid clk?
clk_data is designed for multiple initialization from different clock
types, such as infra_clk_data in clk-mt2701.c. So it will ignore valid
clocks to avoid duplicated clock registration. Here I assume a clock
pointer with error code or NULL to be an invalid (not initialized)
clock.
> > + continue;
> > +
> > + clk = clk_register_divider(NULL, mcd->name, mcd->parent_name,
> > + mcd->flags, base + mcd->div_reg, mcd->div_shift,
> > + mcd->div_width, mcd->clk_divider_flags, lock);
> > +
> > + if (IS_ERR(clk)) {
> > + pr_err("Failed to register clk %s: %ld\n",
> > + mcd->name, PTR_ERR(clk));
> > + continue;
> > + }
> > +
> > + if (clk_data)
> > + clk_data->clks[mcd->id] = clk;
> > + }
> > +}
> > diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
> > index 9f24fcf..f5d6b70 100644
> > --- a/drivers/clk/mediatek/clk-mtk.h
> > +++ b/drivers/clk/mediatek/clk-mtk.h
> > @@ -87,7 +87,8 @@ struct mtk_composite {
> > * In case the rate change propagation to parent clocks is undesirable,
> > * this macro allows to specify the clock flags manually.
> > */
> > -#define MUX_GATE_FLAGS(_id, _name, _parents, _reg, _shift, _width, _gate, _flags) { \
> > +#define MUX_GATE_FLAGS(_id, _name, _parents, _reg, _shift, _width, \
> > + _gate, _flags) { \
> > .id = _id, \
> > .name = _name, \
> > .mux_reg = _reg, \
> > @@ -106,7 +107,8 @@ struct mtk_composite {
> > * parent clock by default.
> > */
> > #define MUX_GATE(_id, _name, _parents, _reg, _shift, _width, _gate) \
> > - MUX_GATE_FLAGS(_id, _name, _parents, _reg, _shift, _width, _gate, CLK_SET_RATE_PARENT)
> > + MUX_GATE_FLAGS(_id, _name, _parents, _reg, _shift, _width, \
> > + _gate, CLK_SET_RATE_PARENT)
> >
> > #define MUX(_id, _name, _parents, _reg, _shift, _width) { \
> > .id = _id, \
> > @@ -121,7 +123,8 @@ struct mtk_composite {
> > .flags = CLK_SET_RATE_PARENT, \
> > }
> >
> > -#define DIV_GATE(_id, _name, _parent, _gate_reg, _gate_shift, _div_reg, _div_width, _div_shift) { \
> > +#define DIV_GATE(_id, _name, _parent, _gate_reg, _gate_shift, _div_reg, \
> > + _div_width, _div_shift) { \
>
> Did anything actually change? Checkpatch fix?
Right. Just limit max line length to 80 chars.
> > .id = _id, \
> > .parent = _parent, \
> > .name = _name, \
^ permalink raw reply
* Re: [PATCH v7, 0/8] Add MediaTek USB3 DRD Driver
From: Chunfeng Yun @ 2016-10-31 3:31 UTC (permalink / raw)
To: Matthias Brugger
Cc: Greg Kroah-Hartman, Felipe Balbi, Mathias Nyman, Oliver Neukum,
Alan Stern, Rob Herring, Mark Rutland, Ian Campbell,
Sergei Shtylyov, Pawel Moll, Kumar Gala, Sascha Hauer,
Alan Cooper, linux-usb-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <28f6db69-88ca-4715-1e46-6d5e5efb949c-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
On Fri, 2016-10-28 at 12:37 +0200, Matthias Brugger wrote:
> Hi Chunfeng,
>
> On 10/19/2016 04:28 AM, Chunfeng Yun wrote:
> > These patches introduce the MediaTek USB3 dual-role controller
> > driver.
> >
> > The driver can be configured as Dual-Role Device (DRD),
> > Peripheral Only and Host Only (xHCI) modes. It works well
> > with Mass Storage, RNDIS and g_zero on FS/HS and SS. And it is
> > tested on MT8173 platform which only contains USB2.0 device IP,
> > and on MT6290 platform which contains USB3.0 device IP.
[...]
> >
> > Change in v2:
> > 1. modify binding docs according to suggestions
> > 2. modify some comments and remove some dummy blank lines
> > 3. fix memory leakage
> >
> >
> > Chunfeng Yun (8):
> > dt-bindings: mt8173-xhci: support host side of dual-role mode
> > dt-bindings: mt8173-mtu3: add devicetree bindings
> > usb: xhci-mtk: make IPPC register optional
> > usb: Add MediaTek USB3 DRD driver
> > usb: mtu3: Super-Speed Peripheral mode support
> > usb: mtu3: host only mode support
> > usb: mtu3: dual-role mode support
> > arm64: dts: mediatek: add USB3 DRD driver
> >
>
> I tried the driver with my mt8173-evb, but wasn't able to get USB
> working (no usb stick detected when adding to the usb port).
>
Can you test it again by USB3.0 type-A port? If it works, then
regulators of vusb33 and vbus are got after PROBE_DEFER of
mt6397-regulator driver;
For OTG port, need cherry pick a patch:
https://patchwork.kernel.org/patch/9055261/
which is abandoned because GPIO driver owner wants to fix all pins with
the same problem.
Then device will be recognized well when connected to PC with OTG cable.
But it is a trouble for OTG host mode, due to vbus 5.5V of OTG port is
originally provided by charger driver which is not upstreamed on EVB
board, we need rework the board to control vbus by gpio.
There is a simple way, you can plug in a self-powered hub to test OTG
host mode.
> # dmesg |grep mtu
> [ 0.428420] mtu3 11271000.usb: failed to get vusb33
> [ 0.510570] mtu3 11271000.usb: failed to get vbus
> [ 0.592103] mtu3 11271000.usb: failed to get vbus
>
>
> Relevant config options:
> CONFIG_USB_MTU3=y
> CONFIG_USB_MTU3_HOST=y
> CONFIG_USB_MTU3_DEBUG=y
> CONFIG_PHY_MT65XX_USB3=y
>
>
> Looks like an error in the device tree. I can see that the mt6397
> regulater get's initialized *after* the mtu3 driver:
> [ 0.505166] mt6397-regulator mt6397-regulator: Chip ID = 0x4097
>
> Not sure if this is related.
> Any idea whats going wrong here?
>
as above.
Sorry for inconvenience
> Cheers,
> Matthias
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v9 2/4] soc: mediatek: Init MT8173 scpsys driver earlier
From: James Liao @ 2016-10-31 2:08 UTC (permalink / raw)
To: Matthias Brugger, Yong Wu
Cc: Sascha Hauer, Rob Herring, Kevin Hilman, Daniel Kurtz,
srv_heupstream, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek
In-Reply-To: <14a1ebb2-fda2-278b-b2f0-8f9c6ff6a83d@gmail.com>
On Mon, 2016-10-31 at 01:08 +0100, Matthias Brugger wrote:
> Hi James,
>
> On 10/20/2016 10:56 AM, James Liao wrote:
> > Some power domain comsumers may init before module_init.
> > So the power domain provider (scpsys) need to be initialized
> > earlier too.
> >
> > Take an example for our IOMMU (M4U) and SMI. SMI is a bridge
> > between IOMMU and multimedia HW. SMI is responsible to
> > enable/disable iommu and help transfer data for each multimedia
> > HW. Both of them have to wait until the power and clocks are
> > enabled.
> >
> > So scpsys driver should be initialized before SMI, and SMI should
> > be initialized before IOMMU, and then init IOMMU consumers
> > (display/vdec/venc/camera etc.).
> >
> > IOMMU is subsys_init by default. So we need to init scpsys driver
> > before subsys_init.
> >
> > Signed-off-by: James Liao <jamesjj.liao@mediatek.com>
> > Reviewed-by: Kevin Hilman <khilman@baylibre.com>
> > ---
>
> I didn't applied this patch for now.
> I answered you in v7 of this series [1]. I would prefer to see if we can
> fix that otherwise.
>
> Would be great if you or Yong could provide some feedback.
>
> Thanks,
> Matthias
>
> [1] https://patchwork.kernel.org/patch/9397405/
>
> > drivers/soc/mediatek/mtk-scpsys.c | 19 ++++++++++++++++++-
> > 1 file changed, 18 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c
> > index fa9ee69..dd7a07d 100644
> > --- a/drivers/soc/mediatek/mtk-scpsys.c
> > +++ b/drivers/soc/mediatek/mtk-scpsys.c
> > @@ -613,4 +613,21 @@ static int scpsys_probe(struct platform_device *pdev)
> > .of_match_table = of_match_ptr(of_scpsys_match_tbl),
> > },
> > };
> > -builtin_platform_driver(scpsys_drv);
> > +
> > +static int __init scpsys_drv_init(void)
> > +{
> > + return platform_driver_register(&scpsys_drv);
> > +}
> > +
> > +/*
> > + * There are some Mediatek drivers which depend on the power domain driver need
> > + * to probe in earlier initcall levels. So scpsys driver also need to probe
> > + * earlier.
> > + *
> > + * IOMMU(M4U) and SMI drivers for example. SMI is a bridge between IOMMU and
> > + * multimedia HW. IOMMU depends on SMI, and SMI is a power domain consumer,
> > + * so the proper probe sequence should be scpsys -> SMI -> IOMMU driver.
> > + * IOMMU drivers are initialized during subsys_init by default, so we need to
> > + * move SMI and scpsys drivers to subsys_init or earlier init levels.
> > + */
> > +subsys_initcall(scpsys_drv_init);
> >
Hi Matthias,
I got it, thanks.
Hi Yong,
Is this patch still needed on latest kernel for IOMMU driver? Or we have
other solutions for IOMMU driver init?
Best regards,
James
^ permalink raw reply
* Re: [PATCH] arm64: dts: mt8173: Fix auxadc node
From: Matthias Brugger @ 2016-10-31 0:15 UTC (permalink / raw)
To: robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
will.deacon-5wv7dgnIgG8, zhiyong.tao-NuS5LvNUpcJWk0Htik3J/w,
s.hauer-bIcnvbaLZ9MEGnE8C9+IrQ
Cc: djkurtz-F7+t8E8rja9g9hUCZPvPmw, p.zabel-bIcnvbaLZ9MEGnE8C9+IrQ,
hans.verkuil-FYB4Gu1CFyUAvxtiuMwx3w,
andrew-ct.chen-NuS5LvNUpcJWk0Htik3J/w,
ck.hu-NuS5LvNUpcJWk0Htik3J/w, bayi.cheng-NuS5LvNUpcJWk0Htik3J/w,
yong.wu-NuS5LvNUpcJWk0Htik3J/w,
dawei.chien-NuS5LvNUpcJWk0Htik3J/w,
chunfeng.yun-NuS5LvNUpcJWk0Htik3J/w,
tiffany.lin-NuS5LvNUpcJWk0Htik3J/w,
fan.chen-NuS5LvNUpcJWk0Htik3J/w,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20161026141500.27105-1-matthias.bgg-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
On 10/26/2016 04:15 PM, Matthias Brugger wrote:
> The devicetree node for mt8173-auxadc lacks the clock and
> io-channel-cells property. This leads to a non-working driver.
>
> mt6577-auxadc 11001000.auxadc: failed to get auxadc clock
> mt6577-auxadc: probe of 11001000.auxadc failed with error -2
>
> Fix these fields to get the device up and running.
>
> Fixes: 748c7d4de46a ("ARM64: dts: mt8173: Add thermal/auxadc device
> nodes")
> Signed-off-by: Matthias Brugger <matthias.bgg-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> ---
Applied.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v9 2/4] soc: mediatek: Init MT8173 scpsys driver earlier
From: Matthias Brugger @ 2016-10-31 0:08 UTC (permalink / raw)
To: James Liao, Sascha Hauer
Cc: Rob Herring, Kevin Hilman, Daniel Kurtz,
srv_heupstream-NuS5LvNUpcJWk0Htik3J/w,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <1476953798-23263-3-git-send-email-jamesjj.liao-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
Hi James,
On 10/20/2016 10:56 AM, James Liao wrote:
> Some power domain comsumers may init before module_init.
> So the power domain provider (scpsys) need to be initialized
> earlier too.
>
> Take an example for our IOMMU (M4U) and SMI. SMI is a bridge
> between IOMMU and multimedia HW. SMI is responsible to
> enable/disable iommu and help transfer data for each multimedia
> HW. Both of them have to wait until the power and clocks are
> enabled.
>
> So scpsys driver should be initialized before SMI, and SMI should
> be initialized before IOMMU, and then init IOMMU consumers
> (display/vdec/venc/camera etc.).
>
> IOMMU is subsys_init by default. So we need to init scpsys driver
> before subsys_init.
>
> Signed-off-by: James Liao <jamesjj.liao-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> Reviewed-by: Kevin Hilman <khilman-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
> ---
I didn't applied this patch for now.
I answered you in v7 of this series [1]. I would prefer to see if we can
fix that otherwise.
Would be great if you or Yong could provide some feedback.
Thanks,
Matthias
[1] https://patchwork.kernel.org/patch/9397405/
> drivers/soc/mediatek/mtk-scpsys.c | 19 ++++++++++++++++++-
> 1 file changed, 18 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c
> index fa9ee69..dd7a07d 100644
> --- a/drivers/soc/mediatek/mtk-scpsys.c
> +++ b/drivers/soc/mediatek/mtk-scpsys.c
> @@ -613,4 +613,21 @@ static int scpsys_probe(struct platform_device *pdev)
> .of_match_table = of_match_ptr(of_scpsys_match_tbl),
> },
> };
> -builtin_platform_driver(scpsys_drv);
> +
> +static int __init scpsys_drv_init(void)
> +{
> + return platform_driver_register(&scpsys_drv);
> +}
> +
> +/*
> + * There are some Mediatek drivers which depend on the power domain driver need
> + * to probe in earlier initcall levels. So scpsys driver also need to probe
> + * earlier.
> + *
> + * IOMMU(M4U) and SMI drivers for example. SMI is a bridge between IOMMU and
> + * multimedia HW. IOMMU depends on SMI, and SMI is a power domain consumer,
> + * so the proper probe sequence should be scpsys -> SMI -> IOMMU driver.
> + * IOMMU drivers are initialized during subsys_init by default, so we need to
> + * move SMI and scpsys drivers to subsys_init or earlier init levels.
> + */
> +subsys_initcall(scpsys_drv_init);
>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v9 3/4] soc: mediatek: Add MT2701 power dt-bindings
From: Matthias Brugger @ 2016-10-31 0:01 UTC (permalink / raw)
To: James Liao, Sascha Hauer
Cc: Rob Herring, Kevin Hilman, Daniel Kurtz,
srv_heupstream-NuS5LvNUpcJWk0Htik3J/w,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Shunli Wang
In-Reply-To: <19220b7f-84c3-eefe-333c-bd1ddfa988a3-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
On 10/31/2016 12:57 AM, Matthias Brugger wrote:
>
>
> On 10/20/2016 10:56 AM, James Liao wrote:
>> From: Shunli Wang <shunli.wang-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
>>
>> Add power dt-bindings for MT2701.
>>
>> Signed-off-by: Shunli Wang <shunli.wang-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
>> Signed-off-by: James Liao <jamesjj.liao-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
>> Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
>> Reviewed-by: Kevin Hilman <khilman-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
>
> Applied to v4.9-next/soc
Of course this has to be applied to v4.9-next/dts, fixed now.
Thanks,
Matthias
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v9 4/4] soc: mediatek: Add MT2701 scpsys driver
From: Matthias Brugger @ 2016-10-30 23:57 UTC (permalink / raw)
To: James Liao, Sascha Hauer
Cc: Rob Herring, Kevin Hilman, Daniel Kurtz, srv_heupstream,
devicetree, linux-kernel, linux-arm-kernel, linux-mediatek,
Shunli Wang
In-Reply-To: <1476953798-23263-5-git-send-email-jamesjj.liao@mediatek.com>
On 10/20/2016 10:56 AM, James Liao wrote:
> From: Shunli Wang <shunli.wang@mediatek.com>
>
> Add scpsys driver for MT2701.
>
> mtk-scpsys now supports MT8173 (arm64) and MT2701 (arm). So it should
> be enabled on both arm64 and arm platforms.
>
> Signed-off-by: Shunli Wang <shunli.wang@mediatek.com>
> Signed-off-by: James Liao <jamesjj.liao@mediatek.com>
> Reviewed-by: Kevin Hilman <khilman@baylibre.com>
> ---
Applied to v4.9-next/soc
^ permalink raw reply
* Re: [PATCH v9 3/4] soc: mediatek: Add MT2701 power dt-bindings
From: Matthias Brugger @ 2016-10-30 23:57 UTC (permalink / raw)
To: James Liao, Sascha Hauer
Cc: Rob Herring, Kevin Hilman, Daniel Kurtz,
srv_heupstream-NuS5LvNUpcJWk0Htik3J/w,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Shunli Wang
In-Reply-To: <1476953798-23263-4-git-send-email-jamesjj.liao-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
On 10/20/2016 10:56 AM, James Liao wrote:
> From: Shunli Wang <shunli.wang-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
>
> Add power dt-bindings for MT2701.
>
> Signed-off-by: Shunli Wang <shunli.wang-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> Signed-off-by: James Liao <jamesjj.liao-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> Reviewed-by: Kevin Hilman <khilman-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
Applied to v4.9-next/soc
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v9 1/4] soc: mediatek: Refine scpsys to support multiple platform
From: Matthias Brugger @ 2016-10-30 23:57 UTC (permalink / raw)
To: James Liao
Cc: Sascha Hauer, Rob Herring, srv_heupstream, devicetree,
Kevin Hilman, linux-kernel, linux-mediatek, linux-arm-kernel
In-Reply-To: <1477647408.24014.6.camel@mtksdaap41>
On 10/28/2016 11:36 AM, James Liao wrote:
> Hi Matthias,
>
> Sorry for late reply due to our email service.
>
> On Tue, 2016-10-25 at 16:04 +0200, Matthias Brugger wrote:
>> Hi James,
>>
>> On 10/20/2016 10:56 AM, James Liao wrote:
>>> -static int scpsys_probe(struct platform_device *pdev)
>>> +static void init_clks(struct platform_device *pdev, struct clk *clk[CLK_MAX])
>>
>> I prefer struct clk **clk.
>
> Okay.
>
>>> +{
>>> + int i;
>>> +
>>> + for (i = CLK_NONE + 1; i < CLK_MAX; i++)
>>> + clk[i] = devm_clk_get(&pdev->dev, clk_names[i]);
>>> +}
>>> +
>>> +static struct scp *init_scp(struct platform_device *pdev,
>>> + const struct scp_domain_data *scp_domain_data, int num)
>>> {
>>> struct genpd_onecell_data *pd_data;
>>> struct resource *res;
>>> - int i, j, ret;
>>> + int i, j;
>>> struct scp *scp;
>>> - struct clk *clk[MT8173_CLK_MAX];
>>> + struct clk *clk[CLK_MAX];
>>
>> should be *[CLK_MAX - 1] but I would prefer to define in the enum:
>> CLK_MAX = CLK_VENC_LT,
>
> After init_clks() the clk[] will have valid contents between
> clk[1]..clk[CLK_MAX-1], so it's necessary to declare clk[] with CLK_MAX
> elements.
>
>> If you are ok with it, I can fix both of my comments when applying.
>
> Yes. struct clk **clk can be applied directly. But I think clk[CLK_MAX]
> should be kept in current implementation.
>
Ok, we won't never use clk[0] but it's ok for now.
Applied to v4.9-next/soc
>
> Best regards,
>
> James
>
>
^ permalink raw reply
* Re: pinctrl: mediatek: build failure if CONFIG_IRQ_DOMAIN is not set
From: Linus Walleij @ 2016-10-29 8:36 UTC (permalink / raw)
To: Paul Bolle
Cc: Matthias Brugger, linux-gpio@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
moderated list:ARM/Mediatek SoC support,
linux-kernel@vger.kernel.org
In-Reply-To: <1477675233.2167.11.camel@tiscali.nl>
On Fri, Oct 28, 2016 at 7:20 PM, Paul Bolle <pebolle@tiscali.nl> wrote:
> 3) Would you like me to submit a proper (but lightly tested) patch or
> do you prefer to fix this yourself?
Please send a tested patch, I'll apply it.
Thanks for finding this!
Yours,
Linus Walleij
^ permalink raw reply
* pinctrl: mediatek: build failure if CONFIG_IRQ_DOMAIN is not set
From: Paul Bolle @ 2016-10-28 17:20 UTC (permalink / raw)
To: Linus Walleij, Matthias Brugger
Cc: linux-gpio, linux-arm-kernel, linux-mediatek, linux-kernel
Hi,
0) A rather spartan build, on x86_64, which did include
drivers/pinctrl/mediatek/pinctrl-mtk-common.o failed like this:
drivers/pinctrl/mediatek/pinctrl-mtk-common.c: In function ‘mtk_gpio_to_irq’:
drivers/pinctrl/mediatek/pinctrl-mtk-common.c:838:8: error: implicit declaration of function ‘irq_find_mapping’ [-Werror=implicit-function-declaration]
irq = irq_find_mapping(pctl->domain, pin->eint.eintnum);
^~~~~~~~~~~~~~~~
drivers/pinctrl/mediatek/pinctrl-mtk-common.c: In function ‘mtk_pctrl_init’:
drivers/pinctrl/mediatek/pinctrl-mtk-common.c:1474:17: error: implicit declaration of function ‘irq_domain_add_linear’ [-Werror=implicit-function-declaration]
pctl->domain = irq_domain_add_linear(np,
^~~~~~~~~~~~~~~~~~~~~
drivers/pinctrl/mediatek/pinctrl-mtk-common.c:1475:27: error: ‘irq_domain_simple_ops’ undeclared (first use in this function)
pctl->devdata->ap_num, &irq_domain_simple_ops, NULL);
^~~~~~~~~~~~~~~~~~~~~
drivers/pinctrl/mediatek/pinctrl-mtk-common.c:1475:27: note: each undeclared identifier is reported only once for each function it appears in
drivers/pinctrl/mediatek/pinctrl-mtk-common.c:1484:14: error: implicit declaration of function ‘irq_create_mapping’ [-Werror=implicit-function-declaration]
int virq = irq_create_mapping(pctl->domain, i);
^~~~~~~~~~~~~~~~~~
cc1: some warnings being treated as errors
make[3]: *** [drivers/pinctrl/mediatek/pinctrl-mtk-common.o] Error 1
make[2]: *** [drivers/pinctrl/mediatek] Error 2
make[1]: *** [drivers/pinctrl] Error 2
make: *** [drivers] Error 2
1) That build had CONFIG_COMPILE_TEST set (obviously) but
CONFIG_IRQ_DOMAIN not set.
2) This quick hack fixes that for me:
diff --git a/drivers/pinctrl/mediatek/Kconfig b/drivers/pinctrl/mediatek/Kconfig
index 419ea4d5964d..066087156dcc 100644
--- a/drivers/pinctrl/mediatek/Kconfig
+++ b/drivers/pinctrl/mediatek/Kconfig
@@ -7,6 +7,7 @@ config PINCTRL_MTK
select GENERIC_PINCONF
select GPIOLIB
select OF_GPIO
+ select IRQ_DOMAIN
# For ARMv7 SoCs
config PINCTRL_MT2701
3) Would you like me to submit a proper (but lightly tested) patch or
do you prefer to fix this yourself?
Thanks,
Paul Bolle
^ permalink raw reply related
* Re: [PATCH] drm/mediatek: fix null pointer dereference
From: Matthias Brugger @ 2016-10-28 10:39 UTC (permalink / raw)
To: CK Hu
Cc: airlied-cv59FeDIM0c, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
p.zabel-bIcnvbaLZ9MEGnE8C9+IrQ,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <1477643686.17640.3.camel@mtksdaap41>
On 10/28/2016 10:34 AM, CK Hu wrote:
> Hi, Matthias:
>
> Even though OVL HW would not be enabled before component_add() in
> current design, your patch would be safe for any situation.
Maybe the FW I use left an interrupt pending before loading the kernel
and this leads to the case where we enter the handler before all data
structures are set up.
>
> Acked-by CK Hu <ck.hu-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
Thanks!
Matthias
^ permalink raw reply
* Re: [PATCH v7, 0/8] Add MediaTek USB3 DRD Driver
From: Matthias Brugger @ 2016-10-28 10:37 UTC (permalink / raw)
To: Chunfeng Yun, Greg Kroah-Hartman, Felipe Balbi, Mathias Nyman
Cc: Oliver Neukum, Alan Stern, Rob Herring, Mark Rutland,
Ian Campbell, Sergei Shtylyov, Pawel Moll, Kumar Gala,
Sascha Hauer, Alan Cooper, linux-usb, devicetree, linux-kernel,
linux-arm-kernel, linux-mediatek
In-Reply-To: <1476844107-31087-1-git-send-email-chunfeng.yun@mediatek.com>
Hi Chunfeng,
On 10/19/2016 04:28 AM, Chunfeng Yun wrote:
> These patches introduce the MediaTek USB3 dual-role controller
> driver.
>
> The driver can be configured as Dual-Role Device (DRD),
> Peripheral Only and Host Only (xHCI) modes. It works well
> with Mass Storage, RNDIS and g_zero on FS/HS and SS. And it is
> tested on MT8173 platform which only contains USB2.0 device IP,
> and on MT6290 platform which contains USB3.0 device IP.
>
> Change in v7:
> 1. split dual-role driver into four patchs
> 2. remove QMU done tasklet
> 3. add a bool in xhci_hcd_mtk to signal absence of IPPC
>
> Change in v6:
> 1. handle endianness of GPD and SETUP data
> 2. remove dummy error log and return suitable error number
> 3. cancel delay work when deregiseter driver
>
> Change in v5:
> 1. modify some comments
> 2. rename some unsuitable variables
> 3. add reg-names property for host node
> 4. add USB_MTU3_DEBUG to control debug messages
>
> Change in v4:
> 1. fix build errors on non-mediatek platforms
> 2. provide manual dual-role switch via debugfs instead of sysfs
>
> Change in v3:
> 1. fix some typo error
> 2. rename mtu3.txt to mt8173-mtu3.txt
>
> Change in v2:
> 1. modify binding docs according to suggestions
> 2. modify some comments and remove some dummy blank lines
> 3. fix memory leakage
>
>
> Chunfeng Yun (8):
> dt-bindings: mt8173-xhci: support host side of dual-role mode
> dt-bindings: mt8173-mtu3: add devicetree bindings
> usb: xhci-mtk: make IPPC register optional
> usb: Add MediaTek USB3 DRD driver
> usb: mtu3: Super-Speed Peripheral mode support
> usb: mtu3: host only mode support
> usb: mtu3: dual-role mode support
> arm64: dts: mediatek: add USB3 DRD driver
>
I tried the driver with my mt8173-evb, but wasn't able to get USB
working (no usb stick detected when adding to the usb port).
# dmesg |grep mtu
[ 0.428420] mtu3 11271000.usb: failed to get vusb33
[ 0.510570] mtu3 11271000.usb: failed to get vbus
[ 0.592103] mtu3 11271000.usb: failed to get vbus
Relevant config options:
CONFIG_USB_MTU3=y
CONFIG_USB_MTU3_HOST=y
CONFIG_USB_MTU3_DEBUG=y
CONFIG_PHY_MT65XX_USB3=y
Looks like an error in the device tree. I can see that the mt6397
regulater get's initialized *after* the mtu3 driver:
[ 0.505166] mt6397-regulator mt6397-regulator: Chip ID = 0x4097
Not sure if this is related.
Any idea whats going wrong here?
Cheers,
Matthias
^ permalink raw reply
* Re: [PATCH v9 1/4] soc: mediatek: Refine scpsys to support multiple platform
From: James Liao @ 2016-10-28 9:36 UTC (permalink / raw)
To: Matthias Brugger
Cc: Sascha Hauer, Rob Herring, srv_heupstream-NuS5LvNUpcJWk0Htik3J/w,
devicetree-u79uwXL29TY76Z2rM5mHXA, Kevin Hilman,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <1d5cda95-467a-4f95-1cc9-b8f156271a54-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Hi Matthias,
Sorry for late reply due to our email service.
On Tue, 2016-10-25 at 16:04 +0200, Matthias Brugger wrote:
> Hi James,
>
> On 10/20/2016 10:56 AM, James Liao wrote:
> > -static int scpsys_probe(struct platform_device *pdev)
> > +static void init_clks(struct platform_device *pdev, struct clk *clk[CLK_MAX])
>
> I prefer struct clk **clk.
Okay.
> > +{
> > + int i;
> > +
> > + for (i = CLK_NONE + 1; i < CLK_MAX; i++)
> > + clk[i] = devm_clk_get(&pdev->dev, clk_names[i]);
> > +}
> > +
> > +static struct scp *init_scp(struct platform_device *pdev,
> > + const struct scp_domain_data *scp_domain_data, int num)
> > {
> > struct genpd_onecell_data *pd_data;
> > struct resource *res;
> > - int i, j, ret;
> > + int i, j;
> > struct scp *scp;
> > - struct clk *clk[MT8173_CLK_MAX];
> > + struct clk *clk[CLK_MAX];
>
> should be *[CLK_MAX - 1] but I would prefer to define in the enum:
> CLK_MAX = CLK_VENC_LT,
After init_clks() the clk[] will have valid contents between
clk[1]..clk[CLK_MAX-1], so it's necessary to declare clk[] with CLK_MAX
elements.
> If you are ok with it, I can fix both of my comments when applying.
Yes. struct clk **clk can be applied directly. But I think clk[CLK_MAX]
should be kept in current implementation.
Best regards,
James
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH] drm/mediatek: fix null pointer dereference
From: CK Hu @ 2016-10-28 8:34 UTC (permalink / raw)
To: Matthias Brugger
Cc: p.zabel, airlied, dri-devel, linux-arm-kernel, linux-mediatek,
linux-kernel
In-Reply-To: <20161026140904.26798-1-matthias.bgg@gmail.com>
Hi, Matthias:
Even though OVL HW would not be enabled before component_add() in
current design, your patch would be safe for any situation.
Acked-by CK Hu <ck.hu@mediatek.com>
Regards,
CK
On Wed, 2016-10-26 at 16:09 +0200, Matthias Brugger wrote:
> The probe function requests the interrupt before initializing
> the ddp component. Which leads to a null pointer dereference at boot.
> Fix this by requesting the interrput after all components got
> initialized properly.
>
> Fixes: 119f5173628a ("drm/mediatek: Add DRM Driver for Mediatek SoC
> MT8173.")
> Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
> ---
> drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 14 +++++++-------
> 1 file changed, 7 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> index 019b7ca..1e78159 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> @@ -250,13 +250,6 @@ static int mtk_disp_ovl_probe(struct platform_device *pdev)
> if (irq < 0)
> return irq;
>
> - ret = devm_request_irq(dev, irq, mtk_disp_ovl_irq_handler,
> - IRQF_TRIGGER_NONE, dev_name(dev), priv);
> - if (ret < 0) {
> - dev_err(dev, "Failed to request irq %d: %d\n", irq, ret);
> - return ret;
> - }
> -
> comp_id = mtk_ddp_comp_get_id(dev->of_node, MTK_DISP_OVL);
> if (comp_id < 0) {
> dev_err(dev, "Failed to identify by alias: %d\n", comp_id);
> @@ -272,6 +265,13 @@ static int mtk_disp_ovl_probe(struct platform_device *pdev)
>
> platform_set_drvdata(pdev, priv);
>
> + ret = devm_request_irq(dev, irq, mtk_disp_ovl_irq_handler,
> + IRQF_TRIGGER_NONE, dev_name(dev), priv);
> + if (ret < 0) {
> + dev_err(dev, "Failed to request irq %d: %d\n", irq, ret);
> + return ret;
> + }
> +
> ret = component_add(dev, &mtk_disp_ovl_component_ops);
> if (ret)
> dev_err(dev, "Failed to add component: %d\n", ret);
^ permalink raw reply
* Re: [PATCH next 1/2] media: mtk-mdp: fix video_device_release argument
From: Vincent Stehlé @ 2016-10-28 7:52 UTC (permalink / raw)
Cc: linux-media, linux-mediatek, linux-arm-kernel, linux-kernel,
Minghsiu Tsai, Hans Verkuil, Mauro Carvalho Chehab
In-Reply-To: <20161027202325.20680-1-vincent.stehle@laposte.net>
On Thu, Oct 27, 2016 at 10:23:24PM +0200, Vincent Stehlé wrote:
> video_device_release() takes a pointer to struct video_device as argument.
> Fix two call sites where the address of the pointer is passed instead.
Sorry, I messed up: please ignore that "fix". The 0day robot made me
realize this is indeed not a proper fix.
The issue remains, though: we cannot call video_device_release() on the
vdev structure member, as this will in turn call kfree(). Most probably,
vdev needs to be dynamically allocated, or the call to
video_device_release() dropped completely.
Sorry for the bad patch.
Best regards,
Vincent.
^ permalink raw reply
* Re: [PATCH v14 1/4] clk: mediatek: Add MT2701 clock support
From: Stephen Boyd @ 2016-10-28 1:17 UTC (permalink / raw)
To: Erin Lo
Cc: Matthias Brugger, Mike Turquette, Rob Herring, Arnd Bergmann,
Sascha Hauer, Daniel Kurtz, Philipp Zabel,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-clk-u79uwXL29TY76Z2rM5mHXA,
srv_heupstream-NuS5LvNUpcJWk0Htik3J/w,
ms.chen-NuS5LvNUpcJWk0Htik3J/w,
robert.chou-NuS5LvNUpcJWk0Htik3J/w, Shunli Wang, James Liao
In-Reply-To: <1477020742-13889-2-git-send-email-erin.lo-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
On 10/21, Erin Lo wrote:
> diff --git a/drivers/clk/mediatek/clk-mt2701-bdp.c b/drivers/clk/mediatek/clk-mt2701-bdp.c
> new file mode 100644
> index 0000000..dbf6ab2
> --- /dev/null
> +++ b/drivers/clk/mediatek/clk-mt2701-bdp.c
> @@ -0,0 +1,148 @@
> +
> +static int mtk_bdpsys_init(struct platform_device *pdev)
> +{
> + struct clk_onecell_data *clk_data;
> + int r;
> + struct device_node *node = pdev->dev.of_node;
> +
> + clk_data = mtk_alloc_clk_data(CLK_BDP_NR);
> +
> + mtk_clk_register_gates(node, bdp_clks, ARRAY_SIZE(bdp_clks),
> + clk_data);
> +
> + r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> +
> + return r;
> +}
> +
> +static const struct of_device_id of_match_clk_mt2701_bdp[] = {
> + { .compatible = "mediatek,mt2701-bdpsys", },
> + {}
> +};
> +
> +static int clk_mt2701_bdp_probe(struct platform_device *pdev)
> +{
> + int r;
> +
> + r = mtk_bdpsys_init(pdev);
Why not just put the contents of that function here? I don't see
the point of this.
> + if (r) {
> + dev_err(&pdev->dev,
> + "could not register clock provider: %s: %d\n",
> + pdev->name, r);
> + }
> +
> + return r;
> +}
> +
> +static struct platform_driver clk_mt2701_bdp_drv = {
> + .probe = clk_mt2701_bdp_probe,
> + .driver = {
> + .name = "clk-mt2701-bdp",
> + .of_match_table = of_match_clk_mt2701_bdp,
> + },
> +};
> +
> +builtin_platform_driver(clk_mt2701_bdp_drv);
> diff --git a/drivers/clk/mediatek/clk-mt2701-eth.c b/drivers/clk/mediatek/clk-mt2701-eth.c
> new file mode 100644
> index 0000000..b2a71a4
> --- /dev/null
> +++ b/drivers/clk/mediatek/clk-mt2701-eth.c
> @@ -0,0 +1,90 @@
> +/*
> + * Copyright (c) 2014 MediaTek Inc.
> + * Author: Shunli Wang <shunli.wang-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/clk-provider.h>
> +#include <linux/platform_device.h>
> +
> +#include "clk-mtk.h"
> +#include "clk-gate.h"
> +
> +#include <dt-bindings/clock/mt2701-clk.h>
> +
> +static const struct mtk_gate_regs eth_cg_regs = {
> + .sta_ofs = 0x0030,
> +};
> +
> +#define GATE_ETH(_id, _name, _parent, _shift) { \
> + .id = _id, \
> + .name = _name, \
> + .parent_name = _parent, \
> + .regs = ð_cg_regs, \
> + .shift = _shift, \
> + .ops = &mtk_clk_gate_ops_no_setclr_inv, \
> + }
> +
> +static const struct mtk_gate eth_clks[] = {
> + GATE_ETH(CLK_ETHSYS_HSDMA, "hsdma_clk", "ethif_sel", 5),
> + GATE_ETH(CLK_ETHSYS_ESW, "esw_clk", "ethpll_500m_ck", 6),
> + GATE_ETH(CLK_ETHSYS_GP2, "gp2_clk", "trgpll", 7),
> + GATE_ETH(CLK_ETHSYS_GP1, "gp1_clk", "ethpll_500m_ck", 8),
> + GATE_ETH(CLK_ETHSYS_PCM, "pcm_clk", "ethif_sel", 11),
> + GATE_ETH(CLK_ETHSYS_GDMA, "gdma_clk", "ethif_sel", 14),
> + GATE_ETH(CLK_ETHSYS_I2S, "i2s_clk", "ethif_sel", 17),
> + GATE_ETH(CLK_ETHSYS_CRYPTO, "crypto_clk", "ethif_sel", 29),
> +};
> +
> +static int mtk_ethsys_init(struct platform_device *pdev)
> +{
> + struct clk_onecell_data *clk_data;
> + int r;
> + struct device_node *node = pdev->dev.of_node;
> +
> + clk_data = mtk_alloc_clk_data(CLK_ETHSYS_NR);
> +
> + mtk_clk_register_gates(node, eth_clks, ARRAY_SIZE(eth_clks),
> + clk_data);
> +
> + r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> +
> + return r;
Just return of_clk_add_provider() please.
> +}
> +
> +static const struct of_device_id of_match_clk_mt2701_eth[] = {
> + { .compatible = "mediatek,mt2701-ethsys", },
> + {}
> +};
> +
> +static int clk_mt2701_eth_probe(struct platform_device *pdev)
> +{
> + int r;
> +
> + r = mtk_ethsys_init(pdev);
Same comment.
> + if (r) {
> + dev_err(&pdev->dev,
> + "could not register clock provider: %s: %d\n",
> + pdev->name, r);
> + }
> +
> + return r;
> +}
> +
> +static struct platform_driver clk_mt2701_eth_drv = {
> + .probe = clk_mt2701_eth_probe,
> + .driver = {
> + .name = "clk-mt2701-eth",
> + .of_match_table = of_match_clk_mt2701_eth,
> + },
> +};
> +
> +builtin_platform_driver(clk_mt2701_eth_drv);
> diff --git a/drivers/clk/mediatek/clk-mt2701-hif.c b/drivers/clk/mediatek/clk-mt2701-hif.c
> new file mode 100644
> index 0000000..e2b0039
> --- /dev/null
> +++ b/drivers/clk/mediatek/clk-mt2701-hif.c
> @@ -0,0 +1,87 @@
> +/*
> + * Copyright (c) 2014 MediaTek Inc.
> + * Author: Shunli Wang <shunli.wang-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/clk-provider.h>
> +#include <linux/platform_device.h>
> +
> +#include "clk-mtk.h"
> +#include "clk-gate.h"
> +
> +#include <dt-bindings/clock/mt2701-clk.h>
> +
> +static const struct mtk_gate_regs hif_cg_regs = {
> + .sta_ofs = 0x0030,
> +};
> +
> +#define GATE_HIF(_id, _name, _parent, _shift) { \
> + .id = _id, \
> + .name = _name, \
> + .parent_name = _parent, \
> + .regs = &hif_cg_regs, \
> + .shift = _shift, \
> + .ops = &mtk_clk_gate_ops_no_setclr_inv, \
> + }
> +
> +static const struct mtk_gate hif_clks[] = {
> + GATE_HIF(CLK_HIFSYS_USB0PHY, "usb0_phy_clk", "ethpll_500m_ck", 21),
> + GATE_HIF(CLK_HIFSYS_USB1PHY, "usb1_phy_clk", "ethpll_500m_ck", 22),
> + GATE_HIF(CLK_HIFSYS_PCIE0, "pcie0_clk", "ethpll_500m_ck", 24),
> + GATE_HIF(CLK_HIFSYS_PCIE1, "pcie1_clk", "ethpll_500m_ck", 25),
> + GATE_HIF(CLK_HIFSYS_PCIE2, "pcie2_clk", "ethpll_500m_ck", 26),
> +};
> +
> +static int mtk_hifsys_init(struct platform_device *pdev)
> +{
> + struct clk_onecell_data *clk_data;
> + int r;
> + struct device_node *node = pdev->dev.of_node;
> +
> + clk_data = mtk_alloc_clk_data(CLK_HIFSYS_NR);
> +
> + mtk_clk_register_gates(node, hif_clks, ARRAY_SIZE(hif_clks),
> + clk_data);
> +
> + r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> +
> + return r;
Just return of_clk_add_provider() please.
> +}
> +
> +static const struct of_device_id of_match_clk_mt2701_hif[] = {
> + { .compatible = "mediatek,mt2701-hifsys", },
> + {}
> +};
> +
> +static int clk_mt2701_hif_probe(struct platform_device *pdev)
> +{
> + int r;
> +
> + r = mtk_hifsys_init(pdev);
There's a pattern. Same comments apply for everything that uses
this style.
> + if (r) {
> + dev_err(&pdev->dev,
> + "could not register clock provider: %s: %d\n",
> + pdev->name, r);
> + }
> +
> + return r;
> +}
> +
> +static struct platform_driver clk_mt2701_hif_drv = {
> + .probe = clk_mt2701_hif_probe,
> + .driver = {
> + .name = "clk-mt2701-hif",
> + .of_match_table = of_match_clk_mt2701_hif,
> + },
> +};
> +
> +builtin_platform_driver(clk_mt2701_hif_drv);
[cut a bunch of same drivers]
> diff --git a/drivers/clk/mediatek/clk-mt2701.c b/drivers/clk/mediatek/clk-mt2701.c
> new file mode 100644
> index 0000000..c225256
> --- /dev/null
> +++ b/drivers/clk/mediatek/clk-mt2701.c
> @@ -0,0 +1,1046 @@
> +/*
> + * Copyright (c) 2014 MediaTek Inc.
> + * Author: Shunli Wang <shunli.wang-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/clk-provider.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +
> +#include "clk-mtk.h"
> +#include "clk-gate.h"
> +
> +#include <dt-bindings/clock/mt2701-clk.h>
> +
> +/*
> + * For some clocks, we don't care what their actual rates are. And these
> + * clocks may change their rate on different products or different scenarios.
> + * So we model these clocks' rate as 0, to denote it's not an actual rate.
> + */
> +#define DUMMY_RATE 0
> +
> +static DEFINE_SPINLOCK(lock);
Please name this something more mtk specific. mt2701_clk_lock?
> +
> +static const struct mtk_fixed_clk top_fixed_clks[] = {
> + FIXED_CLK(CLK_TOP_DPI, "dpi_ck", "clk26m",
> + 108 * MHZ),
> + FIXED_CLK(CLK_TOP_DMPLL, "dmpll_ck", "clk26m",
> + 400 * MHZ),
> + FIXED_CLK(CLK_TOP_VENCPLL, "vencpll_ck", "clk26m",
> + 295750000),
> + FIXED_CLK(CLK_TOP_HDMI_0_PIX340M, "hdmi_0_pix340m", "clk26m",
> + 340 * MHZ),
> + FIXED_CLK(CLK_TOP_HDMI_0_DEEP340M, "hdmi_0_deep340m", "clk26m",
> + 340 * MHZ),
> + FIXED_CLK(CLK_TOP_HDMI_0_PLL340M, "hdmi_0_pll340m", "clk26m",
> + 340 * MHZ),
> + FIXED_CLK(CLK_TOP_HDMITX_CLKDIG_CTS, "hdmitx_dig_cts", "clk26m",
> + 300 * MHZ),
> + FIXED_CLK(CLK_TOP_HADDS2_FB, "hadds2_fbclk", "clk26m",
> + 27 * MHZ),
> + FIXED_CLK(CLK_TOP_WBG_DIG_416M, "wbg_dig_ck_416m", "clk26m",
> + 416 * MHZ),
> + FIXED_CLK(CLK_TOP_DSI0_LNTC_DSI, "dsi0_lntc_dsi", "clk26m",
> + 143 * MHZ),
> + FIXED_CLK(CLK_TOP_HDMI_SCL_RX, "hdmi_scl_rx", "clk26m",
> + 27 * MHZ),
> + FIXED_CLK(CLK_TOP_AUD_EXT1, "aud_ext1", "clk26m",
> + DUMMY_RATE),
> + FIXED_CLK(CLK_TOP_AUD_EXT2, "aud_ext2", "clk26m",
> + DUMMY_RATE),
> + FIXED_CLK(CLK_TOP_NFI1X_PAD, "nfi1x_pad", "clk26m",
> + DUMMY_RATE),
> +};
> +
> +static const struct mtk_fixed_factor top_fixed_divs[] = {
> + FACTOR(CLK_TOP_SYSPLL, "syspll_ck", "mainpll", 1, 1),
> + FACTOR(CLK_TOP_SYSPLL_D2, "syspll_d2", "mainpll", 1, 2),
> + FACTOR(CLK_TOP_SYSPLL_D3, "syspll_d3", "mainpll", 1, 3),
> + FACTOR(CLK_TOP_SYSPLL_D5, "syspll_d5", "mainpll", 1, 5),
> + FACTOR(CLK_TOP_SYSPLL_D7, "syspll_d7", "mainpll", 1, 7),
> + FACTOR(CLK_TOP_SYSPLL1_D2, "syspll1_d2", "syspll_d2", 1, 2),
> + FACTOR(CLK_TOP_SYSPLL1_D4, "syspll1_d4", "syspll_d2", 1, 4),
> + FACTOR(CLK_TOP_SYSPLL1_D8, "syspll1_d8", "syspll_d2", 1, 8),
> + FACTOR(CLK_TOP_SYSPLL1_D16, "syspll1_d16", "syspll_d2", 1, 16),
> + FACTOR(CLK_TOP_SYSPLL2_D2, "syspll2_d2", "syspll_d3", 1, 2),
> + FACTOR(CLK_TOP_SYSPLL2_D4, "syspll2_d4", "syspll_d3", 1, 4),
> + FACTOR(CLK_TOP_SYSPLL2_D8, "syspll2_d8", "syspll_d3", 1, 8),
> + FACTOR(CLK_TOP_SYSPLL3_D2, "syspll3_d2", "syspll_d5", 1, 2),
> + FACTOR(CLK_TOP_SYSPLL3_D4, "syspll3_d4", "syspll_d5", 1, 4),
> + FACTOR(CLK_TOP_SYSPLL4_D2, "syspll4_d2", "syspll_d7", 1, 2),
> + FACTOR(CLK_TOP_SYSPLL4_D4, "syspll4_d4", "syspll_d7", 1, 4),
> +
> + FACTOR(CLK_TOP_UNIVPLL, "univpll_ck", "univpll", 1, 1),
> + FACTOR(CLK_TOP_UNIVPLL_D2, "univpll_d2", "univpll", 1, 2),
> + FACTOR(CLK_TOP_UNIVPLL_D3, "univpll_d3", "univpll", 1, 3),
> + FACTOR(CLK_TOP_UNIVPLL_D5, "univpll_d5", "univpll", 1, 5),
> + FACTOR(CLK_TOP_UNIVPLL_D7, "univpll_d7", "univpll", 1, 7),
> + FACTOR(CLK_TOP_UNIVPLL_D26, "univpll_d26", "univpll", 1, 26),
> + FACTOR(CLK_TOP_UNIVPLL_D52, "univpll_d52", "univpll", 1, 52),
> + FACTOR(CLK_TOP_UNIVPLL_D108, "univpll_d108", "univpll", 1, 108),
> + FACTOR(CLK_TOP_USB_PHY48M, "usb_phy48m_ck", "univpll", 1, 26),
> + FACTOR(CLK_TOP_UNIVPLL1_D2, "univpll1_d2", "univpll_d2", 1, 2),
> + FACTOR(CLK_TOP_UNIVPLL1_D4, "univpll1_d4", "univpll_d2", 1, 4),
> + FACTOR(CLK_TOP_UNIVPLL1_D8, "univpll1_d8", "univpll_d2", 1, 8),
> + FACTOR(CLK_TOP_8BDAC, "8bdac_ck", "univpll_d2", 1, 1),
> + FACTOR(CLK_TOP_UNIVPLL2_D2, "univpll2_d2", "univpll_d3", 1, 2),
> + FACTOR(CLK_TOP_UNIVPLL2_D4, "univpll2_d4", "univpll_d3", 1, 4),
> + FACTOR(CLK_TOP_UNIVPLL2_D8, "univpll2_d8", "univpll_d3", 1, 8),
> + FACTOR(CLK_TOP_UNIVPLL2_D16, "univpll2_d16", "univpll_d3", 1, 16),
> + FACTOR(CLK_TOP_UNIVPLL2_D32, "univpll2_d32", "univpll_d3", 1, 32),
> + FACTOR(CLK_TOP_UNIVPLL3_D2, "univpll3_d2", "univpll_d5", 1, 2),
> + FACTOR(CLK_TOP_UNIVPLL3_D4, "univpll3_d4", "univpll_d5", 1, 4),
> + FACTOR(CLK_TOP_UNIVPLL3_D8, "univpll3_d8", "univpll_d5", 1, 8),
> +
> + FACTOR(CLK_TOP_MSDCPLL, "msdcpll_ck", "msdcpll", 1, 1),
> + FACTOR(CLK_TOP_MSDCPLL_D2, "msdcpll_d2", "msdcpll", 1, 2),
> + FACTOR(CLK_TOP_MSDCPLL_D4, "msdcpll_d4", "msdcpll", 1, 4),
> + FACTOR(CLK_TOP_MSDCPLL_D8, "msdcpll_d8", "msdcpll", 1, 8),
> +
> + FACTOR(CLK_TOP_MMPLL, "mmpll_ck", "mmpll", 1, 1),
> + FACTOR(CLK_TOP_MMPLL_D2, "mmpll_d2", "mmpll", 1, 2),
> +
> + FACTOR(CLK_TOP_DMPLL_D2, "dmpll_d2", "dmpll_ck", 1, 2),
> + FACTOR(CLK_TOP_DMPLL_D4, "dmpll_d4", "dmpll_ck", 1, 4),
> + FACTOR(CLK_TOP_DMPLL_X2, "dmpll_x2", "dmpll_ck", 1, 1),
> +
> + FACTOR(CLK_TOP_TVDPLL, "tvdpll_ck", "tvdpll", 1, 1),
> + FACTOR(CLK_TOP_TVDPLL_D2, "tvdpll_d2", "tvdpll", 1, 2),
> + FACTOR(CLK_TOP_TVDPLL_D4, "tvdpll_d4", "tvdpll", 1, 4),
> +
> + FACTOR(CLK_TOP_VDECPLL, "vdecpll_ck", "vdecpll", 1, 1),
> + FACTOR(CLK_TOP_TVD2PLL, "tvd2pll_ck", "tvd2pll", 1, 1),
> + FACTOR(CLK_TOP_TVD2PLL_D2, "tvd2pll_d2", "tvd2pll", 1, 2),
> +
> + FACTOR(CLK_TOP_MIPIPLL, "mipipll", "dpi_ck", 1, 1),
> + FACTOR(CLK_TOP_MIPIPLL_D2, "mipipll_d2", "dpi_ck", 1, 2),
> + FACTOR(CLK_TOP_MIPIPLL_D4, "mipipll_d4", "dpi_ck", 1, 4),
> +
> + FACTOR(CLK_TOP_HDMIPLL, "hdmipll_ck", "hdmitx_dig_cts", 1, 1),
> + FACTOR(CLK_TOP_HDMIPLL_D2, "hdmipll_d2", "hdmitx_dig_cts", 1, 2),
> + FACTOR(CLK_TOP_HDMIPLL_D3, "hdmipll_d3", "hdmitx_dig_cts", 1, 3),
> +
> + FACTOR(CLK_TOP_ARMPLL_1P3G, "armpll_1p3g_ck", "armpll", 1, 1),
> +
> + FACTOR(CLK_TOP_AUDPLL, "audpll", "audpll_sel", 1, 1),
> + FACTOR(CLK_TOP_AUDPLL_D4, "audpll_d4", "audpll_sel", 1, 4),
> + FACTOR(CLK_TOP_AUDPLL_D8, "audpll_d8", "audpll_sel", 1, 8),
> + FACTOR(CLK_TOP_AUDPLL_D16, "audpll_d16", "audpll_sel", 1, 16),
> + FACTOR(CLK_TOP_AUDPLL_D24, "audpll_d24", "audpll_sel", 1, 24),
> +
> + FACTOR(CLK_TOP_AUD1PLL_98M, "aud1pll_98m_ck", "aud1pll", 1, 3),
> + FACTOR(CLK_TOP_AUD2PLL_90M, "aud2pll_90m_ck", "aud2pll", 1, 3),
> + FACTOR(CLK_TOP_HADDS2PLL_98M, "hadds2pll_98m", "hadds2pll", 1, 3),
> + FACTOR(CLK_TOP_HADDS2PLL_294M, "hadds2pll_294m", "hadds2pll", 1, 1),
> + FACTOR(CLK_TOP_ETHPLL_500M, "ethpll_500m_ck", "ethpll", 1, 1),
> + FACTOR(CLK_TOP_CLK26M_D8, "clk26m_d8", "clk26m", 1, 8),
> + FACTOR(CLK_TOP_32K_INTERNAL, "32k_internal", "clk26m", 1, 793),
> + FACTOR(CLK_TOP_32K_EXTERNAL, "32k_external", "rtc32k", 1, 1),
> +};
> +
> +static const char * const axi_parents[] = {
> + "clk26m",
> + "syspll1_d2",
> + "syspll_d5",
> + "syspll1_d4",
> + "univpll_d5",
> + "univpll2_d2",
> + "mmpll_d2",
> + "dmpll_d2"
> +};
> +
> +static const char * const mem_parents[] = {
> + "clk26m",
> + "dmpll_ck"
> +};
> +
> +static const char * const ddrphycfg_parents[] = {
> + "clk26m",
> + "syspll1_d8"
> +};
> +
> +static const char * const mm_parents[] = {
> + "clk26m",
> + "vencpll_ck",
> + "syspll1_d2",
> + "syspll1_d4",
> + "univpll_d5",
> + "univpll1_d2",
> + "univpll2_d2",
> + "dmpll_ck"
> +};
> +
> +static const char * const pwm_parents[] = {
> + "clk26m",
> + "univpll2_d4",
> + "univpll3_d2",
> + "univpll1_d4",
> +};
> +
> +static const char * const vdec_parents[] = {
> + "clk26m",
> + "vdecpll_ck",
> + "syspll_d5",
> + "syspll1_d4",
> + "univpll_d5",
> + "univpll2_d2",
> + "vencpll_ck",
> + "msdcpll_d2",
> + "mmpll_d2"
> +};
> +
> +static const char * const mfg_parents[] = {
> + "clk26m",
> + "mmpll_ck",
> + "dmpll_x2_ck",
> + "msdcpll_ck",
> + "clk26m",
> + "syspll_d3",
> + "univpll_d3",
> + "univpll1_d2"
> +};
> +
> +static const char * const camtg_parents[] = {
> + "clk26m",
> + "univpll_d26",
> + "univpll2_d2",
> + "syspll3_d2",
> + "syspll3_d4",
> + "msdcpll_d2",
> + "mmpll_d2"
> +};
> +
> +static const char * const uart_parents[] = {
> + "clk26m",
> + "univpll2_d8"
> +};
> +
> +static const char * const spi_parents[] = {
> + "clk26m",
> + "syspll3_d2",
> + "syspll4_d2",
> + "univpll2_d4",
> + "univpll1_d8"
> +};
> +
> +static const char * const usb20_parents[] = {
> + "clk26m",
> + "univpll1_d8",
> + "univpll3_d4"
> +};
> +
> +static const char * const msdc30_parents[] = {
> + "clk26m",
> + "msdcpll_d2",
> + "syspll2_d2",
> + "syspll1_d4",
> + "univpll1_d4",
> + "univpll2_d4"
> +};
> +
> +static const char * const audio_parents[] = {
> + "clk26m",
> + "syspll1_d16"
> +};
> +
> +static const char * const aud_intbus_parents[] = {
> + "clk26m",
> + "syspll1_d4",
> + "syspll3_d2",
> + "syspll4_d2",
> + "univpll3_d2",
> + "univpll2_d4"
> +};
> +
> +static const char * const pmicspi_parents[] = {
> + "clk26m",
> + "syspll1_d8",
> + "syspll2_d4",
> + "syspll4_d2",
> + "syspll3_d4",
> + "syspll2_d8",
> + "syspll1_d16",
> + "univpll3_d4",
> + "univpll_d26",
> + "dmpll_d2",
> + "dmpll_d4"
> +};
> +
> +static const char * const scp_parents[] = {
> + "clk26m",
> + "syspll1_d8",
> + "dmpll_d2",
> + "dmpll_d4"
> +};
> +
> +static const char * const dpi0_parents[] = {
> + "clk26m",
> + "mipipll",
> + "mipipll_d2",
> + "mipipll_d4",
> + "clk26m",
> + "tvdpll_ck",
> + "tvdpll_d2",
> + "tvdpll_d4"
> +};
> +
> +static const char * const dpi1_parents[] = {
> + "clk26m",
> + "tvdpll_ck",
> + "tvdpll_d2",
> + "tvdpll_d4"
> +};
> +
> +static const char * const tve_parents[] = {
> + "clk26m",
> + "mipipll",
> + "mipipll_d2",
> + "mipipll_d4",
> + "clk26m",
> + "tvdpll_ck",
> + "tvdpll_d2",
> + "tvdpll_d4"
> +};
> +
> +static const char * const hdmi_parents[] = {
> + "clk26m",
> + "hdmipll_ck",
> + "hdmipll_d2",
> + "hdmipll_d3"
> +};
> +
> +static const char * const apll_parents[] = {
> + "clk26m",
> + "audpll",
> + "audpll_d4",
> + "audpll_d8",
> + "audpll_d16",
> + "audpll_d24",
> + "clk26m",
> + "clk26m"
> +};
> +
> +static const char * const rtc_parents[] = {
> + "32k_internal",
> + "32k_external",
> + "clk26m",
> + "univpll3_d8"
> +};
> +
> +static const char * const nfi2x_parents[] = {
> + "clk26m",
> + "syspll2_d2",
> + "syspll_d7",
> + "univpll3_d2",
> + "syspll2_d4",
> + "univpll3_d4",
> + "syspll4_d4",
> + "clk26m"
> +};
> +
> +static const char * const emmc_hclk_parents[] = {
> + "clk26m",
> + "syspll1_d2",
> + "syspll1_d4",
> + "syspll2_d2"
> +};
> +
> +static const char * const flash_parents[] = {
> + "clk26m_d8",
> + "clk26m",
> + "syspll2_d8",
> + "syspll3_d4",
> + "univpll3_d4",
> + "syspll4_d2",
> + "syspll2_d4",
> + "univpll2_d4"
> +};
> +
> +static const char * const di_parents[] = {
> + "clk26m",
> + "tvd2pll_ck",
> + "tvd2pll_d2",
> + "clk26m"
> +};
> +
> +static const char * const nr_osd_parents[] = {
> + "clk26m",
> + "vencpll_ck",
> + "syspll1_d2",
> + "syspll1_d4",
> + "univpll_d5",
> + "univpll1_d2",
> + "univpll2_d2",
> + "dmpll_ck"
> +};
> +
> +static const char * const hdmirx_bist_parents[] = {
> + "clk26m",
> + "syspll_d3",
> + "clk26m",
> + "syspll1_d16",
> + "syspll4_d2",
> + "syspll1_d4",
> + "vencpll_ck",
> + "clk26m"
> +};
> +
> +static const char * const intdir_parents[] = {
> + "clk26m",
> + "mmpll_ck",
> + "syspll_d2",
> + "univpll_d2"
> +};
> +
> +static const char * const asm_parents[] = {
> + "clk26m",
> + "univpll2_d4",
> + "univpll2_d2",
> + "syspll_d5"
> +};
> +
> +static const char * const ms_card_parents[] = {
> + "clk26m",
> + "univpll3_d8",
> + "syspll4_d4"
> +};
> +
> +static const char * const ethif_parents[] = {
> + "clk26m",
> + "syspll1_d2",
> + "syspll_d5",
> + "syspll1_d4",
> + "univpll_d5",
> + "univpll1_d2",
> + "dmpll_ck",
> + "dmpll_d2"
> +};
> +
> +static const char * const hdmirx_parents[] = {
> + "clk26m",
> + "univpll_d52"
> +};
> +
> +static const char * const cmsys_parents[] = {
> + "clk26m",
> + "syspll1_d2",
> + "univpll1_d2",
> + "univpll_d5",
> + "syspll_d5",
> + "syspll2_d2",
> + "syspll1_d4",
> + "syspll3_d2",
> + "syspll2_d4",
> + "syspll1_d8",
> + "clk26m",
> + "clk26m",
> + "clk26m",
> + "clk26m",
> + "clk26m"
> +};
> +
> +static const char * const clk_8bdac_parents[] = {
> + "32k_internal",
> + "8bdac_ck",
> + "clk26m",
> + "clk26m"
> +};
> +
> +static const char * const aud2dvd_parents[] = {
> + "a1sys_hp_ck",
> + "a2sys_hp_ck"
> +};
> +
> +static const char * const padmclk_parents[] = {
> + "clk26m",
> + "univpll_d26",
> + "univpll_d52",
> + "univpll_d108",
> + "univpll2_d8",
> + "univpll2_d16",
> + "univpll2_d32"
> +};
> +
> +static const char * const aud_mux_parents[] = {
> + "clk26m",
> + "aud1pll_98m_ck",
> + "aud2pll_90m_ck",
> + "hadds2pll_98m",
> + "audio_ext1_ck",
> + "audio_ext2_ck"
> +};
> +
> +static const char * const aud_src_parents[] = {
> + "aud_mux1_sel",
> + "aud_mux2_sel"
> +};
> +
> +static const char * const cpu_parents[] = {
> + "clk26m",
> + "armpll",
> + "mainpll",
> + "mmpll"
> +};
> +
> +static const struct mtk_composite top_muxes[] = {
> + MUX_GATE_FLAGS(CLK_TOP_AXI_SEL, "axi_sel", axi_parents,
> + 0x0040, 0, 3, 7, CLK_IS_CRITICAL),
> + MUX_GATE_FLAGS(CLK_TOP_MEM_SEL, "mem_sel", mem_parents,
> + 0x0040, 8, 1, 15, CLK_IS_CRITICAL),
> + MUX_GATE_FLAGS(CLK_TOP_DDRPHYCFG_SEL, "ddrphycfg_sel",
> + ddrphycfg_parents, 0x0040, 16, 1, 23, CLK_IS_CRITICAL),
> + MUX_GATE(CLK_TOP_MM_SEL, "mm_sel", mm_parents,
> + 0x0040, 24, 3, 31),
> +
> + MUX_GATE(CLK_TOP_PWM_SEL, "pwm_sel", pwm_parents,
> + 0x0050, 0, 2, 7),
> + MUX_GATE(CLK_TOP_VDEC_SEL, "vdec_sel", vdec_parents,
> + 0x0050, 8, 4, 15),
> + MUX_GATE(CLK_TOP_MFG_SEL, "mfg_sel", mfg_parents,
> + 0x0050, 16, 3, 23),
> + MUX_GATE(CLK_TOP_CAMTG_SEL, "camtg_sel", camtg_parents,
> + 0x0050, 24, 3, 31),
> + MUX_GATE(CLK_TOP_UART_SEL, "uart_sel", uart_parents,
> + 0x0060, 0, 1, 7),
> +
> + MUX_GATE(CLK_TOP_SPI0_SEL, "spi0_sel", spi_parents,
> + 0x0060, 8, 3, 15),
> + MUX_GATE(CLK_TOP_USB20_SEL, "usb20_sel", usb20_parents,
> + 0x0060, 16, 2, 23),
> + MUX_GATE(CLK_TOP_MSDC30_0_SEL, "msdc30_0_sel", msdc30_parents,
> + 0x0060, 24, 3, 31),
> +
> + MUX_GATE(CLK_TOP_MSDC30_1_SEL, "msdc30_1_sel", msdc30_parents,
> + 0x0070, 0, 3, 7),
> + MUX_GATE(CLK_TOP_MSDC30_2_SEL, "msdc30_2_sel", msdc30_parents,
> + 0x0070, 8, 3, 15),
> + MUX_GATE(CLK_TOP_AUDIO_SEL, "audio_sel", msdc30_parents,
> + 0x0070, 16, 1, 23),
> + MUX_GATE(CLK_TOP_AUDINTBUS_SEL, "aud_intbus_sel", aud_intbus_parents,
> + 0x0070, 24, 3, 31),
> +
> + MUX_GATE(CLK_TOP_PMICSPI_SEL, "pmicspi_sel", pmicspi_parents,
> + 0x0080, 0, 4, 7),
> + MUX_GATE(CLK_TOP_SCP_SEL, "scp_sel", scp_parents,
> + 0x0080, 8, 2, 15),
> + MUX_GATE(CLK_TOP_DPI0_SEL, "dpi0_sel", dpi0_parents,
> + 0x0080, 16, 3, 23),
> + MUX_GATE(CLK_TOP_DPI1_SEL, "dpi1_sel", dpi1_parents,
> + 0x0080, 24, 2, 31),
> +
> + MUX_GATE(CLK_TOP_TVE_SEL, "tve_sel", tve_parents,
> + 0x0090, 0, 3, 7),
> + MUX_GATE(CLK_TOP_HDMI_SEL, "hdmi_sel", hdmi_parents,
> + 0x0090, 8, 2, 15),
> + MUX_GATE(CLK_TOP_APLL_SEL, "apll_sel", apll_parents,
> + 0x0090, 16, 3, 23),
> +
> + MUX_GATE_FLAGS(CLK_TOP_RTC_SEL, "rtc_sel", rtc_parents,
> + 0x00A0, 0, 2, 7, CLK_IS_CRITICAL),
> + MUX_GATE(CLK_TOP_NFI2X_SEL, "nfi2x_sel", nfi2x_parents,
> + 0x00A0, 8, 3, 15),
> + MUX_GATE(CLK_TOP_EMMC_HCLK_SEL, "emmc_hclk_sel", emmc_hclk_parents,
> + 0x00A0, 24, 2, 31),
> +
> + MUX_GATE(CLK_TOP_FLASH_SEL, "flash_sel", flash_parents,
> + 0x00B0, 0, 3, 7),
> + MUX_GATE(CLK_TOP_DI_SEL, "di_sel", di_parents,
> + 0x00B0, 8, 2, 15),
> + MUX_GATE(CLK_TOP_NR_SEL, "nr_sel", nr_osd_parents,
> + 0x00B0, 16, 3, 23),
> + MUX_GATE(CLK_TOP_OSD_SEL, "osd_sel", nr_osd_parents,
> + 0x00B0, 24, 3, 31),
> +
> + MUX_GATE(CLK_TOP_HDMIRX_BIST_SEL, "hdmirx_bist_sel",
> + hdmirx_bist_parents, 0x00C0, 0, 3, 7),
> + MUX_GATE(CLK_TOP_INTDIR_SEL, "intdir_sel", intdir_parents,
> + 0x00C0, 8, 2, 15),
> + MUX_GATE(CLK_TOP_ASM_I_SEL, "asm_i_sel", asm_parents,
> + 0x00C0, 16, 2, 23),
> + MUX_GATE(CLK_TOP_ASM_M_SEL, "asm_m_sel", asm_parents,
> + 0x00C0, 24, 3, 31),
> +
> + MUX_GATE(CLK_TOP_ASM_H_SEL, "asm_h_sel", asm_parents,
> + 0x00D0, 0, 2, 7),
> + MUX_GATE(CLK_TOP_MS_CARD_SEL, "ms_card_sel", ms_card_parents,
> + 0x00D0, 16, 2, 23),
> + MUX_GATE(CLK_TOP_ETHIF_SEL, "ethif_sel", ethif_parents,
> + 0x00D0, 24, 3, 31),
> +
> + MUX_GATE(CLK_TOP_HDMIRX26_24_SEL, "hdmirx26_24_sel", hdmirx_parents,
> + 0x00E0, 0, 1, 7),
> + MUX_GATE(CLK_TOP_MSDC30_3_SEL, "msdc30_3_sel", msdc30_parents,
> + 0x00E0, 8, 3, 15),
> + MUX_GATE(CLK_TOP_CMSYS_SEL, "cmsys_sel", cmsys_parents,
> + 0x00E0, 16, 4, 23),
> +
> + MUX_GATE(CLK_TOP_SPI1_SEL, "spi2_sel", spi_parents,
> + 0x00E0, 24, 3, 31),
> + MUX_GATE(CLK_TOP_SPI2_SEL, "spi1_sel", spi_parents,
> + 0x00F0, 0, 3, 7),
> + MUX_GATE(CLK_TOP_8BDAC_SEL, "8bdac_sel", clk_8bdac_parents,
> + 0x00F0, 8, 2, 15),
> + MUX_GATE(CLK_TOP_AUD2DVD_SEL, "aud2dvd_sel", aud2dvd_parents,
> + 0x00F0, 16, 1, 23),
> +
> + MUX(CLK_TOP_PADMCLK_SEL, "padmclk_sel", padmclk_parents,
> + 0x0100, 0, 3),
> +
> + MUX(CLK_TOP_AUD_MUX1_SEL, "aud_mux1_sel", aud_mux_parents,
> + 0x012c, 0, 3),
> + MUX(CLK_TOP_AUD_MUX2_SEL, "aud_mux2_sel", aud_mux_parents,
> + 0x012c, 3, 3),
> + MUX(CLK_TOP_AUDPLL_MUX_SEL, "audpll_sel", aud_mux_parents,
> + 0x012c, 6, 3),
> + MUX_GATE(CLK_TOP_AUD_K1_SRC_SEL, "aud_k1_src_sel", aud_src_parents,
> + 0x012c, 15, 1, 23),
> + MUX_GATE(CLK_TOP_AUD_K2_SRC_SEL, "aud_k2_src_sel", aud_src_parents,
> + 0x012c, 16, 1, 24),
> + MUX_GATE(CLK_TOP_AUD_K3_SRC_SEL, "aud_k3_src_sel", aud_src_parents,
> + 0x012c, 17, 1, 25),
> + MUX_GATE(CLK_TOP_AUD_K4_SRC_SEL, "aud_k4_src_sel", aud_src_parents,
> + 0x012c, 18, 1, 26),
> + MUX_GATE(CLK_TOP_AUD_K5_SRC_SEL, "aud_k5_src_sel", aud_src_parents,
> + 0x012c, 19, 1, 27),
> + MUX_GATE(CLK_TOP_AUD_K6_SRC_SEL, "aud_k6_src_sel", aud_src_parents,
> + 0x012c, 20, 1, 28),
> +};
> +
> +static const struct mtk_clk_divider top_adj_divs[] = {
> + DIV_ADJ(CLK_TOP_AUD_EXTCK1_DIV, "audio_ext1_ck", "aud_ext1",
> + 0x0120, 0, 8),
> + DIV_ADJ(CLK_TOP_AUD_EXTCK2_DIV, "audio_ext2_ck", "aud_ext2",
> + 0x0120, 8, 8),
> + DIV_ADJ(CLK_TOP_AUD_MUX1_DIV, "aud_mux1_div", "aud_mux1_sel",
> + 0x0120, 16, 8),
> + DIV_ADJ(CLK_TOP_AUD_MUX2_DIV, "aud_mux2_div", "aud_mux2_sel",
> + 0x0120, 24, 8),
> + DIV_ADJ(CLK_TOP_AUD_K1_SRC_DIV, "aud_k1_src_div", "aud_k1_src_sel",
> + 0x0124, 0, 8),
> + DIV_ADJ(CLK_TOP_AUD_K2_SRC_DIV, "aud_k2_src_div", "aud_k2_src_sel",
> + 0x0124, 8, 8),
> + DIV_ADJ(CLK_TOP_AUD_K3_SRC_DIV, "aud_k3_src_div", "aud_k3_src_sel",
> + 0x0124, 16, 8),
> + DIV_ADJ(CLK_TOP_AUD_K4_SRC_DIV, "aud_k4_src_div", "aud_k4_src_sel",
> + 0x0124, 24, 8),
> + DIV_ADJ(CLK_TOP_AUD_K5_SRC_DIV, "aud_k5_src_div", "aud_k5_src_sel",
> + 0x0128, 0, 8),
> + DIV_ADJ(CLK_TOP_AUD_K6_SRC_DIV, "aud_k6_src_div", "aud_k6_src_sel",
> + 0x0128, 8, 8),
> +};
> +
> +static const struct mtk_gate_regs top_aud_cg_regs = {
> + .sta_ofs = 0x012C,
> +};
> +
> +#define GATE_TOP_AUD(_id, _name, _parent, _shift) { \
> + .id = _id, \
> + .name = _name, \
> + .parent_name = _parent, \
> + .regs = &top_aud_cg_regs, \
> + .shift = _shift, \
> + .ops = &mtk_clk_gate_ops_no_setclr, \
> + }
> +
> +static const struct mtk_gate top_clks[] = {
> + GATE_TOP_AUD(CLK_TOP_AUD_48K_TIMING, "a1sys_hp_ck", "aud_mux1_div",
> + 21),
> + GATE_TOP_AUD(CLK_TOP_AUD_44K_TIMING, "a2sys_hp_ck", "aud_mux2_div",
> + 22),
> + GATE_TOP_AUD(CLK_TOP_AUD_I2S1_MCLK, "aud_i2s1_mclk", "aud_k1_src_div",
> + 23),
> + GATE_TOP_AUD(CLK_TOP_AUD_I2S2_MCLK, "aud_i2s2_mclk", "aud_k2_src_div",
> + 24),
> + GATE_TOP_AUD(CLK_TOP_AUD_I2S3_MCLK, "aud_i2s3_mclk", "aud_k3_src_div",
> + 25),
> + GATE_TOP_AUD(CLK_TOP_AUD_I2S4_MCLK, "aud_i2s4_mclk", "aud_k4_src_div",
> + 26),
> + GATE_TOP_AUD(CLK_TOP_AUD_I2S5_MCLK, "aud_i2s5_mclk", "aud_k5_src_div",
> + 27),
> + GATE_TOP_AUD(CLK_TOP_AUD_I2S6_MCLK, "aud_i2s6_mclk", "aud_k6_src_div",
> + 28),
> +};
> +
> +void __iomem *devm_of_iomap(struct device *dev, int index)
Sorry what is this?
> +{
> + struct resource res;
> +
> + if (!dev)
> + return NULL;
> +
> + if (of_address_to_resource(dev->of_node, index, &res))
> + return NULL;
> +
> + return devm_ioremap(dev, res.start, resource_size(&res));
Can't we just use platform_get_resouce() and
devm_ioremap_resource() here? It looks like we always have a
platform device.
> +}
> +
> +static int mtk_topckgen_init(struct platform_device *pdev)
> +{
> + struct clk_onecell_data *clk_data;
> + void __iomem *base;
> + int r;
> + struct device_node *node = pdev->dev.of_node;
> +
> + base = devm_of_iomap(&pdev->dev, 0);
> + if (!base)
> + return -ENOMEM;
> +
> + clk_data = mtk_alloc_clk_data(CLK_TOP_NR);
> +
> + mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks),
> + clk_data);
> +
> + mtk_clk_register_factors(top_fixed_divs, ARRAY_SIZE(top_fixed_divs),
> + clk_data);
> +
> + mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes),
> + base, &lock, clk_data);
> +
> + mtk_clk_register_dividers(top_adj_divs, ARRAY_SIZE(top_adj_divs),
> + base, &lock, clk_data);
> +
> + mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks),
> + clk_data);
> +
> + r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> +
> + return r;
> +}
> +
> +static const struct mtk_gate_regs infra_cg_regs = {
> + .set_ofs = 0x0040,
> + .clr_ofs = 0x0044,
> + .sta_ofs = 0x0048,
> +};
> +
> +#define GATE_ICG(_id, _name, _parent, _shift) { \
> + .id = _id, \
> + .name = _name, \
> + .parent_name = _parent, \
> + .regs = &infra_cg_regs, \
> + .shift = _shift, \
> + .ops = &mtk_clk_gate_ops_setclr, \
> + }
> +
> +static const struct mtk_gate infra_clks[] = {
> + GATE_ICG(CLK_INFRA_DBG, "dbgclk", "axi_sel", 0),
> + GATE_ICG(CLK_INFRA_SMI, "smi_ck", "mm_sel", 1),
> + GATE_ICG(CLK_INFRA_QAXI_CM4, "cm4_ck", "axi_sel", 2),
> + GATE_ICG(CLK_INFRA_AUD_SPLIN_B, "audio_splin_bck", "hadds2pll_294m", 4),
> + GATE_ICG(CLK_INFRA_AUDIO, "audio_ck", "clk26m", 5),
> + GATE_ICG(CLK_INFRA_EFUSE, "efuse_ck", "clk26m", 6),
> + GATE_ICG(CLK_INFRA_L2C_SRAM, "l2c_sram_ck", "mm_sel", 7),
> + GATE_ICG(CLK_INFRA_M4U, "m4u_ck", "mem_sel", 8),
> + GATE_ICG(CLK_INFRA_CONNMCU, "connsys_bus", "wbg_dig_ck_416m", 12),
> + GATE_ICG(CLK_INFRA_TRNG, "trng_ck", "axi_sel", 13),
> + GATE_ICG(CLK_INFRA_RAMBUFIF, "rambufif_ck", "mem_sel", 14),
> + GATE_ICG(CLK_INFRA_CPUM, "cpum_ck", "mem_sel", 15),
> + GATE_ICG(CLK_INFRA_KP, "kp_ck", "axi_sel", 16),
> + GATE_ICG(CLK_INFRA_CEC, "cec_ck", "rtc_sel", 18),
> + GATE_ICG(CLK_INFRA_IRRX, "irrx_ck", "axi_sel", 19),
> + GATE_ICG(CLK_INFRA_PMICSPI, "pmicspi_ck", "pmicspi_sel", 22),
> + GATE_ICG(CLK_INFRA_PMICWRAP, "pmicwrap_ck", "axi_sel", 23),
> + GATE_ICG(CLK_INFRA_DDCCI, "ddcci_ck", "axi_sel", 24),
> +};
> +
> +static const struct mtk_fixed_factor infra_fixed_divs[] = {
> + FACTOR(CLK_INFRA_CLK_13M, "clk13m", "clk26m", 1, 2),
> +};
> +
> +static struct clk_onecell_data *infra_clk_data;
> +
> +static void mtk_infrasys_init_early(struct device_node *node)
> +{
> + int r, i;
> +
> + if (!infra_clk_data) {
> + infra_clk_data = mtk_alloc_clk_data(CLK_INFRA_NR);
> +
> + for (i = 0; i < CLK_INFRA_NR; i++)
> + infra_clk_data->clks[i] = ERR_PTR(-EPROBE_DEFER);
> + }
> +
> + mtk_clk_register_factors(infra_fixed_divs, ARRAY_SIZE(infra_fixed_divs),
> + infra_clk_data);
> +
> + r = of_clk_add_provider(node, of_clk_src_onecell_get, infra_clk_data);
> + if (r)
> + pr_err("%s(): could not register clock provider: %d\n",
> + __func__, r);
> +}
> +CLK_OF_DECLARE_DRIVER(mtk_infra, "mediatek,mt2701-infracfg",
> + mtk_infrasys_init_early);
> +
> +static int mtk_infrasys_init(struct platform_device *pdev)
> +{
> + int r, i;
> + struct device_node *node = pdev->dev.of_node;
> +
> + if (!infra_clk_data) {
> + infra_clk_data = mtk_alloc_clk_data(CLK_INFRA_NR);
> + } else {
> + for (i = 0; i < CLK_INFRA_NR; i++) {
> + if (infra_clk_data->clks[i] == ERR_PTR(-EPROBE_DEFER))
> + infra_clk_data->clks[i] = ERR_PTR(-ENOENT);
> + }
> + }
> +
> + mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
> + infra_clk_data);
> + mtk_clk_register_factors(infra_fixed_divs, ARRAY_SIZE(infra_fixed_divs),
> + infra_clk_data);
> +
> + r = of_clk_add_provider(node, of_clk_src_onecell_get, infra_clk_data);
> +
> + return r;
> +}
> +
> +static const struct mtk_gate_regs peri0_cg_regs = {
> + .set_ofs = 0x0008,
> + .clr_ofs = 0x0010,
> + .sta_ofs = 0x0018,
> +};
> +
> +static const struct mtk_gate_regs peri1_cg_regs = {
> + .set_ofs = 0x000c,
> + .clr_ofs = 0x0014,
> + .sta_ofs = 0x001c,
> +};
> +
> +#define GATE_PERI0(_id, _name, _parent, _shift) { \
> + .id = _id, \
> + .name = _name, \
> + .parent_name = _parent, \
> + .regs = &peri0_cg_regs, \
> + .shift = _shift, \
> + .ops = &mtk_clk_gate_ops_setclr, \
> + }
> +
> +#define GATE_PERI1(_id, _name, _parent, _shift) { \
> + .id = _id, \
> + .name = _name, \
> + .parent_name = _parent, \
> + .regs = &peri1_cg_regs, \
> + .shift = _shift, \
> + .ops = &mtk_clk_gate_ops_setclr, \
> + }
> +
> +static const struct mtk_gate peri_clks[] = {
> + GATE_PERI0(CLK_PERI_USB0_MCU, "usb0_mcu_ck", "axi_sel", 31),
> + GATE_PERI0(CLK_PERI_ETH, "eth_ck", "clk26m", 30),
> + GATE_PERI0(CLK_PERI_SPI0, "spi0_ck", "spi0_sel", 29),
> + GATE_PERI0(CLK_PERI_AUXADC, "auxadc_ck", "clk26m", 28),
> + GATE_PERI0(CLK_PERI_I2C3, "i2c3_ck", "clk26m", 27),
> + GATE_PERI0(CLK_PERI_I2C2, "i2c2_ck", "axi_sel", 26),
> + GATE_PERI0(CLK_PERI_I2C1, "i2c1_ck", "axi_sel", 25),
> + GATE_PERI0(CLK_PERI_I2C0, "i2c0_ck", "axi_sel", 24),
> + GATE_PERI0(CLK_PERI_BTIF, "bitif_ck", "axi_sel", 23),
> + GATE_PERI0(CLK_PERI_UART3, "uart3_ck", "axi_sel", 22),
> + GATE_PERI0(CLK_PERI_UART2, "uart2_ck", "axi_sel", 21),
> + GATE_PERI0(CLK_PERI_UART1, "uart1_ck", "axi_sel", 20),
> + GATE_PERI0(CLK_PERI_UART0, "uart0_ck", "axi_sel", 19),
> + GATE_PERI0(CLK_PERI_NLI, "nli_ck", "axi_sel", 18),
> + GATE_PERI0(CLK_PERI_MSDC50_3, "msdc50_3_ck", "emmc_hclk_sel", 17),
> + GATE_PERI0(CLK_PERI_MSDC30_3, "msdc30_3_ck", "msdc30_3_sel", 16),
> + GATE_PERI0(CLK_PERI_MSDC30_2, "msdc30_2_ck", "msdc30_2_sel", 15),
> + GATE_PERI0(CLK_PERI_MSDC30_1, "msdc30_1_ck", "msdc30_1_sel", 14),
> + GATE_PERI0(CLK_PERI_MSDC30_0, "msdc30_0_ck", "msdc30_0_sel", 13),
> + GATE_PERI0(CLK_PERI_AP_DMA, "ap_dma_ck", "axi_sel", 12),
> + GATE_PERI0(CLK_PERI_USB1, "usb1_ck", "usb20_sel", 11),
> + GATE_PERI0(CLK_PERI_USB0, "usb0_ck", "usb20_sel", 10),
> + GATE_PERI0(CLK_PERI_PWM, "pwm_ck", "axi_sel", 9),
> + GATE_PERI0(CLK_PERI_PWM7, "pwm7_ck", "axi_sel", 8),
> + GATE_PERI0(CLK_PERI_PWM6, "pwm6_ck", "axi_sel", 7),
> + GATE_PERI0(CLK_PERI_PWM5, "pwm5_ck", "axi_sel", 6),
> + GATE_PERI0(CLK_PERI_PWM4, "pwm4_ck", "axi_sel", 5),
> + GATE_PERI0(CLK_PERI_PWM3, "pwm3_ck", "axi_sel", 4),
> + GATE_PERI0(CLK_PERI_PWM2, "pwm2_ck", "axi_sel", 3),
> + GATE_PERI0(CLK_PERI_PWM1, "pwm1_ck", "axi_sel", 2),
> + GATE_PERI0(CLK_PERI_THERM, "therm_ck", "axi_sel", 1),
> + GATE_PERI0(CLK_PERI_NFI, "nfi_ck", "nfi2x_sel", 0),
> +
> + GATE_PERI1(CLK_PERI_FCI, "fci_ck", "ms_card_sel", 11),
> + GATE_PERI1(CLK_PERI_SPI2, "spi2_ck", "spi2_sel", 10),
> + GATE_PERI1(CLK_PERI_SPI1, "spi1_ck", "spi1_sel", 9),
> + GATE_PERI1(CLK_PERI_HOST89_DVD, "host89_dvd_ck", "aud2dvd_sel", 8),
> + GATE_PERI1(CLK_PERI_HOST89_SPI, "host89_spi_ck", "spi0_sel", 7),
> + GATE_PERI1(CLK_PERI_HOST89_INT, "host89_int_ck", "axi_sel", 6),
> + GATE_PERI1(CLK_PERI_FLASH, "flash_ck", "nfi2x_sel", 5),
> + GATE_PERI1(CLK_PERI_NFI_PAD, "nfi_pad_ck", "nfi1x_pad", 4),
> + GATE_PERI1(CLK_PERI_NFI_ECC, "nfi_ecc_ck", "nfi1x_pad", 3),
> + GATE_PERI1(CLK_PERI_GCPU, "gcpu_ck", "axi_sel", 2),
> + GATE_PERI1(CLK_PERI_USB_SLV, "usbslv_ck", "axi_sel", 1),
> + GATE_PERI1(CLK_PERI_USB1_MCU, "usb1_mcu_ck", "axi_sel", 0),
> +};
> +
> +static const char * const uart_ck_sel_parents[] = {
> + "clk26m",
> + "uart_sel",
> +};
> +
> +static const struct mtk_composite peri_muxs[] = {
> + MUX(CLK_PERI_UART0_SEL, "uart0_ck_sel", uart_ck_sel_parents,
> + 0x40c, 0, 1),
> + MUX(CLK_PERI_UART1_SEL, "uart1_ck_sel", uart_ck_sel_parents,
> + 0x40c, 1, 1),
> + MUX(CLK_PERI_UART2_SEL, "uart2_ck_sel", uart_ck_sel_parents,
> + 0x40c, 2, 1),
> + MUX(CLK_PERI_UART3_SEL, "uart3_ck_sel", uart_ck_sel_parents,
> + 0x40c, 3, 1),
> +};
> +
> +static int mtk_pericfg_init(struct platform_device *pdev)
> +{
> + struct clk_onecell_data *clk_data;
> + void __iomem *base;
> + int r;
> + struct device_node *node = pdev->dev.of_node;
> +
> + base = devm_of_iomap(&pdev->dev, 0);
> + if (!base)
> + return -ENOMEM;
> +
> + clk_data = mtk_alloc_clk_data(CLK_PERI_NR);
> +
> + mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks),
> + clk_data);
> +
> + mtk_clk_register_composites(peri_muxs, ARRAY_SIZE(peri_muxs), base,
> + &lock, clk_data);
> +
> + r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> +
> + return r;
Just return of_clk_add_provider()?
> +}
[...]
> +
> +static int clk_mt2701_probe(struct platform_device *pdev)
> +{
> + int (*clk_init)(struct platform_device *);
> + int r;
> +
> + clk_init = of_device_get_match_data(&pdev->dev);
> + if (!clk_init)
> + return -EINVAL;
> +
> + r = clk_init(pdev);
> + if (r) {
> + dev_err(&pdev->dev,
> + "could not register clock provider: %s: %d\n",
> + pdev->name, r);
> + }
Braces are unnecessary.
> +
> + return r;
> +}
> +
> +static struct platform_driver clk_mt2701_drv = {
> + .probe = clk_mt2701_probe,
> + .driver = {
> + .name = "clk-mt2701",
> + .owner = THIS_MODULE,
This is unnecessary because platform_driver_register() already
does it.
> + .of_match_table = of_match_clk_mt2701,
> + },
> +};
> +
> +static int __init clk_mt2701_init(void)
> +{
> + return platform_driver_register(&clk_mt2701_drv);
> +}
> +
> +arch_initcall(clk_mt2701_init);
> diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
> index bb30f70..0541df7 100644
> --- a/drivers/clk/mediatek/clk-mtk.c
> +++ b/drivers/clk/mediatek/clk-mtk.c
> @@ -58,6 +58,9 @@ void mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks,
> for (i = 0; i < num; i++) {
> const struct mtk_fixed_clk *rc = &clks[i];
>
> + if (clk_data && !IS_ERR_OR_NULL(clk_data->clks[rc->id]))
> + continue;
> +
> clk = clk_register_fixed_rate(NULL, rc->name, rc->parent, 0,
> rc->rate);
>
> @@ -81,6 +84,9 @@ void mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
> for (i = 0; i < num; i++) {
> const struct mtk_fixed_factor *ff = &clks[i];
>
> + if (clk_data && !IS_ERR_OR_NULL(clk_data->clks[ff->id]))
> + continue;
> +
> clk = clk_register_fixed_factor(NULL, ff->name, ff->parent_name,
> CLK_SET_RATE_PARENT, ff->mult, ff->div);
>
> @@ -116,6 +122,9 @@ int mtk_clk_register_gates(struct device_node *node,
> for (i = 0; i < num; i++) {
> const struct mtk_gate *gate = &clks[i];
>
> + if (!IS_ERR_OR_NULL(clk_data->clks[gate->id]))
> + continue;
> +
> clk = mtk_clk_register_gate(gate->name, gate->parent_name,
> regmap,
> gate->regs->set_ofs,
> @@ -232,6 +241,9 @@ void mtk_clk_register_composites(const struct mtk_composite *mcs,
> for (i = 0; i < num; i++) {
> const struct mtk_composite *mc = &mcs[i];
>
> + if (clk_data && !IS_ERR_OR_NULL(clk_data->clks[mc->id]))
> + continue;
> +
> clk = mtk_clk_register_composite(mc, base, lock);
>
> if (IS_ERR(clk)) {
> @@ -244,3 +256,31 @@ void mtk_clk_register_composites(const struct mtk_composite *mcs,
> clk_data->clks[mc->id] = clk;
> }
> }
> +
> +void mtk_clk_register_dividers(const struct mtk_clk_divider *mcds,
> + int num, void __iomem *base, spinlock_t *lock,
> + struct clk_onecell_data *clk_data)
> +{
> + struct clk *clk;
> + int i;
> +
> + for (i = 0; i < num; i++) {
> + const struct mtk_clk_divider *mcd = &mcds[i];
> +
> + if (clk_data && !IS_ERR_OR_NULL(clk_data->clks[mcd->id]))
NULL is a valid clk. IS_ERR_OR_NULL is usually wrong.
> + continue;
> +
> + clk = clk_register_divider(NULL, mcd->name, mcd->parent_name,
> + mcd->flags, base + mcd->div_reg, mcd->div_shift,
> + mcd->div_width, mcd->clk_divider_flags, lock);
> +
> + if (IS_ERR(clk)) {
> + pr_err("Failed to register clk %s: %ld\n",
> + mcd->name, PTR_ERR(clk));
> + continue;
> + }
> +
> + if (clk_data)
> + clk_data->clks[mcd->id] = clk;
> + }
> +}
> diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
> index 9f24fcf..f5d6b70 100644
> --- a/drivers/clk/mediatek/clk-mtk.h
> +++ b/drivers/clk/mediatek/clk-mtk.h
> @@ -87,7 +87,8 @@ struct mtk_composite {
> * In case the rate change propagation to parent clocks is undesirable,
> * this macro allows to specify the clock flags manually.
> */
> -#define MUX_GATE_FLAGS(_id, _name, _parents, _reg, _shift, _width, _gate, _flags) { \
> +#define MUX_GATE_FLAGS(_id, _name, _parents, _reg, _shift, _width, \
> + _gate, _flags) { \
> .id = _id, \
> .name = _name, \
> .mux_reg = _reg, \
> @@ -106,7 +107,8 @@ struct mtk_composite {
> * parent clock by default.
> */
> #define MUX_GATE(_id, _name, _parents, _reg, _shift, _width, _gate) \
> - MUX_GATE_FLAGS(_id, _name, _parents, _reg, _shift, _width, _gate, CLK_SET_RATE_PARENT)
> + MUX_GATE_FLAGS(_id, _name, _parents, _reg, _shift, _width, \
> + _gate, CLK_SET_RATE_PARENT)
>
> #define MUX(_id, _name, _parents, _reg, _shift, _width) { \
> .id = _id, \
> @@ -121,7 +123,8 @@ struct mtk_composite {
> .flags = CLK_SET_RATE_PARENT, \
> }
>
> -#define DIV_GATE(_id, _name, _parent, _gate_reg, _gate_shift, _div_reg, _div_width, _div_shift) { \
> +#define DIV_GATE(_id, _name, _parent, _gate_reg, _gate_shift, _div_reg, \
> + _div_width, _div_shift) { \
Did anything actually change? Checkpatch fix?
> .id = _id, \
> .parent = _parent, \
> .name = _name, \
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH] [media] media: fix platform_no_drv_owner.cocci warnings
From: kbuild test robot @ 2016-10-27 22:34 UTC (permalink / raw)
To: Minghsiu Tsai
Cc: kbuild-all, Mauro Carvalho Chehab, linux-media, Hans Verkuil,
Matthias Brugger, linux-arm-kernel, linux-mediatek, linux-kernel
In-Reply-To: <201610280623.yEQ4DZSc%fengguang.wu@intel.com>
drivers/media/platform/mtk-mdp/mtk_mdp_core.c:284:3-8: No need to set .owner here. The core will do it.
Remove .owner field if calls are used which set it automatically
Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci
CC: Minghsiu Tsai <minghsiu.tsai@mediatek.com>
Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
---
mtk_mdp_core.c | 1 -
1 file changed, 1 deletion(-)
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
@@ -281,7 +281,6 @@ static struct platform_driver mtk_mdp_dr
.remove = mtk_mdp_remove,
.driver = {
.name = MTK_MDP_MODULE_NAME,
- .owner = THIS_MODULE,
.pm = &mtk_mdp_pm_ops,
.of_match_table = mtk_mdp_of_ids,
}
^ permalink raw reply
* [PATCH next 2/2] media: mtk-mdp: NULL-terminate mtk_mdp_comp_dt_ids
From: Vincent Stehlé @ 2016-10-27 20:23 UTC (permalink / raw)
To: linux-media, linux-mediatek
Cc: linux-arm-kernel, linux-kernel, Vincent Stehlé,
Minghsiu Tsai, Hans Verkuil, Mauro Carvalho Chehab
In-Reply-To: <20161027202325.20680-1-vincent.stehle@laposte.net>
The mtk_mdp_comp_dt_ids[] array should be NULL-terminated; add therefore an
empty entry in the end.
Fixes: c8eb2d7e8202fd9c ("[media] media: Add Mediatek MDP Driver")
Signed-off-by: Vincent Stehlé <vincent.stehle@laposte.net>
Cc: Minghsiu Tsai <minghsiu.tsai@mediatek.com>
Cc: Hans Verkuil <hans.verkuil@cisco.com>
Cc: Mauro Carvalho Chehab <mchehab@s-opensource.com>
---
drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
index 40a229d..53296e2 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
@@ -50,7 +50,8 @@ static const struct of_device_id mtk_mdp_comp_dt_ids[] = {
}, {
.compatible = "mediatek,mt8173-mdp-wrot",
.data = (void *)MTK_MDP_WROT
- }
+ },
+ { },
};
static const struct of_device_id mtk_mdp_of_ids[] = {
--
2.9.3
^ permalink raw reply related
* [PATCH next 1/2] media: mtk-mdp: fix video_device_release argument
From: Vincent Stehlé @ 2016-10-27 20:23 UTC (permalink / raw)
To: linux-media-u79uwXL29TY76Z2rM5mHXA,
linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: Minghsiu Tsai, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
Vincent Stehlé, Mauro Carvalho Chehab, Hans Verkuil,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <1473340146-6598-4-git-send-email-minghsiu.tsai-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
video_device_release() takes a pointer to struct video_device as argument.
Fix two call sites where the address of the pointer is passed instead.
Fixes: c8eb2d7e8202fd9c ("[media] media: Add Mediatek MDP Driver")
Signed-off-by: Vincent Stehlé <vincent.stehle@laposte.net>
Cc: Minghsiu Tsai <minghsiu.tsai@mediatek.com>
Cc: Hans Verkuil <hans.verkuil@cisco.com>
Cc: Mauro Carvalho Chehab <mchehab@s-opensource.com>
---
drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
index 9a747e7..4a9e3e9d 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
@@ -1267,13 +1267,13 @@ int mtk_mdp_register_m2m_device(struct mtk_mdp_dev *mdp)
err_vdev_register:
v4l2_m2m_release(mdp->m2m_dev);
err_m2m_init:
- video_device_release(&mdp->vdev);
+ video_device_release(mdp->vdev);
return ret;
}
void mtk_mdp_unregister_m2m_device(struct mtk_mdp_dev *mdp)
{
- video_device_release(&mdp->vdev);
+ video_device_release(mdp->vdev);
v4l2_m2m_release(mdp->m2m_dev);
}
--
2.9.3
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply related
* Re: [PATCH v7, 0/8] Add MediaTek USB3 DRD Driver
From: Greg Kroah-Hartman @ 2016-10-27 15:05 UTC (permalink / raw)
To: Chunfeng Yun
Cc: Felipe Balbi, Mathias Nyman, Matthias Brugger, Oliver Neukum,
Alan Stern, Rob Herring, Mark Rutland, Ian Campbell,
Sergei Shtylyov, Pawel Moll, Kumar Gala, Sascha Hauer,
Alan Cooper, linux-usb-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <1476844107-31087-1-git-send-email-chunfeng.yun-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
On Wed, Oct 19, 2016 at 10:28:19AM +0800, Chunfeng Yun wrote:
> These patches introduce the MediaTek USB3 dual-role controller
> driver.
>
> The driver can be configured as Dual-Role Device (DRD),
> Peripheral Only and Host Only (xHCI) modes. It works well
> with Mass Storage, RNDIS and g_zero on FS/HS and SS. And it is
> tested on MT8173 platform which only contains USB2.0 device IP,
> and on MT6290 platform which contains USB3.0 device IP.
>
> Change in v7:
> 1. split dual-role driver into four patchs
> 2. remove QMU done tasklet
> 3. add a bool in xhci_hcd_mtk to signal absence of IPPC
Given a lack of objection from anyone, I've now merged these to my tree
to get them a spin in the 0-day build-bot.
thanks,
greg k-h
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [SPAM][PATCH 2/3] irqchip: mtk-cirq: Add mediatek mtk-cirq implement
From: Yingjoe Chen @ 2016-10-27 15:02 UTC (permalink / raw)
To: Youlin Pei
Cc: Mark Rutland, devicetree-u79uwXL29TY76Z2rM5mHXA,
hongkun.cao-NuS5LvNUpcJWk0Htik3J/w, Jason Cooper,
srv_heupstream-NuS5LvNUpcJWk0Htik3J/w, Marc Zyngier,
erin.lo-NuS5LvNUpcJWk0Htik3J/w,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Russell King, Rob Herring,
linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
Matthias Brugger, Thomas Gleixner, yong.wu-NuS5LvNUpcJWk0Htik3J/w
In-Reply-To: <1476335194-26604-3-git-send-email-youlin.pei-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
On Thu, 2016-10-13 at 13:06 +0800, Youlin Pei wrote:
> This commit add the mtk-cirq implement for mt2701.
>
> Signed-off-by: Youlin Pei <youlin.pei-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> ---
> drivers/irqchip/Makefile | 2 +-
> drivers/irqchip/irq-mtk-cirq.c | 257 ++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 258 insertions(+), 1 deletion(-)
> create mode 100644 drivers/irqchip/irq-mtk-cirq.c
>
> diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
> index 4c203b6..eee95c6 100644
> --- a/drivers/irqchip/Makefile
> +++ b/drivers/irqchip/Makefile
> @@ -59,7 +59,7 @@ obj-$(CONFIG_BCM7120_L2_IRQ) += irq-bcm7120-l2.o
> obj-$(CONFIG_BRCMSTB_L2_IRQ) += irq-brcmstb-l2.o
> obj-$(CONFIG_KEYSTONE_IRQ) += irq-keystone.o
> obj-$(CONFIG_MIPS_GIC) += irq-mips-gic.o
> -obj-$(CONFIG_ARCH_MEDIATEK) += irq-mtk-sysirq.o
> +obj-$(CONFIG_ARCH_MEDIATEK) += irq-mtk-sysirq.o irq-mtk-cirq.o
> obj-$(CONFIG_ARCH_DIGICOLOR) += irq-digicolor.o
> obj-$(CONFIG_RENESAS_H8300H_INTC) += irq-renesas-h8300h.o
> obj-$(CONFIG_RENESAS_H8S_INTC) += irq-renesas-h8s.o
> diff --git a/drivers/irqchip/irq-mtk-cirq.c b/drivers/irqchip/irq-mtk-cirq.c
> new file mode 100644
> index 0000000..544767d
> --- /dev/null
> +++ b/drivers/irqchip/irq-mtk-cirq.c
> @@ -0,0 +1,257 @@
> +/*
> + * Copyright (c) 2016 MediaTek Inc.
> + * Author: Youlin.Pei <youlin.pei-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/irq.h>
> +#include <linux/irqchip.h>
> +#include <linux/irqdomain.h>
> +#include <linux/of.h>
> +#include <linux/of_irq.h>
> +#include <linux/of_address.h>
> +#include <linux/io.h>
> +#include <linux/slab.h>
> +#include <linux/spinlock.h>
> +#include <linux/syscore_ops.h>
> +
> +#define CIRQ_MASK_SET 0xC0
> +#define CIRQ_MASK_CLR 0x100
> +#define CIRQ_SENS_SET 0x180
> +#define CIRQ_SENS_CLR 0x1C0
nit: please use lower case for hex value
> +#define CIRQ_POL_SET 0x240
> +#define CIRQ_POL_CLR 0x280
> +#define CIRQ_CONTROL 0x300
> +
> +#define CIRQ_EN 0x1
nit: please align
> +#define CIRQ_EDGE 0x2
> +#define CIRQ_FLUSH 0x4
> +
> +#define CIRQ_IRQ_NUM 0x200
> +
> +struct mtk_cirq_chip_data {
> + void __iomem *base;
> + unsigned int ext_irq_start;
> +};
> +
<deleted..>
> +
> +static int __init mtk_cirq_of_init(struct device_node *node,
> + struct device_node *parent)
> +{
> + struct irq_domain *domain, *domain_parent;
> + int ret;
> +
> + domain_parent = irq_find_host(parent);
> + if (!domain_parent) {
> + pr_err("mtk_cirq: interrupt-parent not found\n");
> + return -EINVAL;
> + }
> +
> + cirq_data = kzalloc(sizeof(*cirq_data), GFP_KERNEL);
> + if (!cirq_data)
> + return -ENOMEM;
> +
> + cirq_data->base = of_iomap(node, 0);
> + if (!cirq_data->base) {
> + pr_err("mtk_cirq: unable to map cirq register\n");
> + ret = -ENXIO;
> + goto out_free;
> + }
> +
> + if (of_property_read_u32(node, "mediatek,ext-irq-start",
> + &cirq_data->ext_irq_start)) {
> + ret = -EINVAL;
> + goto out_free;
Please propagate error returned from of_property_read_u32
Should goto out_unmap when fail here.
Joe.C
> + }
> +
> + domain = irq_domain_add_hierarchy(domain_parent, 0, CIRQ_IRQ_NUM, node,
> + &cirq_domain_ops, cirq_data);
> + if (!domain) {
> + ret = -ENOMEM;
> + goto out_unmap;
> + }
> +
> + mtk_cirq_syscore_init();
> +
> + return 0;
> +
> +out_unmap:
> + iounmap(cirq_data->base);
> +out_free:
> + kfree(cirq_data);
> + return ret;
> +}
> +
> +IRQCHIP_DECLARE(mtk_cirq, "mediatek,mt2701-cirq", mtk_cirq_of_init);
^ permalink raw reply
* Problem with parcel shipping, ID:000707313
From: FedEx 2Day A.M. @ 2016-10-27 8:55 UTC (permalink / raw)
To: linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
[-- Attachment #1: Type: text/plain, Size: 137 bytes --]
Dear Customer,
We could not deliver your parcel.
Shipment Label is attached to email.
Yours trully,
Brett Reed,
FedEx Delivery Agent.
[-- Attachment #2: FedEx_000707313.zip --]
[-- Type: application/zip, Size: 7113 bytes --]
[-- Attachment #3: Type: text/plain, Size: 200 bytes --]
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply
* [PATCH v4] drm/mediatek: fixed the calc method of data rate per lane
From: Jitao Shi @ 2016-10-27 2:21 UTC (permalink / raw)
To: Philipp Zabel, ck.hu, Matthias Brugger
Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
Jitao Shi, Ajay Kumar, Inki Dae, Rahul Sharma, Sean Paul,
Vincent Palatin, Andy Yan, Russell King, devicetree, linux-kernel,
dri-devel, linux-arm-kernel, linux-mediatek, srv_heupstream,
Sascha Hauer, yingjoe.chen
Tune dsi frame rate by pixel clock, dsi add some extra signal (i.e.
Tlpx, Ths-prepare, Ths-zero, Ths-trail,Ths-exit) when enter and exit LP
mode, those signals will cause h-time larger than normal and reduce FPS.
So need to multiply a coefficient to offset the extra signal's effect.
coefficient = ((htotal*bpp/lane_number)+Tlpx+Ths_prep+Ths_zero+
Ths_trail+Ths_exit)/(htotal*bpp/lane_number)
Signed-off-by: Jitao Shi <jitao.shi@mediatek.com>
---
Chnage since v3:
- wrapp the commit msg.
- fix alignment of some lines.
Change since v2:
- move phy timing back to dsi_phy_timconfig.
Change since v1:
- phy_timing2 and phy_timing3 refer clock cycle time.
- define values of LPX HS_PRPR HS_ZERO HS_TRAIL TA_GO TA_SURE TA_GET DA_HS_EXIT.
---
drivers/gpu/drm/mediatek/mtk_dsi.c | 71 +++++++++++++++++++++++++-----------
1 file changed, 49 insertions(+), 22 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 28b2044..5defe58 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -85,16 +85,16 @@
#define LD0_WAKEUP_EN BIT(2)
#define DSI_PHY_TIMECON0 0x110
-#define LPX (0xff << 0)
-#define HS_PRPR (0xff << 8)
-#define HS_ZERO (0xff << 16)
-#define HS_TRAIL (0xff << 24)
+#define LPX (5 << 0)
+#define HS_PRPR (6 << 8)
+#define HS_ZERO (10 << 16)
+#define HS_TRAIL (8 << 24)
#define DSI_PHY_TIMECON1 0x114
-#define TA_GO (0xff << 0)
-#define TA_SURE (0xff << 8)
-#define TA_GET (0xff << 16)
-#define DA_HS_EXIT (0xff << 24)
+#define TA_GO (20 << 0)
+#define TA_SURE (7 << 8)
+#define TA_GET (25 << 16)
+#define DA_HS_EXIT (7 << 24)
#define DSI_PHY_TIMECON2 0x118
#define CONT_DET (0xff << 0)
@@ -161,20 +161,17 @@ static void mtk_dsi_mask(struct mtk_dsi *dsi, u32 offset, u32 mask, u32 data)
static void dsi_phy_timconfig(struct mtk_dsi *dsi)
{
u32 timcon0, timcon1, timcon2, timcon3;
- unsigned int ui, cycle_time;
- unsigned int lpx;
+ u32 ui, cycle_time;
ui = 1000 / dsi->data_rate + 0x01;
cycle_time = 8000 / dsi->data_rate + 0x01;
- lpx = 5;
- timcon0 = (8 << 24) | (0xa << 16) | (0x6 << 8) | lpx;
- timcon1 = (7 << 24) | (5 * lpx << 16) | ((3 * lpx) / 2) << 8 |
- (4 * lpx);
+ timcon0 = LPX | HS_PRPR | HS_ZERO | HS_TRAIL;
+ timcon1 = 4 * LPX | (3 * LPX / 2) << 8 | 5 * LPX << 16 | DA_HS_EXIT;
timcon2 = ((NS_TO_CYCLE(0x64, cycle_time) + 0xa) << 24) |
(NS_TO_CYCLE(0x150, cycle_time) << 16);
- timcon3 = (2 * lpx) << 16 | NS_TO_CYCLE(80 + 52 * ui, cycle_time) << 8 |
- NS_TO_CYCLE(0x40, cycle_time);
+ timcon3 = NS_TO_CYCLE(0x40, cycle_time) | (2 * LPX) << 16 |
+ NS_TO_CYCLE(80 + 52 * ui, cycle_time) << 8;
writel(timcon0, dsi->regs + DSI_PHY_TIMECON0);
writel(timcon1, dsi->regs + DSI_PHY_TIMECON1);
@@ -202,19 +199,49 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
{
struct device *dev = dsi->dev;
int ret;
+ u64 bit_clock, total_bits;
+ u32 htotal, htotal_bits, bit_per_pixel, overhead_cycles, overhead_bits;
if (++dsi->refcount != 1)
return 0;
+ switch (dsi->format) {
+ case MIPI_DSI_FMT_RGB565:
+ bit_per_pixel = 16;
+ break;
+ case MIPI_DSI_FMT_RGB666_PACKED:
+ bit_per_pixel = 18;
+ break;
+ case MIPI_DSI_FMT_RGB666:
+ case MIPI_DSI_FMT_RGB888:
+ default:
+ bit_per_pixel = 24;
+ break;
+ }
/**
- * data_rate = (pixel_clock / 1000) * pixel_dipth * mipi_ratio;
- * pixel_clock unit is Khz, data_rata unit is MHz, so need divide 1000.
- * mipi_ratio is mipi clk coefficient for balance the pixel clk in mipi.
- * we set mipi_ratio is 1.05.
+ * data_rate = (pixel_clock) * bit_per_pixel * mipi_ratio / lane_num;
+ * vm.pixelclock is Khz, data_rata unit is Hz, so need to multiply 1000
+ * mipi_ratio is (htotal * byte_per_pixel / lane_num + Tlpx + Ths_prep
+ * + Thstrail + Ths_exit + Ths_zero) /
+ * (htotal * byte_per_pixel /lane_number)
*/
- dsi->data_rate = dsi->vm.pixelclock * 3 * 21 / (1 * 1000 * 10);
+ bit_clock = dsi->vm.pixelclock * 1000 * bit_per_pixel;
+ htotal = dsi->vm.hactive + dsi->vm.hback_porch + dsi->vm.hfront_porch +
+ dsi->vm.hsync_len;
+ htotal_bits = htotal * bit_per_pixel;
+
+ /**
+ * overhead = lpx + hs_prepare + hs_zero + hs_trail + hs_exit
+ */
+ overhead_cycles = LPX + (HS_PRPR >> 8) + (HS_ZERO >> 16) +
+ (HS_TRAIL >> 24) + (DA_HS_EXIT >> 24);
+ overhead_bits = overhead_cycles * dsi->lanes * 8;
+ total_bits = htotal_bits + overhead_bits;
+
+ dsi->data_rate = DIV_ROUND_UP_ULL(bit_clock * total_bits,
+ htotal_bits * dsi->lanes);
- ret = clk_set_rate(dsi->hs_clk, dsi->data_rate * 1000000);
+ ret = clk_set_rate(dsi->hs_clk, dsi->data_rate);
if (ret < 0) {
dev_err(dev, "Failed to set data rate: %d\n", ret);
goto err_refcount;
--
1.7.9.5
^ 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