drivers/clk/sunxi-ng/ccu-sun20i-d1.c

Source file repositories/reference/linux-study-clean/drivers/clk/sunxi-ng/ccu-sun20i-d1.c

File Facts

System
Linux kernel
Corpus path
drivers/clk/sunxi-ng/ccu-sun20i-d1.c
Extension
.c
Size
44536 bytes
Lines
1418
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
/*
 * Copyright (c) 2020 huangzhenwei@allwinnertech.com
 * Copyright (C) 2021 Samuel Holland <samuel@sholland.org>
 */

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

#include "../clk.h"

#include "ccu_common.h"
#include "ccu_reset.h"

#include "ccu_div.h"
#include "ccu_gate.h"
#include "ccu_mp.h"
#include "ccu_mult.h"
#include "ccu_nk.h"
#include "ccu_nkm.h"
#include "ccu_nkmp.h"
#include "ccu_nm.h"

#include "ccu-sun20i-d1.h"

static const struct clk_parent_data osc24M[] = {
	{ .fw_name = "hosc" }
};

/*
 * For the CPU PLL, the output divider is described as "only for testing"
 * in the user manual. So it's not modelled and forced to 0.
 */
#define SUN20I_D1_PLL_CPUX_REG		0x000
static struct ccu_mult pll_cpux_clk = {
	.enable		= BIT(27),
	.lock		= BIT(28),
	.mult		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
	.common		= {
		.reg		= 0x000,
		.hw.init	= CLK_HW_INIT_PARENTS_DATA("pll-cpux", osc24M,
							   &ccu_mult_ops,
							   CLK_SET_RATE_UNGATE),
	},
};

/* Some PLLs are input * N / div1 / P. Model them as NKMP with no K */
#define SUN20I_D1_PLL_DDR0_REG		0x010
static struct ccu_nkmp pll_ddr0_clk = {
	.enable		= BIT(27),
	.lock		= BIT(28),
	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
	.m		= _SUNXI_CCU_DIV(1, 1), /* input divider */
	.p		= _SUNXI_CCU_DIV(0, 1), /* output divider */
	.common		= {
		.reg		= 0x010,
		.hw.init	= CLK_HW_INIT_PARENTS_DATA("pll-ddr0", osc24M,
							   &ccu_nkmp_ops,
							   CLK_SET_RATE_UNGATE),
	},
};

#define SUN20I_D1_PLL_PERIPH0_REG	0x020
static struct ccu_nm pll_periph0_4x_clk = {
	.enable		= BIT(27),
	.lock		= BIT(28),
	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
	.m		= _SUNXI_CCU_DIV(1, 1), /* input divider */
	.common		= {
		.reg		= 0x020,
		.hw.init	= CLK_HW_INIT_PARENTS_DATA("pll-periph0-4x", osc24M,
							   &ccu_nm_ops,
							   CLK_SET_RATE_UNGATE),
	},
};

static const struct clk_hw *pll_periph0_4x_hws[] = {
	&pll_periph0_4x_clk.common.hw
};
static SUNXI_CCU_M_HWS(pll_periph0_2x_clk, "pll-periph0-2x",
		       pll_periph0_4x_hws, 0x020, 16, 3, 0);
static SUNXI_CCU_M_HWS(pll_periph0_800M_clk, "pll-periph0-800M",
		       pll_periph0_4x_hws, 0x020, 20, 3, 0);

static const struct clk_hw *pll_periph0_2x_hws[] = {
	&pll_periph0_2x_clk.common.hw
};
static CLK_FIXED_FACTOR_HWS(pll_periph0_clk, "pll-periph0",

Annotation

Implementation Notes