Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6f0c8ab1 authored by mtk24296's avatar mtk24296 Committed by yc.li
Browse files

[ALPS08861573] SMI: add flow ctrl dbg dump



[Description]
add flow ctrl dbg dump

[Test]
camera stress

MTK-Commit-Id: d2fac74ec6f4c7d4274877966df35762c3552b90

Signed-off-by: default avatarmtk24296 <yc.li@mediatek.com>
CR-Id: ALPS08861573
Feature: smi driver
Change-Id: I718d7ff97ab281a332aef011e00d016ca4482a1f
parent e60f2d35
Loading
Loading
Loading
Loading
+63 −2
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
#include <linux/pm_opp.h>
#include <linux/pm_runtime.h>
#include <linux/pm_domain.h>
#include <linux/sched/clock.h>
#include <soc/mediatek/smi.h>
#include <dt-bindings/memory/mt2701-larb-port.h>
#include <dt-bindings/memory/mtk-memory-port.h>
@@ -165,6 +166,15 @@ struct mtk_smi_larb_gen {
};

#define SMI_MAX_CG_CTRL_NR		(7)

enum { PRE_SET, POST_SET, SET_TIMIMG_NR};
struct mtk_smi_flow_ctrl_dbg {
	bool active;
	ktime_t time[SET_TIMIMG_NR];
	u32 status[SET_TIMIMG_NR];
	u32 cmd_thrt_val[SET_TIMIMG_NR];
};

struct mtk_smi {
	struct device			*dev;
	int				nr_clks;
@@ -179,6 +189,7 @@ struct mtk_smi {
	bool				skip_busy_check;
	bool				skip_rpm_cb;
	atomic_t			ref_count;
	struct mtk_smi_flow_ctrl_dbg	*flow_ctrl_dbg;
};

#define LARB_MAX_COMMON		(2)
@@ -430,6 +441,20 @@ void mtk_smi_dump_last_pd(const char *user)
}
EXPORT_SYMBOL_GPL(mtk_smi_dump_last_pd);

void mtk_smi_dump_last_flow_ctrl_dbg(struct device *dev)
{
	struct mtk_smi *common = dev_get_drvdata(dev);
	struct mtk_smi_flow_ctrl_dbg *dbg = common->flow_ctrl_dbg;

	if (dbg && dbg->active) {
		dev_notice(dev, "pre set time=%18llu,status:%#x,%#x=%#x\n", dbg->time[PRE_SET],
				dbg->status[PRE_SET], SMI_L1LEN, dbg->cmd_thrt_val[PRE_SET]);
		dev_notice(dev, "post set time=%18llu,status:%#x,%#x=%#x\n", dbg->time[POST_SET],
				dbg->status[POST_SET], SMI_L1LEN, dbg->cmd_thrt_val[POST_SET]);
	}
}
EXPORT_SYMBOL_GPL(mtk_smi_dump_last_flow_ctrl_dbg);

