root/drivers/clk/renesas/clk-emev2.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. emev2_smu_write
  2. emev2_smu_init
  3. emev2_smu_clkdiv_init
  4. emev2_smu_gclk_init

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * EMMA Mobile EV2 common clock framework support
   4  *
   5  * Copyright (C) 2013 Takashi Yoshii <takashi.yoshii.ze@renesas.com>
   6  * Copyright (C) 2012 Magnus Damm
   7  */
   8 #include <linux/clk-provider.h>
   9 #include <linux/clkdev.h>
  10 #include <linux/io.h>
  11 #include <linux/of.h>
  12 #include <linux/of_address.h>
  13 
  14 /* EMEV2 SMU registers */
  15 #define USIAU0_RSTCTRL 0x094
  16 #define USIBU1_RSTCTRL 0x0ac
  17 #define USIBU2_RSTCTRL 0x0b0
  18 #define USIBU3_RSTCTRL 0x0b4
  19 #define IIC0_RSTCTRL 0x0dc
  20 #define IIC1_RSTCTRL 0x0e0
  21 #define STI_RSTCTRL 0x124
  22 #define STI_CLKSEL 0x688
  23 
  24 static DEFINE_SPINLOCK(lock);
  25 
  26 /* not pretty, but hey */
  27 static void __iomem *smu_base;
  28 
  29 static void __init emev2_smu_write(unsigned long value, int offs)
  30 {
  31         BUG_ON(!smu_base || (offs >= PAGE_SIZE));
  32         writel_relaxed(value, smu_base + offs);
  33 }
  34 
  35 static const struct of_device_id smu_id[] __initconst = {
  36         { .compatible = "renesas,emev2-smu", },
  37         {},
  38 };
  39 
  40 static void __init emev2_smu_init(void)
  41 {
  42         struct device_node *np;
  43 
  44         np = of_find_matching_node(NULL, smu_id);
  45         BUG_ON(!np);
  46         smu_base = of_iomap(np, 0);
  47         BUG_ON(!smu_base);
  48         of_node_put(np);
  49 
  50         /* setup STI timer to run on 32.768 kHz and deassert reset */
  51         emev2_smu_write(0, STI_CLKSEL);
  52         emev2_smu_write(1, STI_RSTCTRL);
  53 
  54         /* deassert reset for UART0->UART3 */
  55         emev2_smu_write(2, USIAU0_RSTCTRL);
  56         emev2_smu_write(2, USIBU1_RSTCTRL);
  57         emev2_smu_write(2, USIBU2_RSTCTRL);
  58         emev2_smu_write(2, USIBU3_RSTCTRL);
  59 
  60         /* deassert reset for IIC0->IIC1 */
  61         emev2_smu_write(1, IIC0_RSTCTRL);
  62         emev2_smu_write(1, IIC1_RSTCTRL);
  63 }
  64 
  65 static void __init emev2_smu_clkdiv_init(struct device_node *np)
  66 {
  67         u32 reg[2];
  68         struct clk *clk;
  69         const char *parent_name = of_clk_get_parent_name(np, 0);
  70         if (WARN_ON(of_property_read_u32_array(np, "reg", reg, 2)))
  71                 return;
  72         if (!smu_base)
  73                 emev2_smu_init();
  74         clk = clk_register_divider(NULL, np->name, parent_name, 0,
  75                                    smu_base + reg[0], reg[1], 8, 0, &lock);
  76         of_clk_add_provider(np, of_clk_src_simple_get, clk);
  77         clk_register_clkdev(clk, np->full_name, NULL);
  78         pr_debug("## %s %pOFn %p\n", __func__, np, clk);
  79 }
  80 CLK_OF_DECLARE(emev2_smu_clkdiv, "renesas,emev2-smu-clkdiv",
  81                 emev2_smu_clkdiv_init);
  82 
  83 static void __init emev2_smu_gclk_init(struct device_node *np)
  84 {
  85         u32 reg[2];
  86         struct clk *clk;
  87         const char *parent_name = of_clk_get_parent_name(np, 0);
  88         if (WARN_ON(of_property_read_u32_array(np, "reg", reg, 2)))
  89                 return;
  90         if (!smu_base)
  91                 emev2_smu_init();
  92         clk = clk_register_gate(NULL, np->name, parent_name, 0,
  93                                 smu_base + reg[0], reg[1], 0, &lock);
  94         of_clk_add_provider(np, of_clk_src_simple_get, clk);
  95         clk_register_clkdev(clk, np->full_name, NULL);
  96         pr_debug("## %s %pOFn %p\n", __func__, np, clk);
  97 }
  98 CLK_OF_DECLARE(emev2_smu_gclk, "renesas,emev2-smu-gclk", emev2_smu_gclk_init);

/* [<][>][^][v][top][bottom][index][help] */