// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
 */

#define pr_fmt(fmt)"[drm-dp] %s: " fmt, __func__

#include <linux/debugfs.h>
#include <drm/drm_connector.h>
#include <drm/drm_file.h>

#include "dp_catalog.h"
#include "dp_aux.h"
#include "dp_ctrl.h"
#include "dp_debug.h"
#include "dp_display.h"

#define DEBUG_NAME "msm_dp"

struct msm_dp_debug_private {
	struct msm_dp_link *link;
	struct msm_dp_panel *panel;
	struct drm_connector *connector;
};

static int msm_dp_debug_show(struct seq_file *seq, void *p)
{
	struct msm_dp_debug_private *debug = seq->private;
	u64 lclk = 0;
	u32 link_params_rate;
	const struct drm_display_mode *drm_mode;

	if (!debug)
		return -ENODEV;

	drm_mode = &debug->panel->msm_dp_mode.drm_mode;

	seq_printf(seq, "\tname = %s\n", DEBUG_NAME);
	seq_printf(seq, "\tdrm_dp_link\n\t\trate = %u\n",
			debug->panel->link_info.rate);
	seq_printf(seq, "\t\tnum_lanes = %u\n",
			debug->panel->link_info.num_lanes);
	seq_printf(seq, "\t\tcapabilities = %lu\n",
			debug->panel->link_info.capabilities);
	seq_printf(seq, "\tdp_panel_info:\n\t\tactive = %dx%d\n",
			drm_mode->hdisplay,
			drm_mode->vdisplay);
	seq_printf(seq, "\t\tback_porch = %dx%d\n",
			drm_mode->htotal - drm_mode->hsync_end,
			drm_mode->vtotal - drm_mode->vsync_end);
	seq_printf(seq, "\t\tfront_porch = %dx%d\n",
			drm_mode->hsync_start - drm_mode->hdisplay,
			drm_mode->vsync_start - drm_mode->vdisplay);
	seq_printf(seq, "\t\tsync_width = %dx%d\n",
			drm_mode->hsync_end - drm_mode->hsync_start,
			drm_mode->vsync_end - drm_mode->vsync_start);
	seq_printf(seq, "\t\tactive_low = %dx%d\n",
			debug->panel->msm_dp_mode.h_active_low,
			debug->panel->msm_dp_mode.v_active_low);
	seq_printf(seq, "\t\th_skew = %d\n",
			drm_mode->hskew);
	seq_printf(seq, "\t\trefresh rate = %d\n",
			drm_mode_vrefresh(drm_mode));
	seq_printf(seq, "\t\tpixel clock khz = %d\n",
			drm_mode->clock);
	seq_printf(seq, "\t\tbpp = %d\n",
			debug->panel->msm_dp_mode.bpp);

	/* Link Information */
	seq_printf(seq, "\tdp_link:\n\t\ttest_requested = %d\n",
			debug->link->sink_request);
	seq_printf(seq, "\t\tnum_lanes = %d\n",
			debug->link->link_params.num_lanes);
	link_params_rate = debug->link->link_params.rate;
	seq_printf(seq, "\t\tbw_code = %d\n",
			drm_dp_link_rate_to_bw_code(link_params_rate));
	lclk = debug->link->link_params.rate * 1000;
	seq_printf(seq, "\t\tlclk = %lld\n", lclk);
	seq_printf(seq, "\t\tv_level = %d\n",
			debug->link->phy_params.v_level);
	seq_printf(seq, "\t\tp_level = %d\n",
			debug->link->phy_params.p_level);

	return 0;
}
DEFINE_SHOW_ATTRIBUTE(msm_dp_debug);

