/*
 * Copyright (C) 2017 Sanechips Technology Co., Ltd.
 * Copyright 2017 Linaro Ltd.
 *
 * 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/component.h>
#include <linux/mfd/syscon.h>
#include <linux/regmap.h>

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

#include "zx_drm_drv.h"
#include "zx_vga_regs.h"
#include "zx_vou.h"

struct zx_vga_pwrctrl {
	struct regmap *regmap;
	u32 reg;
	u32 mask;
};

struct zx_vga_i2c {
	struct i2c_adapter adap;
	struct mutex lock;
};

struct zx_vga {
	struct drm_connector connector;
	struct drm_encoder encoder;
	struct zx_vga_i2c *ddc;
	struct device *dev;
	void __iomem *mmio;
	struct clk *i2c_wclk;
	struct zx_vga_pwrctrl pwrctrl;
	struct completion complete;
	bool connected;
};

#define to_zx_vga(x) container_of(x, struct zx_vga, x)

static void zx_vga_encoder_enable(struct drm_encoder *encoder)
{
	struct zx_vga *vga = to_zx_vga(encoder);
	struct zx_vga_pwrctrl *pwrctrl = &vga->pwrctrl;

	/* Set bit to power up VGA DACs */
	regmap_update_bits(pwrctrl->regmap, pwrctrl->reg, pwrctrl->mask,
			   pwrctrl->mask);

	vou_inf_enable(VOU_VGA, encoder->crtc);
}

static void zx_vga_encoder_disable(struct drm_encoder *encoder)
{
	struct zx_vga *vga = to_zx_vga(encoder);
	struct zx_vga_pwrctrl *pwrctrl = &vga->pwrctrl;

	vou_inf_disable(VOU_VGA, encoder->crtc);

	/* Clear bit to power down VGA DACs */
	regmap_update_bits(pwrctrl->regmap, pwrctrl->reg, pwrctrl->mask, 0);
}

static const struct drm_encoder_helper_funcs zx_vga_encoder_helper_funcs = {
	.enable	= zx_vga_encoder_enable,
	.disable = zx_vga_encoder_disable,
};

static const struct drm_encoder_funcs zx_vga_encoder_funcs = {
	.destroy = drm_encoder_cleanup,
};

static int zx_vga_connector_get_modes(struct drm_connector *connector)
{
	struct zx_vga *vga = to_zx_vga(connector);
	struct edid *edid;
	int ret;

	/*
	 * Clear both detection bits to switch I2C bus from device
	 * detecting to EDID reading.
	 */
	zx_writel(vga->mmio + VGA_AUTO_DETECT_SEL, 0);

	edid = drm_get_edid(connector, &vga->ddc->adap);
	if (!edid) {
		/*
		 * If EDID reading fails, we set the device state into
		 * disconnected.  Locking is not required here, since the
		 * VGA_AUTO_DETECT_SEL register write in irq handler cannot
		 * be triggered when both detection bits are cleared as above.
		 */
		zx_writel(vga->mmio + VGA_AUTO_DETECT_SEL,
			  VGA_DETECT_SEL_NO_DEVICE);
		vga->connected = false;
		return 0;
	}

	/*
	 * As edid reading succeeds, device must be connected, so we set
	 * up detection bit for unplug interrupt here.
	 */
	zx_writel(vga->mmio + VGA_AUTO_DETECT_SEL, VGA_DETECT_SEL_HAS_DEVICE);

	drm_mode_connector_update_edid_property(connector, edid);
	ret = drm_add_edid_modes(connector, edid);
	kfree(edid);

	return ret;
}

static enum drm_mode_status
zx_vga_connector_mode_valid(struct drm_connector *connector,
			    struct drm_display_mode *mode)
{
	return MODE_OK;
}

static struct drm_connector_helper_funcs zx_vga_connector_helper_funcs = {
	.get_modes = zx_vga_connector_get_modes,
	.mode_valid = zx_vga_connector_mode_valid,
};

