1
0
mirror of https://github.com/physwizz/a155-U-u1.git synced 2024-11-19 13:27:49 +00:00
a155-U-u1/kernel-5.10/drivers/misc/mediatek/dvfsrc/dvfsrc-debug-v3.c
2024-03-11 06:53:12 +11:00

820 lines
20 KiB
C

// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2019 MediaTek Inc.
*/
#include <linux/arm-smccc.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/soc/mediatek/mtk_dvfsrc.h>
#include <linux/soc/mediatek/mtk_sip_svc.h>
#include "dvfsrc-helper.h"
#include "dvfsrc-common.h"
enum dvfsrc_regs {
DVFSRC_BASIC_CONTROL,
DVFSRC_SW_REQ1,
DVFSRC_INT,
DVFSRC_INT_EN,
DVFSRC_SW_BW_0,
DVFSRC_ISP_HRT,
DVFSRC_DEBUG_STA_0,
DVFSRC_VCORE_REQUEST,
DVFSRC_CURRENT_LEVEL,
DVFSRC_TARGET_LEVEL,
DVFSRC_LAST,
DVFSRC_RECORD_0,
DVFSRC_DDR_REQUEST,
DVSFRC_HRT_REQ_MD_URG,
DVFSRC_HRT_REQ_MD_BW_0,
DVFSRC_HRT_REQ_MD_BW_8,
DVFSRC_MD_TURBO,
DVFSRC_95MD_SCEN_BW4,
DVFSRC_95MD_SCEN_BW0,
DVFSRC_95MD_SCEN_BW0_T,
DVFSRC_RSRV_4,
DVFSRC_MD_DDR_FLOOR_REQUEST,
DVFSRC_QOS_DDR_REQUEST,
};
static const int mt6779_regs[] = {
[DVFSRC_BASIC_CONTROL] = 0x0,
[DVFSRC_SW_REQ1] = 0x4,
[DVFSRC_INT] = 0xC4,
[DVFSRC_INT_EN] = 0xC8,
[DVFSRC_SW_BW_0] = 0x260,
[DVFSRC_ISP_HRT] = 0x290,
[DVFSRC_DEBUG_STA_0] = 0x700,
[DVFSRC_VCORE_REQUEST] = 0x6C,
[DVFSRC_CURRENT_LEVEL] = 0xD44,
[DVFSRC_TARGET_LEVEL] = 0xD48,
[DVFSRC_LAST] = 0xB08,
[DVFSRC_RECORD_0] = 0xB14,
[DVFSRC_DDR_REQUEST] = 0xA00,
[DVSFRC_HRT_REQ_MD_URG] = 0xA88,
[DVFSRC_HRT_REQ_MD_BW_0] = 0xA8C,
[DVFSRC_HRT_REQ_MD_BW_8] = 0xACC,
};
static const int mt6873_regs[] = {
[DVFSRC_BASIC_CONTROL] = 0x0,
[DVFSRC_SW_REQ1] = 0x4,
[DVFSRC_INT] = 0xC4,
[DVFSRC_INT_EN] = 0xC8,
[DVFSRC_SW_BW_0] = 0x260,
[DVFSRC_ISP_HRT] = 0x290,
[DVFSRC_DEBUG_STA_0] = 0x700,
[DVFSRC_VCORE_REQUEST] = 0x6C,
[DVFSRC_CURRENT_LEVEL] = 0xD44,
[DVFSRC_TARGET_LEVEL] = 0xD48,
[DVFSRC_LAST] = 0xAE4,
[DVFSRC_RECORD_0] = 0xAF0,
[DVFSRC_DDR_REQUEST] = 0xA00,
[DVSFRC_HRT_REQ_MD_URG] = 0xA64,
[DVFSRC_HRT_REQ_MD_BW_0] = 0xA8C,
[DVFSRC_HRT_REQ_MD_BW_8] = 0xACC,
[DVFSRC_MD_TURBO] = 0xDC,
[DVFSRC_95MD_SCEN_BW4] = 0x544,
[DVFSRC_95MD_SCEN_BW0] = 0x524,
[DVFSRC_95MD_SCEN_BW0_T] = 0x534,
[DVFSRC_RSRV_4] = 0x610,
};
static const int mt6983_regs[] = {
[DVFSRC_BASIC_CONTROL] = 0x0,
[DVFSRC_SW_REQ1] = 0x10,
[DVFSRC_INT] = 0xC8,
[DVFSRC_INT_EN] = 0xCC,
[DVFSRC_SW_BW_0] = 0x1DC,
[DVFSRC_ISP_HRT] = 0x20C,
[DVFSRC_DEBUG_STA_0] = 0x29C,
[DVFSRC_VCORE_REQUEST] = 0x80,
[DVFSRC_CURRENT_LEVEL] = 0x5F0,
[DVFSRC_TARGET_LEVEL] = 0x5F0,
[DVFSRC_LAST] = 0x3AC,
[DVFSRC_RECORD_0] = 0x3B8,
[DVFSRC_DDR_REQUEST] = 0x2C8,
[DVSFRC_HRT_REQ_MD_URG] = 0x320,
[DVFSRC_HRT_REQ_MD_BW_0] = 0x324,
[DVFSRC_HRT_REQ_MD_BW_8] = 0x344,
[DVFSRC_MD_TURBO] = 0xE0,
[DVFSRC_95MD_SCEN_BW4] = 0x278,
[DVFSRC_95MD_SCEN_BW0] = 0x258,
[DVFSRC_95MD_SCEN_BW0_T] = 0x268,
[DVFSRC_RSRV_4] = 0x290,
[DVFSRC_MD_DDR_FLOOR_REQUEST] = 0x5E4,
[DVFSRC_QOS_DDR_REQUEST] = 0x5E8,
};
enum dvfsrc_spm_regs {
POWERON_CONFIG_EN,
SPM_PC_STA,
SPM_SW_FLAG,
SPM_DVFS_LEVEL,
SPM_DVFS_STA,
SPM_DVS_DFS_LEVEL,
SPM_DVFS_HISTORY_STA0,
SPM_DVFS_HISTORY_STA1,
SPM_DVFS_CMD0,
SPM_DVFS_CMD1,
SPM_DVFS_CMD2,
SPM_DVFS_CMD3,
SPM_DVFS_CMD4,
SPM_TIMER_LATCH,
};
static const int mt6873_spm_regs[] = {
[POWERON_CONFIG_EN] = 0x0,
[SPM_PC_STA] = 0x0194,
[SPM_SW_FLAG] = 0x600,
[SPM_DVFS_LEVEL] = 0x04A4,
[SPM_DVFS_STA] = 0x01F8,
[SPM_DVS_DFS_LEVEL] = 0x04F8,
[SPM_DVFS_CMD0] = 0x710,
[SPM_DVFS_CMD1] = 0x714,
[SPM_DVFS_CMD2] = 0x718,
[SPM_DVFS_CMD3] = 0x71C,
[SPM_DVFS_CMD4] = 0x720,
};
static const int mt6893_spm_regs[] = {
[POWERON_CONFIG_EN] = 0x0,
[SPM_PC_STA] = 0x0194,
[SPM_SW_FLAG] = 0x600,
[SPM_DVFS_LEVEL] = 0x04A4,
[SPM_DVFS_STA] = 0x01F8,
[SPM_DVS_DFS_LEVEL] = 0x04F8,
[SPM_DVFS_CMD0] = 0x750,
[SPM_DVFS_CMD1] = 0x754,
[SPM_DVFS_CMD2] = 0x758,
[SPM_DVFS_CMD3] = 0x75C,
[SPM_DVFS_CMD4] = 0x760,
};
static const int mt6877_spm_regs[] = {
[POWERON_CONFIG_EN] = 0x0,
[SPM_PC_STA] = 0x0194,
[SPM_SW_FLAG] = 0x600,
[SPM_DVFS_LEVEL] = 0x0390,
[SPM_DVFS_STA] = 0x0388,
[SPM_DVS_DFS_LEVEL] = 0x038C,
[SPM_DVFS_CMD0] = 0x0310,
[SPM_DVFS_CMD1] = 0x0314,
[SPM_DVFS_CMD2] = 0x0318,
[SPM_DVFS_CMD3] = 0x031C,
[SPM_DVFS_CMD4] = 0x0320,
[SPM_TIMER_LATCH] = 0x514,
};
static u32 dvfsrc_read(struct mtk_dvfsrc *dvfs, u32 reg, u32 offset)
{
return readl(dvfs->regs + dvfs->dvd->config->regs[reg] + offset);
}
static u32 spm_read(struct mtk_dvfsrc *dvfs, u32 reg)
{
return readl(dvfs->spm_regs + dvfs->dvd->config->spm_regs[reg]);
}
static u32 spm_read_offset(struct mtk_dvfsrc *dvfs, u32 reg, u32 offset)
{
return readl(dvfs->spm_regs + dvfs->dvd->config->spm_regs[reg] + offset);
}
static u32 dvfsrc_get_scp_req(struct mtk_dvfsrc *dvfsrc)
{
/* DVFSRC_DEBUG_STA_2 */
return (dvfsrc_read(dvfsrc, DVFSRC_DEBUG_STA_0, 0x8) >> 14) & 0x1;
}
static u32 dvfsrc_get_hifi_scenario(struct mtk_dvfsrc *dvfsrc)
{
/* DVFSRC_DEBUG_STA_2 */
return (dvfsrc_read(dvfsrc, DVFSRC_DEBUG_STA_0, 0x8) >> 16) & 0xFF;
}
static u32 dvfsrc_get_hifi_vcore_gear(struct mtk_dvfsrc *dvfsrc)
{
u32 hifi_scen;
hifi_scen = __builtin_ffs(dvfsrc_get_hifi_scenario(dvfsrc));
if (hifi_scen)
return (dvfsrc_read(dvfsrc, DVFSRC_VCORE_REQUEST, 0xC) >>
((hifi_scen - 1) * 4)) & 0xF;
else
return 0;
}
static u32 dvfsrc_get_hifi_ddr_gear(struct mtk_dvfsrc *dvfsrc)
{
u32 hifi_scen;
hifi_scen = __builtin_ffs(dvfsrc_get_hifi_scenario(dvfsrc));
if (hifi_scen)
return (dvfsrc_read(dvfsrc, DVFSRC_DDR_REQUEST, 0x14) >>
((hifi_scen - 1) * 4)) & 0xF;
else
return 0;
}
static u32 dvfsrc_get_hifi_rising_ddr_gear(struct mtk_dvfsrc *dvfsrc)
{
u32 val = 0;
u32 last;
switch (dvfsrc->dvd->config->ip_verion) {
case 0:
last = dvfsrc_read(dvfsrc, DVFSRC_LAST, 0);
val = dvfsrc_read(dvfsrc, DVFSRC_RECORD_0, 0x18 + 0x1C * last);
val = (val >> 15) & 0x7;
break;
case 2:
val = dvfsrc_read(dvfsrc, DVFSRC_DEBUG_STA_0, 0);
val = (val >> 22) & 0x7;
break;
case 3:
val = dvfsrc_read(dvfsrc, DVFSRC_DEBUG_STA_0, 0x20);
val = (val >> 4) & 0xF;
default:
break;
}
return val;
}
static u32 dvfsrc_get_md_bw(struct mtk_dvfsrc *dvfsrc)
{
u32 val = 0;
u32 is_urgent, md_scen;
u32 index, shift;
switch (dvfsrc->dvd->config->ip_verion) {
case 0:
val = dvfsrc_read(dvfsrc, DVFSRC_DEBUG_STA_0, 0);
is_urgent = (val >> 16) & 0x1;
md_scen = val & 0xFFFF;
if (is_urgent) {
val = dvfsrc_read(dvfsrc, DVSFRC_HRT_REQ_MD_URG, 0)
& 0x1F;
} else {
index = md_scen / 3;
shift = (md_scen % 3) * 10;
if (index > 10)
return 0;
if (index < 8) {
val = dvfsrc_read(dvfsrc,
DVFSRC_HRT_REQ_MD_BW_0,
index * 4);
} else {
val = dvfsrc_read(dvfsrc,
DVFSRC_HRT_REQ_MD_BW_8,
(index - 8) * 4);
}
val = (val >> shift) & 0x3FF;
}
break;
case 2:
case 3:
val = dvfsrc_read(dvfsrc, DVFSRC_DEBUG_STA_0, 0xC) & 0x3FF;
break;
default:
break;
}
return val;
}
static u32 dvfsrc_get_md_rising_ddr_gear(struct mtk_dvfsrc *dvfsrc)
{
u32 val = 0;
u32 last;
switch (dvfsrc->dvd->config->ip_verion) {
case 0:
/* DVFSRC_RECORD_0_6 */
last = dvfsrc_read(dvfsrc, DVFSRC_LAST, 0);
val = dvfsrc_read(dvfsrc, DVFSRC_RECORD_0, 0x18 + 0x1C * last);
val = (val >> 9) & 0x7;
break;
case 2:
val = dvfsrc_read(dvfsrc, DVFSRC_DEBUG_STA_0, 0);
val = (val >> 29) & 0x7;
break;
case 3:
val = dvfsrc_read(dvfsrc, DVFSRC_DEBUG_STA_0, 0);
val = (val >> 20) & 0xF;
break;
default:
break;
}
return val;
}
static u32 dvfsrc_get_hrt_bw_ddr_gear(struct mtk_dvfsrc *dvfsrc)
{
u32 val = 0;
u32 last;
switch (dvfsrc->dvd->config->ip_verion) {
case 0:
/* DVFSRC_RECORD_0_6 */
last = dvfsrc_read(dvfsrc, DVFSRC_LAST, 0);
val = dvfsrc_read(dvfsrc, DVFSRC_RECORD_0, 0x18 + 0x1C * last);
val = (val >> 2) & 0x7;
break;
case 2:
val = dvfsrc_read(dvfsrc, DVFSRC_DEBUG_STA_0, 0x10);
val = (val >> 16) & 0x7;
break;
case 3:
val = dvfsrc_read(dvfsrc, DVFSRC_DEBUG_STA_0, 0x24);
val = (val >> 16) & 0xF;
break;
default:
break;
}
return val;
}
static u32 dvfsrc_get_md_scen_ddr_gear(struct mtk_dvfsrc *dvfsrc)
{
u32 is_turbo, is_urgent, md_scen;
u32 index, shift;
u32 sta0;
u32 val = 0;
switch (dvfsrc->dvd->config->ip_verion) {
case 0:
val = 0;
break;
case 2:
is_turbo = (dvfsrc_read(dvfsrc, DVFSRC_MD_TURBO, 0x0) == 0) ? 1 : 0;
sta0 = dvfsrc_read(dvfsrc, DVFSRC_DEBUG_STA_0, 0x0);
is_urgent = (sta0 >> 16) & 0x1;
md_scen = sta0 & 0xFFFF;
if (is_urgent)
val = dvfsrc_read(dvfsrc, DVFSRC_95MD_SCEN_BW4, 0x0);
else {
index = md_scen / 8;
shift = (md_scen % 8) * 4;
if (md_scen > 31)
return 0;
if (is_turbo)
val = dvfsrc_read(dvfsrc, DVFSRC_95MD_SCEN_BW0_T
, index * 4);
else
val = dvfsrc_read(dvfsrc, DVFSRC_95MD_SCEN_BW0
, index * 4);
val = (val >> shift) & 0x7;
}
break;
case 3:
val = dvfsrc_read(dvfsrc, DVFSRC_MD_DDR_FLOOR_REQUEST, 0x0);
val = val & 0xF;
break;
default:
break;
}
return val;
}
static u32 dvfsrc_get_md_imp_ddr(struct mtk_dvfsrc *dvfsrc)
{
u32 val = 0;
switch (dvfsrc->dvd->config->ip_verion) {
case 0:
val = 0;
break;
case 2:
val = dvfsrc_read(dvfsrc, DVFSRC_DEBUG_STA_0, 0x10);
val = (val >> 19) & 0x7;
break;
case 3:
val = dvfsrc_read(dvfsrc, DVFSRC_DEBUG_STA_0, 0x10);
val = val & 0xF;
break;
default:
break;
}
return val;
}
static char *dvfsrc_dump_record(struct mtk_dvfsrc *dvfsrc,
char *p, u32 size)
{
int i, rec_offset, offset;
char *buff_end = p + size;
p += sprintf(p, "%-11s: %d\n",
"DVFSRC_LAST",
dvfsrc_read(dvfsrc, DVFSRC_LAST, 0));
if (dvfsrc->dvd->config->ip_verion > 0)
rec_offset = 0x20;
else
rec_offset = 0x1C;
for (i = 0; i < 8; i++) {
offset = i * rec_offset;
p += snprintf(p, buff_end - p,
"[%d]%-4s:%08x,%08x,%08x,%08x\n",
i,
"0~3",
dvfsrc_read(dvfsrc, DVFSRC_RECORD_0, offset + 0x0),
dvfsrc_read(dvfsrc, DVFSRC_RECORD_0, offset + 0x4),
dvfsrc_read(dvfsrc, DVFSRC_RECORD_0, offset + 0x8),
dvfsrc_read(dvfsrc, DVFSRC_RECORD_0, offset + 0xC));
if (dvfsrc->dvd->config->ip_verion > 0) {
p += snprintf(p, buff_end - p,
"[%d]%-4s:%08x,%08x,%08x,%08x\n",
i,
"4~7",
dvfsrc_read(dvfsrc, DVFSRC_RECORD_0, offset + 0x10),
dvfsrc_read(dvfsrc, DVFSRC_RECORD_0, offset + 0x14),
dvfsrc_read(dvfsrc, DVFSRC_RECORD_0, offset + 0x18),
dvfsrc_read(dvfsrc, DVFSRC_RECORD_0, offset + 0x1C));
} else {
p += snprintf(p, buff_end - p,
"[%d]%-4s:%08x,%08x,%08x\n",
i,
"4~6",
dvfsrc_read(dvfsrc, DVFSRC_RECORD_0, offset + 0x10),
dvfsrc_read(dvfsrc, DVFSRC_RECORD_0, offset + 0x14),
dvfsrc_read(dvfsrc, DVFSRC_RECORD_0, offset + 0x18));
}
}
p += snprintf(p, buff_end - p, "\n");
return p;
}
static char *dvfsrc_dump_reg(struct mtk_dvfsrc *dvfsrc, char *p, u32 size)
{
char *buff_end = p + size;
p += snprintf(p, buff_end - p, "%-12s: %08x\n",
"CONTROL",
dvfsrc_read(dvfsrc, DVFSRC_BASIC_CONTROL, 0x0));
p += snprintf(p, buff_end - p, "%-12s: %08x\n",
"CURRENT",
dvfsrc_read(dvfsrc, DVFSRC_CURRENT_LEVEL, 0x0));
p += snprintf(p, buff_end - p, "%-12s: %08x\n",
"TARGET",
dvfsrc_read(dvfsrc, DVFSRC_TARGET_LEVEL, 0x0));
p += snprintf(p, buff_end - p,
"%-12s: %08x, %08x, %08x, %08x\n",
"SW_REQ 1~4",
dvfsrc_read(dvfsrc, DVFSRC_SW_REQ1, 0x0),
dvfsrc_read(dvfsrc, DVFSRC_SW_REQ1, 0x4),
dvfsrc_read(dvfsrc, DVFSRC_SW_REQ1, 0x8),
dvfsrc_read(dvfsrc, DVFSRC_SW_REQ1, 0xC));
p += snprintf(p, buff_end - p,
"%-12s: %08x, %08x, %08x, %08x\n",
"SW_REQ 5~8",
dvfsrc_read(dvfsrc, DVFSRC_SW_REQ1, 0x10),
dvfsrc_read(dvfsrc, DVFSRC_SW_REQ1, 0x14),
dvfsrc_read(dvfsrc, DVFSRC_SW_REQ1, 0x18),
dvfsrc_read(dvfsrc, DVFSRC_SW_REQ1, 0x1C));
p += snprintf(p, buff_end - p,
"%-12s: %d, %d, %d, %d, %d, %d, %d\n",
"SW_BW_0~6",
dvfsrc_read(dvfsrc, DVFSRC_SW_BW_0, 0x0),
dvfsrc_read(dvfsrc, DVFSRC_SW_BW_0, 0x4),
dvfsrc_read(dvfsrc, DVFSRC_SW_BW_0, 0x8),
dvfsrc_read(dvfsrc, DVFSRC_SW_BW_0, 0xC),
dvfsrc_read(dvfsrc, DVFSRC_SW_BW_0, 0x10),
dvfsrc_read(dvfsrc, DVFSRC_SW_BW_0, 0x14),
dvfsrc_read(dvfsrc, DVFSRC_SW_BW_0, 0x18));
if (dvfsrc->dvd->config->ip_verion > 2) {
p += snprintf(p, buff_end - p,
"%-12s: %d, %d, %d\n",
"SW_BW_7~9",
dvfsrc_read(dvfsrc, DVFSRC_SW_BW_0, 0x1C),
dvfsrc_read(dvfsrc, DVFSRC_SW_BW_0, 0x20),
dvfsrc_read(dvfsrc, DVFSRC_SW_BW_0, 0x24));
}
p += snprintf(p, buff_end - p, "%-12s: %x\n",
"INT",
dvfsrc_read(dvfsrc, DVFSRC_INT, 0x0));
p += snprintf(p, buff_end - p, "%-12s: %x\n",
"INT_EN",
dvfsrc_read(dvfsrc, DVFSRC_INT_EN, 0x0));
p += snprintf(p, buff_end - p, "%-12s: %d\n",
"ISP_HRT",
dvfsrc_read(dvfsrc, DVFSRC_ISP_HRT, 0x0));
p += snprintf(p, buff_end - p,
"%-12s: %08x, %08x, %08x, %08x\n",
"DEBUG_STA_0",
dvfsrc_read(dvfsrc, DVFSRC_DEBUG_STA_0, 0x0),
dvfsrc_read(dvfsrc, DVFSRC_DEBUG_STA_0, 0x4),
dvfsrc_read(dvfsrc, DVFSRC_DEBUG_STA_0, 0x8),
dvfsrc_read(dvfsrc, DVFSRC_DEBUG_STA_0, 0xC));
p += snprintf(p, buff_end - p,
"%-12s: %08x, %08x, %08x\n",
"DEBUG_STA_4",
dvfsrc_read(dvfsrc, DVFSRC_DEBUG_STA_0, 0x10),
dvfsrc_read(dvfsrc, DVFSRC_DEBUG_STA_0, 0x14),
dvfsrc_read(dvfsrc, DVFSRC_DEBUG_STA_0, 0x18));
if (dvfsrc->dvd->config->ip_verion > 2) {
p += snprintf(p, buff_end - p,
"%-12s: %08x, %08x, %08x\n",
"DEBUG_STA_7",
dvfsrc_read(dvfsrc, DVFSRC_DEBUG_STA_0, 0x1C),
dvfsrc_read(dvfsrc, DVFSRC_DEBUG_STA_0, 0x20),
dvfsrc_read(dvfsrc, DVFSRC_DEBUG_STA_0, 0x24));
}
p += snprintf(p, buff_end - p, "%-12s: %d\n",
"MD_RISING",
dvfsrc_get_md_rising_ddr_gear(dvfsrc));
p += snprintf(p, buff_end - p, "%-12s: %d\n",
"MD_HRT_BW",
dvfsrc_get_md_bw(dvfsrc));
p += snprintf(p, buff_end - p, "%-12s: %d\n",
"HRT_BW_REQ",
dvfsrc_get_hrt_bw_ddr_gear(dvfsrc));
p += snprintf(p, buff_end - p, "%-12s: %d\n",
"HIFI_VCORE",
dvfsrc_get_hifi_vcore_gear(dvfsrc));
p += snprintf(p, buff_end - p, "%-12s: %d\n",
"HIFI_DDR",
dvfsrc_get_hifi_ddr_gear(dvfsrc));
p += snprintf(p, buff_end - p, "%-12s: %d\n",
"HIFI_RISING",
dvfsrc_get_hifi_rising_ddr_gear(dvfsrc));
p += snprintf(p, buff_end - p, "%-12s: %d, %x\n",
"SCP_VCORE",
dvfsrc_get_scp_req(dvfsrc),
dvfsrc_read(dvfsrc, DVFSRC_VCORE_REQUEST, 0x0));
p += snprintf(p, buff_end - p, "\n");
return p;
}
static char *dvfsrc_dump_mt6873_spm_info(struct mtk_dvfsrc *dvfsrc,
char *p, u32 size)
{
char *buff_end = p + size;
if (!dvfsrc->spm_regs)
return p;
p += snprintf(p, buff_end - p, "%-24s: 0x%08x\n",
"POWERON_CONFIG_EN",
spm_read(dvfsrc, POWERON_CONFIG_EN));
p += snprintf(p, buff_end - p, "%-24s: 0x%08x\n",
"SPM_SW_FLAG_0",
spm_read(dvfsrc, SPM_SW_FLAG));
p += snprintf(p, buff_end - p, "%-24s: 0x%08x\n",
"SPM_PC_STA",
spm_read(dvfsrc, SPM_PC_STA));
p += snprintf(p, buff_end - p, "%-24s: 0x%08x\n",
"SPM_DVFS_LEVEL",
spm_read(dvfsrc, SPM_DVFS_LEVEL));
p += snprintf(p, buff_end - p, "%-24s: 0x%08x\n",
"SPM_DVS_DFS_LEVEL",
spm_read(dvfsrc, SPM_DVS_DFS_LEVEL));
p += snprintf(p, buff_end - p, "%-24s: 0x%08x\n",
"SPM_DVFS_STA",
spm_read(dvfsrc, SPM_DVFS_STA));
p += snprintf(p, buff_end - p,
"%-24s: 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
"SPM_DVFS_CMD0~4",
spm_read(dvfsrc, SPM_DVFS_CMD0),
spm_read(dvfsrc, SPM_DVFS_CMD1),
spm_read(dvfsrc, SPM_DVFS_CMD2),
spm_read(dvfsrc, SPM_DVFS_CMD3),
spm_read(dvfsrc, SPM_DVFS_CMD4));
return p;
}
static char *dvfsrc_dump_mt6983_spm_cmd(struct mtk_dvfsrc *dvfsrc,
char *p, u32 size)
{
char *buff_end = p + size;
int i;
if (!dvfsrc->spm_regs)
return p;
for (i = 0; i < 24; i++) {
p += snprintf(p, buff_end - p, "CMD%d: 0x%08x\n", i,
spm_read_offset(dvfsrc, SPM_DVFS_CMD0, i * 4));
}
return p;
}
static char *dvfsrc_dump_mt6983_spm_timer_latch(struct mtk_dvfsrc *dvfsrc,
char *p, u32 size)
{
char *buff_end = p + size;
int i;
unsigned int offset;
if (!dvfsrc->spm_regs)
return p;
if (!dvfsrc->dvd->spm_stamp_en) {
p += snprintf(p, buff_end - p, "stamp not support\n");
} else {
for (i = 0; i < 8; i++) {
offset = i * 0x10;
p += snprintf(p, buff_end - p, "T[%d] :%08x,%08x,%08x,%08x\n",
i,
spm_read_offset(dvfsrc, SPM_TIMER_LATCH, offset + 0x0),
spm_read_offset(dvfsrc, SPM_TIMER_LATCH, offset + 0x4),
spm_read_offset(dvfsrc, SPM_TIMER_LATCH, offset + 0x8),
spm_read_offset(dvfsrc, SPM_TIMER_LATCH, offset + 0xC));
}
}
return p;
}
#define MTK_SIP_VCOREFS_GET_VCORE_INFO 18
static int dvfsrc_dvfs_get_vcore_info_data(u32 idx)
{
struct arm_smccc_res ares;
arm_smccc_smc(MTK_SIP_VCOREFS_CONTROL, MTK_SIP_VCOREFS_GET_VCORE_INFO,
idx, 0, 0, 0, 0, 0,
&ares);
if (!ares.a0)
return ares.a1;
return 0;
}
static char *dvfsrc_dump_mt6873_vmode_info(struct mtk_dvfsrc *dvfsrc,
char *p, u32 size)
{
char *buff_end = p + size;
int max_info = 3;
int i;
for (i = 0; i < max_info; i++)
p += snprintf(p, buff_end - p, "VBINFO_%d: %08x\n",
i, dvfsrc_dvfs_get_vcore_info_data(i));
p += snprintf(p, buff_end - p, "%s: 0x%08x\n",
"V_MODE",
dvfsrc_read(dvfsrc, DVFSRC_RSRV_4, 0));
return p;
}
static int dvfsrc_query_request_status(struct mtk_dvfsrc *dvfsrc, u32 id)
{
int ret = 0;
switch (id) {
case DVFSRC_MD_RISING_DDR_REQ:
ret = dvfsrc_get_md_rising_ddr_gear(dvfsrc);
break;
case DVFSRC_MD_HRT_BW:
ret = dvfsrc_get_md_bw(dvfsrc);
break;
case DVFSRC_HIFI_VCORE_REQ:
ret = dvfsrc_get_hifi_vcore_gear(dvfsrc);
break;
case DVFSRC_HIFI_DDR_REQ:
ret = dvfsrc_get_hifi_ddr_gear(dvfsrc);
break;
case DVFSRC_HIFI_RISING_DDR_REQ:
ret = dvfsrc_get_hifi_rising_ddr_gear(dvfsrc);
break;
case DVFSRC_HRT_BW_DDR_REQ:
ret = dvfsrc_get_hrt_bw_ddr_gear(dvfsrc);
break;
case DVFSRC_MD_SCEN_DDR_REQ:
ret = dvfsrc_get_md_scen_ddr_gear(dvfsrc);
break;
case DVFSRC_MD_IMP_DDR_REQ:
ret = dvfsrc_get_md_imp_ddr(dvfsrc);
break;
}
return ret;
}
static u64 dvfsrc_query_dvfs_time(struct mtk_dvfsrc *dvfsrc)
{
u32 last, offset;
u64 time_1, time_2;
u64 dvfs_time_us;
last = dvfsrc_read(dvfsrc, DVFSRC_LAST, 0);
offset = last * 0x20;
time_1 = dvfsrc_read(dvfsrc, DVFSRC_RECORD_0, offset + 0x4);
time_1 = time_1 << 32;
time_1 = dvfsrc_read(dvfsrc, DVFSRC_RECORD_0, offset + 0x0) + time_1;
last = (last + 7) % 8;
offset = last * 0x20;
time_2 = dvfsrc_read(dvfsrc, DVFSRC_RECORD_0, offset + 0x4);
time_2 = time_2 << 32;
time_2 = dvfsrc_read(dvfsrc, DVFSRC_RECORD_0, offset + 0x0) + time_2;
dvfs_time_us = (time_1 - time_2) / 13;
return dvfs_time_us;
}
const struct dvfsrc_config mt6779_dvfsrc_config = {
.ip_verion = 0, /*mt6779 series*/
.regs = mt6779_regs,
.dump_record = dvfsrc_dump_record,
.dump_reg = dvfsrc_dump_reg,
.query_request = dvfsrc_query_request_status,
};
const struct dvfsrc_config mt6873_dvfsrc_config = {
.ip_verion = 2, /*mt6873 series*/
.regs = mt6873_regs,
.spm_regs = mt6873_spm_regs,
.dump_record = dvfsrc_dump_record,
.dump_reg = dvfsrc_dump_reg,
.dump_spm_info = dvfsrc_dump_mt6873_spm_info,
.dump_vmode_info = dvfsrc_dump_mt6873_vmode_info,
.query_request = dvfsrc_query_request_status,
.query_dvfs_time = dvfsrc_query_dvfs_time,
};
const struct dvfsrc_config mt6893_dvfsrc_config = {
.ip_verion = 2, /*mt6873 series*/
.regs = mt6873_regs,
.spm_regs = mt6893_spm_regs,
.dump_record = dvfsrc_dump_record,
.dump_reg = dvfsrc_dump_reg,
.dump_spm_info = dvfsrc_dump_mt6873_spm_info,
.dump_vmode_info = dvfsrc_dump_mt6873_vmode_info,
.query_request = dvfsrc_query_request_status,
.query_dvfs_time = dvfsrc_query_dvfs_time,
};
const struct dvfsrc_config mt6877_dvfsrc_config = {
.ip_verion = 2, /*mt6873 series*/
.regs = mt6873_regs,
.spm_regs = mt6877_spm_regs,
.dump_record = dvfsrc_dump_record,
.dump_reg = dvfsrc_dump_reg,
.dump_spm_info = dvfsrc_dump_mt6873_spm_info,
.dump_vmode_info = dvfsrc_dump_mt6873_vmode_info,
.query_request = dvfsrc_query_request_status,
.query_dvfs_time = dvfsrc_query_dvfs_time,
};
const struct dvfsrc_config mt6983_dvfsrc_config = {
.ip_verion = 3, /*mt6983 series*/
.regs = mt6983_regs,
.spm_regs = mt6877_spm_regs,
.dump_record = dvfsrc_dump_record,
.dump_reg = dvfsrc_dump_reg,
.dump_spm_info = dvfsrc_dump_mt6873_spm_info,
.dump_vmode_info = dvfsrc_dump_mt6873_vmode_info,
.query_request = dvfsrc_query_request_status,
.query_dvfs_time = dvfsrc_query_dvfs_time,
.dump_spm_cmd = dvfsrc_dump_mt6983_spm_cmd,
.dump_spm_timer_latch = dvfsrc_dump_mt6983_spm_timer_latch,
};