/*
 * 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/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_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
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);
}

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;
}

struct drm_encoder *sti_dvo_best_encoder(struct drm_connector *connector)
{
	struct sti_dvo_connector *dvo_connector
		= to_sti_dvo_connector(connector);

	/* Best encoder is the one associated during connector creation */
	return dvo_connector->encoder;
}

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,
	.best_encoder = sti_dvo_best_encoder,
};

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 (dvo->panel)
		if (!drm_panel_attach(dvo->panel, connector))
			return connector_status_connected;

	return connector_status_disconnected;
}

static void sti_dvo_connector_destroy(struct drm_connector *connector)
{
	struct sti_dvo_connector *dvo_connector
		= to_sti_dvo_connector(connector);

	drm_connector_unregister(connector);
	drm_connector_cleanup(connector);
	kfree(dvo_connector);
}

static const struct drm_connector_funcs sti_dvo_connector_funcs = {
	.dpms = drm_atomic_helper_connector_dpms,
	.fill_modes = drm_helper_probe_single_connector_modes,
	.detect = sti_dvo_connector_detect,
	.destroy = sti_dvo_connector_destroy,
	.reset = drm_atomic_helper_connector_reset,
	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
};

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;
	err = drm_bridge_add(bridge);
	if (err) {
		DRM_ERROR("Failed to add bridge\n");
		return err;
	}

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

	dvo->bridge = bridge;
	encoder->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_register(drm_connector);
	if (err)
		goto err_connector;

	err = drm_mode_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_connector_unregister(drm_connector);
err_connector:
	drm_bridge_remove(bridge);
	drm_connector_cleanup(drm_connector);
	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");

	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 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");
