// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2016 Rockchip Electronics Co. Ltd.
* Author: Elaine <zhangqing@rock-chips.com>
*/
#include <linux/clk-provider.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/syscore_ops.h>
#include <dt-bindings/clock/rk3328-cru.h>
#include "clk.h"
#define RK3328_GRF_SOC_CON4 0x410
#define RK3328_GRF_SOC_STATUS0 0x480
#define RK3328_GRF_MAC_CON1 0x904
#define RK3328_GRF_MAC_CON2 0x908
enum rk3328_plls {
apll, dpll, cpll, gpll, npll,
};
static struct rockchip_pll_rate_table rk3328_pll_rates[] = {
/* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0),
RK3036_PLL_RATE(1584000000, 1, 66, 1, 1, 1, 0),
RK3036_PLL_RATE(1560000000, 1, 65, 1, 1, 1, 0),
RK3036_PLL_RATE(1536000000, 1, 64, 1, 1, 1, 0),
RK3036_PLL_RATE(1512000000, 1, 63, 1, 1, 1, 0),
RK3036_PLL_RATE(1488000000, 1, 62, 1, 1, 1, 0),
RK3036_PLL_RATE(1464000000, 1, 61, 1, 1, 1, 0),
RK3036_PLL_RATE(1440000000, 1, 60, 1, 1, 1, 0),
RK3036_PLL_RATE(1416000000, 1, 59, 1, 1, 1, 0),
RK3036_PLL_RATE(1392000000, 1, 58, 1, 1, 1, 0),
RK3036_PLL_RATE(1368000000, 1, 57, 1, 1, 1, 0),
RK3036_PLL_RATE(1344000000, 1, 56, 1, 1, 1, 0),
RK3036_PLL_RATE(1320000000, 1, 55, 1, 1, 1, 0),
RK3036_PLL_RATE(1296000000, 1, 54, 1, 1, 1, 0),
RK3036_PLL_RATE(1272000000, 1, 53, 1, 1, 1, 0),
RK3036_PLL_RATE(1248000000, 1, 52, 1, 1, 1, 0),
RK3036_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0),
RK3036_PLL_RATE(1188000000, 2, 99, 1, 1, 1, 0),
RK3036_PLL_RATE(1104000000, 1, 46, 1, 1, 1, 0),
RK3036_PLL_RATE(1100000000, 12, 550, 1, 1, 1, 0),
RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0),
RK3036_PLL_RATE(1000000000, 6, 500, 2, 1, 1, 0),
RK3036_PLL_RATE(984000000, 1, 82, 2, 1, 1, 0),
RK3036_PLL_RATE(960000000, 1, 80, 2, 1, 1, 0),
RK3036_PLL_RATE(936000000, 1, 78, 2, 1, 1, 0),
RK3036_PLL_RATE(912000000, 1, 76, 2, 1, 1, 0),
RK3036_PLL_RATE(900000000, 4, 300, 2, 1, 1, 0),
RK3036_PLL_RATE(888000000, 1, 74, 2, 1, 1, 0),
RK3036_PLL_RATE(864000000, 1, 72, 2, 1, 1, 0),
RK3036_PLL_RATE(840000000, 1, 70, 2, 1, 1, 0),
RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0),
RK3036_PLL_RATE(800000000, 6, 400, 2, 1, 1, 0),
RK3036_PLL_RATE(700000000, 6, 350, 2, 1, 1, 0),
RK3036_PLL_RATE(696000000, 1, 58, 2, 1, 1, 0),
RK3036_PLL_RATE(600000000, 1, 75, 3, 1, 1, 0),
RK3036_PLL_RATE(594000000, 2, 99, 2, 1, 1, 0),
RK3036_PLL_RATE(504000000, 1, 63, 3, 1, 1, 0),
RK3036_PLL_RATE(500000000, 6, 250, 2, 1, 1, 0),
RK3036_PLL_RATE(408000000, 1, 68, 2, 2, 1, 0),
RK3036_PLL_RATE(312000000, 1, 52, 2, 2, 1, 0),
RK3036_PLL_RATE(216000000, 1, 72, 4, 2, 1, 0),
RK3036_PLL_RATE(96000000, 1, 64, 4, 4, 1, 0),
{ /* sentinel */ },
};
static struct rockchip_pll_rate_table rk3328_pll_frac_rates[] = {
/* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
RK3036_PLL_RATE(1016064000, 3, 127, 1, 1, 0, 134218),
/* vco = 1016064000 */
RK3036_PLL_RATE(983040000, 24, 983, 1, 1, 0, 671089),
/* vco = 983040000 */
RK3036_PLL_RATE(491520000, 24, 983, 2, 1, 0, 671089),
/* vco = 983040000 */
RK3036_PLL_RATE(61440000, 6, 215, 7, 2, 0, 671089),
/* vco = 860156000 */
RK3036_PLL_RATE(56448000, 12, 451, 4, 4, 0, 9797895),
/* vco = 903168000 */
RK3036_PLL_RATE(40960000, 12, 409, 4, 5, 0, 10066330),
/* vco = 819200000 */
{ /* sentinel */ },
};
#define RK3328_DIV_ACLKM_MASK 0x7
#define RK3328_DIV_ACLKM_SHIFT 4
#define RK3328_DIV_PCLK_DBG_MASK 0xf
#define RK3328_DIV_PCLK_DBG_SHIFT 0
#define RK3328_CLKSEL1(_aclk_core, _pclk_dbg) \
{ \
.reg = RK3328_CLKSEL_CON(1), \
.val = HIWORD_UPDATE(_aclk_core, RK3328_DIV_ACLKM_MASK, \
RK3328_DIV_ACLKM_SHIFT) | \
HIWORD_UPDATE(_pclk_dbg, RK3328_DIV_PCLK_DBG_MASK, \
RK3328_DIV_PCLK_DBG_SHIFT), \
}
#define RK3328_CPUCLK_RATE(_prate, _aclk_core, _pclk_dbg) \
{ \
.prate = _prate, \
.divs = { \
RK3328_CLKSEL1(_aclk_core, _pclk_dbg), \
}, \
}
static struct rockchip_cpuclk_rate_table rk3328_cpuclk_rates[] __initdata = {
RK3328_CPUCLK_RATE(1800000000, 1, 7),
RK3328_CPUCLK_RATE(1704000000, 1, 7),
RK3328_CPUCLK_RATE(1608000000, 1, 7),
RK3328_CPUCLK_RATE(1512000000, 1, 7),