static enum drm_connector_status
zx_vga_connector_detect(struct drm_connector *connector, bool force)
{
	struct zx_vga *vga = to_zx_vga(connector);

	return vga->connected ? connector_status_connected :
				connector_status_disconnected;
}

static const struct drm_connector_funcs zx_vga_connector_funcs = {
	.fill_modes = drm_helper_probe_single_connector_modes,
	.detect = zx_vga_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,
};

static int zx_vga_register(struct drm_device *drm, struct zx_vga *vga)
{
	struct drm_encoder *encoder = &vga->encoder;
	struct drm_connector *connector = &vga->connector;
	struct device *dev = vga->dev;
	int ret;

	encoder->possible_crtcs = VOU_CRTC_MASK;

	ret = drm_encoder_init(drm, encoder, &zx_vga_encoder_funcs,
			       DRM_MODE_ENCODER_DAC, NULL);
	if (ret) {
		DRM_DEV_ERROR(dev, "failed to init encoder: %d\n", ret);
		return ret;
	};

	drm_encoder_helper_add(encoder, &zx_vga_encoder_helper_funcs);

	vga->connector.polled = DRM_CONNECTOR_POLL_HPD;

	ret = drm_connector_init(drm, connector, &zx_vga_connector_funcs,
				 DRM_MODE_CONNECTOR_VGA);
	if (ret) {
		DRM_DEV_ERROR(dev, "failed to init connector: %d\n", ret);
		goto clean_encoder;
	};

	drm_connector_helper_add(connector, &zx_vga_connector_helper_funcs);

	ret = drm_mode_connector_attach_encoder(connector, encoder);
	if (ret) {
		DRM_DEV_ERROR(dev, "failed to attach encoder: %d\n", ret);
		goto clean_connector;
	};

	return 0;

clean_connector:
	drm_connector_cleanup(connector);
clean_encoder:
	drm_encoder_cleanup(encoder);
	return ret;
}

static int zx_vga_pwrctrl_init(struct zx_vga *vga)
{
	struct zx_vga_pwrctrl *pwrctrl = &vga->pwrctrl;
	struct device *dev = vga->dev;
	struct of_phandle_args out_args;
	struct regmap *regmap;
	int ret;

	ret = of_parse_phandle_with_fixed_args(dev->of_node,
				"zte,vga-power-control", 2, 0, &out_args);
	if (ret)
		return ret;

	regmap = syscon_node_to_regmap(out_args.np);
	if (IS_ERR(regmap)) {
		ret = PTR_ERR(regmap);
		goto out;
	}

	pwrctrl->regmap = regmap;
	pwrctrl->reg = out_args.args[0];
	pwrctrl->mask = out_args.args[1];

out:
	of_node_put(out_args.np);
	return ret;
}

static int zx_vga_i2c_read(struct zx_vga *vga, struct i2c_msg *msg)
{
	int len = msg->len;
	u8 *buf = msg->buf;
	u32 offset = 0;
	int i;

	reinit_completion(&vga->complete);

	/* Select combo write */
	zx_writel_mask(vga->mmio + VGA_CMD_CFG, VGA_CMD_COMBO, VGA_CMD_COMBO);
	zx_writel_mask(vga->mmio + VGA_CMD_CFG, VGA_CMD_RW, 0);

	while (len > 0) {
		u32 cnt;

		/* Clear RX FIFO */
		zx_writel_mask(vga->mmio + VGA_RXF_CTRL, VGA_RX_FIFO_CLEAR,
			       VGA_RX_FIFO_CLEAR);

		/* Data offset to read from */
		zx_writel(vga->mmio + VGA_SUB_ADDR, offset);

		/* Kick off the transfer */
		zx_writel_mask(vga->mmio + VGA_CMD_CFG, VGA_CMD_TRANS,
			       VGA_CMD_TRANS);

		if (!wait_for_completion_timeout(&vga->complete,
						 msecs_to_jiffies(1000))) {
			DRM_DEV_ERROR(vga->dev, "transfer timeout\n");
			return -ETIMEDOUT;
		}

		cnt = zx_readl(vga->mmio + VGA_RXF_STATUS);
		cnt = (cnt & VGA_RXF_COUNT_MASK) >> VGA_RXF_COUNT_SHIFT;
		/* FIFO status may report more data than we need to read */
		cnt = min_t(u32, len, cnt);

		for (i = 0; i < cnt; i++)
			*buf++ = zx_readl(vga->mmio + VGA_DATA);

		len -= cnt;
		offset += cnt;
	}

	return 0;
}

