From nobody Sun Sep 22 03:24:48 2024 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id F00E9C4332F for ; Wed, 4 May 2022 12:33:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1349714AbiEDMgi (ORCPT ); Wed, 4 May 2022 08:36:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48838 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1349649AbiEDMge (ORCPT ); Wed, 4 May 2022 08:36:34 -0400 Received: from mail-ed1-x535.google.com (mail-ed1-x535.google.com [IPv6:2a00:1450:4864:20::535]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BCACD1581D; Wed, 4 May 2022 05:32:48 -0700 (PDT) Received: by mail-ed1-x535.google.com with SMTP id y21so1537965edo.2; Wed, 04 May 2022 05:32:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=nswliUYJDJdG6CmPVRzfwj66mOMfbOUhuBr9zAj+qHk=; b=hFOgjzNbM6cgHXf/rclnvi7ZV8yJ4g+3nLPVeylpuvEpvuHk407dzSMHFN+qXykJBw mJPpZcuithSCc7ZVcoAF6XZEihX3XKtwLfWRe6inqJtXAc+xTJ17RUP8+1nxNoI3VPkj eb67C6DEgkvO5+2zdwmH0CfCvGxP5uWC/yIBd06snDc0/GtIlYjEVfUidou1cvzkQIgd bPT/xzOcRR2dIIZNncD0dl1T794S5bR4Gkal1ZDt6iQwMEHM7tpj7bLU4+ew93EJR+9L C2JZmlUgvbiK1qSLcRuKHfQxqqzh6Xz9l/O49WrW68k0CgCQj0OmOQ+m6jdLdnhRlX06 kA9g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=nswliUYJDJdG6CmPVRzfwj66mOMfbOUhuBr9zAj+qHk=; b=5lUwsCdFCSfkJ6ueE0qpp959fDkKbERdgCt4gnr9vJDA+oZQPKAcboh/oKE1/AXC5s T7IXqrB3kV0S/VzdejDPqZNr2lkom8UQNe1ICH8MfwyT5PBaoCu1QMhH3JAqiA9Mv00w +QyY5JdCCKQBsREcii4dGu1TfiBvO4dAXkaMYdC+gbVbA33vTx7FQFxRwb1+J6SmY6NU YnL6S0WrAGx8dlFt0+lOjCwUoC+glCpHO6B+s1BlPQWi6ucFWy86py8SgPC0hL/dZJWp Xy/3KDria0rR5DQXXb2Llxyh52iRTZ0MLRi/kxV5hctT3xQ4Z9qduHXPQS8kYSQK5AEy T7OQ== X-Gm-Message-State: AOAM532xbWEs0eK98XYyqgbFyLAlbKIJYp/AFODlTjp8IY2sWni0+jBG ovIU94vWI6sjYlBusWvEP5Q= X-Google-Smtp-Source: ABdhPJxtddZCpjPMiVat9qF6Hh1mwfDMy6hkM45eYD1tDNP+R0MWTS1+y8jR32JJ3jLOsBhD4OHl5g== X-Received: by 2002:a05:6402:35c7:b0:427:d231:3740 with SMTP id z7-20020a05640235c700b00427d2313740mr11838717edc.40.1651667567029; Wed, 04 May 2022 05:32:47 -0700 (PDT) Received: from localhost.localdomain (185-177-124-12.hosted-by-worldstream.net. [185.177.124.12]) by smtp.gmail.com with ESMTPSA id ig1-20020a1709072e0100b006f3ef214e7asm5688693ejc.224.2022.05.04.05.32.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 May 2022 05:32:46 -0700 (PDT) From: Yassine Oudjana X-Google-Original-From: Yassine Oudjana To: Matthias Brugger , Stephen Boyd , Michael Turquette , Philipp Zabel , Rob Herring , Krzysztof Kozlowski Cc: Yassine Oudjana , Yassine Oudjana , Chun-Jie Chen , Chen-Yu Tsai , Tinghan Shen , AngeloGioacchino Del Regno , Weiyi Lu , Ikjoon Jang , Miles Chen , Sam Shih , Bartosz Golaszewski , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, linux-mediatek@lists.infradead.org, linux-arm-kernel@lists.infradead.org Subject: [PATCH 07/13] clk: mediatek: Add driver for MT6735 topckgen Date: Wed, 4 May 2022 16:25:56 +0400 Message-Id: <20220504122601.335495-8-y.oudjana@protonmail.com> X-Mailer: git-send-email 2.36.0 In-Reply-To: <20220504122601.335495-1-y.oudjana@protonmail.com> References: <20220504122601.335495-1-y.oudjana@protonmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: Yassine Oudjana Add a driver for MT6735 topckgen clocks. Signed-off-by: Yassine Oudjana --- MAINTAINERS | 1 + drivers/clk/mediatek/Kconfig | 7 + drivers/clk/mediatek/Makefile | 1 + drivers/clk/mediatek/clk-mt6735-topckgen.c | 1159 ++++++++++++++++++++ 4 files changed, 1168 insertions(+) create mode 100644 drivers/clk/mediatek/clk-mt6735-topckgen.c diff --git a/MAINTAINERS b/MAINTAINERS index 1077712edb4b..d9d6449f910e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -12443,6 +12443,7 @@ L: linux-clk@vger.kernel.org L: linux-mediatek@lists.infradead.org (moderated for non-subscribers) S: Maintained F: drivers/clk/mediatek/clk-mt6735-apmixed.c +F: drivers/clk/mediatek/clk-mt6735-topckgen.c F: include/dt-bindings/clock/mediatek,mt6735-apmixedsys.h F: include/dt-bindings/clock/mediatek,mt6735-infracfg.h F: include/dt-bindings/clock/mediatek,mt6735-pericfg.h diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig index ab364892f602..7c19e2d7bb02 100644 --- a/drivers/clk/mediatek/Kconfig +++ b/drivers/clk/mediatek/Kconfig @@ -124,6 +124,13 @@ config COMMON_CLK_MT6735_APMIXED help This driver supports MediaTek MT6735 apmixedsys clocks. =20 +config COMMON_CLK_MT6735_TOPCKGEN + tristate "Clock driver for MediaTek MT6735 topckgen" + depends on ARCH_MEDIATEK || COMPILE_TEST + select COMMON_CLK_MEDIATEK + help + This driver supports MediaTek MT6735 topckgen clocks. + config COMMON_CLK_MT6765 bool "Clock driver for MediaTek MT6765" depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile index 7f45a22c6178..e8e892c4145f 100644 --- a/drivers/clk/mediatek/Makefile +++ b/drivers/clk/mediatek/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_COMMON_CLK_MEDIATEK) +=3D clk-mtk.o clk-pll.o clk-gate.o clk-= apmixed.o clk-cpumux.o reset.o clk-mux.o =20 obj-$(CONFIG_COMMON_CLK_MT6735_APMIXED) +=3D clk-mt6735-apmixed.o +obj-$(CONFIG_COMMON_CLK_MT6735_TOPCKGEN) +=3D clk-mt6735-topckgen.o obj-$(CONFIG_COMMON_CLK_MT6765) +=3D clk-mt6765.o obj-$(CONFIG_COMMON_CLK_MT6765_AUDIOSYS) +=3D clk-mt6765-audio.o obj-$(CONFIG_COMMON_CLK_MT6765_CAMSYS) +=3D clk-mt6765-cam.o diff --git a/drivers/clk/mediatek/clk-mt6735-topckgen.c b/drivers/clk/media= tek/clk-mt6735-topckgen.c new file mode 100644 index 000000000000..444c87aed71e --- /dev/null +++ b/drivers/clk/mediatek/clk-mt6735-topckgen.c @@ -0,0 +1,1159 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 Yassine Oudjana + */ + +#include +#include + +#include "clk-mtk.h" +#include "clk-mux.h" + +#include + +#define CLK_CFG_0 0x40 +#define CLK_CFG_0_SET 0x44 +#define CLK_CFG_0_CLR 0x48 +#define CLK_CFG_1 0x50 +#define CLK_CFG_1_SET 0x54 +#define CLK_CFG_1_CLR 0x58 +#define CLK_CFG_2 0x60 +#define CLK_CFG_2_SET 0x64 +#define CLK_CFG_2_CLR 0x68 +#define CLK_CFG_3 0x70 +#define CLK_CFG_3_SET 0x74 +#define CLK_CFG_3_CLR 0x78 +#define CLK_CFG_4 0x80 +#define CLK_CFG_4_SET 0x84 +#define CLK_CFG_4_CLR 0x88 +#define CLK_CFG_5 0x90 +#define CLK_CFG_5_SET 0x94 +#define CLK_CFG_5_CLR 0x98 +#define CLK_CFG_6 0xa0 +#define CLK_CFG_6_SET 0xa4 +#define CLK_CFG_6_CLR 0xa8 +#define CLK_CFG_7 0xb0 +#define CLK_CFG_7_SET 0xb4 +#define CLK_CFG_7_CLR 0xb8 + +static DEFINE_SPINLOCK(mt6735_topckgen_lock); + +/* Some clocks with unknown details are modeled as fixed clocks */ +static const struct mtk_fixed_clk top_fixed_clks[] =3D { + { + /* + * This clock is available as a parent option for multiple + * muxes and seems like an alternative name for clk26m at first, + * but it appears alongside it in several muxes which should + * mean it is a separate clock. + */ + .id =3D AD_SYS_26M_CK, + .name =3D "ad_sys_26m_ck", + .parent =3D "clk26m", + .rate =3D 26 * MHZ, + }, + { + /* + * This clock is the parent of DMPLL divisors. It might be MEMPLL + * or its parent, as DMPLL appears to be an alternative name for + * MEMPLL. + */ + .id =3D CLKPH_MCK_O, + .name =3D "clkph_mck_o", + .parent =3D NULL + }, + { + /* + * DMPLL clock (dmpll_ck), controlled by DDRPHY. + */ + .id =3D DMPLL, + .name =3D "dmpll", + .parent =3D "clkph_mck_o" + }, + { + /* + * MIPI DPI clock. Parent option for dpi0_sel. Unknown parent. + */ + .id =3D DPI_CK, + .name =3D "dpi_ck", + .parent =3D NULL + }, + { + /* + * This clock is a child of WHPLL which is controlled by + * the modem. + */ + .id =3D WHPLL_AUDIO_CK, + .name =3D "whpll_audio_ck", + .parent =3D NULL + }, +}; + +static const struct mtk_fixed_factor top_divs[] =3D { + { + .id =3D SYSPLL_D2, + .name =3D "syspll_d2", + .parent_name =3D "mainpll", + .mult =3D 1, + .div =3D 2 + }, + { + .id =3D SYSPLL_D3, + .name =3D "syspll_d3", + .parent_name =3D "mainpll", + .mult =3D 1, + .div =3D 3 + }, + { + .id =3D SYSPLL_D5, + .name =3D "syspll_d5", + .parent_name =3D "mainpll", + .mult =3D 1, + .div =3D 5 + }, + { + .id =3D SYSPLL1_D2, + .name =3D "syspll1_d2", + .parent_name =3D "mainpll", + .mult =3D 1, + .div =3D 2 + }, + { + .id =3D SYSPLL1_D4, + .name =3D "syspll1_d4", + .parent_name =3D "mainpll", + .mult =3D 1, + .div =3D 4 + }, + { + .id =3D SYSPLL1_D8, + .name =3D "syspll1_d8", + .parent_name =3D "mainpll", + .mult =3D 1, + .div =3D 8 + }, + { + .id =3D SYSPLL1_D16, + .name =3D "syspll1_d16", + .parent_name =3D "mainpll", + .mult =3D 1, + .div =3D 16 + }, + { + .id =3D SYSPLL2_D2, + .name =3D "syspll2_d2", + .parent_name =3D "mainpll", + .mult =3D 1, + .div =3D 2 + }, + { + .id =3D SYSPLL2_D4, + .name =3D "syspll2_d4", + .parent_name =3D "mainpll", + .mult =3D 1, + .div =3D 4 + }, + { + .id =3D SYSPLL3_D2, + .name =3D "syspll3_d2", + .parent_name =3D "mainpll", + .mult =3D 1, + .div =3D 2 + }, + { + .id =3D SYSPLL3_D4, + .name =3D "syspll3_d4", + .parent_name =3D "mainpll", + .mult =3D 1, + .div =3D 4 + }, + { + .id =3D SYSPLL4_D2, + .name =3D "syspll4_d2", + .parent_name =3D "mainpll", + .mult =3D 1, + .div =3D 2 + }, + { + .id =3D SYSPLL4_D4, + .name =3D "syspll4_d4", + .parent_name =3D "mainpll", + .mult =3D 1, + .div =3D 4 + }, + { + .id =3D UNIVPLL_D2, + .name =3D "univpll_d2", + .parent_name =3D "univpll", + .mult =3D 1, + .div =3D 2 + }, + { + .id =3D UNIVPLL_D3, + .name =3D "univpll_d3", + .parent_name =3D "univpll", + .mult =3D 1, + .div =3D 3 + }, + { + .id =3D UNIVPLL_D5, + .name =3D "univpll_d5", + .parent_name =3D "univpll", + .mult =3D 1, + .div =3D 5 + }, + { + .id =3D UNIVPLL_D26, + .name =3D "univpll_d26", + .parent_name =3D "univpll", + .mult =3D 1, + .div =3D 26 + }, + { + .id =3D UNIVPLL1_D2, + .name =3D "univpll1_d2", + .parent_name =3D "univpll", + .mult =3D 1, + .div =3D 2 + }, + { + .id =3D UNIVPLL1_D4, + .name =3D "univpll1_d4", + .parent_name =3D "univpll", + .mult =3D 1, + .div =3D 4 + }, + { + .id =3D UNIVPLL1_D8, + .name =3D "univpll1_d8", + .parent_name =3D "univpll", + .mult =3D 1, + .div =3D 8 + }, + { + .id =3D UNIVPLL2_D2, + .name =3D "univpll2_d2", + .parent_name =3D "univpll", + .mult =3D 1, + .div =3D 2 + }, + { + .id =3D UNIVPLL2_D4, + .name =3D "univpll2_d4", + .parent_name =3D "univpll", + .mult =3D 1, + .div =3D 4 + }, + { + .id =3D UNIVPLL2_D8, + .name =3D "univpll2_d8", + .parent_name =3D "univpll", + .mult =3D 1, + .div =3D 8 + }, + { + .id =3D UNIVPLL3_D2, + .name =3D "univpll3_d2", + .parent_name =3D "univpll", + .mult =3D 1, + .div =3D 2 + }, + { + .id =3D UNIVPLL3_D4, + .name =3D "univpll3_d4", + .parent_name =3D "univpll", + .mult =3D 1, + .div =3D 4 + }, + { + .id =3D MSDCPLL_D2, + .name =3D "msdcpll_d2", + .parent_name =3D "msdcpll", + .mult =3D 1, + .div =3D 2 + }, + { + .id =3D MSDCPLL_D4, + .name =3D "msdcpll_d4", + .parent_name =3D "msdcpll", + .mult =3D 1, + .div =3D 4 + }, + { + .id =3D MSDCPLL_D8, + .name =3D "msdcpll_d8", + .parent_name =3D "msdcpll", + .mult =3D 1, + .div =3D 8 + }, + { + .id =3D MSDCPLL_D16, + .name =3D "msdcpll_d16", + .parent_name =3D "msdcpll", + .mult =3D 1, + .div =3D 16 + }, + { + .id =3D VENCPLL_D3, + .name =3D "vencpll_d3", + .parent_name =3D "vencpll", + .mult =3D 1, + .div =3D 3 + }, + { + .id =3D TVDPLL_D2, + .name =3D "tvdpll_d2", + .parent_name =3D "tvdpll", + .mult =3D 1, + .div =3D 2 + }, + { + .id =3D TVDPLL_D4, + .name =3D "tvdpll_d4", + .parent_name =3D "tvdpll", + .mult =3D 1, + .div =3D 4 + }, + { + .id =3D DMPLL_D2, + .name =3D "dmpll_d2", + .parent_name =3D "clkph_mck_o", + .mult =3D 1, + .div =3D 2 + }, + { + .id =3D DMPLL_D4, + .name =3D "dmpll_d4", + .parent_name =3D "clkph_mck_o", + .mult =3D 1, + .div =3D 4 + }, + { + .id =3D DMPLL_D8, + .name =3D "dmpll_d8", + .parent_name =3D "clkph_mck_o", + .mult =3D 1, + .div =3D 8 + }, + { + .id =3D AD_SYS_26M_D2, + .name =3D "ad_sys_26m_d2", + .parent_name =3D "clk26m", + .mult =3D 1, + .div =3D 2 + }, +}; + +static const char * const axi_sel_parents[] =3D { + "clk26m", + "syspll1_d2", + "syspll_d5", + "syspll1_d4", + "univpll_d5", + "univpll2_d2", + "dmpll", + "dmpll_d2" +}; + +static const char * const mem_sel_parents[] =3D { + "clk26m", + "dmpll" +}; + +static const char * const ddrphycfg_parents[] =3D { + "clk26m", + "syspll1_d8" +}; + +static const char * const mm_sel_parents[] =3D { + "clk26m", + "vencpll", + "syspll1_d2", + "syspll_d5", + "syspll1_d4", + "univpll_d5", + "univpll2_d2", + "dmpll" +}; + +static const char * const pwm_sel_parents[] =3D { + "clk26m", + "univpll2_d4", + "univpll3_d2", + "univpll1_d4" +}; + +static const char * const vdec_sel_parents[] =3D { + "clk26m", + "syspll1_d2", + "syspll_d5", + "syspll1_d4", + "univpll_d5", + "syspll_d2", + "syspll2_d2", + "msdcpll_d2" +}; + +static const char * const mfg_sel_parents[] =3D { + "clk26m", + "mmpll", + "clk26m", + "clk26m", + "clk26m", + "clk26m", + "clk26m", + "clk26m", + "clk26m", + "syspll_d3", + "syspll1_d2", + "syspll_d5", + "univpll_d3", + "univpll1_d2" +}; + +static const char * const camtg_sel_parents[] =3D { + "clk26m", + "univpll_d26", + "univpll2_d2", + "syspll3_d2", + "syspll3_d4", + "msdcpll_d4" +}; + +static const char * const uart_sel_parents[] =3D { + "clk26m", + "univpll2_d8" +}; + +static const char * const spi_sel_parents[] =3D { + "clk26m", + "syspll3_d2", + "msdcpll_d8", + "syspll2_d4", + "syspll4_d2", + "univpll2_d4", + "univpll1_d8" +}; + +static const char * const usb20_sel_parents[] =3D { + "clk26m", + "univpll1_d8", + "univpll3_d4" +}; + +static const char * const msdc50_0_sel_parents[] =3D { + "clk26m", + "syspll1_d2", + "syspll2_d2", + "syspll4_d2", + "univpll_d5", + "univpll1_d4" +}; + +static const char * const msdc30_0_sel_parents[] =3D { + "clk26m", + "msdcpll", + "msdcpll_d2", + "msdcpll_d4", + "syspll2_d2", + "syspll1_d4", + "univpll1_d4", + "univpll_d3", + "univpll_d26", + "syspll2_d4", + "univpll_d2" +}; + +static const char * const msdc30_1_2_sel_parents[] =3D { + "clk26m", + "univpll2_d2", + "msdcpll_d4", + "syspll2_d2", + "syspll1_d4", + "univpll1_d4", + "univpll_d26", + "syspll2_d4" +}; + +static const char * const msdc30_3_sel_parents[] =3D { + "clk26m", + "univpll2_d2", + "msdcpll_d4", + "syspll2_d2", + "syspll1_d4", + "univpll1_d4", + "univpll_d26", + "msdcpll_d16", + "syspll2_d4" +}; + +static const char * const audio_sel_parents[] =3D { + "clk26m", + "syspll3_d4", + "syspll4_d4", + "syspll1_d16" +}; + +static const char * const aud_intbus_sel_parents[] =3D { + "clk26m", + "syspll1_d4", + "syspll4_d2", + "dmpll_d4" +}; + +static const char * const pmicspi_sel_parents[] =3D { + "clk26m", + "syspll1_d8", + "syspll3_d4", + "syspll1_d16", + "univpll3_d4", + "univpll_d26", + "dmpll_d4", + "dmpll_d8" +}; + +static const char * const scp_sel_parents[] =3D { + "clk26m", + "syspll1_d8", + "dmpll_d2", + "dmpll_d4" +}; + +static const char * const atb_sel_parents[] =3D { + "clk26m", + "syspll1_d2", + "syspll_d5", + "dmpll" +}; + +static const char * const dpi0_sel_parents[] =3D { + "clk26m", + "tvdpll", + "tvdpll_d2", + "tvdpll_d4", + "dpi_ck" +}; + +static const char * const scam_sel_parents[] =3D { + "clk26m", + "syspll3_d2", + "univpll2_d4", + "vencpll_d3" +}; + +static const char * const mfg13m_sel_parents[] =3D { + "clk26m", + "ad_sys_26m_d2" +}; + +static const char * const aud_1_2_sel_parents[] =3D { + "clk26m", + "apll1" +}; + +static const char * const irda_sel_parents[] =3D { + "clk26m", + "univpll2_d4" +}; + +static const char * const irtx_sel_parents[] =3D { + "clk26m", + "ad_sys_26m_ck" +}; + +static const char * const disppwm_sel_parents[] =3D { + "clk26m", + "univpll2_d4", + "syspll4_d2_d8", + "ad_sys_26m_ck" +}; + +static const struct mtk_mux top_muxes[] =3D { + { + .id =3D AXI_SEL, + .name =3D "axi_sel", + .parent_names =3D axi_sel_parents, + .num_parents =3D ARRAY_SIZE(axi_sel_parents), + .flags =3D CLK_SET_RATE_PARENT, + + .mux_ofs =3D CLK_CFG_0, + .set_ofs =3D CLK_CFG_0_SET, + .clr_ofs =3D CLK_CFG_0_CLR, + + .mux_shift =3D 0, + .mux_width =3D 3, + + .ops =3D &mtk_mux_clr_set_upd_ops, + }, + { + .id =3D MEM_SEL, + .name =3D "mem_sel", + .parent_names =3D mem_sel_parents, + .num_parents =3D ARRAY_SIZE(mem_sel_parents), + .flags =3D CLK_SET_RATE_PARENT, + + .mux_ofs =3D CLK_CFG_0, + .set_ofs =3D CLK_CFG_0_SET, + .clr_ofs =3D CLK_CFG_0_CLR, + + .mux_shift =3D 8, + .mux_width =3D 1, + + .ops =3D &mtk_mux_clr_set_upd_ops, + }, + { + .id =3D DDRPHY_SEL, + .name =3D "ddrphycfg_sel", + .parent_names =3D ddrphycfg_parents, + .num_parents =3D ARRAY_SIZE(ddrphycfg_parents), + .flags =3D CLK_SET_RATE_PARENT, + + .mux_ofs =3D CLK_CFG_0, + .set_ofs =3D CLK_CFG_0_SET, + .clr_ofs =3D CLK_CFG_0_CLR, + + .mux_shift =3D 16, + .mux_width =3D 1, + + .ops =3D &mtk_mux_clr_set_upd_ops, + }, + { + .id =3D MM_SEL, + .name =3D "mm_sel", + .parent_names =3D mm_sel_parents, + .num_parents =3D ARRAY_SIZE(mm_sel_parents), + .flags =3D CLK_SET_RATE_PARENT, + + .mux_ofs =3D CLK_CFG_0, + .set_ofs =3D CLK_CFG_0_SET, + .clr_ofs =3D CLK_CFG_0_CLR, + + .mux_shift =3D 24, + .mux_width =3D 3, + .gate_shift =3D 31, + + .ops =3D &mtk_mux_gate_clr_set_upd_ops, + }, + { + .id =3D PWM_SEL, + .name =3D "pwm_sel", + .parent_names =3D pwm_sel_parents, + .num_parents =3D ARRAY_SIZE(pwm_sel_parents), + .flags =3D CLK_SET_RATE_PARENT, + + .mux_ofs =3D CLK_CFG_1, + .set_ofs =3D CLK_CFG_1_SET, + .clr_ofs =3D CLK_CFG_1_CLR, + + .mux_shift =3D 0, + .mux_width =3D 2, + .gate_shift =3D 7, + + .ops =3D &mtk_mux_gate_clr_set_upd_ops, + }, + { + .id =3D VDEC_SEL, + .name =3D "vdec_sel", + .parent_names =3D vdec_sel_parents, + .num_parents =3D ARRAY_SIZE(vdec_sel_parents), + .flags =3D CLK_SET_RATE_PARENT, + + .mux_ofs =3D CLK_CFG_1, + .set_ofs =3D CLK_CFG_1_SET, + .clr_ofs =3D CLK_CFG_1_CLR, + + .mux_shift =3D 8, + .mux_width =3D 3, + .gate_shift =3D 15, + + .ops =3D &mtk_mux_gate_clr_set_upd_ops, + }, + { + .id =3D MFG_SEL, + .name =3D "mfg_sel", + .parent_names =3D mfg_sel_parents, + .num_parents =3D ARRAY_SIZE(mfg_sel_parents), + .flags =3D CLK_SET_RATE_PARENT, + + .mux_ofs =3D CLK_CFG_1, + .set_ofs =3D CLK_CFG_1_SET, + .clr_ofs =3D CLK_CFG_1_CLR, + + .mux_shift =3D 16, + .mux_width =3D 4, + .gate_shift =3D 23, + + .ops =3D &mtk_mux_gate_clr_set_upd_ops, + }, + { + .id =3D CAMTG_SEL, + .name =3D "camtg_sel", + .parent_names =3D camtg_sel_parents, + .num_parents =3D ARRAY_SIZE(camtg_sel_parents), + .flags =3D CLK_SET_RATE_PARENT, + + .mux_ofs =3D CLK_CFG_1, + .set_ofs =3D CLK_CFG_1_SET, + .clr_ofs =3D CLK_CFG_1_CLR, + + .mux_shift =3D 24, + .mux_width =3D 3, + .gate_shift =3D 31, + + .ops =3D &mtk_mux_gate_clr_set_upd_ops, + }, + { + .id =3D UART_SEL, + .name =3D "uart_sel", + .parent_names =3D uart_sel_parents, + .num_parents =3D ARRAY_SIZE(uart_sel_parents), + .flags =3D CLK_SET_RATE_PARENT, + + .mux_ofs =3D CLK_CFG_2, + .set_ofs =3D CLK_CFG_2_SET, + .clr_ofs =3D CLK_CFG_2_CLR, + + .mux_shift =3D 0, + .mux_width =3D 1, + .gate_shift =3D 7, + + .ops =3D &mtk_mux_gate_clr_set_upd_ops, + }, + { + .id =3D SPI_SEL, + .name =3D "spi_sel", + .parent_names =3D spi_sel_parents, + .num_parents =3D ARRAY_SIZE(spi_sel_parents), + .flags =3D CLK_SET_RATE_PARENT, + + .mux_ofs =3D CLK_CFG_2, + .set_ofs =3D CLK_CFG_2_SET, + .clr_ofs =3D CLK_CFG_2_CLR, + + .mux_shift =3D 8, + .mux_width =3D 3, + .gate_shift =3D 15, + + .ops =3D &mtk_mux_gate_clr_set_upd_ops, + }, + { + .id =3D USB20_SEL, + .name =3D "usb20_sel", + .parent_names =3D usb20_sel_parents, + .num_parents =3D ARRAY_SIZE(usb20_sel_parents), + .flags =3D CLK_SET_RATE_PARENT, + + .mux_ofs =3D CLK_CFG_2, + .set_ofs =3D CLK_CFG_2_SET, + .clr_ofs =3D CLK_CFG_2_CLR, + + .mux_shift =3D 16, + .mux_width =3D 2, + .gate_shift =3D 23, + + .ops =3D &mtk_mux_gate_clr_set_upd_ops, + }, + { + .id =3D MSDC50_0_SEL, + .name =3D "msdc50_0_sel", + .parent_names =3D msdc50_0_sel_parents, + .num_parents =3D ARRAY_SIZE(msdc50_0_sel_parents), + .flags =3D CLK_SET_RATE_PARENT, + + .mux_ofs =3D CLK_CFG_2, + .set_ofs =3D CLK_CFG_2_SET, + .clr_ofs =3D CLK_CFG_2_CLR, + + .mux_shift =3D 24, + .mux_width =3D 3, + .gate_shift =3D 31, + + .ops =3D &mtk_mux_gate_clr_set_upd_ops, + }, + { + .id =3D MSDC30_0_SEL, + .name =3D "msdc30_0_sel", + .parent_names =3D msdc30_0_sel_parents, + .num_parents =3D ARRAY_SIZE(msdc30_0_sel_parents), + .flags =3D CLK_SET_RATE_PARENT, + + .mux_ofs =3D CLK_CFG_3, + .set_ofs =3D CLK_CFG_3_SET, + .clr_ofs =3D CLK_CFG_3_CLR, + + .mux_shift =3D 0, + .mux_width =3D 4, + .gate_shift =3D 7, + + .ops =3D &mtk_mux_gate_clr_set_upd_ops, + }, + { + .id =3D MSDC30_1_SEL, + .name =3D "msdc30_1_sel", + .parent_names =3D msdc30_1_2_sel_parents, + .num_parents =3D ARRAY_SIZE(msdc30_1_2_sel_parents), + .flags =3D CLK_SET_RATE_PARENT, + + .mux_ofs =3D CLK_CFG_3, + .set_ofs =3D CLK_CFG_3_SET, + .clr_ofs =3D CLK_CFG_3_CLR, + + .mux_shift =3D 8, + .mux_width =3D 3, + .gate_shift =3D 15, + + .ops =3D &mtk_mux_gate_clr_set_upd_ops, + }, + { + .id =3D MSDC30_2_SEL, + .name =3D "msdc30_2_sel", + .parent_names =3D msdc30_1_2_sel_parents, + .num_parents =3D ARRAY_SIZE(msdc30_1_2_sel_parents), + .flags =3D CLK_SET_RATE_PARENT, + + .mux_ofs =3D CLK_CFG_3, + .set_ofs =3D CLK_CFG_3_SET, + .clr_ofs =3D CLK_CFG_3_CLR, + + .mux_shift =3D 16, + .mux_width =3D 3, + .gate_shift =3D 23, + + .ops =3D &mtk_mux_gate_clr_set_upd_ops, + }, + { + .id =3D MSDC30_3_SEL, + .name =3D "msdc30_3_sel", + .parent_names =3D msdc30_3_sel_parents, + .num_parents =3D ARRAY_SIZE(msdc30_3_sel_parents), + .flags =3D CLK_SET_RATE_PARENT, + + .mux_ofs =3D CLK_CFG_3, + .set_ofs =3D CLK_CFG_3_SET, + .clr_ofs =3D CLK_CFG_3_CLR, + + .mux_shift =3D 24, + .mux_width =3D 4, + .gate_shift =3D 31, + + .ops =3D &mtk_mux_gate_clr_set_upd_ops, + }, + { + .id =3D AUDIO_SEL, + .name =3D "audio_sel", + .parent_names =3D audio_sel_parents, + .num_parents =3D ARRAY_SIZE(audio_sel_parents), + .flags =3D CLK_SET_RATE_PARENT, + + .mux_ofs =3D CLK_CFG_4, + .set_ofs =3D CLK_CFG_4_SET, + .clr_ofs =3D CLK_CFG_4_CLR, + + .mux_shift =3D 0, + .mux_width =3D 2, + .gate_shift =3D 7, + + .ops =3D &mtk_mux_gate_clr_set_upd_ops, + }, + { + .id =3D AUDINTBUS_SEL, + .name =3D "aud_intbus_sel", + .parent_names =3D aud_intbus_sel_parents, + .num_parents =3D ARRAY_SIZE(aud_intbus_sel_parents), + .flags =3D CLK_SET_RATE_PARENT, + + .mux_ofs =3D CLK_CFG_4, + .set_ofs =3D CLK_CFG_4_SET, + .clr_ofs =3D CLK_CFG_4_CLR, + + .mux_shift =3D 8, + .mux_width =3D 2, + .gate_shift =3D 15, + + .ops =3D &mtk_mux_gate_clr_set_upd_ops, + }, + { + .id =3D PMICSPI_SEL, + .name =3D "pmicspi_sel", + .parent_names =3D pmicspi_sel_parents, + .num_parents =3D ARRAY_SIZE(pmicspi_sel_parents), + .flags =3D CLK_SET_RATE_PARENT, + + .mux_ofs =3D CLK_CFG_4, + .set_ofs =3D CLK_CFG_4_SET, + .clr_ofs =3D CLK_CFG_4_CLR, + + .mux_shift =3D 16, + .mux_width =3D 3, + + .ops =3D &mtk_mux_clr_set_upd_ops, + }, + { + .id =3D SCP_SEL, + .name =3D "scp_sel", + .parent_names =3D scp_sel_parents, + .num_parents =3D ARRAY_SIZE(scp_sel_parents), + .flags =3D CLK_SET_RATE_PARENT, + + .mux_ofs =3D CLK_CFG_4, + .set_ofs =3D CLK_CFG_4_SET, + .clr_ofs =3D CLK_CFG_4_CLR, + + .mux_shift =3D 24, + .mux_width =3D 2, + .gate_shift =3D 31, + + .ops =3D &mtk_mux_gate_clr_set_upd_ops, + }, + { + .id =3D ATB_SEL, + .name =3D "atb_sel", + .parent_names =3D atb_sel_parents, + .num_parents =3D ARRAY_SIZE(atb_sel_parents), + .flags =3D CLK_SET_RATE_PARENT, + + .mux_ofs =3D CLK_CFG_5, + .set_ofs =3D CLK_CFG_5_SET, + .clr_ofs =3D CLK_CFG_5_CLR, + + .mux_shift =3D 0, + .mux_width =3D 2, + .gate_shift =3D 7, + + .ops =3D &mtk_mux_gate_clr_set_upd_ops, + }, + { + .id =3D DPI0_SEL, + .name =3D "dpi0_sel", + .parent_names =3D dpi0_sel_parents, + .num_parents =3D ARRAY_SIZE(dpi0_sel_parents), + .flags =3D CLK_SET_RATE_PARENT, + + .mux_ofs =3D CLK_CFG_5, + .set_ofs =3D CLK_CFG_5_SET, + .clr_ofs =3D CLK_CFG_5_CLR, + + .mux_shift =3D 8, + .mux_width =3D 3, + .gate_shift =3D 15, + + .ops =3D &mtk_mux_gate_clr_set_upd_ops, + }, + { + .id =3D SCAM_SEL, + .name =3D "scam_sel", + .parent_names =3D scam_sel_parents, + .num_parents =3D ARRAY_SIZE(scam_sel_parents), + .flags =3D CLK_SET_RATE_PARENT, + + .mux_ofs =3D CLK_CFG_5, + .set_ofs =3D CLK_CFG_5_SET, + .clr_ofs =3D CLK_CFG_5_CLR, + + .mux_shift =3D 16, + .mux_width =3D 2, + .gate_shift =3D 23, + + .ops =3D &mtk_mux_gate_clr_set_upd_ops, + }, + { + .id =3D MFG13M_SEL, + .name =3D "mfg13m_sel", + .parent_names =3D mfg13m_sel_parents, + .num_parents =3D ARRAY_SIZE(mfg13m_sel_parents), + .flags =3D CLK_SET_RATE_PARENT, + + .mux_ofs =3D CLK_CFG_5, + .set_ofs =3D CLK_CFG_5_SET, + .clr_ofs =3D CLK_CFG_5_CLR, + + .mux_shift =3D 24, + .mux_width =3D 1, + .gate_shift =3D 31, + + .ops =3D &mtk_mux_gate_clr_set_upd_ops, + }, + { + .id =3D AUD1_SEL, + .name =3D "aud_1_sel", + .parent_names =3D aud_1_2_sel_parents, + .num_parents =3D ARRAY_SIZE(aud_1_2_sel_parents), + .flags =3D CLK_SET_RATE_PARENT, + + .mux_ofs =3D CLK_CFG_6, + .set_ofs =3D CLK_CFG_6_SET, + .clr_ofs =3D CLK_CFG_6_CLR, + + .mux_shift =3D 0, + .mux_width =3D 1, + .gate_shift =3D 7, + + .ops =3D &mtk_mux_gate_clr_set_upd_ops, + }, + { + .id =3D AUD2_SEL, + .name =3D "aud_2_sel", + .parent_names =3D aud_1_2_sel_parents, + .num_parents =3D ARRAY_SIZE(aud_1_2_sel_parents), + .flags =3D CLK_SET_RATE_PARENT, + + .mux_ofs =3D CLK_CFG_6, + .set_ofs =3D CLK_CFG_6_SET, + .clr_ofs =3D CLK_CFG_6_CLR, + + .mux_shift =3D 8, + .mux_width =3D 1, + .gate_shift =3D 15, + + .ops =3D &mtk_mux_gate_clr_set_upd_ops, + }, + { + .id =3D IRDA_SEL, + .name =3D "irda_sel", + .parent_names =3D irda_sel_parents, + .num_parents =3D ARRAY_SIZE(irda_sel_parents), + .flags =3D CLK_SET_RATE_PARENT, + + .mux_ofs =3D CLK_CFG_6, + .set_ofs =3D CLK_CFG_6_SET, + .clr_ofs =3D CLK_CFG_6_CLR, + + .mux_shift =3D 16, + .mux_width =3D 1, + .gate_shift =3D 23, + + .ops =3D &mtk_mux_gate_clr_set_upd_ops, + }, + { + .id =3D IRTX_SEL, + .name =3D "irtx_sel", + .parent_names =3D irtx_sel_parents, + .num_parents =3D ARRAY_SIZE(irtx_sel_parents), + .flags =3D CLK_SET_RATE_PARENT, + + .mux_ofs =3D CLK_CFG_6, + .set_ofs =3D CLK_CFG_6_SET, + .clr_ofs =3D CLK_CFG_6_CLR, + + .mux_shift =3D 24, + .mux_width =3D 1, + .gate_shift =3D 31, + + .ops =3D &mtk_mux_gate_clr_set_upd_ops, + }, + { + .id =3D DISPPWM_SEL, + .name =3D "disppwm_sel", + .parent_names =3D disppwm_sel_parents, + .num_parents =3D ARRAY_SIZE(disppwm_sel_parents), + .flags =3D CLK_SET_RATE_PARENT, + + .mux_ofs =3D CLK_CFG_7, + .set_ofs =3D CLK_CFG_7_SET, + .clr_ofs =3D CLK_CFG_7_CLR, + + .mux_shift =3D 0, + .mux_width =3D 2, + .gate_shift =3D 7, + + .ops =3D &mtk_mux_gate_clr_set_upd_ops, + }, +}; + +int clk_mt6735_topckgen_probe(struct platform_device *pdev) +{ + void __iomem *base; + struct resource *res =3D platform_get_resource(pdev, IORESOURCE_MEM, 0); + struct clk_onecell_data *clk_data; + int ret; + + base =3D devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); + + clk_data =3D mtk_alloc_clk_data(ARRAY_SIZE(top_fixed_clks) + + ARRAY_SIZE(top_divs) + + ARRAY_SIZE(top_muxes)); + if (!clk_data) + return -ENOMEM; + platform_set_drvdata(pdev, clk_data); + + ret =3D mtk_clk_register_fixed_clks(top_fixed_clks, + ARRAY_SIZE(top_fixed_clks), clk_data); + if (ret) { + dev_err(&pdev->dev, "Failed to register fixed clocks: %pe\n", + ERR_PTR(ret)); + goto free_clk_data; + } + + ret =3D mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data= ); + if (ret) { + dev_err(&pdev->dev, "Failed to register dividers: %pe\n", + ERR_PTR(ret)); + goto unregister_fixed_clks; + } + + ret =3D mtk_clk_register_muxes(top_muxes, ARRAY_SIZE(top_muxes), + pdev->dev.of_node, &mt6735_topckgen_lock, + clk_data); + if (ret) { + dev_err(&pdev->dev, "Failed to register muxes: %pe\n", + ERR_PTR(ret)); + goto unregister_factors; + } + + ret =3D of_clk_add_provider(pdev->dev.of_node, of_clk_src_onecell_get, + clk_data); + if (ret) { + dev_err(&pdev->dev, + "Failed to register clock provider: %pe\n", + ERR_PTR(ret)); + goto unregister_muxes; + } + + return 0; +unregister_muxes: + mtk_clk_unregister_muxes(top_muxes, ARRAY_SIZE(top_muxes), clk_data); +unregister_factors: + mtk_clk_unregister_factors(top_divs, ARRAY_SIZE(top_divs), clk_data); +unregister_fixed_clks: + mtk_clk_unregister_fixed_clks(top_fixed_clks, + ARRAY_SIZE(top_fixed_clks), clk_data); +free_clk_data: + mtk_free_clk_data(clk_data); + + return ret; +} + +int clk_mt6735_topckgen_remove(struct platform_device *pdev) +{ + struct clk_onecell_data *clk_data =3D platform_get_drvdata(pdev); + + of_clk_del_provider(pdev->dev.of_node); + mtk_clk_unregister_muxes(top_muxes, ARRAY_SIZE(top_muxes), clk_data); + mtk_clk_unregister_factors(top_divs, ARRAY_SIZE(top_divs), clk_data); + mtk_clk_unregister_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks), + clk_data); + mtk_free_clk_data(clk_data); + + return 0; +} + +static const struct of_device_id of_match_mt6735_topckgen[] =3D { + { .compatible =3D "mediatek,mt6735-topckgen" }, + { /* sentinel */ } +}; + +static struct platform_driver clk_mt6735_topckgen =3D { + .probe =3D clk_mt6735_topckgen_probe, + .remove =3D clk_mt6735_topckgen_remove, + .driver =3D { + .name =3D "clk-mt6735-topckgen", + .of_match_table =3D of_match_mt6735_topckgen, + }, +}; +module_platform_driver(clk_mt6735_topckgen); + +MODULE_AUTHOR("Yassine Oudjana "); +MODULE_DESCRIPTION("Mediatek MT6735 topckgen clock driver"); +MODULE_LICENSE("GPL"); --=20 2.36.0