Skip to content

Commit 5c1ca8c

Browse files
TonyXie06rkhuangtao
authored andcommitted
PM / devfreq: rockchip_dmc: support wait_complete.
Change-Id: Ie3f173f632068f261b84a204bbd36b26b10e1981 Signed-off-by: Tony Xie <tony.xie@rock-chips.com> Signed-off-by: YouMin Chen <cym@rock-chips.com>
1 parent 46cb48d commit 5c1ca8c

4 files changed

Lines changed: 77 additions & 3 deletions

File tree

drivers/clk/rockchip/clk-ddr.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <linux/of.h>
2424
#include <linux/rockchip/rockchip_sip.h>
2525
#include <linux/slab.h>
26+
#include <soc/rockchip/rockchip_dmc.h>
2627
#include <soc/rockchip/rockchip_sip.h>
2728
#include <soc/rockchip/scpi.h>
2829
#include <uapi/drm/drm_mode.h>
@@ -219,6 +220,7 @@ struct share_params {
219220
* 0: never wait flag1
220221
*/
221222
u32 wait_flag0;
223+
u32 complt_hwirq;
222224
/* if need, add parameter after */
223225
};
224226

@@ -261,6 +263,9 @@ static int rockchip_ddrclk_sip_set_rate_v2(struct clk_hw *hw,
261263
res = sip_smc_dram(SHARE_PAGE_TYPE_DDR, 0,
262264
ROCKCHIP_SIP_CONFIG_DRAM_SET_RATE);
263265

266+
if ((int)res.a1 == SIP_RET_SET_RATE_TIMEOUT)
267+
rockchip_dmcfreq_wait_complete();
268+
264269
return res.a0;
265270
}
266271

drivers/devfreq/rockchip_dmc.c

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,10 @@
2828
#include <linux/fb.h>
2929
#include <linux/input.h>
3030
#include <linux/interrupt.h>
31+
#include <linux/irq.h>
3132
#include <linux/module.h>
3233
#include <linux/of.h>
34+
#include <linux/of_irq.h>
3335
#include <linux/platform_device.h>
3436
#include <linux/pm_opp.h>
3537
#include <linux/reboot.h>
@@ -100,6 +102,7 @@ struct share_params {
100102
* 0: never wait flag1
101103
*/
102104
u32 wait_flag0;
105+
u32 complt_hwirq;
103106
/* if need, add parameter after */
104107
};
105108

@@ -1578,16 +1581,50 @@ static int rockchip_ddr_set_auto_self_refresh(uint32_t en)
15781581
return res.a0;
15791582
}
15801583

