/*
 * Copyright (C) STMicroelectronics SA 2014
 * Author: Vincent Abriou <vincent.abriou@st.com> for STMicroelectronics.
 * License terms:  GNU General Public License (GPL), version 2
 */

#include <linux/clk.h>
#include <linux/component.h>
#include <linux/debugfs.h>
#include <linux/module.h>
#include <linux/of_gpio.h>
#include <linux/platform_device.h>

#include <drm/drmP.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_panel.h>

#include "sti_awg_utils.h"
#include "sti_drv.h"
#include "sti_mixer.h"

/* DVO registers */
#define DVO_AWG_DIGSYNC_CTRL      0x0000
#define DVO_DOF_CFG               0x0004
#define DVO_LUT_PROG_LOW          0x0008
#define DVO_LUT_PROG_MID          0x000C
#define DVO_LUT_PROG_HIGH         0x0010
#define DVO_DIGSYNC_INSTR_I       0x0100

#define DVO_AWG_CTRL_EN           BIT(0)
#define DVO_AWG_FRAME_BASED_SYNC  BIT(2)

#define DVO_DOF_EN_LOWBYTE        BIT(0)
#define DVO_DOF_EN_MIDBYTE        BIT(1)
#define DVO_DOF_EN_HIGHBYTE       BIT(2)
#define DVO_DOF_EN                BIT(6)
#define DVO_DOF_MOD_COUNT_SHIFT   8

#define DVO_LUT_ZERO              0
#define DVO_LUT_Y_G               1
#define DVO_LUT_Y_G_DEL           2
#define DVO_LUT_CB_B              3
#define DVO_LUT_CB_B_DEL          4
#define DVO_LUT_CR_R              5
#define DVO_LUT_CR_R_DEL          6
#define DVO_LUT_HOLD              7

struct dvo_config {
	u32 flags;
	u32 lowbyte;
	u32 midbyte;
	u32 highbyte;
	int (*awg_fwgen_fct)(
			struct awg_code_generation_params *fw_gen_params,
			struct awg_timing *timing);
};

static struct dvo_config rgb_24bit_de_cfg = {
	.flags         = (0L << DVO_DOF_MOD_COUNT_SHIFT),
	.lowbyte       = DVO_LUT_CR_R,
	.midbyte       = DVO_LUT_Y_G,
	.highbyte      = DVO_LUT_CB_B,
	.awg_fwgen_fct = sti_awg_generate_code_data_enable_mode,
};

/**
 * STI digital video output structure
 *
 * @dev: driver device
 * @drm_dev: pointer to drm device
 * @mode: current display mode selected
 * @regs: dvo registers
 * @clk_pix: pixel clock for dvo
 * @clk: clock for dvo
 * @clk_main_parent: dvo parent clock if main path used
 * @clk_aux_parent: dvo parent clock if aux path used
 * @panel_node: panel node reference from device tree
 * @panel: reference to the panel connected to the dvo
 * @enabled: true if dvo is enabled else false
 * @encoder: drm_encoder it is bound
 */
struct sti_dvo {
	struct device dev;
	struct drm_device *drm_dev;
	struct drm_display_mode mode;
	void __iomem *regs;
	struct clk *clk_pix;
	struct clk *clk;
	struct clk *clk_main_parent;
	struct clk *clk_aux_parent;
	struct device_node *panel_node;
	struct drm_panel *panel;
	struct dvo_config *config;
	bool enabled;
	struct drm_encoder *encoder;
	struct drm_bridge *bridge;
};

struct sti_dvo_connector {
	struct drm_connector drm_connector;
	struct drm_encoder *encoder;
	struct sti_dvo *dvo;
};

#define to_sti_dvo_connector(x) \
	container_of(x, struct sti_dvo_connector, drm_connector)

