arch/arm/mach-omap1/clock.c

Source file repositories/reference/linux-study-clean/arch/arm/mach-omap1/clock.c

File Facts

System
Linux kernel
Corpus path
arch/arm/mach-omap1/clock.c
Extension
.c
Size
21663 bytes
Lines
848
Domain
Architecture Layer
Bucket
arch/arm
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0-only
/*
 *  linux/arch/arm/mach-omap1/clock.c
 *
 *  Copyright (C) 2004 - 2005, 2009-2010 Nokia Corporation
 *  Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
 *
 *  Modified to use omap shared clock framework by
 *  Tony Lindgren <tony@atomide.com>
 */
#include <linux/kernel.h>
#include <linux/export.h>
#include <linux/list.h>
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/clkdev.h>
#include <linux/clk-provider.h>
#include <linux/soc/ti/omap1-io.h>
#include <linux/spinlock.h>

#include <asm/mach-types.h>

#include "hardware.h"
#include "soc.h"
#include "iomap.h"
#include "clock.h"
#include "opp.h"
#include "sram.h"

__u32 arm_idlect1_mask;
/* provide direct internal access (not via clk API) to some clocks */
struct omap1_clk *api_ck_p, *ck_dpll1_p, *ck_ref_p;

/* protect registeres shared among clk_enable/disable() and clk_set_rate() operations */
static DEFINE_SPINLOCK(arm_ckctl_lock);
static DEFINE_SPINLOCK(arm_idlect2_lock);
static DEFINE_SPINLOCK(mod_conf_ctrl_0_lock);
static DEFINE_SPINLOCK(mod_conf_ctrl_1_lock);
static DEFINE_SPINLOCK(swd_clk_div_ctrl_sel_lock);

/*
 * Omap1 specific clock functions
 */

unsigned long omap1_uart_recalc(struct omap1_clk *clk, unsigned long p_rate)
{
	unsigned int val = __raw_readl(clk->enable_reg);
	return val & 1 << clk->enable_bit ? 48000000 : 12000000;
}

unsigned long omap1_sossi_recalc(struct omap1_clk *clk, unsigned long p_rate)
{
	u32 div = omap_readl(MOD_CONF_CTRL_1);

	div = (div >> 17) & 0x7;
	div++;

	return p_rate / div;
}

static void omap1_clk_allow_idle(struct omap1_clk *clk)
{
	struct arm_idlect1_clk * iclk = (struct arm_idlect1_clk *)clk;

	if (!(clk->flags & CLOCK_IDLE_CONTROL))
		return;

	if (iclk->no_idle_count > 0 && !(--iclk->no_idle_count))
		arm_idlect1_mask |= 1 << iclk->idlect_shift;
}

static void omap1_clk_deny_idle(struct omap1_clk *clk)
{
	struct arm_idlect1_clk * iclk = (struct arm_idlect1_clk *)clk;

	if (!(clk->flags & CLOCK_IDLE_CONTROL))
		return;

	if (iclk->no_idle_count++ == 0)
		arm_idlect1_mask &= ~(1 << iclk->idlect_shift);
}

static __u16 verify_ckctl_value(__u16 newval)
{
	/* This function checks for following limitations set
	 * by the hardware (all conditions must be true):
	 * DSPMMU_CK == DSP_CK  or  DSPMMU_CK == DSP_CK/2
	 * ARM_CK >= TC_CK

Annotation

Implementation Notes