mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 03:15:31 +09:00
Merge commit '6971f2340a338d235d0227336beff69f6573d032'
* commit '6971f2340a338d235d0227336beff69f6573d032': arm64: dts: rockchip: rk3562: Add pm_shaping for power domains soc: rockchip: power-domain: Add support to save and restore shaping Change-Id: I82b6d65334ad4740405dee7975faf86f7a529ead
This commit is contained in:
@@ -899,26 +899,51 @@
|
||||
reg = <0x0 0xfee03800 0x0 0x20>;
|
||||
};
|
||||
|
||||
shaping_dam2ddr: shaping@fee03888 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfee03888 0x0 0x4>;
|
||||
};
|
||||
|
||||
qos_mcu: qos@fee10000 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfee10000 0x0 0x20>;
|
||||
};
|
||||
|
||||
shaping_mcu: shaping@fee10088 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfee10088 0x0 0x4>;
|
||||
};
|
||||
|
||||
qos_dft_apb: qos@fee10100 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfee10100 0x0 0x20>;
|
||||
};
|
||||
|
||||
shaping_dft_apb: shaping@fee10188 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfee10188 0x0 0x4>;
|
||||
};
|
||||
|
||||
qos_gmac: qos@fee10200 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfee10200 0x0 0x20>;
|
||||
};
|
||||
|
||||
shaping_gmac: shaping@fee10288 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfee10288 0x0 0x4>;
|
||||
};
|
||||
|
||||
qos_mac100: qos@fee10300 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfee10300 0x0 0x20>;
|
||||
};
|
||||
|
||||
shaping_mac100: shaping@fee10388 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfee10388 0x0 0x4>;
|
||||
};
|
||||
|
||||
qos_dcf: qos@fee10400 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfee10400 0x0 0x20>;
|
||||
@@ -929,117 +954,233 @@
|
||||
reg = <0x0 0xfee20000 0x0 0x20>;
|
||||
};
|
||||
|
||||
shaping_cpu: shaping@fee20088 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfee20088 0x0 0x4>;
|
||||
};
|
||||
|
||||
qos_daplite_apb: qos@fee20100 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfee20100 0x0 0x20>;
|
||||
};
|
||||
|
||||
shaping_daplite_apb: shaping@fee20188 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfee20188 0x0 0x4>;
|
||||
};
|
||||
|
||||
qos_gpu: qos@fee30000 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfee30000 0x0 0x20>;
|
||||
priority-init = <0x202>;
|
||||
};
|
||||
|
||||
shaping_gpu: shaping@fee30088 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfee30088 0x0 0x4>;
|
||||
};
|
||||
|
||||
qos_npu: qos@fee40000 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfee40000 0x0 0x20>;
|
||||
};
|
||||
|
||||
shaping_npu: shaping@fee40088 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfee40088 0x0 0x4>;
|
||||
};
|
||||
|
||||
qos_rkvdec: qos@fee50000 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfee50000 0x0 0x20>;
|
||||
};
|
||||
|
||||
shaping_rkvdec: shaping@fee50088 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfee50088 0x0 0x4>;
|
||||
};
|
||||
|
||||
qos_vepu: qos@fee60000 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfee60000 0x0 0x20>;
|
||||
};
|
||||
|
||||
shaping_vepu: shaping@fee60088 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfee60088 0x0 0x4>;
|
||||
};
|
||||
|
||||
qos_isp: qos@fee70000 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfee70000 0x0 0x20>;
|
||||
};
|
||||
|
||||
shaping_isp: shaping@fee70088 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfee70088 0x0 0x4>;
|
||||
};
|
||||
|
||||
qos_vicap: qos@fee70100 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfee70100 0x0 0x20>;
|
||||
};
|
||||
|
||||
shaping_vicap: shaping@fee70188 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfee70188 0x0 0x4>;
|
||||
};
|
||||
|
||||
qos_vop: qos@fee80000 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfee80000 0x0 0x20>;
|
||||
};
|
||||
|
||||
shaping_vop: shaping@fee80088 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfee80088 0x0 0x4>;
|
||||
};
|
||||
|
||||
qos_jpeg: qos@fee90000 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfee90000 0x0 0x20>;
|
||||
};
|
||||
|
||||
shaping_jpeg: shaping@fee90088 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfee90088 0x0 0x4>;
|
||||
};
|
||||
|
||||
qos_rga_rd: qos@fee90100 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfee90100 0x0 0x20>;
|
||||
};
|
||||
|
||||
shaping_rga_rd: shaping@fee90188 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfee90188 0x0 0x4>;
|
||||
};
|
||||
|
||||
qos_rga_wr: qos@fee90200 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfee90200 0x0 0x20>;
|
||||
};
|
||||
|
||||
shaping_rga_wr: shaping@fee90288 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfee90288 0x0 0x4>;
|
||||
};
|
||||
|
||||
qos_pcie: qos@feea0000 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfeea0000 0x0 0x20>;
|
||||
};
|
||||
|
||||
shaping_pcie: shaping@feea0088 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfeea0088 0x0 0x4>;
|
||||
shaping-init = <0x5>;
|
||||
};
|
||||
|
||||
qos_usb3: qos@feea0100 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfeea0100 0x0 0x20>;
|
||||
};
|
||||
|
||||
shaping_usb3: shaping@feea0188 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfeea0188 0x0 0x4>;
|
||||
};
|
||||
|
||||
qos_crypto_apb: qos@feeb0000 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfeeb0000 0x0 0x20>;
|
||||
};
|
||||
|
||||
shaping_crypto_apb: shaping@feeb0088 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfeeb0088 0x0 0x4>;
|
||||
};
|
||||
|
||||
qos_crypto: qos@feeb0100 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfeeb0100 0x0 0x20>;
|
||||
};
|
||||
|
||||
shaping_crypto: shaping@feeb0188 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfeeb0188 0x0 0x4>;
|
||||
};
|
||||
|
||||
qos_dmac: qos@feeb0200 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfeeb0200 0x0 0x20>;
|
||||
};
|
||||
|
||||
shaping_dmac: shaping@feeb0288 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfeeb0288 0x0 0x4>;
|
||||
};
|
||||
|
||||
qos_emmc: qos@feeb0300 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfeeb0300 0x0 0x20>;
|
||||
};
|
||||
|
||||
shaping_emmc: shaping@feeb0388 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfeeb0388 0x0 0x4>;
|
||||
};
|
||||
|
||||
qos_fspi: qos@feeb0400 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfeeb0400 0x0 0x20>;
|
||||
};
|
||||
|
||||
shaping_fspi: shaping@feeb0488 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfeeb0488 0x0 0x4>;
|
||||
};
|
||||
|
||||
qos_rkdma: qos@feeb0500 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfeeb0500 0x0 0x20>;
|
||||
};
|
||||
|
||||
shaping_rkdma: shaping@feeb0588 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfeeb0588 0x0 0x4>;
|
||||
};
|
||||
|
||||
qos_sdmmc0: qos@feeb0600 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfeeb0600 0x0 0x20>;
|
||||
};
|
||||
|
||||
shaping_sdmmc0: shaping@feeb0688 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfeeb0688 0x0 0x4>;
|
||||
};
|
||||
|
||||
qos_sdmmc1: qos@feeb0700 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfeeb0700 0x0 0x20>;
|
||||
};
|
||||
|
||||
shaping_sdmmc1: shaping@feeb0788 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfeeb0788 0x0 0x4>;
|
||||
};
|
||||
|
||||
qos_usb2: qos@feeb0800 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfeeb0800 0x0 0x20>;
|
||||
};
|
||||
|
||||
shaping_usb2: shaping@feeb0888 {
|
||||
compatible = "syscon";
|
||||
reg = <0x0 0xfeeb0888 0x0 0x4>;
|
||||
};
|
||||
|
||||
pmu_grf: syscon@ff010000 {
|
||||
compatible = "rockchip,rk3562-pmu-grf", "syscon", "simple-mfd";
|
||||
reg = <0x0 0xff010000 0x0 0x10000>;
|
||||
@@ -1250,16 +1391,19 @@
|
||||
pd_gpu@RK3562_PD_GPU {
|
||||
reg = <RK3562_PD_GPU>;
|
||||
pm_qos = <&qos_gpu>;
|
||||
pm_shaping = <&shaping_gpu>;
|
||||
};
|
||||
/* These power domains are grouped by VD_NPU */
|
||||
pd_npu@RK3562_PD_NPU {
|
||||
reg = <RK3562_PD_NPU>;
|
||||
pm_qos = <&qos_npu>;
|
||||
pm_shaping = <&shaping_npu>;
|
||||
};
|
||||
/* These power domains are grouped by VD_LOGIC */
|
||||
pd_vdpu@RK3562_PD_VDPU {
|
||||
reg = <RK3562_PD_VDPU>;
|
||||
pm_qos = <&qos_rkvdec>;
|
||||
pm_shaping = <&shaping_rkvdec>;
|
||||
};
|
||||
pd_vi@RK3562_PD_VI {
|
||||
reg = <RK3562_PD_VI>;
|
||||
@@ -1267,10 +1411,13 @@
|
||||
#size-cells = <0>;
|
||||
pm_qos = <&qos_isp>,
|
||||
<&qos_vicap>;
|
||||
pm_shaping = <&shaping_isp>,
|
||||
<&shaping_vicap>;
|
||||
|
||||
pd_vepu@RK3562_PD_VEPU {
|
||||
reg = <RK3562_PD_VEPU>;
|
||||
pm_qos = <&qos_vepu>;
|
||||
pm_shaping = <&shaping_vepu>;
|
||||
};
|
||||
};
|
||||
pd_vo@RK3562_PD_VO {
|
||||
@@ -1278,18 +1425,24 @@
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
pm_qos = <&qos_vop>;
|
||||
pm_shaping= <&shaping_vop>;
|
||||
|
||||
pd_rga@RK3562_PD_RGA {
|
||||
reg = <RK3562_PD_RGA>;
|
||||
pm_qos = <&qos_rga_rd>,
|
||||
<&qos_rga_wr>,
|
||||
<&qos_jpeg>;
|
||||
pm_shaping = <&shaping_rga_rd>,
|
||||
<&shaping_rga_wr>,
|
||||
<&shaping_jpeg>;
|
||||
};
|
||||
};
|
||||
pd_php@RK3562_PD_PHP {
|
||||
reg = <RK3562_PD_PHP>;
|
||||
pm_qos = <&qos_pcie>,
|
||||
<&qos_usb3>;
|
||||
pm_shaping = <&shaping_pcie>,
|
||||
<&shaping_usb3>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -95,19 +95,26 @@ struct rockchip_pmu_info {
|
||||
#define QOS_SATURATION 0x14
|
||||
#define QOS_EXTCONTROL 0x18
|
||||
|
||||
#define SHAPING_NBPKTMAX0 0x0
|
||||
|
||||
struct rockchip_pm_domain {
|
||||
struct generic_pm_domain genpd;
|
||||
const struct rockchip_domain_info *info;
|
||||
struct rockchip_pmu *pmu;
|
||||
int num_qos;
|
||||
int num_shaping;
|
||||
struct regmap **qos_regmap;
|
||||
struct regmap **shaping_regmap;
|
||||
u32 *qos_save_regs[MAX_QOS_REGS_NUM];
|
||||
u32 *shaping_save_regs;
|
||||
bool *qos_is_need_init[MAX_QOS_REGS_NUM];
|
||||
bool *shaping_is_need_init;
|
||||
int num_clks;
|
||||
struct clk_bulk_data *clks;
|
||||
bool is_ignore_pwr;
|
||||
bool is_qos_saved;
|
||||
bool is_qos_need_init;
|
||||
bool is_shaping_need_init;
|
||||
struct regulator *supply;
|
||||
};
|
||||
|
||||
@@ -560,6 +567,45 @@ int rockchip_pmu_idle_request(struct device *dev, bool idle)
|
||||
}
|
||||
EXPORT_SYMBOL(rockchip_pmu_idle_request);
|
||||
|
||||
static int rockchip_pmu_save_shaping(struct rockchip_pm_domain *pd)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < pd->num_shaping; i++)
|
||||
regmap_read(pd->shaping_regmap[i], SHAPING_NBPKTMAX0,
|
||||
&pd->shaping_save_regs[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rockchip_pmu_restore_shaping(struct rockchip_pm_domain *pd)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < pd->num_shaping; i++)
|
||||
regmap_write(pd->shaping_regmap[i], SHAPING_NBPKTMAX0,
|
||||
pd->shaping_save_regs[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rockchip_pmu_init_shaping(struct rockchip_pm_domain *pd)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!pd->is_shaping_need_init)
|
||||
return;
|
||||
|
||||
for (i = 0; i < pd->num_shaping; i++)
|
||||
if (pd->shaping_is_need_init[i])
|
||||
regmap_write(pd->shaping_regmap[i], SHAPING_NBPKTMAX0,
|
||||
pd->shaping_save_regs[i]);
|
||||
|
||||
kfree(pd->shaping_is_need_init);
|
||||
pd->shaping_is_need_init = NULL;
|
||||
pd->is_shaping_need_init = false;
|
||||
}
|
||||
|
||||
static int rockchip_pmu_save_qos(struct rockchip_pm_domain *pd)
|
||||
{
|
||||
int i;
|
||||
@@ -581,7 +627,8 @@ static int rockchip_pmu_save_qos(struct rockchip_pm_domain *pd)
|
||||
QOS_EXTCONTROL,
|
||||
&pd->qos_save_regs[4][i]);
|
||||
}
|
||||
return 0;
|
||||
|
||||
return rockchip_pmu_save_shaping(pd);
|
||||
}
|
||||
|
||||
static int rockchip_pmu_restore_qos(struct rockchip_pm_domain *pd)
|
||||
@@ -606,13 +653,15 @@ static int rockchip_pmu_restore_qos(struct rockchip_pm_domain *pd)
|
||||
pd->qos_save_regs[4][i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return rockchip_pmu_restore_shaping(pd);
|
||||
}
|
||||
|
||||
static void rockchip_pmu_init_qos(struct rockchip_pm_domain *pd)
|
||||
{
|
||||
int i;
|
||||
|
||||
rockchip_pmu_init_shaping(pd);
|
||||
|
||||
if (!pd->is_qos_need_init)
|
||||
return;
|
||||
|
||||
@@ -906,7 +955,7 @@ static int rockchip_pd_power(struct rockchip_pm_domain *pd, bool power_on)
|
||||
|
||||
if (pd->is_qos_saved)
|
||||
rockchip_pmu_restore_qos(pd);
|
||||
if (pd->is_qos_need_init)
|
||||
if (pd->is_qos_need_init || pd->is_shaping_need_init)
|
||||
rockchip_pmu_init_qos(pd);
|
||||
}
|
||||
|
||||
@@ -1046,8 +1095,13 @@ static void rockchip_pd_qos_init(struct rockchip_pm_domain *pd)
|
||||
if (!pd->is_qos_need_init) {
|
||||
kfree(pd->qos_is_need_init[0]);
|
||||
pd->qos_is_need_init[0] = NULL;
|
||||
return;
|
||||
}
|
||||
if (!pd->is_shaping_need_init) {
|
||||
kfree(pd->shaping_is_need_init);
|
||||
pd->shaping_is_need_init = NULL;
|
||||
}
|
||||
if (!pd->is_qos_need_init && !pd->is_shaping_need_init)
|
||||
return;
|
||||
|
||||
is_pd_on = rockchip_pmu_domain_is_on(pd);
|
||||
if (is_pd_on) {
|
||||
@@ -1081,6 +1135,79 @@ static int rockchip_pd_add_alwasy_on_flag(struct rockchip_pm_domain *pd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rockchip_pd_of_get_shaping(struct rockchip_pm_domain *pd,
|
||||
struct device_node *node)
|
||||
{
|
||||
struct rockchip_pmu *pmu = pd->pmu;
|
||||
struct device_node *shaping_node;
|
||||
int num_shaping = 0, num_shaping_reg = 0;
|
||||
int error, i;
|
||||
u32 val;
|
||||
|
||||
num_shaping = of_count_phandle_with_args(node, "pm_shaping", NULL);
|
||||
|
||||
for (i = 0; i < num_shaping; i++) {
|
||||
shaping_node = of_parse_phandle(node, "pm_shaping", i);
|
||||
if (shaping_node && of_device_is_available(shaping_node))
|
||||
pd->num_shaping++;
|
||||
of_node_put(shaping_node);
|
||||
}
|
||||
|
||||
if (pd->num_shaping > 0) {
|
||||
pd->shaping_regmap = devm_kcalloc(pmu->dev, pd->num_shaping,
|
||||
sizeof(*pd->shaping_regmap),
|
||||
GFP_KERNEL);
|
||||
if (!pd->shaping_regmap)
|
||||
return -ENOMEM;
|
||||
pd->shaping_save_regs = devm_kmalloc(pmu->dev, sizeof(u32) *
|
||||
pd->num_shaping,
|
||||
GFP_KERNEL);
|
||||
if (!pd->shaping_save_regs)
|
||||
return -ENOMEM;
|
||||
pd->shaping_is_need_init = kcalloc(pd->num_shaping, sizeof(bool),
|
||||
GFP_KERNEL);
|
||||
if (!pd->shaping_is_need_init)
|
||||
return -ENOMEM;
|
||||
for (i = 0; i < num_shaping; i++) {
|
||||
shaping_node = of_parse_phandle(node, "pm_shaping", i);
|
||||
if (!shaping_node) {
|
||||
error = -ENODEV;
|
||||
goto err_free_init;
|
||||
}
|
||||
if (of_device_is_available(shaping_node)) {
|
||||
pd->shaping_regmap[num_shaping_reg] =
|
||||
syscon_node_to_regmap(shaping_node);
|
||||
if (IS_ERR(pd->shaping_regmap[num_shaping_reg])) {
|
||||
of_node_put(shaping_node);
|
||||
error = -ENODEV;
|
||||
goto err_free_init;
|
||||
}
|
||||
if (!of_property_read_u32(shaping_node,
|
||||
"shaping-init",
|
||||
&val)) {
|
||||
pd->shaping_save_regs[i] = val;
|
||||
pd->shaping_is_need_init[i] = true;
|
||||
pd->is_shaping_need_init = true;
|
||||
}
|
||||
num_shaping_reg++;
|
||||
}
|
||||
of_node_put(shaping_node);
|
||||
if (num_shaping_reg > pd->num_shaping) {
|
||||
error = -EINVAL;
|
||||
goto err_free_init;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_init:
|
||||
kfree(pd->shaping_is_need_init);
|
||||
pd->shaping_is_need_init = NULL;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu,
|
||||
struct device_node *node)
|
||||
{
|
||||
@@ -1258,6 +1385,10 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu,
|
||||
}
|
||||
}
|
||||
|
||||
error = rockchip_pd_of_get_shaping(pd, node);
|
||||
if (error)
|
||||
goto err_unprepare_clocks;
|
||||
|
||||
if (pd->info->name)
|
||||
pd->genpd.name = pd->info->name;
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user