From nobody Mon Feb 9 11:04:51 2026 Received: from mail-pf1-f193.google.com (mail-pf1-f193.google.com [209.85.210.193]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BE20F44D6AE for ; Wed, 21 Jan 2026 07:15:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.193 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768979708; cv=none; b=Qg6JmWolBbNssVjSzYHx9a8VNrwV9hdTI7IaL2uPBElLL5AF5wV9faK7TJfizwZV9TqeTOIGS6JDfk8sYVMl00F1irJadNvjKqfTTNHh/lGJHh26VVm/f9mLw8h9qHsAbklUCzCH62CZqCvVdxnbwBsuH38nbHSnwcbOmWoFNZ4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768979708; c=relaxed/simple; bh=hVIbjeWWfCC1fLZAaLtalPtNjeD3aZPOoFYM5G9L8To=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=J66x0UexvpBmmGAo6j4h04PEOiwBDl8vRDOD7cUfCuD5tFX0ct09qUhPJxz+ICAN0469RrACRCy6DUtD47fVo/Z0sWpet+UmJ+eBij5frFdCo7wfMJzv4CkJZiF/TyqmmyC0eBcqa+nDhba6XhA4veqX1n0y/LildVuVAHHnnkw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=jnvOJX9t; arc=none smtp.client-ip=209.85.210.193 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="jnvOJX9t" Received: by mail-pf1-f193.google.com with SMTP id d2e1a72fcca58-81f42a49437so3134636b3a.0 for ; Tue, 20 Jan 2026 23:15:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1768979704; x=1769584504; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ehF00h1J1+PscAuONXxcxl4R5AqguvklIpS5sM1PBgM=; b=jnvOJX9tAnx2hj9LaHKvZGcLGtHl2QNYjFAoDIL8EGi2DAE2YIpMif42mlk9GU59Od T6ACh6pSDVe4KvUh05STgxBanisvriaKdP3OoX1qgMuV8kLeILjaJ/HoT+VncEmpQm07 HtHTKd4N6VZoJjHJehuf0ekPNXfCnFh29yYtn+crkAbYFw7/OtUvZBbddb2aBTkrpJ/b 0OFVJBZGdgIKmVT4jktsbPkESw3nO9LrWXXcVo6vKB2fCIq5gB9i2WsiLN6xOdHMplQf eTz8+PIJy6PyvjwUTKwWtlLl0Vj2y+A5qHTpgqjSDjHNixOabq1YSlg3oh2+L6hUZgSy mYHQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768979704; x=1769584504; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=ehF00h1J1+PscAuONXxcxl4R5AqguvklIpS5sM1PBgM=; b=P8Wq1dc4dxddoi9HbGaqIHYgl/8jd3JaKRJg9zPLt5C7HFwA5wlBNr/OnOl4NGMfP8 /1UI/UR+iJufXeiDfmE8TUWnnn4L6AjRwYqK5JvAsXHGqaqoswjI86ETBj1Jkze8nSHD XnVjlGNk/UxEGCGtjnyXYMocElo1My12z+v+OptFOGGM8RnxQck1A9ERT9bqq/l2HvLI vkJZGo/ZbZZUOefoFEph/kE7waHFWqhvCZ/TsGUpW42b5345djSpz3P8zQaQ5h/dclMc U2s3by2BeSd8prZCVlgzYtqmkoOWZrbuXtNOSYs/BG08SC84aXf0cJW0GfWa9vNqNQsk zCiw== X-Forwarded-Encrypted: i=1; AJvYcCU60ZBD9wo9sMf2WgPtcwIHNTMVXuTZPTTEvFtdj2BhhhsEbQ9Ywltq/3ubcW62QXgskFrzmDvXIGu0954=@vger.kernel.org X-Gm-Message-State: AOJu0Yz7BB8Gnyt/T3PPmUMXorM5f06XYUVLteK7ytwO3ZKjAj6MLml6 N1G8YRRu1FlqM1J6JtQuOhjmBVupQg8ZX1HNeN48lHXCYCbJYnh3EkkcYdY5YwL3fuaCvtBY X-Gm-Gg: AZuq6aJEO+mgjUXwNmQZvRiJgkpGWXbievvWnU1HYHB0FQn7HOV5cG+4hPWSMLYAfBo IXSo4teFYk2uSnN3aJYXGnKNsZDNi9PBgJHUHoYwcLtDAOEd59zTAIrccAh8C9l59dvvzayGmdY ibvCqoptO1Is0vqdw1qf4cA++yfYBPOyT75woDm5yDGitybKCZ+1Dq7szmcIydtncIt29gz7lYJ PcDa7URSxD49JX1/zvFyn75os2xtJbhm6Vv4RP/blBU7CZqbyRbZvORca0+5a/k5aAtsuvJGIDq lTQi/AxRzCZq2BZrK4OPlouBsp1/c8L2eHhTI0mx771V4GqFEDZL+drOF/JbOMtRHmYnNPj93UP M+6Jf0BEthoxci0CBbpJqtVpV6MdWopN19EYCjU5Vj7ROU0banp6GFKjLV/CrsmbU8tKaJpHBvz 2DoA8= X-Received: by 2002:a05:6a21:4d8b:b0:35d:ce99:cc23 with SMTP id adf61e73a8af0-38e45e32611mr4062852637.49.1768979703659; Tue, 20 Jan 2026 23:15:03 -0800 (PST) Received: from k.. ([223.74.152.156]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-352fb191a62sm507411a91.5.2026.01.20.23.15.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 20 Jan 2026 23:15:03 -0800 (PST) From: Nadi Ke To: mturquette@baylibre.com, sboyd@kernel.org, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, orsonzhai@gmail.com, baolin.wang@linux.alibaba.com Cc: zhang.lyra@gmail.com, linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Nadi Ke Subject: [PATCH v2 2/2] Add clock driver for Unisoc SC9832E SoC. Date: Wed, 21 Jan 2026 15:14:12 +0800 Message-Id: <20260121071412.256215-3-kenadicanady@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260121071412.256215-1-kenadicanady@gmail.com> References: <20260121071412.256215-1-kenadicanady@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This driver supports the PLLs, gates, and other clock dividers found on the SC9832E platform. It utilizes the common Spreadtrum clock infrastructure. The PMU gate clocks are handled by matching the system controller's compatible string ("sprd,sc9832e-glbregs") directly, as these registers are interleaved within the PMU region. Signed-off-by: Nadi Ke --- Changes in v2: - Updated the OF match table to match 'sprd,sc9832e-glbregs' instead of the removed child node compatible string. - Fixed a compilation error due to a typo in variable names. - Updated Author email address. --- drivers/clk/sprd/Kconfig | 10 + drivers/clk/sprd/Makefile | 1 + drivers/clk/sprd/sc9832e-clk.c | 1077 ++++++++++++++++++++++++++++++++ 3 files changed, 1088 insertions(+) create mode 100644 drivers/clk/sprd/sc9832e-clk.c diff --git a/drivers/clk/sprd/Kconfig b/drivers/clk/sprd/Kconfig index 2f19c8d58..cba558365 100644 --- a/drivers/clk/sprd/Kconfig +++ b/drivers/clk/sprd/Kconfig @@ -8,6 +8,16 @@ config SPRD_COMMON_CLK if SPRD_COMMON_CLK =20 # SoC Drivers +config SPRD_SC9832E_CLK + tristate "Support for the Spreadtrum SC9832E clocks" + depends on (ARM64 && ARCH_SPRD) || COMPILE_TEST + default ARM64 && ARCH_SPRD + help + This enables the clock control unit for Unisoc SC9832E SoCs. + The driver provides support for various clock controllers including + AP, AON, and peripheral gate clocks. + Say Y if you want to use the Spreadtrum SC9832E SoC platform. + If unsure, say N. =20 config SPRD_SC9860_CLK tristate "Support for the Spreadtrum SC9860 clocks" diff --git a/drivers/clk/sprd/Makefile b/drivers/clk/sprd/Makefile index f25b2c390..7b67d8510 100644 --- a/drivers/clk/sprd/Makefile +++ b/drivers/clk/sprd/Makefile @@ -9,6 +9,7 @@ clk-sprd-y +=3D composite.o clk-sprd-y +=3D pll.o =20 ## SoC support +obj-$(CONFIG_SPRD_SC9832E_CLK) +=3D sc9832e-clk.o obj-$(CONFIG_SPRD_SC9860_CLK) +=3D sc9860-clk.o obj-$(CONFIG_SPRD_SC9863A_CLK) +=3D sc9863a-clk.o obj-$(CONFIG_SPRD_UMS512_CLK) +=3D ums512-clk.o diff --git a/drivers/clk/sprd/sc9832e-clk.c b/drivers/clk/sprd/sc9832e-clk.c new file mode 100644 index 000000000..0574097b0 --- /dev/null +++ b/drivers/clk/sprd/sc9832e-clk.c @@ -0,0 +1,1077 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Unisoc SC9832E clock driver + * + * Copyright (C) 2015 Spreadtrum, Inc. + * Copyright (C) 2026 Nadi Ke + * Author: Nadi Ke + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include "common.h" +#include "composite.h" +#include "div.h" +#include "gate.h" +#include "mux.h" +#include "pll.h" + +#define CLK_PMU_GATE_NUM (CLK_GPLL_GATE + 1) +#define CLK_PLL_NUM (CLK_ISPPLL_468M + 1) +#define CLK_MPLL_NUM (CLK_MPLL_50M + 1) +#define CLK_DPLL_NUM (CLK_DPLL_40M + 1) +#define CLK_RPLL_NUM (CLK_RPLL_26M + 1) +#define CLK_AP_AHB_GATE_NUM (CLK_SDIO1_32K_EB + 1) +#define CLK_AON_APB_GATE_NUM (CLK_CA7_DAP_EB + 1) +#define CLK_AP_CLK_NUM (CLK_DSI_LANEBYTE + 1) +#define CLK_AON_CLK_NUM (CLK_MM_ISP + 1) +#define CLK_AP_APB_GATE_NUM (CLK_INTC3_EB + 1) + +static SPRD_PLL_SC_GATE_CLK_FW_NAME(isppll_gate, "isppll-gate", "ext-26m", + 0x88, 0x1000, BIT(0), 0, 0, 240); +static SPRD_PLL_SC_GATE_CLK_FW_NAME(mpll_gate, "mpll-gate", "ext-26m", + 0x94, 0x1000, BIT(0), 0, 0, 240); +static SPRD_PLL_SC_GATE_CLK_FW_NAME(dpll_gate, "dpll-gate", "ext-26m", + 0x98, 0x1000, BIT(0), 0, 0, 240); +static SPRD_PLL_SC_GATE_CLK_FW_NAME(lpll_gate, "lpll-gate", "ext-26m", + 0x9c, 0x1000, BIT(0), 0, 0, 240); +static SPRD_PLL_SC_GATE_CLK_FW_NAME(gpll_gate, "gpll-gate", "ext-26m", + 0xa8, 0x1000, BIT(0), 0, 0, 240); + +static struct sprd_clk_common *sc9832e_pmu_gate_clks[] =3D { + &isppll_gate.common, + &mpll_gate.common, + &dpll_gate.common, + &lpll_gate.common, + &gpll_gate.common, +}; + +static struct clk_hw_onecell_data sc9832e_pmu_gate_hws =3D { + .hws =3D { + [CLK_ISPPLL_GATE] =3D &isppll_gate.common.hw, + [CLK_MPLL_GATE] =3D &mpll_gate.common.hw, + [CLK_DPLL_GATE] =3D &dpll_gate.common.hw, + [CLK_LPLL_GATE] =3D &lpll_gate.common.hw, + [CLK_GPLL_GATE] =3D &gpll_gate.common.hw, + }, + .num =3D CLK_PMU_GATE_NUM, +}; + +static const struct sprd_clk_desc sc9832e_pmu_gate_desc =3D { + .clk_clks =3D sc9832e_pmu_gate_clks, + .num_clk_clks =3D ARRAY_SIZE(sc9832e_pmu_gate_clks), + .hw_clks =3D &sc9832e_pmu_gate_hws, +}; + +static const u64 itable[5] =3D {4, 1000000000, 1200000000, + 1400000000, 1600000000}; + +static const struct clk_bit_field f_pll_layout_a[PLL_FACT_MAX] =3D { + { .shift =3D 0, .width =3D 0 }, /* lock_done */ + { .shift =3D 0, .width =3D 1 }, /* div_s */ + { .shift =3D 1, .width =3D 1 }, /* mod_en */ + { .shift =3D 2, .width =3D 1 }, /* sdm_en */ + { .shift =3D 0, .width =3D 0 }, /* refin */ + { .shift =3D 6, .width =3D 2 }, /* ibias */ + { .shift =3D 8, .width =3D 11 }, /* n */ + { .shift =3D 55, .width =3D 7 }, /* nint */ + { .shift =3D 32, .width =3D 23}, /* kint */ + { .shift =3D 0, .width =3D 0 }, /* prediv */ + { .shift =3D 0, .width =3D 0 }, /* postdiv */ +}; + +static const struct clk_bit_field f_pll_layout_b[PLL_FACT_MAX] =3D { + { .shift =3D 0, .width =3D 0 }, /* lock_done */ + { .shift =3D 1, .width =3D 1 }, /* div_s */ + { .shift =3D 2, .width =3D 1 }, /* mod_en */ + { .shift =3D 3, .width =3D 1 }, /* sdm_en */ + { .shift =3D 0, .width =3D 1 }, /* refin */ + { .shift =3D 7, .width =3D 2 }, /* ibias */ + { .shift =3D 9, .width =3D 11 }, /* n */ + { .shift =3D 55, .width =3D 7 }, /* nint */ + { .shift =3D 32, .width =3D 23}, /* kint */ + { .shift =3D 0, .width =3D 0 }, /* prediv */ + { .shift =3D 0, .width =3D 0 }, /* postdiv */ +}; + +static const struct clk_bit_field f_pll_layout_c[PLL_FACT_MAX] =3D { + { .shift =3D 0, .width =3D 0 }, /* lock_done */ + { .shift =3D 9, .width =3D 1 }, /* div_s */ + { .shift =3D 10, .width =3D 1 }, /* mod_en */ + { .shift =3D 11, .width =3D 1 }, /* sdm_en */ + { .shift =3D 0, .width =3D 0 }, /* refin */ + { .shift =3D 15, .width =3D 2 }, /* ibias */ + { .shift =3D 17, .width =3D 11 }, /* n */ + { .shift =3D 55, .width =3D 7 }, /* nint */ + { .shift =3D 32, .width =3D 23}, /* kint */ + { .shift =3D 0, .width =3D 0 }, /* prediv */ + { .shift =3D 0, .width =3D 1 }, /* postdiv */ +}; + +static const struct clk_bit_field f_pll_layout_d[PLL_FACT_MAX] =3D { + { .shift =3D 0, .width =3D 0 }, /* lock_done */ + { .shift =3D 3, .width =3D 1 }, /* div_s */ + { .shift =3D 4, .width =3D 1 }, /* mod_en */ + { .shift =3D 5, .width =3D 1 }, /* sdm_en */ + { .shift =3D 1, .width =3D 2 }, /* refin */ + { .shift =3D 9, .width =3D 2 }, /* ibias */ + { .shift =3D 11, .width =3D 11 }, /* n */ + { .shift =3D 55, .width =3D 7 }, /* nint */ + { .shift =3D 32, .width =3D 23}, /* kint */ + { .shift =3D 0, .width =3D 0 }, /* prediv */ + { .shift =3D 0, .width =3D 0 }, /* postdiv */ +}; + +static SPRD_PLL_FW_NAME(twpll, "twpll", "ext-26m", 0x0c, 3, itable, + f_pll_layout_a, 240, 1000, 1000, 0, 0); +static CLK_FIXED_FACTOR_HW(twpll_768m, "twpll-768m", &twpll.common.hw, 2, = 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_384m, "twpll-384m", &twpll.common.hw, 4, = 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_192m, "twpll-192m", &twpll.common.hw, 8, = 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_96m, "twpll-96m", &twpll.common.hw, 16, 1= , 0); +static CLK_FIXED_FACTOR_HW(twpll_48m, "twpll-48m", &twpll.common.hw, 32, 1= , 0); +static CLK_FIXED_FACTOR_HW(twpll_24m, "twpll-24m", &twpll.common.hw, 64, 1= , 0); +static CLK_FIXED_FACTOR_HW(twpll_12m, "twpll-12m", &twpll.common.hw, 128, = 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_512m, "twpll-512m", &twpll.common.hw, 3, = 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_256m, "twpll-256m", &twpll.common.hw, 6, = 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_128m, "twpll-128m", &twpll.common.hw, 12,= 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_64m, "twpll-64m", &twpll.common.hw, 24, 1= , 0); +static CLK_FIXED_FACTOR_HW(twpll_307m2, "twpll-307m2", &twpll.common.hw, 5= , 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_219m4, "twpll-219m4", &twpll.common.hw, 7= , 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_170m6, "twpll-170m6", &twpll.common.hw, 9= , 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_153m6, "twpll-153m6", &twpll.common.hw, 1= 0, 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_76m8, "twpll-76m8", &twpll.common.hw, 20,= 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_51m2, "twpll-51m2", &twpll.common.hw, 30,= 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_38m4, "twpll-38m4", &twpll.common.hw, 40,= 1, 0); +static CLK_FIXED_FACTOR_HW(twpll_19m2, "twpll-19m2", &twpll.common.hw, 80,= 1, 0); + +static SPRD_PLL_HW(lpll, "lpll", &lpll_gate.common.hw, 0x1c, 3, itable, + f_pll_layout_a, 240, 1000, 1000, 0, 0); +static CLK_FIXED_FACTOR_HW(lpll_409m6, "lpll-409m6", &lpll.common.hw, 3, 1= , 0); +static CLK_FIXED_FACTOR_HW(lpll_245m76, "lpll-245m76", &lpll.common.hw, 5,= 1, 0); + +static SPRD_PLL_HW(gpll, "gpll", &gpll_gate.common.hw, 0x2c, 3, itable, + f_pll_layout_b, 240, 1000, 1000, 0, 0); + +static SPRD_PLL_HW(isppll, "isppll", &isppll_gate.common.hw, 0x3c, 3, itab= le, + f_pll_layout_b, 240, 1000, 1000, 0, 0); +static CLK_FIXED_FACTOR_HW(isppll_468m, "isppll-468m", &isppll.common.hw, = 2, 1, 0); + +static struct sprd_clk_common *sc9832e_pll_clks[] =3D { + &twpll.common, + &lpll.common, + &gpll.common, + &isppll.common, +}; + +static struct clk_hw_onecell_data sc9832e_pll_hws =3D { + .hws =3D { + [CLK_TWPLL] =3D &twpll.common.hw, + [CLK_TWPLL_768M] =3D &twpll_768m.hw, + [CLK_TWPLL_384M] =3D &twpll_384m.hw, + [CLK_TWPLL_192M] =3D &twpll_192m.hw, + [CLK_TWPLL_96M] =3D &twpll_96m.hw, + [CLK_TWPLL_48M] =3D &twpll_48m.hw, + [CLK_TWPLL_24M] =3D &twpll_24m.hw, + [CLK_TWPLL_12M] =3D &twpll_12m.hw, + [CLK_TWPLL_512M] =3D &twpll_512m.hw, + [CLK_TWPLL_256M] =3D &twpll_256m.hw, + [CLK_TWPLL_128M] =3D &twpll_128m.hw, + [CLK_TWPLL_64M] =3D &twpll_64m.hw, + [CLK_TWPLL_307M2] =3D &twpll_307m2.hw, + [CLK_TWPLL_219M4] =3D &twpll_219m4.hw, + [CLK_TWPLL_170M6] =3D &twpll_170m6.hw, + [CLK_TWPLL_153M6] =3D &twpll_153m6.hw, + [CLK_TWPLL_76M8] =3D &twpll_76m8.hw, + [CLK_TWPLL_51M2] =3D &twpll_51m2.hw, + [CLK_TWPLL_38M4] =3D &twpll_38m4.hw, + [CLK_TWPLL_19M2] =3D &twpll_19m2.hw, + [CLK_LPLL] =3D &lpll.common.hw, + [CLK_LPLL_409M6] =3D &lpll_409m6.hw, + [CLK_LPLL_245M76] =3D &lpll_245m76.hw, + [CLK_GPLL] =3D &gpll.common.hw, + [CLK_ISPPLL] =3D &isppll.common.hw, + [CLK_ISPPLL_468M] =3D &isppll_468m.hw, + }, + .num =3D CLK_PLL_NUM, +}; + +static const struct sprd_clk_desc sc9832e_pll_desc =3D { + .clk_clks =3D sc9832e_pll_clks, + .num_clk_clks =3D ARRAY_SIZE(sc9832e_pll_clks), + .hw_clks =3D &sc9832e_pll_hws, +}; + +static SPRD_PLL_HW(mpll, "mpll", &mpll_gate.common.hw, 0x0, 3, itable, + f_pll_layout_a, 240, 1000, 1000, 0, 0); +static CLK_FIXED_FACTOR_HW(mpll_50m, "mpll-50m", &mpll.common.hw, 18, 1, 0= ); + +static struct sprd_clk_common *sc9832e_mpll_clks[] =3D { + &mpll.common, +}; + +static struct clk_hw_onecell_data sc9832e_mpll_hws =3D { + .hws =3D { + [CLK_MPLL] =3D &mpll.common.hw, + [CLK_MPLL_50M] =3D &mpll_50m.hw, + }, + .num =3D CLK_MPLL_NUM, +}; + +static const struct sprd_clk_desc sc9832e_mpll_desc =3D { + .clk_clks =3D sc9832e_mpll_clks, + .num_clk_clks =3D ARRAY_SIZE(sc9832e_mpll_clks), + .hw_clks =3D &sc9832e_mpll_hws, +}; + +static SPRD_PLL_HW(dpll, "dpll", &dpll_gate.common.hw, 0x0, 3, itable, + f_pll_layout_c, 240, 1000, 1000, 0, 0); +static CLK_FIXED_FACTOR_HW(dpll_40m, "dpll-40m", &dpll.common.hw, 32, 1, 0= ); + +static struct sprd_clk_common *sc9832e_dpll_clks[] =3D { + &dpll.common, +}; + +static struct clk_hw_onecell_data sc9832e_dpll_hws =3D { + .hws =3D { + [CLK_DPLL] =3D &dpll.common.hw, + [CLK_DPLL_40M] =3D &dpll_40m.hw, + }, + .num =3D CLK_DPLL_NUM, +}; + +static const struct sprd_clk_desc sc9832e_dpll_desc =3D { + .clk_clks =3D sc9832e_dpll_clks, + .num_clk_clks =3D ARRAY_SIZE(sc9832e_dpll_clks), + .hw_clks =3D &sc9832e_dpll_hws, +}; + +static SPRD_SC_GATE_CLK_FW_NAME(audio_gate, "audio-gate", "ext-26m", + 0x08, 0x1000, BIT(8), 0, 0); +static SPRD_PLL_FW_NAME(rpll, "rpll", "ext-26m", 0x14, + 3, itable, f_pll_layout_d, 240, 1000, 1000, 0, 0); + +static CLK_FIXED_FACTOR_HW(rpll_390m, "rpll-390m", &rpll.common.hw, 2, 1, = 0); +static CLK_FIXED_FACTOR_HW(rpll_260m, "rpll-260m", &rpll.common.hw, 3, 1, = 0); +static CLK_FIXED_FACTOR_HW(rpll_195m, "rpll-195m", &rpll.common.hw, 4, 1, = 0); +static CLK_FIXED_FACTOR_HW(rpll_26m, "rpll-26m", &rpll.common.hw, 30, 1, 0= ); + +static struct sprd_clk_common *sc9832e_rpll_clks[] =3D { + &audio_gate.common, + &rpll.common, +}; + +static struct clk_hw_onecell_data sc9832e_rpll_hws =3D { + .hws =3D { + [CLK_AUDIO_GATE] =3D &audio_gate.common.hw, + [CLK_RPLL] =3D &rpll.common.hw, + [CLK_RPLL_390M] =3D &rpll_390m.hw, + [CLK_RPLL_260M] =3D &rpll_260m.hw, + [CLK_RPLL_195M] =3D &rpll_195m.hw, + [CLK_RPLL_26M] =3D &rpll_26m.hw, + }, + .num =3D CLK_RPLL_NUM, +}; + +static const struct sprd_clk_desc sc9832e_rpll_desc =3D { + .clk_clks =3D sc9832e_rpll_clks, + .num_clk_clks =3D ARRAY_SIZE(sc9832e_rpll_clks), + .hw_clks =3D &sc9832e_rpll_hws, +}; + +static SPRD_SC_GATE_CLK_FW_NAME(dsi_eb, "dsi-eb", "ap-axi", 0x0, 0x1000, B= IT(0), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(dispc_eb, "dispc-eb", "ap-axi", 0x0, 0x100= 0, BIT(1), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(vsp_eb, "vsp-eb", "ap-axi", 0x0, 0x1000, B= IT(2), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(gsp_eb, "gsp-eb", "ap-axi", 0x0, 0x1000, B= IT(3), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(otg_eb, "otg-eb", "ap-axi", 0x0, 0x1000, B= IT(4), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(dma_pub_eb, "dma-pub-eb", "ap-axi", 0x0, 0= x1000, BIT(5), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(ce_pub_eb, "ce-pub-eb", "ap-axi", 0x0, 0x1= 000, BIT(6), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(ahb_ckg_eb, "ahb-ckg-eb", "ap-axi", 0x0, 0= x1000, BIT(7), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(sdio0_eb, "sdio0-eb", "ap-axi", 0x0, 0x100= 0, BIT(8), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(sdio1_eb, "sdio1-eb", "ap-axi", 0x0, 0x100= 0, BIT(9), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(nandc_eb, "nandc-eb", "ap-axi", 0x0, 0x100= 0, BIT(10), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(emmc_eb, "emmc-eb", "ap-axi", 0x0, 0x1000,= BIT(11), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(spinlock_eb, "spinlock-eb", "ap-axi", 0x0,= 0x1000, BIT(12), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(ce_efuse_eb, "ce-efuse-eb", "ap-axi", 0x0,= 0x1000, BIT(13), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(emmc_32k_eb, "emmc-32k-eb", "ap-axi", 0x0,= 0x1000, BIT(14), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(sdio0_32k_eb, "sdio0-32k-eb", "ap-axi", 0x= 0, 0x1000, BIT(15), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(sdio1_32k_eb, "sdio1-32k-eb", "ap-axi", 0x= 0, 0x1000, BIT(16), 0, 0); + +static struct sprd_clk_common *sc9832e_apahb_gate_clks[] =3D { + &dsi_eb.common, + &dispc_eb.common, + &vsp_eb.common, + &gsp_eb.common, + &otg_eb.common, + &dma_pub_eb.common, + &ce_pub_eb.common, + &ahb_ckg_eb.common, + &sdio0_eb.common, + &sdio1_eb.common, + &nandc_eb.common, + &emmc_eb.common, + &spinlock_eb.common, + &ce_efuse_eb.common, + &emmc_32k_eb.common, + &sdio0_32k_eb.common, + &sdio1_32k_eb.common, +}; + +static struct clk_hw_onecell_data sc9832e_apahb_gate_hws =3D { + .hws =3D { + [CLK_DSI_EB] =3D &dsi_eb.common.hw, + [CLK_DISPC_EB] =3D &dispc_eb.common.hw, + [CLK_VSP_EB] =3D &vsp_eb.common.hw, + [CLK_GSP_EB] =3D &gsp_eb.common.hw, + [CLK_OTG_EB] =3D &otg_eb.common.hw, + [CLK_DMA_PUB_EB] =3D &dma_pub_eb.common.hw, + [CLK_CE_PUB_EB] =3D &ce_pub_eb.common.hw, + [CLK_AHB_CKG_EB] =3D &ahb_ckg_eb.common.hw, + [CLK_SDIO0_EB] =3D &sdio0_eb.common.hw, + [CLK_SDIO1_EB] =3D &sdio1_eb.common.hw, + [CLK_NANDC_EB] =3D &nandc_eb.common.hw, + [CLK_EMMC_EB] =3D &emmc_eb.common.hw, + [CLK_SPINLOCK_EB] =3D &spinlock_eb.common.hw, + [CLK_CE_EFUSE_EB] =3D &ce_efuse_eb.common.hw, + [CLK_EMMC_32K_EB] =3D &emmc_32k_eb.common.hw, + [CLK_SDIO0_32K_EB] =3D &sdio0_32k_eb.common.hw, + [CLK_SDIO1_32K_EB] =3D &sdio1_32k_eb.common.hw, + }, + .num =3D CLK_AP_AHB_GATE_NUM, +}; + +static const struct sprd_clk_desc sc9832e_apahb_gate_desc =3D { + .clk_clks =3D sc9832e_apahb_gate_clks, + .num_clk_clks =3D ARRAY_SIZE(sc9832e_apahb_gate_clks), + .hw_clks =3D &sc9832e_apahb_gate_hws, +}; + +static SPRD_SC_GATE_CLK_FW_NAME(adc_eb, "adc-eb", "clk_aon_apb", 0x0, 0x10= 00, BIT(0), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(fm_eb, "fm-eb", "clk_aon_apb", 0x0, 0x1000= , BIT(1), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(tpc_eb, "tpc-eb", "clk_aon_apb", 0x0, 0x10= 00, BIT(2), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(gpio_eb, "gpio-eb", "clk_aon_apb", 0x0, 0x= 1000, BIT(3), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(pwm0_eb, "pwm0-eb", "clk_aon_apb", 0x0, 0x= 1000, BIT(4), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(pwm1_eb, "pwm1-eb", "clk_aon_apb", 0x0, 0x= 1000, BIT(5), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(pwm2_eb, "pwm2-eb", "clk_aon_apb", 0x0, 0x= 1000, BIT(6), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(pwm3_eb, "pwm3-eb", "clk_aon_apb", 0x0, 0x= 1000, BIT(7), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(kpd_eb, "kpd-eb", "clk_aon_apb", 0x0, 0x10= 00, BIT(8), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(aon_syst_eb, "aon-syst-eb", "clk_aon_apb", + 0x0, 0x1000, BIT(9), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(ap_syst_eb, "ap-syst-eb", "clk_aon_apb", + 0x0, 0x1000, BIT(10), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(aon_tmr_eb, "aon-tmr-eb", "clk_aon_apb", + 0x0, 0x1000, BIT(11), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(ap_tmr0_eb, "ap-tmr0-eb", "clk_aon_apb", + 0x0, 0x1000, BIT(12), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(efuse_eb, "efuse-eb", "clk_aon_apb", 0x0, = 0x1000, BIT(13), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(eic_eb, "eic-eb", "clk_aon_apb", 0x0, 0x10= 00, BIT(14), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(intc_eb, "intc-eb", "clk_aon_apb", 0x0, 0x= 1000, BIT(15), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(adi_eb, "adi-eb", "clk_aon_apb", 0x0, 0x10= 00, BIT(16), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(audif_eb, "audif-eb", "clk_aon_apb", 0x0, = 0x1000, BIT(17), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(aud_eb, "aud-eb", "clk_aon_apb", 0x0, 0x10= 00, BIT(18), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(vbc_eb, "vbc-eb", "clk_aon_apb", 0x0, 0x10= 00, BIT(19), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(pin_eb, "pin-eb", "clk_aon_apb", 0x0, 0x10= 00, BIT(20), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(ipi_eb, "ipi-eb", "clk_aon_apb", 0x0, 0x10= 00, BIT(21), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(splk_eb, "splk-eb", "clk_aon_apb", 0x0, 0x= 1000, BIT(22), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(ap_wdg_eb, "ap-wdg-eb", "clk_aon_apb", 0x0= , 0x1000, BIT(24), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(mm_eb, "mm-eb", "clk_aon_apb", 0x0, 0x1000= , BIT(25), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(aon_apb_ckg_eb, "aon-apb-ckg-eb", "clk_aon= _apb", + 0x0, 0x1000, BIT(26), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(gpu_eb, "gpu-eb", "clk_aon_apb", 0x0, 0x10= 00, BIT(27), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(ca7_ts0_eb, "ca7-ts0-eb", "clk_aon_apb", + 0x0, 0x1000, BIT(28), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(ca7_dap_eb, "ca7-dap-eb", "clk_aon_apb", + 0x0, 0x1000, BIT(29), 0, 0); + +static struct sprd_clk_common *sc9832e_aonapb_gate_clks[] =3D { + &adc_eb.common, + &fm_eb.common, + &tpc_eb.common, + &gpio_eb.common, + &pwm0_eb.common, + &pwm1_eb.common, + &pwm2_eb.common, + &pwm3_eb.common, + &kpd_eb.common, + &aon_syst_eb.common, + &ap_syst_eb.common, + &aon_tmr_eb.common, + &ap_tmr0_eb.common, + &efuse_eb.common, + &eic_eb.common, + &intc_eb.common, + &adi_eb.common, + &audif_eb.common, + &aud_eb.common, + &vbc_eb.common, + &pin_eb.common, + &ipi_eb.common, + &splk_eb.common, + &ap_wdg_eb.common, + &mm_eb.common, + &aon_apb_ckg_eb.common, + &gpu_eb.common, + &ca7_ts0_eb.common, + &ca7_dap_eb.common, +}; + +static struct clk_hw_onecell_data sc9832e_aonapb_gate_hws =3D { + .hws =3D { + [CLK_ADC_EB] =3D &adc_eb.common.hw, + [CLK_FM_EB] =3D &fm_eb.common.hw, + [CLK_TPC_EB] =3D &tpc_eb.common.hw, + [CLK_GPIO_EB] =3D &gpio_eb.common.hw, + [CLK_PWM0_EB] =3D &pwm0_eb.common.hw, + [CLK_PWM1_EB] =3D &pwm1_eb.common.hw, + [CLK_PWM2_EB] =3D &pwm2_eb.common.hw, + [CLK_PWM3_EB] =3D &pwm3_eb.common.hw, + [CLK_KPD_EB] =3D &kpd_eb.common.hw, + [CLK_AON_SYST_EB] =3D &aon_syst_eb.common.hw, + [CLK_AP_SYST_EB] =3D &ap_syst_eb.common.hw, + [CLK_AON_TMR_EB] =3D &aon_tmr_eb.common.hw, + [CLK_AP_TMR0_EB] =3D &ap_tmr0_eb.common.hw, + [CLK_EFUSE_EB] =3D &efuse_eb.common.hw, + [CLK_EIC_EB] =3D &eic_eb.common.hw, + [CLK_INTC_EB] =3D &intc_eb.common.hw, + [CLK_ADI_EB] =3D &adi_eb.common.hw, + [CLK_AUDIF_EB] =3D &audif_eb.common.hw, + [CLK_AUD_EB] =3D &aud_eb.common.hw, + [CLK_VBC_EB] =3D &vbc_eb.common.hw, + [CLK_PIN_EB] =3D &pin_eb.common.hw, + [CLK_IPI_EB] =3D &ipi_eb.common.hw, + [CLK_SPLK_EB] =3D &splk_eb.common.hw, + [CLK_AP_WDG_EB] =3D &ap_wdg_eb.common.hw, + [CLK_MM_EB] =3D &mm_eb.common.hw, + [CLK_AON_APB_CKG_EB] =3D &aon_apb_ckg_eb.common.hw, + [CLK_GPU_EB] =3D &gpu_eb.common.hw, + [CLK_CA7_TS0_EB] =3D &ca7_ts0_eb.common.hw, + [CLK_CA7_DAP_EB] =3D &ca7_dap_eb.common.hw, + }, + .num =3D CLK_AON_APB_GATE_NUM, +}; + +static const struct sprd_clk_desc sc9832e_aonapb_gate_desc =3D { + .clk_clks =3D sc9832e_aonapb_gate_clks, + .num_clk_clks =3D ARRAY_SIZE(sc9832e_aonapb_gate_clks), + .hw_clks =3D &sc9832e_aonapb_gate_hws, +}; + +#define SC9832E_MUX_FLAG \ + (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_NO_REPARENT) + +static const struct clk_parent_data ap_apb_parents[] =3D { + { .fw_name =3D "ext-26m" }, + { .hw =3D &twpll_64m.hw }, + { .hw =3D &twpll_96m.hw }, + { .hw =3D &twpll_128m.hw }, +}; + +static SPRD_MUX_CLK_DATA(ap_apb, "ap-apb", ap_apb_parents, 0x20, + 0, 2, SC9832E_MUX_FLAG); + +static const struct clk_parent_data nandc_ecc_parents[] =3D { + { .fw_name =3D "ext-26m" }, + { .hw =3D &twpll_256m.hw }, + { .hw =3D &twpll_307m2.hw }, +}; + +static SPRD_COMP_CLK_DATA(nandc_ecc, "nandc-ecc", nandc_ecc_parents, 0x24, + 0, 2, 8, 3, 0); + +static const struct clk_parent_data otg_ref_parents[] =3D { + { .hw =3D &twpll_12m.hw }, + { .hw =3D &twpll_24m.hw }, +}; + +static SPRD_MUX_CLK_DATA(otg_ref_clk, "otg-ref-clk", otg_ref_parents, 0x28, + 0, 1, SC9832E_MUX_FLAG); + +static SPRD_GATE_CLK_HW(otg_utmi, "otg-utmi", &ap_apb.common.hw, 0x2c, + BIT(16), 0, 0); + +static const struct clk_parent_data ap_uart_parents[] =3D { + { .fw_name =3D "ext-26m" }, + { .hw =3D &twpll_48m.hw }, + { .hw =3D &twpll_51m2.hw }, + { .hw =3D &twpll_96m.hw }, +}; + +static SPRD_COMP_CLK_DATA(ap_uart1, "ap-uart1", ap_uart_parents, 0x30, + 0, 2, 8, 3, 0); + +static const struct clk_parent_data i2c_parents[] =3D { + { .fw_name =3D "ext-26m" }, + { .hw =3D &twpll_48m.hw }, + { .hw =3D &twpll_51m2.hw }, + { .hw =3D &twpll_153m6.hw }, +}; + +static SPRD_COMP_CLK_DATA(ap_i2c0, "ap-i2c0", i2c_parents, 0x34, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_i2c1, "ap-i2c1", i2c_parents, 0x38, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_i2c2, "ap-i2c2", i2c_parents, 0x3c, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_i2c3, "ap-i2c3", i2c_parents, 0x40, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_i2c4, "ap-i2c4", i2c_parents, 0x44, + 0, 2, 8, 3, 0); + +static const struct clk_parent_data spi_parents[] =3D { + { .fw_name =3D "ext-26m" }, + { .hw =3D &twpll_128m.hw }, + { .hw =3D &twpll_153m6.hw }, + { .hw =3D &twpll_192m.hw }, +}; + +static SPRD_COMP_CLK_DATA(ap_spi0, "ap-spi0", spi_parents, 0x48, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_spi2, "ap-spi2", spi_parents, 0x4c, + 0, 2, 8, 3, 0); +static SPRD_COMP_CLK_DATA(ap_hs_spi, "ap-hs-spi", spi_parents, 0x50, + 0, 2, 8, 3, 0); + +static const struct clk_parent_data iis_parents[] =3D { + { .fw_name =3D "ext-26m" }, + { .hw =3D &twpll_128m.hw }, + { .hw =3D &twpll_153m6.hw }, +}; + +static SPRD_COMP_CLK_DATA(ap_iis0, "ap-iis0", iis_parents, 0x54, + 0, 2, 8, 3, 0); + +static const struct clk_parent_data ap_ce_parents[] =3D { + { .fw_name =3D "ext-26m" }, + { .hw =3D &twpll_96m.hw }, + { .hw =3D &twpll_192m.hw }, + { .hw =3D &twpll_256m.hw }, +}; + +static SPRD_MUX_CLK_DATA(ap_ce, "ap-ce", ap_ce_parents, 0x58, + 0, 2, SC9832E_MUX_FLAG); + +static const struct clk_parent_data nandc_2x_parents[] =3D { + { .fw_name =3D "ext-26m" }, + { .hw =3D &twpll_153m6.hw }, + { .hw =3D &twpll_170m6.hw }, + { .hw =3D &rpll_195m.hw }, + { .hw =3D &twpll_219m4.hw }, + { .hw =3D &lpll_245m76.hw }, + { .hw =3D &rpll_260m.hw }, + { .hw =3D &twpll_307m2.hw }, + { .hw =3D &rpll_390m.hw }, +}; + +static SPRD_COMP_CLK_DATA(nandc_2x, "nandc-2x", nandc_2x_parents, 0x78, + 0, 4, 8, 4, 0); + +static const struct clk_parent_data sdio_parents[] =3D { + { .fw_name =3D "ext-1m" }, + { .fw_name =3D "ext-26m" }, + { .hw =3D &twpll_307m2.hw }, + { .hw =3D &twpll_384m.hw }, + { .hw =3D &rpll_390m.hw }, + { .hw =3D &lpll_409m6.hw }, +}; + +static SPRD_MUX_CLK_DATA(sdio0_2x, "sdio0-2x", sdio_parents, 0x80, + 0, 3, SC9832E_MUX_FLAG); +static SPRD_MUX_CLK_DATA(sdio1_2x, "sdio1-2x", sdio_parents, 0x88, + 0, 3, SC9832E_MUX_FLAG); +static SPRD_MUX_CLK_DATA(emmc_2x, "emmc-2x", sdio_parents, 0x90, + 0, 3, SC9832E_MUX_FLAG); + +static const struct clk_parent_data vsp_parents[] =3D { + { .hw =3D &twpll_76m8.hw }, + { .hw =3D &twpll_128m.hw }, + { .hw =3D &twpll_256m.hw }, + { .hw =3D &twpll_307m2.hw }, +}; + +static SPRD_MUX_CLK_DATA(clk_vsp, "vsp-clk", vsp_parents, 0x98, + 0, 2, SC9832E_MUX_FLAG); + +static const struct clk_parent_data gsp_parents[] =3D { + { .hw =3D &twpll_153m6.hw }, + { .hw =3D &twpll_192m.hw }, + { .hw =3D &twpll_256m.hw }, + { .hw =3D &twpll_384m.hw }, +}; + +static SPRD_MUX_CLK_DATA(clk_gsp, "gsp-clk", gsp_parents, 0x9c, + 0, 2, SC9832E_MUX_FLAG); + +static const struct clk_parent_data dispc0_parents[] =3D { + { .hw =3D &twpll_153m6.hw }, + { .hw =3D &twpll_192m.hw }, + { .hw =3D &twpll_256m.hw }, + { .hw =3D &twpll_384m.hw }, +}; + +static SPRD_MUX_CLK_DATA(clk_dispc0, "dispc0-clk", dispc0_parents, 0xa0, + 0, 2, SC9832E_MUX_FLAG); + +static const struct clk_parent_data dispc0_dpi_parents[] =3D { + { .hw =3D &twpll_96m.hw }, + { .hw =3D &twpll_128m.hw }, + { .hw =3D &twpll_153m6.hw }, +}; + +static SPRD_COMP_CLK_DATA(clk_dispc0_dpi, "dispc0-dpi-clk", dispc0_dpi_par= ents, 0xa4, + 0, 2, 8, 4, 0); + +static SPRD_GATE_CLK_HW(dsi_rxesc, "dsi-rxesc", &ap_apb.common.hw, 0xa8, + BIT(16), 0, 0); +static SPRD_GATE_CLK_HW(dsi_lanebyte, "dsi-lanebyte", &ap_apb.common.hw, 0= xac, + BIT(16), 0, 0); + +static struct sprd_clk_common *sc9832e_ap_clks[] =3D { + &ap_apb.common, + &nandc_ecc.common, + &otg_ref_clk.common, + &otg_utmi.common, + &ap_uart1.common, + &ap_i2c0.common, + &ap_i2c1.common, + &ap_i2c2.common, + &ap_i2c3.common, + &ap_i2c4.common, + &ap_spi0.common, + &ap_spi2.common, + &ap_hs_spi.common, + &ap_iis0.common, + &ap_ce.common, + &nandc_2x.common, + &sdio0_2x.common, + &sdio1_2x.common, + &emmc_2x.common, + &clk_vsp.common, + &clk_gsp.common, + &clk_dispc0.common, + &clk_dispc0_dpi.common, + &dsi_rxesc.common, + &dsi_lanebyte.common, +}; + +static struct clk_hw_onecell_data sc9832e_ap_clk_hws =3D { + .hws =3D { + [CLK_AP_APB] =3D &ap_apb.common.hw, + [CLK_NANDC_ECC] =3D &nandc_ecc.common.hw, + [CLK_OTG_REF] =3D &otg_ref_clk.common.hw, + [CLK_OTG_UTMI] =3D &otg_utmi.common.hw, + [CLK_UART1] =3D &ap_uart1.common.hw, + [CLK_I2C0] =3D &ap_i2c0.common.hw, + [CLK_I2C1] =3D &ap_i2c1.common.hw, + [CLK_I2C2] =3D &ap_i2c2.common.hw, + [CLK_I2C3] =3D &ap_i2c3.common.hw, + [CLK_I2C4] =3D &ap_i2c4.common.hw, + [CLK_SPI0] =3D &ap_spi0.common.hw, + [CLK_SPI2] =3D &ap_spi2.common.hw, + [CLK_HS_SPI] =3D &ap_hs_spi.common.hw, + [CLK_IIS0] =3D &ap_iis0.common.hw, + [CLK_CE] =3D &ap_ce.common.hw, + [CLK_NANDC_2X] =3D &nandc_2x.common.hw, + [CLK_SDIO0_2X] =3D &sdio0_2x.common.hw, + [CLK_SDIO1_2X] =3D &sdio1_2x.common.hw, + [CLK_EMMC_2X] =3D &emmc_2x.common.hw, + [CLK_VSP] =3D &clk_vsp.common.hw, + [CLK_GSP] =3D &clk_gsp.common.hw, + [CLK_DISPC0] =3D &clk_dispc0.common.hw, + [CLK_DISPC0_DPI] =3D &clk_dispc0_dpi.common.hw, + [CLK_DSI_RXESC] =3D &dsi_rxesc.common.hw, + [CLK_DSI_LANEBYTE] =3D &dsi_lanebyte.common.hw, + }, + .num =3D CLK_AP_CLK_NUM, +}; + +static const struct sprd_clk_desc sc9832e_ap_clk_desc =3D { + .clk_clks =3D sc9832e_ap_clks, + .num_clk_clks =3D ARRAY_SIZE(sc9832e_ap_clks), + .hw_clks =3D &sc9832e_ap_clk_hws, +}; + +static const struct clk_parent_data aon_apb_parents[] =3D { + { .fw_name =3D "ext-26m" }, + { .hw =3D &twpll_76m8.hw }, + { .hw =3D &twpll_96m.hw }, + { .hw =3D &twpll_128m.hw }, +}; + +static SPRD_COMP_CLK_DATA(aon_apb, "aon-apb", aon_apb_parents, 0x220, + 0, 2, 8, 2, 0); + +static const struct clk_parent_data adi_parents[] =3D { + { .fw_name =3D "ext-26m" }, + { .hw =3D &twpll_38m4.hw }, + { .hw =3D &twpll_51m2.hw }, +}; + +static SPRD_MUX_CLK_DATA(adi_clk, "adi-clk", adi_parents, 0x224, + 0, 2, SC9832E_MUX_FLAG); + +static const struct clk_parent_data aux_parents[] =3D { + { .fw_name =3D "ext-32k" }, + { .hw =3D &rpll_26m.hw }, + { .fw_name =3D "ext-26m" }, +}; + +static SPRD_COMP_CLK_DATA(aux0_clk, "aux0-clk", aux_parents, 0x088, + 0, 2, 16, 4, 0); +static SPRD_COMP_CLK_DATA(aux1_clk, "aux1-clk", aux_parents, 0x088, + 4, 2, 20, 4, 0); + +static const struct clk_parent_data pwm_parents[] =3D { + { .fw_name =3D "ext-32k" }, + { .fw_name =3D "ext-26m" }, + { .hw =3D &rpll_26m.hw }, + { .hw =3D &twpll_48m.hw }, +}; + +static SPRD_MUX_CLK_DATA(pwm0_clk, "pwm0-clk", pwm_parents, 0x238, + 0, 2, SC9832E_MUX_FLAG); +static SPRD_MUX_CLK_DATA(pwm1_clk, "pwm1-clk", pwm_parents, 0x23c, + 0, 2, SC9832E_MUX_FLAG); +static SPRD_MUX_CLK_DATA(pwm2_clk, "pwm2-clk", pwm_parents, 0x240, + 0, 2, SC9832E_MUX_FLAG); +static SPRD_MUX_CLK_DATA(pwm3_clk, "pwm3-clk", pwm_parents, 0x244, + 0, 2, SC9832E_MUX_FLAG); + +static const struct clk_parent_data thm_parents[] =3D { + { .fw_name =3D "ext-32k" }, + { .fw_name =3D "ext-250k" }, +}; + +static SPRD_MUX_CLK_DATA(thm0_clk, "thm0-clk", thm_parents, 0x258, + 0, 1, SC9832E_MUX_FLAG); +static SPRD_MUX_CLK_DATA(thm1_clk, "thm1-clk", thm_parents, 0x25c, + 0, 1, SC9832E_MUX_FLAG); + +static const struct clk_parent_data audif_parents[] =3D { + { .fw_name =3D "ext-26m" }, + { .hw =3D &twpll_38m4.hw }, + { .hw =3D &twpll_51m2.hw }, +}; + +static SPRD_MUX_CLK_DATA(audif_clk, "audif-clk", audif_parents, 0x264, + 0, 2, SC9832E_MUX_FLAG); + +static SPRD_GATE_CLK_HW(aud_iis_da0, "aud-iis-da0", &ap_apb.common.hw, 0x2= 6c, + BIT(16), 0, 0); +static SPRD_GATE_CLK_HW(aud_iis_ad0, "aud-iis-ad0", &ap_apb.common.hw, 0x2= 70, + BIT(16), 0, 0); + +static const struct clk_parent_data ca53_dap_parents[] =3D { + { .fw_name =3D "ext-26m" }, + { .hw =3D &twpll_76m8.hw }, + { .hw =3D &twpll_128m.hw }, + { .hw =3D &twpll_153m6.hw }, +}; + +static SPRD_MUX_CLK_DATA(ca53_dap_clk, "ca53-dap-clk", ca53_dap_parents, 0= x274, + 0, 2, SC9832E_MUX_FLAG); + +static SPRD_GATE_CLK_HW(ca53_dmtck, "ca53-dmtck", &ap_apb.common.hw, 0x278, + BIT(16), 0, 0); + +static const struct clk_parent_data ca53_ts_parents[] =3D { + { .fw_name =3D "ext-32k" }, + { .fw_name =3D "ext-26m" }, + { .hw =3D &twpll_128m.hw }, + { .hw =3D &twpll_153m6.hw }, +}; + +static SPRD_MUX_CLK_DATA(ca53_ts_clk, "ca53-ts-clk", ca53_ts_parents, 0x27= c, + 0, 2, SC9832E_MUX_FLAG); + +static SPRD_GATE_CLK_HW(djtag_tck, "djtag-tck", &ap_apb.common.hw, 0x280, + BIT(16), 0, 0); + +static const struct clk_parent_data emc_ref_parents[] =3D { + { .fw_name =3D "ext-6m5" }, + { .fw_name =3D "ext-13m" }, + { .fw_name =3D "ext-26m" }, +}; + +static SPRD_MUX_CLK_DATA(emc_ref_clk, "emc-ref-clk", emc_ref_parents, 0x28= c, + 0, 2, SC9832E_MUX_FLAG); + +static const struct clk_parent_data cssys_parents[] =3D { + { .fw_name =3D "ext-26m" }, + { .hw =3D &twpll_96m.hw }, + { .hw =3D &twpll_128m.hw }, + { .hw =3D &twpll_153m6.hw }, + { .hw =3D &twpll_256m.hw }, +}; + +static SPRD_COMP_CLK_DATA(cssys_clk, "cssys-clk", cssys_parents, 0x290, + 0, 3, 8, 2, 0); + +static const struct clk_parent_data tmr_parents[] =3D { + { .fw_name =3D "ext-32k" }, + { .fw_name =3D "ext-4m3" }, +}; + +static SPRD_MUX_CLK_DATA(tmr_clk, "tmr-clk", tmr_parents, 0x298, + 0, 1, SC9832E_MUX_FLAG); + +static SPRD_GATE_CLK_HW(dsi_test, "dsi-test", &ap_apb.common.hw, 0x2a0, + BIT(16), 0, 0); + +static const struct clk_parent_data sdphy_apb_parents[] =3D { + { .fw_name =3D "ext-26m" }, + { .hw =3D &twpll_48m.hw }, +}; + +static SPRD_MUX_CLK_DATA(sdphy_apb_clk, "sdphy-apb-clk", sdphy_apb_parents= , 0x2b8, + 0, 1, SC9832E_MUX_FLAG); + +static const struct clk_parent_data aio_apb_parents[] =3D { + { .fw_name =3D "ext-26m" }, + { .hw =3D &twpll_48m.hw }, +}; + +static SPRD_COMP_CLK_DATA(aio_apb_clk, "aio-apb-clk", aio_apb_parents, 0x2= c4, + 0, 1, 8, 2, 0); + +static SPRD_GATE_CLK_HW(dtck_hw, "dtck-hw", &ap_apb.common.hw, 0x2c8, + BIT(16), 0, 0); + +static const struct clk_parent_data ap_mm_parents[] =3D { + { .fw_name =3D "ext-26m" }, + { .hw =3D &twpll_96m.hw }, + { .hw =3D &twpll_128m.hw }, +}; + +static SPRD_COMP_CLK_DATA(ap_mm_clk, "ap-mm-clk", ap_mm_parents, 0x2cc, + 0, 2, 8, 2, 0); + +static const struct clk_parent_data ap_axi_parents[] =3D { + { .fw_name =3D "ext-26m" }, + { .hw =3D &twpll_76m8.hw }, + { .hw =3D &twpll_128m.hw }, + { .hw =3D &twpll_256m.hw }, +}; + +static SPRD_MUX_CLK_DATA(ap_axi_clk, "ap-axi-clk", ap_axi_parents, 0x2d0, + 0, 2, SC9832E_MUX_FLAG); + +static const struct clk_parent_data nic_gpu_parents[] =3D { + { .hw =3D &twpll_256m.hw }, + { .hw =3D &twpll_307m2.hw }, + { .hw =3D &twpll_384m.hw }, + { .hw =3D &twpll_512m.hw }, + { .hw =3D &gpll.common.hw }, +}; + +static SPRD_COMP_CLK_DATA(nic_gpu_clk, "nic-gpu-clk", nic_gpu_parents, 0x2= d8, + 0, 3, 8, 3, 0); + +static const struct clk_parent_data mm_isp_parents[] =3D { + { .hw =3D &twpll_128m.hw }, + { .hw =3D &twpll_256m.hw }, + { .hw =3D &twpll_307m2.hw }, + { .hw =3D &twpll_384m.hw }, + { .hw =3D &isppll_468m.hw }, +}; + +static SPRD_MUX_CLK_DATA(mm_isp_clk, "mm-isp-clk", mm_isp_parents, 0x2dc, + 0, 3, SC9832E_MUX_FLAG); + +static struct sprd_clk_common *sc9832e_aon_clks[] =3D { + &aon_apb.common, + &adi_clk.common, + &aux0_clk.common, + &aux1_clk.common, + &pwm0_clk.common, + &pwm1_clk.common, + &pwm2_clk.common, + &pwm3_clk.common, + &thm0_clk.common, + &thm1_clk.common, + &audif_clk.common, + &aud_iis_da0.common, + &aud_iis_ad0.common, + &ca53_dap_clk.common, + &ca53_dmtck.common, + &ca53_ts_clk.common, + &djtag_tck.common, + &emc_ref_clk.common, + &cssys_clk.common, + &tmr_clk.common, + &dsi_test.common, + &sdphy_apb_clk.common, + &aio_apb_clk.common, + &dtck_hw.common, + &ap_mm_clk.common, + &ap_axi_clk.common, + &nic_gpu_clk.common, + &mm_isp_clk.common, +}; + +static struct clk_hw_onecell_data sc9832e_aon_clk_hws =3D { + .hws =3D { + [CLK_AON_APB] =3D &aon_apb.common.hw, + [CLK_ADI] =3D &adi_clk.common.hw, + [CLK_AUX0] =3D &aux0_clk.common.hw, + [CLK_AUX1] =3D &aux1_clk.common.hw, + [CLK_PWM0] =3D &pwm0_clk.common.hw, + [CLK_PWM1] =3D &pwm1_clk.common.hw, + [CLK_PWM2] =3D &pwm2_clk.common.hw, + [CLK_PWM3] =3D &pwm3_clk.common.hw, + [CLK_THM0] =3D &thm0_clk.common.hw, + [CLK_THM1] =3D &thm1_clk.common.hw, + [CLK_AUDIF] =3D &audif_clk.common.hw, + [CLK_AUD_IIS_DA0] =3D &aud_iis_da0.common.hw, + [CLK_AUD_IIS_AD0] =3D &aud_iis_ad0.common.hw, + [CLK_CA53_DAP] =3D &ca53_dap_clk.common.hw, + [CLK_CA53_DMTCK] =3D &ca53_dmtck.common.hw, + [CLK_CA53_TS] =3D &ca53_ts_clk.common.hw, + [CLK_DJTAG_TCK] =3D &djtag_tck.common.hw, + [CLK_EMC_REF] =3D &emc_ref_clk.common.hw, + [CLK_CSSYS] =3D &cssys_clk.common.hw, + [CLK_TMR] =3D &tmr_clk.common.hw, + [CLK_DSI_TEST] =3D &dsi_test.common.hw, + [CLK_SDPHY_APB] =3D &sdphy_apb_clk.common.hw, + [CLK_AIO_APB] =3D &aio_apb_clk.common.hw, + [CLK_DTCK_HW] =3D &dtck_hw.common.hw, + [CLK_AP_MM] =3D &ap_mm_clk.common.hw, + [CLK_AP_AXI] =3D &ap_axi_clk.common.hw, + [CLK_NIC_GPU] =3D &nic_gpu_clk.common.hw, + [CLK_MM_ISP] =3D &mm_isp_clk.common.hw, + }, + .num =3D CLK_AON_CLK_NUM, +}; + +static const struct sprd_clk_desc sc9832e_aon_clk_desc =3D { + .clk_clks =3D sc9832e_aon_clks, + .num_clk_clks =3D ARRAY_SIZE(sc9832e_aon_clks), + .hw_clks =3D &sc9832e_aon_clk_hws, +}; + +static SPRD_SC_GATE_CLK_FW_NAME(sim0_eb, "sim0-eb", "ext-26m", 0x0, 0x1000= , BIT(0), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(iis0_eb, "iis0-eb", "ext-26m", 0x0, 0x1000= , BIT(1), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(apb_reg_eb, "apb-reg-eb", "ext-26m", 0x0, = 0x1000, BIT(2), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(spi0_eb, "spi0-eb", "ext-26m", 0x0, 0x1000= , BIT(5), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(spi2_eb, "spi2-eb", "ext-26m", 0x0, 0x1000= , BIT(7), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(i2c0_eb, "i2c0-eb", "ext-26m", 0x0, 0x1000= , BIT(8), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(i2c1_eb, "i2c1-eb", "ext-26m", 0x0, 0x1000= , BIT(9), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(i2c2_eb, "i2c2-eb", "ext-26m", 0x0, 0x1000= , BIT(10), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(i2c3_eb, "i2c3-eb", "ext-26m", 0x0, 0x1000= , BIT(11), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(i2c4_eb, "i2c4-eb", "ext-26m", 0x0, 0x1000= , BIT(12), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(uart1_eb, "uart1-eb", "ap-apb", 0x0, 0x100= 0, BIT(14), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(sim0_32k_eb, "sim0-32k-eb", "ext-26m", 0x0= , 0x1000, BIT(18), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(intc0_eb, "intc0-eb", "ext-26m", 0x0, 0x10= 00, BIT(19), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(intc1_eb, "intc1-eb", "ext-26m", 0x0, 0x10= 00, BIT(20), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(intc2_eb, "intc2-eb", "ext-26m", 0x0, 0x10= 00, BIT(21), 0, 0); +static SPRD_SC_GATE_CLK_FW_NAME(intc3_eb, "intc3-eb", "ext-26m", 0x0, 0x10= 00, BIT(22), 0, 0); + +static struct sprd_clk_common *sc9832e_apapb_gate_clks[] =3D { + &sim0_eb.common, + &iis0_eb.common, + &apb_reg_eb.common, + &spi0_eb.common, + &spi2_eb.common, + &i2c0_eb.common, + &i2c1_eb.common, + &i2c2_eb.common, + &i2c3_eb.common, + &i2c4_eb.common, + &uart1_eb.common, + &sim0_32k_eb.common, + &intc0_eb.common, + &intc1_eb.common, + &intc2_eb.common, + &intc3_eb.common, +}; + +static struct clk_hw_onecell_data sc9832e_apapb_gate_hws =3D { + .hws =3D { + [CLK_SIM0_EB] =3D &sim0_eb.common.hw, + [CLK_IIS0_EB] =3D &iis0_eb.common.hw, + [CLK_APB_REG_EB] =3D &apb_reg_eb.common.hw, + [CLK_SPI0_EB] =3D &spi0_eb.common.hw, + [CLK_SPI2_EB] =3D &spi2_eb.common.hw, + [CLK_I2C0_EB] =3D &i2c0_eb.common.hw, + [CLK_I2C1_EB] =3D &i2c1_eb.common.hw, + [CLK_I2C2_EB] =3D &i2c2_eb.common.hw, + [CLK_I2C3_EB] =3D &i2c3_eb.common.hw, + [CLK_I2C4_EB] =3D &i2c4_eb.common.hw, + [CLK_UART1_EB] =3D &uart1_eb.common.hw, + [CLK_SIM0_32K_EB] =3D &sim0_32k_eb.common.hw, + [CLK_INTC0_EB] =3D &intc0_eb.common.hw, + [CLK_INTC1_EB] =3D &intc1_eb.common.hw, + [CLK_INTC2_EB] =3D &intc2_eb.common.hw, + [CLK_INTC3_EB] =3D &intc3_eb.common.hw, + }, + .num =3D CLK_AP_APB_GATE_NUM, +}; + +static const struct sprd_clk_desc sc9832e_apapb_gate_desc =3D { + .clk_clks =3D sc9832e_apapb_gate_clks, + .num_clk_clks =3D ARRAY_SIZE(sc9832e_apapb_gate_clks), + .hw_clks =3D &sc9832e_apapb_gate_hws, +}; + +static const struct of_device_id sprd_sc9832e_clk_ids[] =3D { + { .compatible =3D "sprd,sc9832e-glbregs", /* 0x402b0000 */ + .data =3D &sc9832e_pmu_gate_desc }, + { .compatible =3D "sprd,sc9832e-pll", /* 0x403c0000 */ + .data =3D &sc9832e_pll_desc }, + { .compatible =3D "sprd,sc9832e-mpll", /* 0x403f0000 */ + .data =3D &sc9832e_mpll_desc }, + { .compatible =3D "sprd,sc9832e-dpll", /* 0x403d0000 */ + .data =3D &sc9832e_dpll_desc }, + { .compatible =3D "sprd,sc9832e-rpll", /* 0x40410000 */ + .data =3D &sc9832e_rpll_desc }, + { .compatible =3D "sprd,sc9832e-apahb-gate", /* 0x20e00000 */ + .data =3D &sc9832e_apahb_gate_desc }, + { .compatible =3D "sprd,sc9832e-aonapb-gate", /* 0x402e0000 */ + .data =3D &sc9832e_aonapb_gate_desc }, + { .compatible =3D "sprd,sc9832e-ap-clk", /* 0x21500000 */ + .data =3D &sc9832e_ap_clk_desc }, + { .compatible =3D "sprd,sc9832e-aon-clk", /* 0x402d0000 */ + .data =3D &sc9832e_aon_clk_desc }, + { .compatible =3D "sprd,sc9832e-apapb-gate", /* 0x71300000 */ + .data =3D &sc9832e_apapb_gate_desc }, + { } +}; +MODULE_DEVICE_TABLE(of, sprd_sc9832e_clk_ids); + +static int sc9832e_clk_probe(struct platform_device *pdev) +{ + const struct of_device_id *match; + const struct sprd_clk_desc *desc; + int ret; + + match =3D of_match_node(sprd_sc9832e_clk_ids, pdev->dev.of_node); + if (!match) + return -ENODEV; + + desc =3D match->data; + + ret =3D sprd_clk_regmap_init(pdev, desc); + if (ret) + return ret; + + return sprd_clk_probe(&pdev->dev, desc->hw_clks); +} + +static struct platform_driver sprd_sc9832e_clk_driver =3D { + .probe =3D sc9832e_clk_probe, + .driver =3D { + .name =3D "sc9832e-clk", + .of_match_table =3D sprd_sc9832e_clk_ids, + }, +}; + +module_platform_driver(sprd_sc9832e_clk_driver); + +MODULE_DESCRIPTION("Spreadtrum SC9832E Clock Driver"); +MODULE_LICENSE("GPL"); + --=20 2.34.1