drivers/clk/sprd/sc9863a-clk.c

Source file repositories/reference/linux-study-clean/drivers/clk/sprd/sc9863a-clk.c

File Facts

System
Linux kernel
Corpus path
drivers/clk/sprd/sc9863a-clk.c
Extension
.c
Size
65403 bytes
Lines
1806
Domain
Driver Families
Bucket
drivers/clk
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Unisoc SC9863A clock driver
 *
 * Copyright (C) 2019 Unisoc, Inc.
 * Author: Chunyan Zhang <chunyan.zhang@unisoc.com>
 */

#include <linux/clk-provider.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>

#include <dt-bindings/clock/sprd,sc9863a-clk.h>

#include "common.h"
#include "composite.h"
#include "div.h"
#include "gate.h"
#include "mux.h"
#include "pll.h"

/* mpll*_gate clocks control cpu cores, they were enabled by default */
static SPRD_PLL_SC_GATE_CLK_FW_NAME(mpll0_gate, "mpll0-gate", "ext-26m", 0x94,
				    0x1000, BIT(0), CLK_IGNORE_UNUSED, 0, 240);
static SPRD_PLL_SC_GATE_CLK_FW_NAME(dpll0_gate, "dpll0-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 SPRD_PLL_SC_GATE_CLK_FW_NAME(dpll1_gate, "dpll1-gate", "ext-26m", 0x1dc,
				    0x1000, BIT(0), 0, 0, 240);
static SPRD_PLL_SC_GATE_CLK_FW_NAME(mpll1_gate, "mpll1-gate", "ext-26m", 0x1e0,
				    0x1000, BIT(0), CLK_IGNORE_UNUSED, 0, 240);
static SPRD_PLL_SC_GATE_CLK_FW_NAME(mpll2_gate, "mpll2-gate", "ext-26m", 0x1e4,
				    0x1000, BIT(0), CLK_IGNORE_UNUSED, 0, 240);
static SPRD_PLL_SC_GATE_CLK_FW_NAME(isppll_gate, "isppll-gate", "ext-26m",
				    0x1e8, 0x1000, BIT(0), 0, 0, 240);

static struct sprd_clk_common *sc9863a_pmu_gate_clks[] = {
	/* address base is 0x402b0000 */
	&mpll0_gate.common,
	&dpll0_gate.common,
	&lpll_gate.common,
	&gpll_gate.common,
	&dpll1_gate.common,
	&mpll1_gate.common,
	&mpll2_gate.common,
	&isppll_gate.common,
};

static struct clk_hw_onecell_data sc9863a_pmu_gate_hws = {
	.hws	= {
		[CLK_MPLL0_GATE]	= &mpll0_gate.common.hw,
		[CLK_DPLL0_GATE]	= &dpll0_gate.common.hw,
		[CLK_LPLL_GATE]		= &lpll_gate.common.hw,
		[CLK_GPLL_GATE]		= &gpll_gate.common.hw,
		[CLK_DPLL1_GATE]	= &dpll1_gate.common.hw,
		[CLK_MPLL1_GATE]	= &mpll1_gate.common.hw,
		[CLK_MPLL2_GATE]	= &mpll2_gate.common.hw,
		[CLK_ISPPLL_GATE]	= &isppll_gate.common.hw,
	},
	.num	= CLK_PMU_APB_NUM,
};

static const struct sprd_clk_desc sc9863a_pmu_gate_desc = {
	.clk_clks	= sc9863a_pmu_gate_clks,
	.num_clk_clks	= ARRAY_SIZE(sc9863a_pmu_gate_clks),
	.hw_clks        = &sc9863a_pmu_gate_hws,
};

static const u64 itable[5] = {4, 1000000000, 1200000000,
			      1400000000, 1600000000};

static const struct clk_bit_field f_twpll[PLL_FACT_MAX] = {
	{ .shift = 95,	.width = 1 },	/* lock_done	*/
	{ .shift = 0,	.width = 1 },	/* div_s	*/
	{ .shift = 1,	.width = 1 },	/* mod_en	*/
	{ .shift = 2,	.width = 1 },	/* sdm_en	*/
	{ .shift = 0,	.width = 0 },	/* refin	*/
	{ .shift = 3,	.width = 3 },	/* ibias	*/
	{ .shift = 8,	.width = 11 },	/* n		*/
	{ .shift = 55,	.width = 7 },	/* nint		*/
	{ .shift = 32,	.width = 23},	/* kint		*/
	{ .shift = 0,	.width = 0 },	/* prediv	*/
	{ .shift = 0,	.width = 0 },	/* postdiv	*/
};

Annotation

Implementation Notes