drivers/clk/ingenic/jz4770-cgu.c

Source file repositories/reference/linux-study-clean/drivers/clk/ingenic/jz4770-cgu.c

File Facts

System
Linux kernel
Corpus path
drivers/clk/ingenic/jz4770-cgu.c
Extension
.c
Size
11975 bytes
Lines
464
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
/*
 * JZ4770 SoC CGU driver
 * Copyright 2018, Paul Cercueil <paul@crapouillou.net>
 */

#include <linux/bitops.h>
#include <linux/clk-provider.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/of.h>

#include <dt-bindings/clock/ingenic,jz4770-cgu.h>

#include "cgu.h"
#include "pm.h"

/*
 * CPM registers offset address definition
 */
#define CGU_REG_CPCCR		0x00
#define CGU_REG_LCR		0x04
#define CGU_REG_CPPCR0		0x10
#define CGU_REG_CLKGR0		0x20
#define CGU_REG_OPCR		0x24
#define CGU_REG_CLKGR1		0x28
#define CGU_REG_CPPCR1		0x30
#define CGU_REG_USBPCR1		0x48
#define CGU_REG_USBCDR		0x50
#define CGU_REG_I2SCDR		0x60
#define CGU_REG_LPCDR		0x64
#define CGU_REG_MSC0CDR		0x68
#define CGU_REG_UHCCDR		0x6c
#define CGU_REG_SSICDR		0x74
#define CGU_REG_CIMCDR		0x7c
#define CGU_REG_GPSCDR		0x80
#define CGU_REG_PCMCDR		0x84
#define CGU_REG_GPUCDR		0x88
#define CGU_REG_MSC1CDR		0xA4
#define CGU_REG_MSC2CDR		0xA8
#define CGU_REG_BCHCDR		0xAC

/* bits within the OPCR register */
#define OPCR_SPENDH		BIT(5)		/* UHC PHY suspend */

/* bits within the USBPCR1 register */
#define USBPCR1_UHC_POWER	BIT(5)		/* UHC PHY power down */

static struct ingenic_cgu *cgu;

static int jz4770_uhc_phy_enable(struct clk_hw *hw)
{
	void __iomem *reg_opcr		= cgu->base + CGU_REG_OPCR;
	void __iomem *reg_usbpcr1	= cgu->base + CGU_REG_USBPCR1;

	writel(readl(reg_opcr) & ~OPCR_SPENDH, reg_opcr);
	writel(readl(reg_usbpcr1) | USBPCR1_UHC_POWER, reg_usbpcr1);
	return 0;
}

static void jz4770_uhc_phy_disable(struct clk_hw *hw)
{
	void __iomem *reg_opcr		= cgu->base + CGU_REG_OPCR;
	void __iomem *reg_usbpcr1	= cgu->base + CGU_REG_USBPCR1;

	writel(readl(reg_usbpcr1) & ~USBPCR1_UHC_POWER, reg_usbpcr1);
	writel(readl(reg_opcr) | OPCR_SPENDH, reg_opcr);
}

static int jz4770_uhc_phy_is_enabled(struct clk_hw *hw)
{
	void __iomem *reg_opcr		= cgu->base + CGU_REG_OPCR;
	void __iomem *reg_usbpcr1	= cgu->base + CGU_REG_USBPCR1;

	return !(readl(reg_opcr) & OPCR_SPENDH) &&
		(readl(reg_usbpcr1) & USBPCR1_UHC_POWER);
}

static const struct clk_ops jz4770_uhc_phy_ops = {
	.enable = jz4770_uhc_phy_enable,
	.disable = jz4770_uhc_phy_disable,
	.is_enabled = jz4770_uhc_phy_is_enabled,
};

static const s8 pll_od_encoding[8] = {
	0x0, 0x1, -1, 0x2, -1, -1, -1, 0x3,
};

static const u8 jz4770_cgu_cpccr_div_table[] = {
	1, 2, 3, 4, 6, 8, 12,

Annotation

Implementation Notes