131 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Copyright 2019-2020 NXP4 */5 6#include <linux/debugfs.h>7#include <linux/device.h>8#include <linux/io.h>9#include <linux/kernel.h>10#include <linux/pm_runtime.h>11#include <linux/seq_file.h>12#include <linux/types.h>13 14#include "imx8-isi-core.h"15#include "imx8-isi-regs.h"16 17static inline u32 mxc_isi_read(struct mxc_isi_pipe *pipe, u32 reg)18{19 return readl(pipe->regs + reg);20}21 22static int mxc_isi_debug_dump_regs_show(struct seq_file *m, void *p)23{24#define MXC_ISI_DEBUG_REG(name) { name, #name }25 struct debug_regs {26 u32 offset;27 const char * const name;28 };29 static const struct debug_regs registers[] = {30 MXC_ISI_DEBUG_REG(CHNL_CTRL),31 MXC_ISI_DEBUG_REG(CHNL_IMG_CTRL),32 MXC_ISI_DEBUG_REG(CHNL_OUT_BUF_CTRL),33 MXC_ISI_DEBUG_REG(CHNL_IMG_CFG),34 MXC_ISI_DEBUG_REG(CHNL_IER),35 MXC_ISI_DEBUG_REG(CHNL_STS),36 MXC_ISI_DEBUG_REG(CHNL_SCALE_FACTOR),37 MXC_ISI_DEBUG_REG(CHNL_SCALE_OFFSET),38 MXC_ISI_DEBUG_REG(CHNL_CROP_ULC),39 MXC_ISI_DEBUG_REG(CHNL_CROP_LRC),40 MXC_ISI_DEBUG_REG(CHNL_CSC_COEFF0),41 MXC_ISI_DEBUG_REG(CHNL_CSC_COEFF1),42 MXC_ISI_DEBUG_REG(CHNL_CSC_COEFF2),43 MXC_ISI_DEBUG_REG(CHNL_CSC_COEFF3),44 MXC_ISI_DEBUG_REG(CHNL_CSC_COEFF4),45 MXC_ISI_DEBUG_REG(CHNL_CSC_COEFF5),46 MXC_ISI_DEBUG_REG(CHNL_ROI_0_ALPHA),47 MXC_ISI_DEBUG_REG(CHNL_ROI_0_ULC),48 MXC_ISI_DEBUG_REG(CHNL_ROI_0_LRC),49 MXC_ISI_DEBUG_REG(CHNL_ROI_1_ALPHA),50 MXC_ISI_DEBUG_REG(CHNL_ROI_1_ULC),51 MXC_ISI_DEBUG_REG(CHNL_ROI_1_LRC),52 MXC_ISI_DEBUG_REG(CHNL_ROI_2_ALPHA),53 MXC_ISI_DEBUG_REG(CHNL_ROI_2_ULC),54 MXC_ISI_DEBUG_REG(CHNL_ROI_2_LRC),55 MXC_ISI_DEBUG_REG(CHNL_ROI_3_ALPHA),56 MXC_ISI_DEBUG_REG(CHNL_ROI_3_ULC),57 MXC_ISI_DEBUG_REG(CHNL_ROI_3_LRC),58 MXC_ISI_DEBUG_REG(CHNL_OUT_BUF1_ADDR_Y),59 MXC_ISI_DEBUG_REG(CHNL_OUT_BUF1_ADDR_U),60 MXC_ISI_DEBUG_REG(CHNL_OUT_BUF1_ADDR_V),61 MXC_ISI_DEBUG_REG(CHNL_OUT_BUF_PITCH),62 MXC_ISI_DEBUG_REG(CHNL_IN_BUF_ADDR),63 MXC_ISI_DEBUG_REG(CHNL_IN_BUF_PITCH),64 MXC_ISI_DEBUG_REG(CHNL_MEM_RD_CTRL),65 MXC_ISI_DEBUG_REG(CHNL_OUT_BUF2_ADDR_Y),66 MXC_ISI_DEBUG_REG(CHNL_OUT_BUF2_ADDR_U),67 MXC_ISI_DEBUG_REG(CHNL_OUT_BUF2_ADDR_V),68 MXC_ISI_DEBUG_REG(CHNL_SCL_IMG_CFG),69 MXC_ISI_DEBUG_REG(CHNL_FLOW_CTRL),70 };71 /* These registers contain the upper 4 bits of 36-bit DMA addresses. */72 static const struct debug_regs registers_36bit_dma[] = {73 MXC_ISI_DEBUG_REG(CHNL_Y_BUF1_XTND_ADDR),74 MXC_ISI_DEBUG_REG(CHNL_U_BUF1_XTND_ADDR),75 MXC_ISI_DEBUG_REG(CHNL_V_BUF1_XTND_ADDR),76 MXC_ISI_DEBUG_REG(CHNL_Y_BUF2_XTND_ADDR),77 MXC_ISI_DEBUG_REG(CHNL_U_BUF2_XTND_ADDR),78 MXC_ISI_DEBUG_REG(CHNL_V_BUF2_XTND_ADDR),79 MXC_ISI_DEBUG_REG(CHNL_IN_BUF_XTND_ADDR),80 };81 82 struct mxc_isi_pipe *pipe = m->private;83 unsigned int i;84 85 if (!pm_runtime_get_if_in_use(pipe->isi->dev))86 return 0;87 88 seq_printf(m, "--- ISI pipe %u registers ---\n", pipe->id);89 90 for (i = 0; i < ARRAY_SIZE(registers); ++i)91 seq_printf(m, "%21s[0x%02x]: 0x%08x\n",92 registers[i].name, registers[i].offset,93 mxc_isi_read(pipe, registers[i].offset));94 95 if (pipe->isi->pdata->has_36bit_dma) {96 for (i = 0; i < ARRAY_SIZE(registers_36bit_dma); ++i) {97 const struct debug_regs *reg = ®isters_36bit_dma[i];98 99 seq_printf(m, "%21s[0x%02x]: 0x%08x\n",100 reg->name, reg->offset,101 mxc_isi_read(pipe, reg->offset));102 }103 }104 105 pm_runtime_put(pipe->isi->dev);106 107 return 0;108}109DEFINE_SHOW_ATTRIBUTE(mxc_isi_debug_dump_regs);110 111void mxc_isi_debug_init(struct mxc_isi_dev *isi)112{113 unsigned int i;114 115 isi->debugfs_root = debugfs_create_dir(dev_name(isi->dev), NULL);116 117 for (i = 0; i < isi->pdata->num_channels; ++i) {118 struct mxc_isi_pipe *pipe = &isi->pipes[i];119 char name[8];120 121 sprintf(name, "pipe%u", pipe->id);122 debugfs_create_file(name, 0444, isi->debugfs_root, pipe,123 &mxc_isi_debug_dump_regs_fops);124 }125}126 127void mxc_isi_debug_cleanup(struct mxc_isi_dev *isi)128{129 debugfs_remove_recursive(isi->debugfs_root);130}131