#define BLANKING_LEVEL 16
static int dvo_awg_generate_code(struct sti_dvo *dvo, u8 *ram_size, u32 *ram_code)
{
	struct drm_display_mode *mode = &dvo->mode;
	struct dvo_config *config = dvo->config;
	struct awg_code_generation_params fw_gen_params;
	struct awg_timing timing;

	fw_gen_params.ram_code = ram_code;
	fw_gen_params.instruction_offset = 0;

	timing.total_lines = mode->vtotal;
	timing.active_lines = mode->vdisplay;
	timing.blanking_lines = mode->vsync_start - mode->vdisplay;
	timing.trailing_lines = mode->vtotal - mode->vsync_start;
	timing.total_pixels = mode->htotal;
	timing.active_pixels = mode->hdisplay;
	timing.blanking_pixels = mode->hsync_start - mode->hdisplay;
	timing.trailing_pixels = mode->htotal - mode->hsync_start;
	timing.blanking_level = BLANKING_LEVEL;

	if (config->awg_fwgen_fct(&fw_gen_params, &timing)) {
		DRM_ERROR("AWG firmware not properly generated\n");
		return -EINVAL;
	}

	*ram_size = fw_gen_params.instruction_offset;

	return 0;
}

/* Configure AWG, writing instructions
 *
 * @dvo: pointer to DVO structure
 * @awg_ram_code: pointer to AWG instructions table
 * @nb: nb of AWG instructions
 */
static void dvo_awg_configure(struct sti_dvo *dvo, u32 *awg_ram_code, int nb)
{
	int i;

	DRM_DEBUG_DRIVER("\n");

	for (i = 0; i < nb; i++)
		writel(awg_ram_code[i],
		       dvo->regs + DVO_DIGSYNC_INSTR_I + i * 4);
	for (i = nb; i < AWG_MAX_INST; i++)
		writel(0, dvo->regs + DVO_DIGSYNC_INSTR_I + i * 4);

	writel(DVO_AWG_CTRL_EN, dvo->regs + DVO_AWG_DIGSYNC_CTRL);
}

#define DBGFS_DUMP(reg) seq_printf(s, "\n  %-25s 0x%08X", #reg, \
				   readl(dvo->regs + reg))

static void dvo_dbg_awg_microcode(struct seq_file *s, void __iomem *reg)
{
	unsigned int i;

	seq_puts(s, "\n\n");
	seq_puts(s, "  DVO AWG microcode:");
	for (i = 0; i < AWG_MAX_INST; i++) {
		if (i % 8 == 0)
			seq_printf(s, "\n  %04X:", i);
		seq_printf(s, " %04X", readl(reg + i * 4));
	}
}

static int dvo_dbg_show(struct seq_file *s, void *data)
{
	struct drm_info_node *node = s->private;
	struct sti_dvo *dvo = (struct sti_dvo *)node->info_ent->data;

	seq_printf(s, "DVO: (vaddr = 0x%p)", dvo->regs);
	DBGFS_DUMP(DVO_AWG_DIGSYNC_CTRL);
	DBGFS_DUMP(DVO_DOF_CFG);
	DBGFS_DUMP(DVO_LUT_PROG_LOW);
	DBGFS_DUMP(DVO_LUT_PROG_MID);
	DBGFS_DUMP(DVO_LUT_PROG_HIGH);
	dvo_dbg_awg_microcode(s, dvo->regs + DVO_DIGSYNC_INSTR_I);
	seq_putc(s, '\n');
	return 0;
}

static struct drm_info_list dvo_debugfs_files[] = {
	{ "dvo", dvo_dbg_show, 0, NULL },
};

static int dvo_debugfs_init(struct sti_dvo *dvo, struct drm_minor *minor)
{
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(dvo_debugfs_files); i++)
		dvo_debugfs_files[i].data = dvo;

	return drm_debugfs_create_files(dvo_debugfs_files,
					ARRAY_SIZE(dvo_debugfs_files),
					minor->debugfs_root, minor);
}