1584+
struct dmcfreq_wait_ctrl_t {
1585+
wait_queue_head_t wait_wq;
1586+
int wait_flag;
1587+
int wait_en;
1588+
int wait_time_out_ms;
1589+
};
1590+
1591+
static struct dmcfreq_wait_ctrl_t wait_ctrl;
1592+
1593+
static irqreturn_t wait_complete_irq(int irqno, void *dev_id)
1594+
{
1595+
struct dmcfreq_wait_ctrl_t *ctrl = dev_id;
1596+
1597+
ctrl->wait_flag = 0;
1598+
wake_up(&ctrl->wait_wq);
1599+
return IRQ_HANDLED;
1600+
}
1601+
1602+
int rockchip_dmcfreq_wait_complete(void)
1603+
{
1604+
if (!wait_ctrl.wait_en) {
1605+
pr_err("%s: Do not support time out!\n", __func__);
1606+
return 0;
1607+
}
1608+
wait_ctrl.wait_flag = -1;
1609+
wait_event_timeout(wait_ctrl.wait_wq, (wait_ctrl.wait_flag == 0),
1610+
msecs_to_jiffies(wait_ctrl.wait_time_out_ms));
1611+
return 0;
1612+
}
1613+
15811614
static int px30_dmc_init(struct platform_device *pdev,
15821615
struct rockchip_dmcfreq *dmcfreq)
15831616
{
15841617
struct arm_smccc_res res;
15851618
u32 size;
1619+
int ret;
1620+
int complt_irq;
1621+
u32 complt_hwirq;
1622+
struct irq_data *complt_irq_data;
15861623

15871624
res = sip_smc_dram(0, 0,
15881625
ROCKCHIP_SIP_CONFIG_DRAM_GET_VERSION);
15891626
dev_notice(&pdev->dev, "current ATF version 0x%lx!\n", res.a1);
1590-
if (res.a0 || res.a1 < 0x101) {
1627+
if (res.a0 || res.a1 < 0x103) {
15911628
dev_err(&pdev->dev,
15921629
"trusted firmware need to update or is invalid!\n");
15931630
return -ENXIO;
@@ -1610,6 +1647,28 @@ static int px30_dmc_init(struct platform_device *pdev,
16101647
of_get_px30_timings(&pdev->dev, pdev->dev.of_node,
16111648
(uint32_t *)ddr_psci_param);
16121649

1650+
init_waitqueue_head(&wait_ctrl.wait_wq);
1651+
wait_ctrl.wait_en = 1;
1652+
wait_ctrl.wait_time_out_ms = 17 * 5;
1653+
1654+
complt_irq = platform_get_irq_byname(pdev, "complete_irq");
1655+
if (complt_irq < 0) {
1656+
dev_err(&pdev->dev, "no IRQ for complete_irq: %d\n",
1657+
complt_irq);
1658+
return complt_irq;
1659+
}
1660+
1661+
ret = devm_request_irq(&pdev->dev, complt_irq, wait_complete_irq,
1662+
0, dev_name(&pdev->dev), &wait_ctrl);
1663+
if (ret < 0) {
1664+
dev_err(&pdev->dev, "cannot request complete_irq\n");
1665+
return ret;
1666+
}
1667+
1668+
complt_irq_data = irq_get_irq_data(complt_irq);
1669+
complt_hwirq = irqd_to_hwirq(complt_irq_data);
1670+
ddr_psci_param->complt_hwirq = complt_hwirq;
1671+
16131672
res = sip_smc_dram(SHARE_PAGE_TYPE_DDR, 0,
16141673
ROCKCHIP_SIP_CONFIG_DRAM_INIT);
16151674
if (res.a0) {
@@ -2995,8 +3054,6 @@ static int rockchip_dmcfreq_probe(struct platform_device *pdev)
29953054
dev_err(dev, "failed to register input handler\n");
29963055
}
29973056

2998-
rockchip_set_system_status(SYS_STATUS_NORMAL);
2999-
30003057
ret = ddr_power_model_simple_init(data);
30013058

30023059
if (!ret) {
@@ -3012,6 +3069,8 @@ static int rockchip_dmcfreq_probe(struct platform_device *pdev)
30123069
}
30133070
}
30143071

3072+
rockchip_set_system_status(SYS_STATUS_NORMAL);
3073+
30153074
return 0;
30163075
}
30173076

include/linux/rockchip/rockchip_sip.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
#define SIP_RET_INVALID_PARAMS -3
5858
#define SIP_RET_INVALID_ADDRESS -4
5959
#define SIP_RET_DENIED -5
60+
#define SIP_RET_SET_RATE_TIMEOUT -6
6061

6162
/* SIP_UARTDBG_CFG64 call types */
6263
#define UARTDBG_CFG_INIT 0xf0

include/soc/rockchip/rockchip_dmc.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,13 @@ static inline int rockchip_drm_register_notifier_to_dmc(struct devfreq *devfreq)
3333
}
3434
#endif
3535

36+
#ifdef CONFIG_ARM_ROCKCHIP_DMC_DEVFREQ
37+
int rockchip_dmcfreq_wait_complete(void);
38+
#else
39+
static inline int rockchip_dmcfreq_wait_complete(void)
40+
{
41+
return 0;
42+
}
43+
#endif
44+
3645
#endif

0 commit comments

Comments
 (0)