/*
* Copyright (C) 2013 NVIDIA Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/clk.h>
#include <linux/debugfs.h>
#include <linux/host1x.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/reset.h>
#include <drm/drm_mipi_dsi.h>
#include <drm/drm_panel.h>
#include <video/mipi_display.h>
#include "dc.h"
#include "drm.h"
#include "dsi.h"
#include "mipi-phy.h"
#define DSI_VIDEO_FIFO_DEPTH (1920 / 4)
#define DSI_HOST_FIFO_DEPTH 64
struct tegra_dsi {
struct host1x_client client;
struct tegra_output output;
struct device *dev;
void __iomem *regs;
struct reset_control *rst;
struct clk *clk_parent;
struct clk *clk_lp;
struct clk *clk;
struct drm_info_list *debugfs_files;
struct drm_minor *minor;
struct dentry *debugfs;
enum mipi_dsi_pixel_format format;
unsigned int lanes;
struct tegra_mipi_device *mipi;
struct mipi_dsi_host host;
};
static inline struct tegra_dsi *
host1x_client_to_dsi(struct host1x_client *client)
{
return container_of(client, struct tegra_dsi, client);
}
static inline struct tegra_dsi *host_to_tegra(struct mipi_dsi_host *host)
{
return container_of(host, struct tegra_dsi, host);
}
static inline struct tegra_dsi *to_dsi(struct tegra_output *output)
{
return container_of(output, struct tegra_dsi, output);
}
static inline unsigned long tegra_dsi_readl(struct tegra_dsi *dsi,
unsigned long reg)
{
return readl(dsi->regs + (reg << 2));
}
static inline void tegra_dsi_writel(struct tegra_dsi *dsi, unsigned long value,
unsigned long reg)
{
writel(value, dsi->regs + (reg << 2));
}
static int tegra_dsi_show_regs(struct seq_file *s, void *data)
{
struct drm_info_node *node = s->private;
struct tegra_dsi *dsi = node->info_ent->data;
#define DUMP_REG(name) \
seq_printf(s, "%-32s %#05x %08lx\n", #name, name, \
tegra_dsi_readl(dsi, name))
DUMP_REG(DSI_INCR_SYNCPT);
DUMP_REG(DSI_INCR_SYNCPT_CONTROL);
DUMP_REG(DSI_INCR_SYNCPT_ERROR);
DUMP_REG(DSI_CTXSW);
DUMP_REG(DSI_RD_DATA);
DUMP_REG(DSI_WR_DATA);
DUMP_REG(DSI_POWER_CONTROL);
DUMP_REG(DSI_INT_ENABLE);
DUMP_REG(DSI_INT_STATUS);
DUMP_REG(DSI_INT_MASK);
DUMP_REG(DSI_HOST_CONTROL);
DUMP_REG(DSI_CONTROL);
DUMP_REG(DSI_SOL_DELAY);
DUMP_REG(DSI_MAX_THRESHOLD);
DUMP_REG(DSI_TRIGGER);
DUMP_REG(DSI_TX_CRC);
DUMP_REG(DSI_STATUS);
DUMP_REG(DSI_INIT_SEQ_CONTROL);
DUMP_REG(DSI_INIT_SEQ_DATA_0);
DUMP_REG(DSI_INIT_SEQ_DATA_1);
DUMP_REG(DSI_INIT_SEQ_DATA_2);
DUMP_REG(DSI_INIT_SEQ_DATA_3);
DUMP_REG(DSI_INIT_SEQ_DATA_4);
DUMP_REG(DSI_INIT_SEQ_DATA_5);
DUMP_REG(DSI_INIT_SEQ_DATA_6);
DUMP_REG(DSI_INIT_SEQ_DATA_7);
DUMP_REG(DSI_PKT_SEQ_0_LO);
DUMP_REG(DSI_PKT_SEQ_0_HI);
DUMP_REG(DSI_PKT_SEQ_1_LO);
DUMP_REG(DSI_PKT_SEQ_1_HI);
DUMP_REG(DSI_PKT_SEQ_2_LO);
DUMP_REG(DSI_PKT_SEQ_2_HI);
DUMP_REG(DSI_PKT_SEQ_3_LO);
DUMP_REG(DSI_PKT_SEQ_3_HI);
DUMP_REG(DSI_PKT_SEQ_4_LO);
DUMP_REG(DSI_PKT_SEQ_4_HI);
DUMP_REG(DSI_PKT_SEQ_5_LO);
DUMP_REG(DSI_PKT_SEQ_5_HI);
DUMP_REG(DSI_DCS_CMDS);
DUMP_REG(DSI_PKT_LEN_0_1);
DUMP_REG(DSI_PKT_LEN_2_3);
DUMP_REG(DSI_PKT_LEN_4_5);
DUMP_REG(DSI_PKT_LEN_6_7);
DUMP_REG(DSI_PHY_TIMING_0);
DUMP_REG(DSI_PHY_TIMING_1);
DUMP_REG(DSI_PHY_TIMING_2);
DUMP_REG(DSI_BTA_TIMING);
DUMP_REG(DSI_TIMEOUT_0);
DUMP_REG(DSI_TIMEOUT_1);
DUMP_REG(DSI_TO_TALLY);
DUMP_REG(DSI_PAD_CONTROL_0);
DUMP_REG(DSI_PAD_CONTROL_CD);
DUMP_REG(DSI_PAD_CD_STATUS);
DUMP_REG(DSI_VIDEO_MODE_CONTROL);
DUMP_REG(DSI_PAD_CONTROL_1);
DUMP_REG(DSI_PAD_CONTROL_2);
DUMP_REG(DSI_PAD_CONTROL_3);
DUMP_REG(DSI_PAD_CONTROL_4);
DUMP_REG(DSI_GANGED_MODE_CONTROL);
DUMP_REG(DSI_GANGED_MODE_START);
DUMP_REG(DSI_GANGED_MODE_SIZE);
DUMP_REG(DSI_RAW_DATA_BYTE_COUNT);
DUMP_REG(DSI_ULTRA_LOW_POWER_CONTROL);
DUMP_REG(DSI_INIT_SEQ_DATA_8);
DUMP_REG(DSI_INIT_SEQ_DATA_9);
DUMP_REG(DSI_INIT_SEQ_DATA_10);
DUMP_REG(DSI_INIT_SEQ_DATA_11);
DUMP_REG(DSI_INIT_SEQ_DATA_12);
DUMP_REG(DSI_INIT_SEQ_DATA_13);
DUMP_REG(DSI_INIT_SEQ_DATA_14);
DUMP_REG(DSI_INIT_SEQ_DATA_15);
#undef DUMP_REG
return 0;
}
static struct drm_info_list debugfs_files[] = {
{ "regs", tegra_dsi_show_regs, 0, NULL },
};
static int tegra_dsi_debugfs_init(struct tegra_dsi *dsi,
struct drm_minor *minor)
{
const char *name = dev_name(dsi->dev);
unsigned int i;
int err;
dsi