drivers/clk/versatile/clk-icst.c

Source file repositories/reference/linux-study-clean/drivers/clk/versatile/clk-icst.c

File Facts

System
Linux kernel
Corpus path
drivers/clk/versatile/clk-icst.c
Extension
.c
Size
16020 bytes
Lines
587
Domain
Driver Families
Bucket
drivers/clk
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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

struct clk_icst {
	struct clk_hw hw;
	struct regmap *map;
	u32 vcoreg_off;
	u32 lockreg_off;
	struct icst_params *params;
	unsigned long rate;
	enum icst_control_type ctype;
};

#define to_icst(_hw) container_of(_hw, struct clk_icst, hw)

/**
 * vco_get() - get ICST VCO settings from a certain ICST
 * @icst: the ICST clock to get
 * @vco: the VCO struct to return the value in
 */
static int vco_get(struct clk_icst *icst, struct icst_vco *vco)
{
	u32 val;
	int ret;

	ret = regmap_read(icst->map, icst->vcoreg_off, &val);
	if (ret)
		return ret;

	/*
	 * The Integrator/AP core clock can only access the low eight
	 * bits of the v PLL divider. Bit 8 is tied low and always zero,
	 * r is hardwired to 22 and output divider s is hardwired to 1
	 * (divide by 2) according to the document
	 * "Integrator CM926EJ-S, CM946E-S, CM966E-S, CM1026EJ-S and
	 * CM1136JF-S User Guide" ARM DUI 0138E, page 3-13 thru 3-14.
	 */
	if (icst->ctype == ICST_INTEGRATOR_AP_CM) {
		vco->v = val & INTEGRATOR_AP_CM_BITS;
		vco->r = 22;
		vco->s = 1;
		return 0;
	}

	/*
	 * The Integrator/AP system clock on the base board can only
	 * access the low eight bits of the v PLL divider. Bit 8 is tied low
	 * and always zero, r is hardwired to 46, and the output divider is
	 * hardwired to 3 (divide by 4) according to the document
	 * "Integrator AP ASIC Development Motherboard" ARM DUI 0098B,
	 * page 3-16.
	 */
	if (icst->ctype == ICST_INTEGRATOR_AP_SYS) {
		vco->v = val & INTEGRATOR_AP_SYS_BITS;
		vco->r = 46;
		vco->s = 3;
		return 0;
	}

	/*
	 * The Integrator/AP PCI clock is using an odd pattern to create
	 * the child clock, basically a single bit called DIVX/Y is used
	 * to select between two different hardwired values: setting the
	 * bit to 0 yields v = 17, r = 22 and OD = 1, whereas setting the
	 * bit to 1 yields v = 14, r = 14 and OD = 1 giving the frequencies
	 * 33 or 25 MHz respectively.
	 */
	if (icst->ctype == ICST_INTEGRATOR_AP_PCI) {
		bool divxy = !!(val & INTEGRATOR_AP_PCI_25_33_MHZ);

		vco->v = divxy ? 17 : 14;
		vco->r = divxy ? 22 : 14;
		vco->s = 1;
		return 0;
	}

	/*
	 * The Integrator/CP core clock can access the low eight bits
	 * of the v PLL divider. Bit 8 is tied low and always zero,
	 * r is hardwired to 22 and the output divider s is accessible
	 * in bits 8 thru 10 according to the document
	 * "Integrator/CM940T, CM920T, CM740T, and CM720T User Guide"
	 * ARM DUI 0157A, page 3-20 thru 3-23 and 4-10.
	 */
	if (icst->ctype == ICST_INTEGRATOR_CP_CM_CORE) {
		vco->v = val & 0xFF;
		vco->r = 22;
		vco->s = (val >> 8) & 7;
		return 0;
	}

	if (icst->ctype == ICST_INTEGRATOR_CP_CM_MEM) {
		vco->v = (val >> 12) & 0xFF;

Annotation

Implementation Notes