162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright 2019-2020 NXP
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#include <linux/debugfs.h>
762306a36Sopenharmony_ci#include <linux/device.h>
862306a36Sopenharmony_ci#include <linux/io.h>
962306a36Sopenharmony_ci#include <linux/kernel.h>
1062306a36Sopenharmony_ci#include <linux/pm_runtime.h>
1162306a36Sopenharmony_ci#include <linux/seq_file.h>
1262306a36Sopenharmony_ci#include <linux/types.h>
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#include "imx8-isi-core.h"
1562306a36Sopenharmony_ci#include "imx8-isi-regs.h"
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_cistatic inline u32 mxc_isi_read(struct mxc_isi_pipe *pipe, u32 reg)
1862306a36Sopenharmony_ci{
1962306a36Sopenharmony_ci	return readl(pipe->regs + reg);
2062306a36Sopenharmony_ci}
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_cistatic int mxc_isi_debug_dump_regs_show(struct seq_file *m, void *p)
2362306a36Sopenharmony_ci{
2462306a36Sopenharmony_ci#define MXC_ISI_DEBUG_REG(name)		{ name, #name }
2562306a36Sopenharmony_ci	static const struct {
2662306a36Sopenharmony_ci		u32 offset;
2762306a36Sopenharmony_ci		const char * const name;
2862306a36Sopenharmony_ci	} registers[] = {
2962306a36Sopenharmony_ci		MXC_ISI_DEBUG_REG(CHNL_CTRL),
3062306a36Sopenharmony_ci		MXC_ISI_DEBUG_REG(CHNL_IMG_CTRL),
3162306a36Sopenharmony_ci		MXC_ISI_DEBUG_REG(CHNL_OUT_BUF_CTRL),
3262306a36Sopenharmony_ci		MXC_ISI_DEBUG_REG(CHNL_IMG_CFG),
3362306a36Sopenharmony_ci		MXC_ISI_DEBUG_REG(CHNL_IER),
3462306a36Sopenharmony_ci		MXC_ISI_DEBUG_REG(CHNL_STS),
3562306a36Sopenharmony_ci		MXC_ISI_DEBUG_REG(CHNL_SCALE_FACTOR),
3662306a36Sopenharmony_ci		MXC_ISI_DEBUG_REG(CHNL_SCALE_OFFSET),
3762306a36Sopenharmony_ci		MXC_ISI_DEBUG_REG(CHNL_CROP_ULC),
3862306a36Sopenharmony_ci		MXC_ISI_DEBUG_REG(CHNL_CROP_LRC),
3962306a36Sopenharmony_ci		MXC_ISI_DEBUG_REG(CHNL_CSC_COEFF0),
4062306a36Sopenharmony_ci		MXC_ISI_DEBUG_REG(CHNL_CSC_COEFF1),
4162306a36Sopenharmony_ci		MXC_ISI_DEBUG_REG(CHNL_CSC_COEFF2),
4262306a36Sopenharmony_ci		MXC_ISI_DEBUG_REG(CHNL_CSC_COEFF3),
4362306a36Sopenharmony_ci		MXC_ISI_DEBUG_REG(CHNL_CSC_COEFF4),
4462306a36Sopenharmony_ci		MXC_ISI_DEBUG_REG(CHNL_CSC_COEFF5),
4562306a36Sopenharmony_ci		MXC_ISI_DEBUG_REG(CHNL_ROI_0_ALPHA),
4662306a36Sopenharmony_ci		MXC_ISI_DEBUG_REG(CHNL_ROI_0_ULC),
4762306a36Sopenharmony_ci		MXC_ISI_DEBUG_REG(CHNL_ROI_0_LRC),
4862306a36Sopenharmony_ci		MXC_ISI_DEBUG_REG(CHNL_ROI_1_ALPHA),
4962306a36Sopenharmony_ci		MXC_ISI_DEBUG_REG(CHNL_ROI_1_ULC),
5062306a36Sopenharmony_ci		MXC_ISI_DEBUG_REG(CHNL_ROI_1_LRC),
5162306a36Sopenharmony_ci		MXC_ISI_DEBUG_REG(CHNL_ROI_2_ALPHA),
5262306a36Sopenharmony_ci		MXC_ISI_DEBUG_REG(CHNL_ROI_2_ULC),
5362306a36Sopenharmony_ci		MXC_ISI_DEBUG_REG(CHNL_ROI_2_LRC),
5462306a36Sopenharmony_ci		MXC_ISI_DEBUG_REG(CHNL_ROI_3_ALPHA),
5562306a36Sopenharmony_ci		MXC_ISI_DEBUG_REG(CHNL_ROI_3_ULC),
5662306a36Sopenharmony_ci		MXC_ISI_DEBUG_REG(CHNL_ROI_3_LRC),
5762306a36Sopenharmony_ci		MXC_ISI_DEBUG_REG(CHNL_OUT_BUF1_ADDR_Y),
5862306a36Sopenharmony_ci		MXC_ISI_DEBUG_REG(CHNL_OUT_BUF1_ADDR_U),
5962306a36Sopenharmony_ci		MXC_ISI_DEBUG_REG(CHNL_OUT_BUF1_ADDR_V),
6062306a36Sopenharmony_ci		MXC_ISI_DEBUG_REG(CHNL_OUT_BUF_PITCH),
6162306a36Sopenharmony_ci		MXC_ISI_DEBUG_REG(CHNL_IN_BUF_ADDR),
6262306a36Sopenharmony_ci		MXC_ISI_DEBUG_REG(CHNL_IN_BUF_PITCH),
6362306a36Sopenharmony_ci		MXC_ISI_DEBUG_REG(CHNL_MEM_RD_CTRL),
6462306a36Sopenharmony_ci		MXC_ISI_DEBUG_REG(CHNL_OUT_BUF2_ADDR_Y),
6562306a36Sopenharmony_ci		MXC_ISI_DEBUG_REG(CHNL_OUT_BUF2_ADDR_U),
6662306a36Sopenharmony_ci		MXC_ISI_DEBUG_REG(CHNL_OUT_BUF2_ADDR_V),
6762306a36Sopenharmony_ci		MXC_ISI_DEBUG_REG(CHNL_SCL_IMG_CFG),
6862306a36Sopenharmony_ci		MXC_ISI_DEBUG_REG(CHNL_FLOW_CTRL),
6962306a36Sopenharmony_ci	};
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci	struct mxc_isi_pipe *pipe = m->private;
7262306a36Sopenharmony_ci	unsigned int i;
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci	if (!pm_runtime_get_if_in_use(pipe->isi->dev))
7562306a36Sopenharmony_ci		return 0;
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ci	seq_printf(m, "--- ISI pipe %u registers ---\n", pipe->id);
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(registers); ++i)
8062306a36Sopenharmony_ci		seq_printf(m, "%20s[0x%02x]: 0x%08x\n",
8162306a36Sopenharmony_ci			   registers[i].name, registers[i].offset,
8262306a36Sopenharmony_ci			   mxc_isi_read(pipe, registers[i].offset));
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci	pm_runtime_put(pipe->isi->dev);
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci	return 0;
8762306a36Sopenharmony_ci}
8862306a36Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(mxc_isi_debug_dump_regs);
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_civoid mxc_isi_debug_init(struct mxc_isi_dev *isi)
9162306a36Sopenharmony_ci{
9262306a36Sopenharmony_ci	unsigned int i;
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci	isi->debugfs_root = debugfs_create_dir(dev_name(isi->dev), NULL);
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ci	for (i = 0; i < isi->pdata->num_channels; ++i) {
9762306a36Sopenharmony_ci		struct mxc_isi_pipe *pipe = &isi->pipes[i];
9862306a36Sopenharmony_ci		char name[8];
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci		sprintf(name, "pipe%u", pipe->id);
10162306a36Sopenharmony_ci		debugfs_create_file(name, 0444, isi->debugfs_root, pipe,
10262306a36Sopenharmony_ci				    &mxc_isi_debug_dump_regs_fops);
10362306a36Sopenharmony_ci	}
10462306a36Sopenharmony_ci}
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_civoid mxc_isi_debug_cleanup(struct mxc_isi_dev *isi)
10762306a36Sopenharmony_ci{
10862306a36Sopenharmony_ci	debugfs_remove_recursive(isi->debugfs_root);
10962306a36Sopenharmony_ci}
110