static int mtk_smi_clk_enable(const struct mtk_smi *smi)
{
	int i, j, ret;
@@ -4254,6 +4279,12 @@ static int mtk_smi_common_probe(struct platform_device *pdev)
	if (of_parse_phandle(dev->of_node, "mediatek,cmdq", 0))
		kthr = kthread_run(smi_cmdq, dev, __func__);

	common->flow_ctrl_dbg = devm_kzalloc(dev, sizeof(*common->flow_ctrl_dbg), GFP_KERNEL);
	if (!common->flow_ctrl_dbg)
		return -ENOMEM;
	if (of_property_read_bool(dev->of_node, "flow-ctrl-dbg"))
		common->flow_ctrl_dbg->active = true;

	if (of_property_read_bool(dev->of_node, "init-power-on")) {
		dev_notice(dev, "%s: init power on\n", __func__);
		ret = pm_runtime_get_sync(dev);
@@ -4289,6 +4320,30 @@ static int mtk_smi_common_remove(struct platform_device *pdev)
	return 0;
}

static void smi_flow_ctrl_dbg(struct mtk_smi *common, u32 stat)
{
	u32 val;

	if (!common->flow_ctrl_dbg->active)
		return;

	common->flow_ctrl_dbg->time[stat] = sched_clock();

	val = readl_relaxed(common->base + SMI_DEBUG_MISC);
	if (!(val & 0x1)) {
		dev_notice(common->dev, "%s:check fail! stat=%d, %#x=%#x\n",
					__func__, stat, SMI_DEBUG_MISC, val);
		raw_notifier_call_chain(&smi_driver_notifier_list, common->commid, NULL);
	}
	common->flow_ctrl_dbg->status[stat] = val;

	val = readl_relaxed(common->base + SMI_L1LEN);
	if ((val == 0xa) && (stat == PRE_SET))
		dev_notice(common->dev, "%s:check fail! stat=%d, %#x=%#x\n",
					__func__, stat, SMI_L1LEN, val);
	common->flow_ctrl_dbg->cmd_thrt_val[stat] = val;
}

static int __maybe_unused mtk_smi_common_resume(struct device *dev)
{
	struct mtk_smi *common = dev_get_drvdata(dev);
@@ -4326,12 +4381,18 @@ static int __maybe_unused mtk_smi_common_resume(struct device *dev)
			writel_relaxed(
				common->plat->bwl[common->commid * SMI_COMMON_LARB_NR_MAX + i],
				common->base + SMI_L1ARB(i));
		for (i = 0; i < SMI_COMMON_MISC_NR; i++)
		for (i = 0; i < SMI_COMMON_MISC_NR; i++) {
			if (common->plat->misc[
				common->commid * SMI_COMMON_MISC_NR + i].offset == SMI_L1LEN)
				smi_flow_ctrl_dbg(common, PRE_SET);
			writel_relaxed(common->plat->misc[
				common->commid * SMI_COMMON_MISC_NR + i].value,
				common->base + common->plat->misc[
				common->commid * SMI_COMMON_MISC_NR + i].offset);

			if (common->plat->misc[
				common->commid * SMI_COMMON_MISC_NR + i].offset == SMI_L1LEN)
				smi_flow_ctrl_dbg(common, POST_SET);
		}
	} else {
		for (i = 0; i < SMI_COMMON_LARB_NR_MAX; i++)
			writel_relaxed(common->plat->bwl[i],
+16 −0
Original line number Diff line number Diff line
@@ -1331,6 +1331,21 @@ s32 mtk_smi_dbg_cg_status(void)
}
EXPORT_SYMBOL_GPL(mtk_smi_dbg_cg_status);

static void mtk_smi_dbg_flow_ctrl_dump(void)
{
	struct mtk_smi_dbg	*smi = gsmi;
	struct mtk_smi_dbg_node	node;
	s32			i;

	//check COMM status
	for (i = 0; i < ARRAY_SIZE(smi->comm); i++) {
		node = smi->comm[i];
		if (!node.dev || !node.va)
			continue;
		mtk_smi_dump_last_flow_ctrl_dbg(node.dev);
	}
}

int mtk_smi_set_disp_ops(const struct smi_disp_ops *ops)
{
	struct mtk_smi_dbg	*smi = gsmi;
@@ -1848,6 +1863,7 @@ s32 mtk_smi_dbg_hang_detect(char *user)
	}

	mtk_smi_dump_last_pd(user);
	mtk_smi_dbg_flow_ctrl_dump();

	if (!smi_enter_met) {
		smi_hang_detect_bw_monitor(false);
+1 −0
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@ s32 smi_sysram_enable(struct device *larbdev, const u32 master_id,
s32 mtk_smi_sysram_set(struct device *larbdev, const u32 master_id,
			u32 set_val, const char *user);
s32 mtk_smi_dbg_cg_status(void);
void mtk_smi_dump_last_flow_ctrl_dbg(struct device *dev);
void mtk_smi_check_comm_ref_cnt(struct device *dev);
void mtk_smi_check_larb_ref_cnt(struct device *dev);
int mtk_smi_larb_ultra_dis(struct device *larbdev, bool is_dis);