static int msm_dp_test_data_show(struct seq_file *m, void *data)
{
	const struct msm_dp_debug_private *debug = m->private;
	const struct drm_connector *connector = debug->connector;
	u32 bpc;

	if (connector->status == connector_status_connected) {
		bpc = debug->link->test_video.test_bit_depth;
		seq_printf(m, "hdisplay: %d\n",
				debug->link->test_video.test_h_width);
		seq_printf(m, "vdisplay: %d\n",
				debug->link->test_video.test_v_height);
		seq_printf(m, "bpc: %u\n",
				msm_dp_link_bit_depth_to_bpp(bpc) / 3);
	} else {
		seq_puts(m, "0");
	}

	return 0;
}
DEFINE_SHOW_ATTRIBUTE(msm_dp_test_data);

static int msm_dp_test_type_show(struct seq_file *m, void *data)
{
	const struct msm_dp_debug_private *debug = m->private;
	const struct drm_connector *connector = debug->connector;

	if (connector->status == connector_status_connected)
		seq_printf(m, "%02x", DP_TEST_LINK_VIDEO_PATTERN);
	else
		seq_puts(m, "0");

	return 0;
}
DEFINE_SHOW_ATTRIBUTE(msm_dp_test_type);

static ssize_t msm_dp_test_active_write(struct file *file,
		const char __user *ubuf,
		size_t len, loff_t *offp)
{
	char *input_buffer;
	int status = 0;
	const struct msm_dp_debug_private *debug;
	const struct drm_connector *connector;
	int val = 0;

	debug = ((struct seq_file *)file->private_data)->private;
	connector = debug->connector;

	if (len == 0)
		return 0;

	input_buffer = memdup_user_nul(ubuf, len);
	if (IS_ERR(input_buffer))
		return PTR_ERR(input_buffer);

	DRM_DEBUG_DRIVER("Copied %d bytes from user\n", (unsigned int)len);

	if (connector->status == connector_status_connected) {
		status = kstrtoint(input_buffer, 10, &val);
		if (status < 0) {
			kfree(input_buffer);
			return status;
		}
		DRM_DEBUG_DRIVER("Got %d for test active\n", val);
		/* To prevent erroneous activation of the compliance
		 * testing code, only accept an actual value of 1 here
		 */
		if (val == 1)
			debug->panel->video_test = true;
		else
			debug->panel->video_test = false;
	}
	kfree(input_buffer);

	*offp += len;
	return len;
}

static int msm_dp_test_active_show(struct seq_file *m, void *data)
{
	struct msm_dp_debug_private *debug = m->private;
	struct drm_connector *connector = debug->connector;

	if (connector->status == connector_status_connected) {
		if (debug->panel->video_test)
			seq_puts(m, "1");
		else
			seq_puts(m, "0");
	} else {
		seq_puts(m, "0");
	}

	return 0;
}

static int msm_dp_test_active_open(struct inode *inode,
		struct file *file)
{
	return single_open(file, msm_dp_test_active_show,
			inode->i_private);
}

static const struct file_operations test_active_fops = {
	.owner = THIS_MODULE,
	.open = msm_dp_test_active_open,
	.read = seq_read,
	.llseek = seq_lseek,
	.release = single_release,
	.write = msm_dp_test_active_write
};

int msm_dp_debug_init(struct device *dev, struct msm_dp_panel *panel,
		  struct msm_dp_link *link,
		  struct drm_connector *connector,
		  struct dentry *root, bool is_edp)
{
	struct msm_dp_debug_private *debug;

	if (!dev || !panel || !link) {
		DRM_ERROR("invalid input\n");
		return -EINVAL;
	}

	debug = devm_kzalloc(dev, sizeof(*debug), GFP_KERNEL);
	if (!debug)
		return -ENOMEM;

	debug->link = link;
	debug->panel = panel;

	debugfs_create_file("dp_debug", 0444, root,
			debug, &msm_dp_debug_fops);

	if (!is_edp) {
		debugfs_create_file("dp_test_active", 0444,
				    root,
				    debug, &test_active_fops);

		debugfs_create_file("dp_test_data", 0444,
				    root,
				    debug, &msm_dp_test_data_fops);

		debugfs_create_file("dp_test_type", 0444,
				    root,
				    debug, &msm_dp_test_type_fops);
	}

	return 0;
}
