drivers/staging/sm750fb/ddk750_chip.c

Source file repositories/reference/linux-study-clean/drivers/staging/sm750fb/ddk750_chip.c

File Facts

System
Linux kernel
Corpus path
drivers/staging/sm750fb/ddk750_chip.c
Extension
.c
Size
9730 bytes
Lines
408
Domain
Driver Families
Bucket
drivers/staging
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

if (rev_id == SM750LE_REVISION_ID) {
			chip = SM750LE;
			pr_info("found sm750le\n");
		}
	} else {
		chip = SM_UNKNOWN;
	}
}

static unsigned int get_mxclk_freq(void)
{
	unsigned int pll_reg;
	unsigned int M, N, OD, POD;

	if (sm750_get_chip_type() == SM750LE)
		return MHz(130);

	pll_reg = peek32(MXCLK_PLL_CTRL);
	M = (pll_reg & PLL_CTRL_M_MASK) >> PLL_CTRL_M_SHIFT;
	N = (pll_reg & PLL_CTRL_N_MASK) >> PLL_CTRL_N_SHIFT;
	OD = (pll_reg & PLL_CTRL_OD_MASK) >> PLL_CTRL_OD_SHIFT;
	POD = (pll_reg & PLL_CTRL_POD_MASK) >> PLL_CTRL_POD_SHIFT;

	return DEFAULT_INPUT_CLOCK * M / N / BIT(OD) / BIT(POD);
}

/*
 * This function set up the main chip clock.
 *
 * Input: Frequency to be set.
 */
static void set_chip_clock(unsigned int frequency)
{
	struct pll_value pll;

	/* Cheok_0509: For SM750LE, the chip clock is fixed. Nothing to set. */
	if (sm750_get_chip_type() == SM750LE)
		return;

	if (frequency) {
		/*
		 * Set up PLL structure to hold the value to be set in clocks.
		 */
		pll.input_freq = DEFAULT_INPUT_CLOCK; /* Defined in CLOCK.H */
		pll.clock_type = MXCLK_PLL;

		/*
		 * Call sm750_calc_pll_value() to fill the other fields
		 * of the PLL structure. Sometimes, the chip cannot set
		 * up the exact clock required by the User.
		 * Return value of sm750_calc_pll_value gives the actual
		 * possible clock.
		 */
		sm750_calc_pll_value(frequency, &pll);

		/* Master Clock Control: MXCLK_PLL */
		poke32(MXCLK_PLL_CTRL, sm750_format_pll_reg(&pll));
	}
}

static void set_memory_clock(unsigned int frequency)
{
	unsigned int reg, divisor;

	/*
	 * Cheok_0509: For SM750LE, the memory clock is fixed.
	 * Nothing to set.
	 */
	if (sm750_get_chip_type() == SM750LE)
		return;

	if (frequency) {
		/*
		 * Set the frequency to the maximum frequency
		 * that the DDR Memory can take which is 336MHz.
		 */
		if (frequency > MHz(336))
			frequency = MHz(336);

		/* Calculate the divisor */
		divisor = DIV_ROUND_CLOSEST(get_mxclk_freq(), frequency);

		/* Set the corresponding divisor in the register. */
		reg = peek32(CURRENT_GATE) & ~CURRENT_GATE_M2XCLK_MASK;
		switch (divisor) {
		default:
		case 1:
			reg |= CURRENT_GATE_M2XCLK_DIV_1;
			break;
		case 2:

Annotation

Implementation Notes