mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-10 04:48:04 +09:00
clk: rockchip: support setting ddr clock via SCPI APIs
On rk3368, let a mcu scaling ddr clock via SCPI (System Control and Power Interface) APIs. Change-Id: I95342b876caad991e6d1319c5e4ec793365c7981 Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com>
This commit is contained in:
@@ -20,9 +20,12 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/slab.h>
|
||||
#include <soc/rockchip/rockchip_sip.h>
|
||||
#include <soc/rockchip/scpi.h>
|
||||
|
||||
#include "clk.h"
|
||||
|
||||
#define MHZ (1000000)
|
||||
|
||||
struct rockchip_ddrclk {
|
||||
struct clk_hw hw;
|
||||
void __iomem *reg_base;
|
||||
@@ -102,6 +105,40 @@ static const struct clk_ops rockchip_ddrclk_sip_ops = {
|
||||
.get_parent = rockchip_ddrclk_get_parent,
|
||||
};
|
||||
|
||||
static int rockchip_ddrclk_scpi_set_rate(struct clk_hw *hw, unsigned long drate,
|
||||
unsigned long prate)
|
||||
{
|
||||
u32 ret;
|
||||
u32 lcdc_type = 7;
|
||||
|
||||
ret = scpi_ddr_set_clk_rate(drate / MHZ, lcdc_type);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static unsigned long rockchip_ddrclk_scpi_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
return (MHZ * scpi_ddr_get_clk_rate());
|
||||
}
|
||||
|
||||
static long rockchip_ddrclk_scpi_round_rate(struct clk_hw *hw,
|
||||
unsigned long rate,
|
||||
unsigned long *prate)
|
||||
{
|
||||
rate = rate / MHZ;
|
||||
rate = (rate / 12) * 12;
|
||||
|
||||
return (rate * MHZ);
|
||||
}
|
||||
|
||||
static const struct clk_ops rockchip_ddrclk_scpi_ops = {
|
||||
.recalc_rate = rockchip_ddrclk_scpi_recalc_rate,
|
||||
.set_rate = rockchip_ddrclk_scpi_set_rate,
|
||||
.round_rate = rockchip_ddrclk_scpi_round_rate,
|
||||
.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,
|
||||
@@ -130,6 +167,9 @@ struct clk *rockchip_clk_register_ddrclk(const char *name, int flags,
|
||||
case ROCKCHIP_DDRCLK_SIP:
|
||||
init.ops = &rockchip_ddrclk_sip_ops;
|
||||
break;
|
||||
case ROCKCHIP_DDRCLK_SCPI:
|
||||
init.ops = &rockchip_ddrclk_scpi_ops;
|
||||
break;
|
||||
default:
|
||||
pr_err("%s: unsupported ddrclk type %d\n", __func__, ddr_flag);
|
||||
kfree(ddrclk);
|
||||
|
||||
@@ -309,8 +309,10 @@ struct clk *rockchip_clk_register_mmc(const char *name,
|
||||
* there may have serval ways to set ddr clock, use
|
||||
* this flag to distinguish them.
|
||||
* ROCKCHIP_DDRCLK_SIP: use SIP call to bl31 to change ddrclk rate.
|
||||
* ROCKCHIP_DDRCLK_SCPI: use SCPI APIs to let mcu change ddrclk rate.
|
||||
*/
|
||||
#define ROCKCHIP_DDRCLK_SIP 0x01
|
||||
#define ROCKCHIP_DDRCLK_SCPI 0x02
|
||||
|
||||
struct clk *rockchip_clk_register_ddrclk(const char *name, int flags,
|
||||
const char *const *parent_names,
|
||||
|
||||
Reference in New Issue
Block a user