static void sti_dvo_disable(struct drm_bridge *bridge)
{
	struct sti_dvo *dvo = bridge->driver_private;

	if (!dvo->enabled)
		return;

	DRM_DEBUG_DRIVER("\n");

	if (dvo->config->awg_fwgen_fct)
		writel(0x00000000, dvo->regs + DVO_AWG_DIGSYNC_CTRL);

	writel(0x00000000, dvo->regs + DVO_DOF_CFG);

	if (dvo->panel)
		dvo->panel->funcs->disable(dvo->panel);

	/* Disable/unprepare dvo clock */
	clk_disable_unprepare(dvo->clk_pix);
	clk_disable_unprepare(dvo->clk);

	dvo->enabled = false;
}

static void sti_dvo_pre_enable(struct drm_bridge *bridge)
{
	struct sti_dvo *dvo = bridge->driver_private;
	struct dvo_config *config = dvo->config;
	u32 val;

	DRM_DEBUG_DRIVER("\n");

	if (dvo->enabled)
		return;

	/* Make sure DVO is disabled */
	writel(0x00000000, dvo->regs + DVO_DOF_CFG);
	writel(0x00000000, dvo->regs + DVO_AWG_DIGSYNC_CTRL);

	if (config->awg_fwgen_fct) {
		u8 nb_instr;
		u32 awg_ram_code[AWG_MAX_INST];
		/* Configure AWG */
		if (!dvo_awg_generate_code(dvo, &nb_instr, awg_ram_code))
			dvo_awg_configure(dvo, awg_ram_code, nb_instr);
		else
			return;
	}

	/* Prepare/enable clocks */
	if (clk_prepare_enable(dvo->clk_pix))
		DRM_ERROR("Failed to prepare/enable dvo_pix clk\n");
	if (clk_prepare_enable(dvo->clk))
		DRM_ERROR("Failed to prepare/enable dvo clk\n");

	if (dvo->panel)
		dvo->panel->funcs->enable(dvo->panel);

	/* Set LUT */
	writel(config->lowbyte,  dvo->regs + DVO_LUT_PROG_LOW);
	writel(config->midbyte,  dvo->regs + DVO_LUT_PROG_MID);
	writel(config->highbyte, dvo->regs + DVO_LUT_PROG_HIGH);

	/* Digital output formatter config */
	val = (config->flags | DVO_DOF_EN);
	writel(val, dvo->regs + DVO_DOF_CFG);

	dvo->enabled = true;
}

static void sti_dvo_set_mode(struct drm_bridge *bridge,
			     struct drm_display_mode *mode,
			     struct drm_display_mode *adjusted_mode)
{
	struct sti_dvo *dvo = bridge->driver_private;
	struct sti_mixer *mixer = to_sti_mixer(dvo->encoder->crtc);
	int rate = mode->clock * 1000;
	struct clk *clkp;
	int ret;

	DRM_DEBUG_DRIVER("\n");

	memcpy(&dvo->mode, mode, sizeof(struct drm_display_mode));

	/* According to the path used (main or aux), the dvo clocks should
	 * have a different parent clock. */
	if (mixer->id == STI_MIXER_MAIN)
		clkp = dvo->clk_main_parent;
	else
		clkp = dvo->clk_aux_parent;

	if (clkp) {
		clk_set_parent(dvo->clk_pix, clkp);
		clk_set_parent(dvo->clk, clkp);
	}

	/* DVO clocks = compositor clock */
	ret = clk_set_rate(dvo->clk_pix, rate);
	if (ret < 0) {
		DRM_ERROR("Cannot set rate (%dHz) for dvo_pix clk\n", rate);
		return;
	}

	ret = clk_set_rate(dvo->clk, rate);
	if (ret < 0) {
		DRM_ERROR("Cannot set rate (%dHz) for dvo clk\n", rate);
		return;
	}

	/* For now, we only support 24bit data enable (DE) synchro format */
	dvo->config = &rgb_24bit_de_cfg;
}

static void sti_dvo_bridge_nope(struct drm_bridge *bridge)
{
	/* do nothing */
}

static const struct drm_bridge_funcs sti_dvo_bridge_funcs = {
	.pre_enable = sti_dvo_pre_enable,
	.enable = sti_dvo_bridge_nope,
	.disable = sti_dvo_disable,
	.post_disable = sti_dvo_bridge_nope,
	.mode_set = sti_dvo_set_mode,
};