static int zx_vga_i2c_write(struct zx_vga *vga, struct i2c_msg *msg)
{
	/*
	 * The DDC I2C adapter is only for reading EDID data, so we assume
	 * that the write to this adapter must be the EDID data offset.
	 */
	if ((msg->len != 1) || ((msg->addr != DDC_ADDR)))
		return -EINVAL;

	/* Hardware will take care of the slave address shifting */
	zx_writel(vga->mmio + VGA_DEVICE_ADDR, msg->addr);

	return 0;
}

static int zx_vga_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
			   int num)
{
	struct zx_vga *vga = i2c_get_adapdata(adap);
	struct zx_vga_i2c *ddc = vga->ddc;
	int ret = 0;
	int i;

	mutex_lock(&ddc->lock);

	for (i = 0; i < num; i++) {
		if (msgs[i].flags & I2C_M_RD)
			ret = zx_vga_i2c_read(vga, &msgs[i]);
		else
			ret = zx_vga_i2c_write(vga, &msgs[i]);

		if (ret < 0)
			break;
	}

	if (!ret)
		ret = num;

	mutex_unlock(&ddc->lock);

	return ret;
}

static u32 zx_vga_i2c_func(struct i2c_adapter *adapter)
{
	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
}

static const struct i2c_algorithm zx_vga_algorithm = {
	.master_xfer	= zx_vga_i2c_xfer,
	.functionality	= zx_vga_i2c_func,
};

static int zx_vga_ddc_register(struct zx_vga *vga)
{
	struct device *dev = vga->dev;
	struct i2c_adapter *adap;
	struct zx_vga_i2c *ddc;
	int ret;

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

	vga->ddc = ddc;
	mutex_init(&ddc->lock);

	adap = &ddc->adap;
	adap->owner = THIS_MODULE;
	adap->class = I2C_CLASS_DDC;
	adap->dev.parent = dev;
	adap->algo = &zx_vga_algorithm;
	snprintf(adap->name, sizeof(adap->name), "zx vga i2c");

	ret = i2c_add_adapter(adap);
	if (ret) {
		DRM_DEV_ERROR(dev, "failed to add I2C adapter: %d\n", ret);
		return ret;
	}

	i2c_set_adapdata(adap, vga);

	return 0;
}

static irqreturn_t zx_vga_irq_thread(int irq, void *dev_id)
{
	struct zx_vga *vga = dev_id;

	drm_helper_hpd_irq_event(vga->connector.dev);

	return IRQ_HANDLED;
}

static irqreturn_t zx_vga_irq_handler(int irq, void *dev_id)
{
	struct zx_vga *vga = dev_id;
	u32 status;

	status = zx_readl(vga->mmio + VGA_I2C_STATUS);

	/* Clear interrupt status */
	zx_writel_mask(vga->mmio + VGA_I2C_STATUS, VGA_CLEAR_IRQ,
		       VGA_CLEAR_IRQ);

	if (status & VGA_DEVICE_CONNECTED) {
		/*
		 * Since VGA_DETECT_SEL bits need to be reset for switching DDC
		 * bus from device detection to EDID read, rather than setting
		 * up HAS_DEVICE bit here, we need to do that in .get_modes
		 * hook for unplug detecting after EDID read succeeds.
		 */
		vga->connected = true;
		return IRQ_WAKE_THREAD;
	}

	if (status & VGA_DEVICE_DISCONNECTED) {
		zx_writel(vga->mmio + VGA_AUTO_DETECT_SEL,
			  VGA_DETECT_SEL_NO_DEVICE);
		vga->connected = false;
		return IRQ_WAKE_THREAD;
	}

	if (status & VGA_TRANS_DONE) {
		complete(&vga->complete);
		return IRQ_HANDLED;
	}

	return IRQ_NONE;
}

