/*
* Copyright (C) 2015 - 2016 ZTE Corporation.
* Copyright (C) 2016 Linaro Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/clk-provider.h>
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <dt-bindings/clock/zx296718-clock.h>
#include "clk.h"
/* TOP CRM */
#define TOP_CLK_MUX0 0x04
#define TOP_CLK_MUX1 0x08
#define TOP_CLK_MUX2 0x0c
#define TOP_CLK_MUX3 0x10
#define TOP_CLK_MUX4 0x14
#define TOP_CLK_MUX5 0x18
#define TOP_CLK_MUX6 0x1c
#define TOP_CLK_MUX7 0x20
#define TOP_CLK_MUX9 0x28
#define TOP_CLK_GATE0 0x34
#define TOP_CLK_GATE1 0x38
#define TOP_CLK_GATE2 0x3c
#define TOP_CLK_GATE3 0x40
#define TOP_CLK_GATE4 0x44
#define TOP_CLK_GATE5 0x48
#define TOP_CLK_GATE6 0x4c
#define TOP_CLK_DIV0 0x58
#define PLL_CPU_REG 0x80
#define PLL_VGA_REG 0xb0
#define PLL_DDR_REG 0xa0
/* LSP0 CRM */
#define LSP0_TIMER3_CLK 0x4
#define LSP0_TIMER4_CLK 0x8
#define LSP0_TIMER5_CLK 0xc
#define LSP0_UART3_CLK 0x10
#define LSP0_UART1_CLK 0x14
#define LSP0_UART2_CLK 0x18
#define LSP0_SPIFC0_CLK 0x1c
#define LSP0_I2C4_CLK 0x20
#define LSP0_I2C5_CLK 0x24
#define LSP0_SSP0_CLK 0x28
#define LSP0_SSP1_CLK 0x2c
#define LSP0_USIM0_CLK 0x30
#define LSP0_GPIO_CLK 0x34
#define LSP0_I2C3_CLK 0x38
/* LSP1 CRM */
#define LSP1_UART4_CLK 0x08
#define LSP1_UART5_CLK 0x0c
#define LSP1_PWM_CLK 0x10
#define LSP1_I2C2_CLK 0x14
#define LSP1_SSP2_CLK 0x1c
#define LSP1_SSP3_CLK 0x20
#define LSP1_SSP4_CLK 0x24
#define LSP1_USIM1_CLK 0x28
/* audio lsp */
#define AUDIO_I2S0_DIV_CFG1 0x10
#define AUDIO_I2S0_DIV_CFG2 0x14
#define AUDIO_I2S0_CLK 0x18
#define AUDIO_I2S1_DIV_CFG1 0x20
#define AUDIO_I2S1_DIV_CFG2 0x24
#define AUDIO_I2S1_CLK 0x28
#define AUDIO_I2S2_DIV_CFG1 0x30
#define AUDIO_I2S2_DIV_CFG2 0x34
#define AUDIO_I2S2_CLK 0x38
#define AUDIO_I2S3_DIV_CFG1 0x40
#define AUDIO_I2S3_DIV_CFG2 0x44
#define AUDIO_I2S3_CLK 0x48
#define AUDIO_I2C0_CLK 0x50
#define AUDIO_SPDIF0_DIV_CFG1 0x60
#define AUDIO_SPDIF0_DIV_CFG2 0x64
#define AUDIO_SPDIF0_CLK 0x68
#define AUDIO_SPDIF1_DIV_CFG1 0x70
#define AUDIO_SPDIF1_DIV_CFG2 0x74
#define AUDIO_SPDIF1_CLK 0x78
#define AUDIO_TIMER_CLK 0x80
#define AUDIO_TDM_CLK 0x90
#define AUDIO_TS_CLK 0xa0
static DEFINE_SPINLOCK(clk_lock);
static const struct zx_pll_config pll_cpu_table[] = {
PLL_RATE(1312000000, 0x00103621, 0x04aaaaaa),
PLL_RATE(1407000000, 0x00103a21, 0x04aaaaaa),
PLL_RATE(1503000000, 0x00103e21, 0x04aaaaaa),
PLL_RATE(1600000000, 0x00104221, 0x04aaaaaa),
};
static const struct zx_pll_config pll_vga_table[] = {
PLL_RATE(36000000, 0x00102464, 0x04000000), /* 800x600@56 */
PLL_RATE(40000000, 0x00102864, 0x04000000), /* 800x600@60 */
PLL_RATE(49500000, 0x00103164, 0x04800000), /* 800x600@75 */
PLL_RATE(50000000, 0x00103264, 0x04000000), /* 800x600@72 */
PLL_RATE(56250000, 0x00103864, 0x04400000), /* 800x600@85 */
PLL_RATE(65000000, 0x00104164, 0x04000000), /* 1024x768@60 */
PLL_RATE(74375000, 0x00104a64, 0x04600000), /* 1280x720@60 */
PLL_RATE(75000000, 0x00104b64, 0x04800000), /* 1024x768@70 */
PLL_RATE(78750000, 0x00104e64, 0x04c00000), /* 1024x768@75 */
PLL_RATE(85500000, 0x00105564, 0x04800000), /* 1360x768@60 */
PLL_RATE(106500000, 0x00106a64, 0x04800000), /* 1440x900@60 */
PLL_RATE(108000000, 0x00106c64, 0x04000000), /* 1280x1024@60 */
PLL_RATE(110000000, 0x00106e64, 0x04000000), /* 1024x768@85 */
PLL_RATE(135000000, 0x00105a44, 0x04000000), /* 1280x1024@75 */
PLL_RATE(136750000, 0x00104462, 0x04600000), /* 1440x900@75 */
PLL_RATE(148500000, 0x00104a62, 0x04400000), /* 1920x1080@60 */
PLL_RATE(157000000, 0x00104e62, 0x04800000), /* 1440x900@85 */
PLL_RATE(157500000, 0x00104e62, 0x04c00000), /* 1280x1024@85 */
PLL_RATE(162000000, 0x00105162, 0x04000000), /* 1600x1200@60 */
PLL_RATE(193250000, 0x00106062, 0x04a00000), /* 1920x1200@60 */
};
PNAME(osc) = {
"osc24m",
"osc32k",
};
PNAME(dbg_wclk_p) = {
"clk334m",
"clk466m",
"clk396m",
"clk250m",
};
PNAME(a72_coreclk_p) = {
"osc24m",
"pll_mm0_1188m",
"pll_mm1_1296m",
"clk1000m",
"clk648m",
"clk1600m",
"pll_audio_1800m",
"pll_vga_1800m",
};
PNAME(cpu_periclk_p) = {
"osc24m",
"clk500m",
"clk594m",
"clk466m",
"clk294m",
"clk334m",
"clk250m",
"clk125m",
};
PNAME(a53_coreclk_p) = {
"osc24m",
"clk1000m",
"pll_mm0_1188m",
"clk648m",
"clk500m",
"clk800m",
"clk1600m",
"pll_audio_1800m",
};
PNAME(sec_wclk_p) = {
"osc24m",
"clk396m",
"clk334m",
"clk297m",
"clk250m",
"clk198m",
"clk148m5",
"clk99m",
};
PNAME(sd_nand_wclk_p) = {
"osc24m",
"clk