cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

clk-loongson1b.c (4026B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Copyright (c) 2012-2016 Zhang, Keguang <keguang.zhang@gmail.com>
      4 */
      5
      6#include <linux/clkdev.h>
      7#include <linux/clk-provider.h>
      8#include <linux/io.h>
      9#include <linux/err.h>
     10
     11#include <loongson1.h>
     12#include "clk.h"
     13
     14#define OSC		(33 * 1000000)
     15#define DIV_APB		2
     16
     17static DEFINE_SPINLOCK(_lock);
     18
     19static unsigned long ls1x_pll_recalc_rate(struct clk_hw *hw,
     20					  unsigned long parent_rate)
     21{
     22	u32 pll, rate;
     23
     24	pll = __raw_readl(LS1X_CLK_PLL_FREQ);
     25	rate = 12 + (pll & GENMASK(5, 0));
     26	rate *= OSC;
     27	rate >>= 1;
     28
     29	return rate;
     30}
     31
     32static const struct clk_ops ls1x_pll_clk_ops = {
     33	.recalc_rate = ls1x_pll_recalc_rate,
     34};
     35
     36static const char *const cpu_parents[] = { "cpu_clk_div", "osc_clk", };
     37static const char *const ahb_parents[] = { "ahb_clk_div", "osc_clk", };
     38static const char *const dc_parents[] = { "dc_clk_div", "osc_clk", };
     39
     40void __init ls1x_clk_init(void)
     41{
     42	struct clk_hw *hw;
     43
     44	hw = clk_hw_register_fixed_rate(NULL, "osc_clk", NULL, 0, OSC);
     45	clk_hw_register_clkdev(hw, "osc_clk", NULL);
     46
     47	/* clock derived from 33 MHz OSC clk */
     48	hw = clk_hw_register_pll(NULL, "pll_clk", "osc_clk",
     49				 &ls1x_pll_clk_ops, 0);
     50	clk_hw_register_clkdev(hw, "pll_clk", NULL);
     51
     52	/* clock derived from PLL clk */
     53	/*                                 _____
     54	 *         _______________________|     |
     55	 * OSC ___/                       | MUX |___ CPU CLK
     56	 *        \___ PLL ___ CPU DIV ___|     |
     57	 *                                |_____|
     58	 */
     59	hw = clk_hw_register_divider(NULL, "cpu_clk_div", "pll_clk",
     60				   CLK_GET_RATE_NOCACHE, LS1X_CLK_PLL_DIV,
     61				   DIV_CPU_SHIFT, DIV_CPU_WIDTH,
     62				   CLK_DIVIDER_ONE_BASED |
     63				   CLK_DIVIDER_ROUND_CLOSEST, &_lock);
     64	clk_hw_register_clkdev(hw, "cpu_clk_div", NULL);
     65	hw = clk_hw_register_mux(NULL, "cpu_clk", cpu_parents,
     66			       ARRAY_SIZE(cpu_parents),
     67			       CLK_SET_RATE_NO_REPARENT, LS1X_CLK_PLL_DIV,
     68			       BYPASS_CPU_SHIFT, BYPASS_CPU_WIDTH, 0, &_lock);
     69	clk_hw_register_clkdev(hw, "cpu_clk", NULL);
     70
     71	/*                                 _____
     72	 *         _______________________|     |
     73	 * OSC ___/                       | MUX |___ DC  CLK
     74	 *        \___ PLL ___ DC  DIV ___|     |
     75	 *                                |_____|
     76	 */
     77	hw = clk_hw_register_divider(NULL, "dc_clk_div", "pll_clk",
     78				   0, LS1X_CLK_PLL_DIV, DIV_DC_SHIFT,
     79				   DIV_DC_WIDTH, CLK_DIVIDER_ONE_BASED, &_lock);
     80	clk_hw_register_clkdev(hw, "dc_clk_div", NULL);
     81	hw = clk_hw_register_mux(NULL, "dc_clk", dc_parents,
     82			       ARRAY_SIZE(dc_parents),
     83			       CLK_SET_RATE_NO_REPARENT, LS1X_CLK_PLL_DIV,
     84			       BYPASS_DC_SHIFT, BYPASS_DC_WIDTH, 0, &_lock);
     85	clk_hw_register_clkdev(hw, "dc_clk", NULL);
     86
     87	/*                                 _____
     88	 *         _______________________|     |
     89	 * OSC ___/                       | MUX |___ DDR CLK
     90	 *        \___ PLL ___ DDR DIV ___|     |
     91	 *                                |_____|
     92	 */
     93	hw = clk_hw_register_divider(NULL, "ahb_clk_div", "pll_clk",
     94				   0, LS1X_CLK_PLL_DIV, DIV_DDR_SHIFT,
     95				   DIV_DDR_WIDTH, CLK_DIVIDER_ONE_BASED,
     96				   &_lock);
     97	clk_hw_register_clkdev(hw, "ahb_clk_div", NULL);
     98	hw = clk_hw_register_mux(NULL, "ahb_clk", ahb_parents,
     99			       ARRAY_SIZE(ahb_parents),
    100			       CLK_SET_RATE_NO_REPARENT, LS1X_CLK_PLL_DIV,
    101			       BYPASS_DDR_SHIFT, BYPASS_DDR_WIDTH, 0, &_lock);
    102	clk_hw_register_clkdev(hw, "ahb_clk", NULL);
    103	clk_hw_register_clkdev(hw, "ls1x-dma", NULL);
    104	clk_hw_register_clkdev(hw, "stmmaceth", NULL);
    105
    106	/* clock derived from AHB clk */
    107	/* APB clk is always half of the AHB clk */
    108	hw = clk_hw_register_fixed_factor(NULL, "apb_clk", "ahb_clk", 0, 1,
    109					DIV_APB);
    110	clk_hw_register_clkdev(hw, "apb_clk", NULL);
    111	clk_hw_register_clkdev(hw, "ls1x-ac97", NULL);
    112	clk_hw_register_clkdev(hw, "ls1x-i2c", NULL);
    113	clk_hw_register_clkdev(hw, "ls1x-nand", NULL);
    114	clk_hw_register_clkdev(hw, "ls1x-pwmtimer", NULL);
    115	clk_hw_register_clkdev(hw, "ls1x-spi", NULL);
    116	clk_hw_register_clkdev(hw, "ls1x-wdt", NULL);
    117	clk_hw_register_clkdev(hw, "serial8250", NULL);
    118}