uboot/drivers/clk/renesas/renesas-cpg-mssr.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0+ */
   2/*
   3 * Renesas RCar Gen3 CPG MSSR driver
   4 *
   5 * Copyright (C) 2017-2018 Marek Vasut <marek.vasut@gmail.com>
   6 *
   7 * Based on the following driver from Linux kernel:
   8 * r8a7796 Clock Pulse Generator / Module Standby and Software Reset
   9 *
  10 * Copyright (C) 2016 Glider bvba
  11 */
  12
  13#ifndef __DRIVERS_CLK_RENESAS_CPG_MSSR__
  14#define __DRIVERS_CLK_RENESAS_CPG_MSSR__
  15
  16#include <linux/bitops.h>
  17
  18enum clk_reg_layout {
  19        CLK_REG_LAYOUT_RCAR_GEN2_AND_GEN3 = 0,
  20        CLK_REG_LAYOUT_RCAR_V3U,
  21};
  22
  23struct cpg_mssr_info {
  24        const struct cpg_core_clk       *core_clk;
  25        unsigned int                    core_clk_size;
  26        enum clk_reg_layout             reg_layout;
  27        const struct mssr_mod_clk       *mod_clk;
  28        unsigned int                    mod_clk_size;
  29        const struct mstp_stop_table    *mstp_table;
  30        unsigned int                    mstp_table_size;
  31        const char                      *reset_node;
  32        unsigned int                    reset_modemr_offset;
  33        const char                      *extalr_node;
  34        const char                      *extal_usb_node;
  35        unsigned int                    mod_clk_base;
  36        unsigned int                    clk_extal_id;
  37        unsigned int                    clk_extalr_id;
  38        unsigned int                    clk_extal_usb_id;
  39        unsigned int                    pll0_div;
  40        const void                      *(*get_pll_config)(const u32 cpg_mode);
  41        const u16                       *status_regs;
  42        const u16                       *control_regs;
  43        const u16                       *reset_regs;
  44        const u16                       *reset_clear_regs;
  45};
  46
  47/*
  48 * Definitions of CPG Core Clocks
  49 *
  50 * These include:
  51 *   - Clock outputs exported to DT
  52 *   - External input clocks
  53 *   - Internal CPG clocks
  54 */
  55struct cpg_core_clk {
  56        /* Common */
  57        const char *name;
  58        unsigned int id;
  59        unsigned int type;
  60        /* Depending on type */
  61        unsigned int parent;    /* Core Clocks only */
  62        unsigned int div;
  63        unsigned int mult;
  64        unsigned int offset;
  65};
  66
  67enum clk_types {
  68        /* Generic */
  69        CLK_TYPE_IN,            /* External Clock Input */
  70        CLK_TYPE_FF,            /* Fixed Factor Clock */
  71        CLK_TYPE_DIV6P1,        /* DIV6 Clock with 1 parent clock */
  72        CLK_TYPE_DIV6_RO,       /* DIV6 Clock read only with extra divisor */
  73        CLK_TYPE_FR,            /* Fixed Rate Clock */
  74
  75        /* Custom definitions start here */
  76        CLK_TYPE_CUSTOM,
  77};
  78
  79#define DEF_TYPE(_name, _id, _type...)  \
  80        { .name = _name, .id = _id, .type = _type }
  81#define DEF_BASE(_name, _id, _type, _parent...) \
  82        DEF_TYPE(_name, _id, _type, .parent = _parent)
  83
  84#define DEF_INPUT(_name, _id) \
  85        DEF_TYPE(_name, _id, CLK_TYPE_IN)
  86#define DEF_FIXED(_name, _id, _parent, _div, _mult)     \
  87        DEF_BASE(_name, _id, CLK_TYPE_FF, _parent, .div = _div, .mult = _mult)
  88#define DEF_DIV6P1(_name, _id, _parent, _offset)        \
  89        DEF_BASE(_name, _id, CLK_TYPE_DIV6P1, _parent, .offset = _offset)
  90#define DEF_DIV6_RO(_name, _id, _parent, _offset, _div) \
  91        DEF_BASE(_name, _id, CLK_TYPE_DIV6_RO, _parent, .offset = _offset, .div = _div, .mult = 1)
  92#define DEF_RATE(_name, _id, _rate)     \
  93        DEF_TYPE(_name, _id, CLK_TYPE_FR, .mult = _rate)
  94
  95/*
  96 * Definitions of Module Clocks
  97 */
  98struct mssr_mod_clk {
  99        const char *name;
 100        unsigned int id;
 101        unsigned int parent;    /* Add MOD_CLK_BASE for Module Clocks */
 102};
 103
 104/* Convert from sparse base-100 to packed index space */
 105#define MOD_CLK_PACK(x) ((x) - ((x) / 100) * (100 - 32))
 106
 107#define MOD_CLK_ID(x)   (MOD_CLK_BASE + MOD_CLK_PACK(x))
 108
 109#define DEF_MOD(_name, _mod, _parent...)        \
 110        { .name = _name, .id = MOD_CLK_ID(_mod), .parent = _parent }
 111
 112struct mstp_stop_table {
 113        u32     sdis;
 114        u32     sen;
 115        u32     rdis;
 116        u32     ren;
 117};
 118
 119#define TSTR0           0x04
 120#define TSTR0_STR0      BIT(0)
 121
 122bool renesas_clk_is_mod(struct clk *clk);
 123int renesas_clk_get_mod(struct clk *clk, struct cpg_mssr_info *info,
 124                        const struct mssr_mod_clk **mssr);
 125int renesas_clk_get_core(struct clk *clk, struct cpg_mssr_info *info,
 126                         const struct cpg_core_clk **core);
 127int renesas_clk_get_parent(struct clk *clk, struct cpg_mssr_info *info,
 128                           struct clk *parent);
 129int renesas_clk_endisable(struct clk *clk, void __iomem *base,
 130                          struct cpg_mssr_info *info, bool enable);
 131int renesas_clk_remove(void __iomem *base, struct cpg_mssr_info *info);
 132
 133/*
 134 * Module Standby and Software Reset register offets.
 135 *
 136 * If the registers exist, these are valid for SH-Mobile, R-Mobile,
 137 * R-Car Gen2, R-Car Gen3, and RZ/G1.
 138 * These are NOT valid for R-Car Gen1 and RZ/A1!
 139 */
 140
 141/*
 142 * Module Stop Status Register offsets
 143 */
 144
 145static const u16 mstpsr[] = {
 146        0x030, 0x038, 0x040, 0x048, 0x04C, 0x03C, 0x1C0, 0x1C4,
 147        0x9A0, 0x9A4, 0x9A8, 0x9AC,
 148};
 149
 150static const u16 mstpsr_for_v3u[] = {
 151        0x2E00, 0x2E04, 0x2E08, 0x2E0C, 0x2E10, 0x2E14, 0x2E18, 0x2E1C,
 152        0x2E20, 0x2E24, 0x2E28, 0x2E2C, 0x2E30, 0x2E34, 0x2E38,
 153};
 154
 155/*
 156 * System Module Stop Control Register offsets
 157 */
 158
 159static const u16 smstpcr[] = {
 160        0x130, 0x134, 0x138, 0x13C, 0x140, 0x144, 0x148, 0x14C,
 161        0x990, 0x994, 0x998, 0x99C,
 162};
 163
 164static const u16 mstpcr_for_v3u[] = {
 165        0x2D00, 0x2D04, 0x2D08, 0x2D0C, 0x2D10, 0x2D14, 0x2D18, 0x2D1C,
 166        0x2D20, 0x2D24, 0x2D28, 0x2D2C, 0x2D30, 0x2D34, 0x2D38,
 167};
 168
 169/*
 170 * Software Reset Register offsets
 171 */
 172
 173static const u16 srcr[] = {
 174        0x0A0, 0x0A8, 0x0B0, 0x0B8, 0x0BC, 0x0C4, 0x1C8, 0x1CC,
 175        0x920, 0x924, 0x928, 0x92C,
 176};
 177
 178static const u16 srcr_for_v3u[] = {
 179        0x2C00, 0x2C04, 0x2C08, 0x2C0C, 0x2C10, 0x2C14, 0x2C18, 0x2C1C,
 180        0x2C20, 0x2C24, 0x2C28, 0x2C2C, 0x2C30, 0x2C34, 0x2C38,
 181};
 182
 183/* Realtime Module Stop Control Register offsets */
 184#define RMSTPCR(i)      ((i) < 8 ? smstpcr[i] - 0x20 : smstpcr[i] - 0x10)
 185
 186/* Modem Module Stop Control Register offsets (r8a73a4) */
 187#define MMSTPCR(i)      (smstpcr[i] + 0x20)
 188
 189/* Software Reset Clearing Register offsets */
 190
 191static const u16 srstclr[] = {
 192        0x940, 0x944, 0x948, 0x94C, 0x950, 0x954, 0x958, 0x95C,
 193        0x960, 0x964, 0x968, 0x96C,
 194};
 195
 196static const u16 srstclr_for_v3u[] = {
 197        0x2C80, 0x2C84, 0x2C88, 0x2C8C, 0x2C90, 0x2C94, 0x2C98, 0x2C9C,
 198        0x2CA0, 0x2CA4, 0x2CA8, 0x2CAC, 0x2CB0, 0x2CB4, 0x2CB8,
 199};
 200
 201#endif /* __DRIVERS_CLK_RENESAS_CPG_MSSR__ */
 202