static int sti_dvo_connector_get_modes(struct drm_connector *connector)
{
	struct sti_dvo_connector *dvo_connector
		= to_sti_dvo_connector(connector);
	struct sti_dvo *dvo = dvo_connector->dvo;

	if (dvo->panel)
		return dvo->panel->funcs->get_modes(dvo->panel);

	return 0;
}

#define CLK_TOLERANCE_HZ 50

static int sti_dvo_connector_mode_valid(struct drm_connector *connector,
					struct drm_display_mode *mode)
{
	int target = mode->clock * 1000;
	int target_min = target - CLK_TOLERANCE_HZ;
	int target_max = target + CLK_TOLERANCE_HZ;
	int result;
	struct sti_dvo_connector *dvo_connector
		= to_sti_dvo_connector(connector);
	struct sti_dvo *dvo = dvo_connector->dvo;

	result = clk_round_rate(dvo->clk_pix, target);

	DRM_DEBUG_DRIVER("target rate = %d => available rate = %d\n",
			 target, result);

	if ((result < target_min) || (result > target_max)) {
		DRM_DEBUG_DRIVER("dvo pixclk=%d not supported\n", target);
		return MODE_BAD;
	}

	return MODE_OK;
}

static const
struct drm_connector_helper_funcs sti_dvo_connector_helper_funcs = {
	.get_modes = sti_dvo_connector_get_modes,
	.mode_valid = sti_dvo_connector_mode_valid,
};

static enum drm_connector_status
sti_dvo_connector_detect(struct drm_connector *connector, bool force)
{
	struct sti_dvo_connector *dvo_connector
		= to_sti_dvo_connector(connector);
	struct sti_dvo *dvo = dvo_connector->dvo;

	DRM_DEBUG_DRIVER("\n");

	if (!dvo->panel) {
		dvo->panel = of_drm_find_panel(dvo->panel_node);
		if (IS_ERR(dvo->panel))
			dvo->panel = NULL;
		else
			drm_panel_attach(dvo->panel, connector);
	}

	if (dvo->panel)
		return connector_status_connected;

	return connector_status_disconnected;
}

static int sti_dvo_late_register(struct drm_connector *connector)
{
	struct sti_dvo_connector *dvo_connector
		= to_sti_dvo_connector(connector);
	struct sti_dvo *dvo = dvo_connector->dvo;

	if (dvo_debugfs_init(dvo, dvo->drm_dev->primary)) {
		DRM_ERROR("DVO debugfs setup failed\n");
		return -EINVAL;
	}

	return 0;
}

static const struct drm_connector_funcs sti_dvo_connector_funcs = {
	.fill_modes = drm_helper_probe_single_connector_modes,
	.detect = sti_dvo_connector_detect,
	.destroy = drm_connector_cleanup,
	.reset = drm_atomic_helper_connector_reset,
	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
	.late_register = sti_dvo_late_register,
};

static struct drm_encoder *sti_dvo_find_encoder(struct drm_device *dev)
{
	struct drm_encoder *encoder;

	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
		if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS)
			return encoder;
	}

	return NULL;
}

static int sti_dvo_bind(struct device *dev, struct device *master, void *data)
{
	struct sti_dvo *dvo = dev_get_drvdata(dev);
	struct drm_device *drm_dev = data;
	struct drm_encoder *encoder;
	struct sti_dvo_connector *connector;
	struct drm_connector *drm_connector;
	struct drm_bridge *bridge;
	int err;

	/* Set the drm device handle */
	dvo->drm_dev = drm_dev;

	encoder = sti_dvo_find_encoder(drm_dev);
	if (!encoder)
		return -ENOMEM;

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

	connector->dvo = dvo;

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

	bridge->driver_private = dvo;
	bridge->funcs = &sti_dvo_bridge_funcs;
	bridge->of_node = dvo->dev.of_node;
	drm_bridge_add(bridge);

	err = drm_bridge_attach(encoder, bridge, NULL);
	if (err) {
		DRM_ERROR("Failed to attach bridge\n");
		return err;
	}

	dvo->bridge = bridge;
	connector->encoder = encoder;
	dvo->encoder = encoder;

	drm_connector = (struct drm_connector *)connector;

	drm_connector->polled = DRM_CONNECTOR_POLL_HPD;

	drm_connector_init(drm_dev, drm_connector,
			   &sti_dvo_connector_funcs, DRM_MODE_CONNECTOR_LVDS);
	drm_connector_helper_add(drm_connector,
				 &sti_dvo_connector_helper_funcs);

	err = drm_connector_attach_encoder(drm_connector, encoder);
	if (err) {
		DRM_ERROR("Failed to attach a connector to a encoder\n");
		goto err_sysfs;
	}

	return 0;

err_sysfs:
	drm_bridge_remove(bridge);
	return -EINVAL;
}