static void zx_vga_hw_init(struct zx_vga *vga)
{
	unsigned long ref = clk_get_rate(vga->i2c_wclk);
	int div;

	/*
	 * Set up I2C fast speed divider per formula below to get 400kHz.
	 *   scl = ref / ((div + 1) * 4)
	 */
	div = DIV_ROUND_UP(ref / 1000, 400 * 4) - 1;
	zx_writel(vga->mmio + VGA_CLK_DIV_FS, div);

	/* Set up device detection */
	zx_writel(vga->mmio + VGA_AUTO_DETECT_PARA, 0x80);
	zx_writel(vga->mmio + VGA_AUTO_DETECT_SEL, VGA_DETECT_SEL_NO_DEVICE);

	/*
	 * We need to poke monitor via DDC bus to get connection irq
	 * start working.
	 */
	zx_writel(vga->mmio + VGA_DEVICE_ADDR, DDC_ADDR);
	zx_writel_mask(vga->mmio + VGA_CMD_CFG, VGA_CMD_TRANS, VGA_CMD_TRANS);
}

static int zx_vga_bind(struct device *dev, struct device *master, void *data)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct drm_device *drm = data;
	struct resource *res;
	struct zx_vga *vga;
	int irq;
	int ret;

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

	vga->dev = dev;
	dev_set_drvdata(dev, vga);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	vga->mmio = devm_ioremap_resource(dev, res);
	if (IS_ERR(vga->mmio))
		return PTR_ERR(vga->mmio);

	irq = platform_get_irq(pdev, 0);
	if (irq < 0)
		return irq;

	vga->i2c_wclk = devm_clk_get(dev, "i2c_wclk");
	if (IS_ERR(vga->i2c_wclk)) {
		ret = PTR_ERR(vga->i2c_wclk);
		DRM_DEV_ERROR(dev, "failed to get i2c_wclk: %d\n", ret);
		return ret;
	}

	ret = zx_vga_pwrctrl_init(vga);
	if (ret) {
		DRM_DEV_ERROR(dev, "failed to init power control: %d\n", ret);
		return ret;
	}

	ret = zx_vga_ddc_register(vga);
	if (ret) {
		DRM_DEV_ERROR(dev, "failed to register ddc: %d\n", ret);
		return ret;
	}

	ret = zx_vga_register(drm, vga);
	if (ret) {
		DRM_DEV_ERROR(dev, "failed to register vga: %d\n", ret);
		return ret;
	}

	init_completion(&vga->complete);

	ret = devm_request_threaded_irq(dev, irq, zx_vga_irq_handler,
					zx_vga_irq_thread, IRQF_SHARED,
					dev_name(dev), vga);
	if (ret) {
		DRM_DEV_ERROR(dev, "failed to request threaded irq: %d\n", ret);
		return ret;
	}

	ret = clk_prepare_enable(vga->i2c_wclk);
	if (ret)
		return ret;

	zx_vga_hw_init(vga);

	return 0;
}

static void zx_vga_unbind(struct device *dev, struct device *master,
			  void *data)
{
	struct zx_vga *vga = dev_get_drvdata(dev);

	clk_disable_unprepare(vga->i2c_wclk);
}

static const struct component_ops zx_vga_component_ops = {
	.bind = zx_vga_bind,
	.unbind = zx_vga_unbind,
};

static int zx_vga_probe(struct platform_device *pdev)
{
	return component_add(&pdev->dev, &zx_vga_component_ops);
}

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

static const struct of_device_id zx_vga_of_match[] = {
	{ .compatible = "zte,zx296718-vga", },
	{ /* end */ },
};
MODULE_DEVICE_TABLE(of, zx_vga_of_match);

struct platform_driver zx_vga_driver = {
	.probe = zx_vga_probe,
	.remove = zx_vga_remove,
	.driver	= {
		.name = "zx-vga",
		.of_match_table	= zx_vga_of_match,
	},
};
