mirror of
https://github.com/Ysurac/openmptcprouter.git
synced 2025-02-13 11:51:54 +00:00
211 lines
5.7 KiB
Diff
211 lines
5.7 KiB
Diff
|
From ce6d3614888e6358466f0e84e248177a6bca5258 Mon Sep 17 00:00:00 2001
|
||
|
From: Tang Yun ping <typ@rock-chips.com>
|
||
|
Date: Thu, 4 May 2017 20:49:58 +0800
|
||
|
Subject: [PATCH] clk: rockchip: support setting ddr clock via SIP Version 2
|
||
|
APIs
|
||
|
|
||
|
commit 764e893ee82321938fc6f4349e9e7caf06a04410 rockchip.
|
||
|
|
||
|
Signed-off-by: Tang Yun ping <typ@rock-chips.com>
|
||
|
Signed-off-by: hmz007 <hmz007@gmail.com>
|
||
|
---
|
||
|
drivers/clk/rockchip/clk-ddr.c | 130 ++++++++++++++++++++++++++++
|
||
|
drivers/clk/rockchip/clk-rk3328.c | 7 +-
|
||
|
drivers/clk/rockchip/clk.h | 3 +-
|
||
|
include/soc/rockchip/rockchip_sip.h | 11 +++
|
||
|
4 files changed, 147 insertions(+), 4 deletions(-)
|
||
|
|
||
|
--- a/drivers/clk/rockchip/clk-ddr.c
|
||
|
+++ b/drivers/clk/rockchip/clk-ddr.c
|
||
|
@@ -87,6 +87,133 @@ static const struct clk_ops rockchip_ddr
|
||
|
.get_parent = rockchip_ddrclk_get_parent,
|
||
|
};
|
||
|
|
||
|
+/* See v4.4/include/dt-bindings/display/rk_fb.h */
|
||
|
+#define SCREEN_NULL 0
|
||
|
+#define SCREEN_HDMI 6
|
||
|
+
|
||
|
+static inline int rk_drm_get_lcdc_type(void)
|
||
|
+{
|
||
|
+ return SCREEN_NULL;
|
||
|
+}
|
||
|
+
|
||
|
+struct share_params {
|
||
|
+ u32 hz;
|
||
|
+ u32 lcdc_type;
|
||
|
+ u32 vop;
|
||
|
+ u32 vop_dclk_mode;
|
||
|
+ u32 sr_idle_en;
|
||
|
+ u32 addr_mcu_el3;
|
||
|
+ /*
|
||
|
+ * 1: need to wait flag1
|
||
|
+ * 0: never wait flag1
|
||
|
+ */
|
||
|
+ u32 wait_flag1;
|
||
|
+ /*
|
||
|
+ * 1: need to wait flag1
|
||
|
+ * 0: never wait flag1
|
||
|
+ */
|
||
|
+ u32 wait_flag0;
|
||
|
+ u32 complt_hwirq;
|
||
|
+ /* if need, add parameter after */
|
||
|
+};
|
||
|
+
|
||
|
+struct rockchip_ddrclk_data {
|
||
|
+ u32 inited_flag;
|
||
|
+ void __iomem *share_memory;
|
||
|
+};
|
||
|
+
|
||
|
+static struct rockchip_ddrclk_data ddr_data;
|
||
|
+
|
||
|
+static void rockchip_ddrclk_data_init(void)
|
||
|
+{
|
||
|
+ struct arm_smccc_res res;
|
||
|
+
|
||
|
+ arm_smccc_smc(ROCKCHIP_SIP_SHARE_MEM,
|
||
|
+ 1, SHARE_PAGE_TYPE_DDR, 0,
|
||
|
+ 0, 0, 0, 0, &res);
|
||
|
+
|
||
|
+ if (!res.a0) {
|
||
|
+ ddr_data.share_memory = (void __iomem *)ioremap(res.a1, 1<<12);
|
||
|
+ ddr_data.inited_flag = 1;
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+static int rockchip_ddrclk_sip_set_rate_v2(struct clk_hw *hw,
|
||
|
+ unsigned long drate,
|
||
|
+ unsigned long prate)
|
||
|
+{
|
||
|
+ struct share_params *p;
|
||
|
+ struct arm_smccc_res res;
|
||
|
+
|
||
|
+ if (!ddr_data.inited_flag)
|
||
|
+ rockchip_ddrclk_data_init();
|
||
|
+
|
||
|
+ p = (struct share_params *)ddr_data.share_memory;
|
||
|
+
|
||
|
+ p->hz = drate;
|
||
|
+ p->lcdc_type = rk_drm_get_lcdc_type();
|
||
|
+ p->wait_flag1 = 1;
|
||
|
+ p->wait_flag0 = 1;
|
||
|
+
|
||
|
+ arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ,
|
||
|
+ SHARE_PAGE_TYPE_DDR, 0,
|
||
|
+ ROCKCHIP_SIP_CONFIG_DRAM_SET_RATE,
|
||
|
+ 0, 0, 0, 0, &res);
|
||
|
+
|
||
|
+ if ((int)res.a1 == -6) {
|
||
|
+ pr_err("%s: timeout, drate = %lumhz\n", __func__, drate/1000000);
|
||
|
+ /* TODO: rockchip_dmcfreq_wait_complete(); */
|
||
|
+ }
|
||
|
+
|
||
|
+ return res.a0;
|
||
|
+}
|
||
|
+
|
||
|
+static unsigned long rockchip_ddrclk_sip_recalc_rate_v2
|
||
|
+ (struct clk_hw *hw, unsigned long parent_rate)
|
||
|
+{
|
||
|
+ struct arm_smccc_res res;
|
||
|
+
|
||
|
+ arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ,
|
||
|
+ SHARE_PAGE_TYPE_DDR, 0,
|
||
|
+ ROCKCHIP_SIP_CONFIG_DRAM_GET_RATE,
|
||
|
+ 0, 0, 0, 0, &res);
|
||
|
+ if (!res.a0)
|
||
|
+ return res.a1;
|
||
|
+ else
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+static long rockchip_ddrclk_sip_round_rate_v2(struct clk_hw *hw,
|
||
|
+ unsigned long rate,
|
||
|
+ unsigned long *prate)
|
||
|
+{
|
||
|
+ struct share_params *p;
|
||
|
+ struct arm_smccc_res res;
|
||
|
+
|
||
|
+ if (!ddr_data.inited_flag)
|
||
|
+ rockchip_ddrclk_data_init();
|
||
|
+
|
||
|
+ p = (struct share_params *)ddr_data.share_memory;
|
||
|
+
|
||
|
+ p->hz = rate;
|
||
|
+
|
||
|
+ arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ,
|
||
|
+ SHARE_PAGE_TYPE_DDR, 0,
|
||
|
+ ROCKCHIP_SIP_CONFIG_DRAM_ROUND_RATE,
|
||
|
+ 0, 0, 0, 0, &res);
|
||
|
+ if (!res.a0)
|
||
|
+ return res.a1;
|
||
|
+ else
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+static const struct clk_ops rockchip_ddrclk_sip_ops_v2 = {
|
||
|
+ .recalc_rate = rockchip_ddrclk_sip_recalc_rate_v2,
|
||
|
+ .set_rate = rockchip_ddrclk_sip_set_rate_v2,
|
||
|
+ .round_rate = rockchip_ddrclk_sip_round_rate_v2,
|
||
|
+ .get_parent = rockchip_ddrclk_get_parent,
|
||
|
+};
|
||
|
+
|
||
|
struct clk *rockchip_clk_register_ddrclk(const char *name, int flags,
|
||
|
const char *const *parent_names,
|
||
|
u8 num_parents, int mux_offset,
|
||
|
@@ -114,6 +241,9 @@ struct clk *rockchip_clk_register_ddrclk
|
||
|
case ROCKCHIP_DDRCLK_SIP:
|
||
|
init.ops = &rockchip_ddrclk_sip_ops;
|
||
|
break;
|
||
|
+ case ROCKCHIP_DDRCLK_SIP_V2:
|
||
|
+ init.ops = &rockchip_ddrclk_sip_ops_v2;
|
||
|
+ break;
|
||
|
default:
|
||
|
pr_err("%s: unsupported ddrclk type %d\n", __func__, ddr_flag);
|
||
|
kfree(ddrclk);
|
||
|
--- a/drivers/clk/rockchip/clk-rk3328.c
|
||
|
+++ b/drivers/clk/rockchip/clk-rk3328.c
|
||
|
@@ -315,9 +315,10 @@ static struct rockchip_clk_branch rk3328
|
||
|
RK3328_CLKGATE_CON(14), 1, GFLAGS),
|
||
|
|
||
|
/* PD_DDR */
|
||
|
- COMPOSITE(0, "clk_ddr", mux_ddrphy_p, CLK_IGNORE_UNUSED,
|
||
|
- RK3328_CLKSEL_CON(3), 8, 2, MFLAGS, 0, 3, DFLAGS | CLK_DIVIDER_POWER_OF_TWO,
|
||
|
- RK3328_CLKGATE_CON(0), 4, GFLAGS),
|
||
|
+ COMPOSITE_DDRCLK(SCLK_DDRCLK, "sclk_ddrc", mux_ddrphy_p, 0,
|
||
|
+ RK3328_CLKSEL_CON(3), 8, 2, 0, 3,
|
||
|
+ ROCKCHIP_DDRCLK_SIP_V2),
|
||
|
+
|
||
|
GATE(0, "clk_ddrmsch", "clk_ddr", CLK_IGNORE_UNUSED,
|
||
|
RK3328_CLKGATE_CON(18), 6, GFLAGS),
|
||
|
GATE(0, "clk_ddrupctl", "clk_ddr", CLK_IGNORE_UNUSED,
|
||
|
--- a/drivers/clk/rockchip/clk.h
|
||
|
+++ b/drivers/clk/rockchip/clk.h
|
||
|
@@ -418,7 +418,8 @@ struct clk *rockchip_clk_register_mmc(co
|
||
|
* DDRCLK flags, including method of setting the rate
|
||
|
* ROCKCHIP_DDRCLK_SIP: use SIP call to bl31 to change ddrclk rate.
|
||
|
*/
|
||
|
-#define ROCKCHIP_DDRCLK_SIP BIT(0)
|
||
|
+#define ROCKCHIP_DDRCLK_SIP 0x01
|
||
|
+#define ROCKCHIP_DDRCLK_SIP_V2 0x03
|
||
|
|
||
|
struct clk *rockchip_clk_register_ddrclk(const char *name, int flags,
|
||
|
const char *const *parent_names,
|
||
|
--- a/include/soc/rockchip/rockchip_sip.h
|
||
|
+++ b/include/soc/rockchip/rockchip_sip.h
|
||
|
@@ -16,5 +16,16 @@
|
||
|
#define ROCKCHIP_SIP_CONFIG_DRAM_CLR_IRQ 0x06
|
||
|
#define ROCKCHIP_SIP_CONFIG_DRAM_SET_PARAM 0x07
|
||
|
#define ROCKCHIP_SIP_CONFIG_DRAM_SET_ODT_PD 0x08
|
||
|
+#define ROCKCHIP_SIP_CONFIG_DRAM_GET_VERSION 0x08
|
||
|
+
|
||
|
+#define ROCKCHIP_SIP_SHARE_MEM 0x82000009
|
||
|
+
|
||
|
+/* Share mem page types */
|
||
|
+typedef enum {
|
||
|
+ SHARE_PAGE_TYPE_INVALID = 0,
|
||
|
+ SHARE_PAGE_TYPE_UARTDBG,
|
||
|
+ SHARE_PAGE_TYPE_DDR,
|
||
|
+ SHARE_PAGE_TYPE_MAX,
|
||
|
+} share_page_type_t;
|
||
|
|
||
|
#endif
|