static void sti_dvo_unbind(struct device *dev,
			   struct device *master, void *data)
{
	struct sti_dvo *dvo = dev_get_drvdata(dev);

	drm_bridge_remove(dvo->bridge);
}

static const struct component_ops sti_dvo_ops = {
	.bind = sti_dvo_bind,
	.unbind = sti_dvo_unbind,
};

static int sti_dvo_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct sti_dvo *dvo;
	struct resource *res;
	struct device_node *np = dev->of_node;

	DRM_INFO("%s\n", __func__);

	dvo = devm_kzalloc(dev, sizeof(*dvo), GFP_KERNEL);
	if (!dvo) {
		DRM_ERROR("Failed to allocate memory for DVO\n");
		return -ENOMEM;
	}

	dvo->dev = pdev->dev;

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dvo-reg");
	if (!res) {
		DRM_ERROR("Invalid dvo resource\n");
		return -ENOMEM;
	}
	dvo->regs = devm_ioremap_nocache(dev, res->start,
			resource_size(res));
	if (!dvo->regs)
		return -ENOMEM;

	dvo->clk_pix = devm_clk_get(dev, "dvo_pix");
	if (IS_ERR(dvo->clk_pix)) {
		DRM_ERROR("Cannot get dvo_pix clock\n");
		return PTR_ERR(dvo->clk_pix);
	}

	dvo->clk = devm_clk_get(dev, "dvo");
	if (IS_ERR(dvo->clk)) {
		DRM_ERROR("Cannot get dvo clock\n");
		return PTR_ERR(dvo->clk);
	}

	dvo->clk_main_parent = devm_clk_get(dev, "main_parent");
	if (IS_ERR(dvo->clk_main_parent)) {
		DRM_DEBUG_DRIVER("Cannot get main_parent clock\n");
		dvo->clk_main_parent = NULL;
	}

	dvo->clk_aux_parent = devm_clk_get(dev, "aux_parent");
	if (IS_ERR(dvo->clk_aux_parent)) {
		DRM_DEBUG_DRIVER("Cannot get aux_parent clock\n");
		dvo->clk_aux_parent = NULL;
	}

	dvo->panel_node = of_parse_phandle(np, "sti,panel", 0);
	if (!dvo->panel_node)
		DRM_ERROR("No panel associated to the dvo output\n");
	of_node_put(dvo->panel_node);

	platform_set_drvdata(pdev, dvo);

	return component_add(&pdev->dev, &sti_dvo_ops);
}

static int sti_dvo_remove(struct platform_device *pdev)
{
	component_del(&pdev->dev, &sti_dvo_ops);
	return 0;
}

static const struct of_device_id dvo_of_match[] = {
	{ .compatible = "st,stih407-dvo", },
	{ /* end node */ }
};
MODULE_DEVICE_TABLE(of, dvo_of_match);

struct platform_driver sti_dvo_driver = {
	.driver = {
		.name = "sti-dvo",
		.owner = THIS_MODULE,
		.of_match_table = dvo_of_match,
	},
	.probe = sti_dvo_probe,
	.remove = sti_dvo_remove,
};

MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@st.com>");
MODULE_DESCRIPTION("STMicroelectronics SoC DRM driver");
MODULE_LICENSE("GPL");
