/*
 * Copyright (C) 2016 Freescale Semiconductor, Inc.
 * Copyright 2017-2018 NXP
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 */

#include <linux/io.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/platform_device.h>
#include <linux/types.h>
#include <video/dpu.h>
#include "dpu-prv.h"

#define PIXENGCFG_STATIC		0x8
#define POWERDOWN			BIT(4)
#define SYNC_MODE			BIT(8)
#define SW_RESET			BIT(11)
#define DIV(n)				(((n) & 0xFF) << 16)
#define DIV_RESET			0x80
#define PIXENGCFG_DYNAMIC		0xC
#define PIXENGCFG_REQUEST		0x10
#define SHDLDREQ(n)			BIT(n)
#define SEL_SHDLDREQ			BIT(0)
#define PIXENGCFG_TRIGGER		0x14
#define SYNC_TRIGGER			BIT(0)
#define TRIGGER_SEQUENCE_COMPLETE	BIT(4)
#define PIXENGCFG_STATUS		0x18
#define SYNC_BUSY			BIT(8)
#define KICK_MODE			BIT(8)
#define PERFCOUNTMODE			BIT(12)
#define CONTROL				0xC
#define GAMMAAPPLYENABLE		BIT(0)
#define SOFTWAREKICK			0x10
#define KICK				BIT(0)
#define STATUS				0x14
#define CNT_ERR_STS			BIT(0)
#define CONTROLWORD			0x18
#define CURPIXELCNT			0x1C
static u16 get_xval(u32 pixel_cnt)
{
	return pixel_cnt & 0xFFFF;
}

static u16 get_yval(u32 pixel_cnt)
{
	return pixel_cnt >> 16;
}
#define LASTPIXELCNT			0x20
#define PERFCOUNTER			0x24

struct dpu_extdst {
	void __iomem *pec_base;
	void __iomem *base;
	struct mutex mutex;
	int id;
	bool inuse;
	struct dpu_soc *dpu;
};

static inline u32 dpu_pec_ed_read(struct dpu_extdst *ed, unsigned int offset)
{
	return readl(ed->pec_base + offset);
}

static inline void dpu_pec_ed_write(struct dpu_extdst *ed, u32 value,
				unsigned int offset)
{
	writel(value, ed->pec_base + offset);
}

static inline u32 dpu_ed_read(struct dpu_extdst *ed, unsigned int offset)
{
	return readl(ed->base + offset);
}

static inline void dpu_ed_write(struct dpu_extdst *ed, u32 value,
				unsigned int offset)
{
	writel(value, ed->base + offset);
}

static inline bool dpu_ed_is_safety_stream(struct dpu_extdst *ed)
{
	if (ed->id == 4 || ed->id == 5)
		return true;

	return false;
}

static inline bool dpu_ed_src_sel_is_extsrc(extdst_src_sel_t src)
{
	if (src == ED_SRC_EXTSRC4 || src == ED_SRC_EXTSRC5)
		return true;

	return false;
}

void extdst_pixengcfg_shden(struct dpu_extdst *ed, bool enable)
{
	u32 val;

	mutex_lock(&ed->mutex);
	val = dpu_pec_ed_read(ed, PIXENGCFG_STATIC);
	if (enable)
		val |= SHDEN;
	else
		val &= ~SHDEN;
	dpu_pec_ed_write(ed, val, PIXENGCFG_STATIC);
	mutex_unlock(&ed->mutex);
}
EXPORT_SYMBOL_GPL(extdst_pixengcfg_shden);

void extdst_pixengcfg_powerdown(struct dpu_extdst *ed, bool powerdown)
{
	u32 val;

	mutex_lock(&ed->mutex);
	val = dpu_pec_ed_read(ed, PIXENGCFG_STATIC);
	if (powerdown)
		val |= POWERDOWN;
	else
		val &= ~POWERDOWN;
	dpu_pec_ed_write(ed, val, PIXENGCFG_STATIC);
	mutex_unlock(&ed->mutex);
}
EXPORT_SYMBOL_GPL(extdst_pixengcfg_powerdown);

void extdst_pixengcfg_sync_mode(struct dpu_extdst *ed, ed_sync_mode_t mode)
{
	u32 val;

	mutex_lock(&ed->mutex);
	val = dpu_pec_ed_read(ed, PIXENGCFG_STATIC);
	if (mode == AUTO)
		val |= SYNC_MODE;
	else
		val &= ~SYNC_MODE;
	dpu_pec_ed_write(ed, val, PIXENGCFG_STATIC);
	mutex_unlock(&ed->mutex);
}
EXPORT_SYMBOL_GPL(extdst_pixengcfg_sync_mode);

void extdst_pixengcfg_reset(struct dpu_extdst *ed, bool reset)
{
	u32 val;

	mutex_lock(&ed->mutex);
	val = dpu_pec_ed_read(ed, PIXENGCFG_STATIC);
	if (reset)
		val |= SW_RESET;
	else
		val &= ~SW_RESET;
	dpu_pec_ed_write(ed, val, PIXENGCFG_STATIC);
	mutex_unlock(&ed->mutex);
}
EXPORT_SYMBOL_GPL(extdst_pixengcfg_reset);

void extdst_pixengcfg_div(struct dpu_extdst *ed, u16 div)
{
	u32 val;

	mutex_lock(&ed->mutex);
	val = dpu_pec_ed_read(ed, PIXENGCFG_STATIC);
	val &= ~0xFF0000;
	val |= DIV(div);
	dpu_pec_ed_write(ed, val, PIXENGCFG_STATIC);
	mutex_unlock(&ed->mutex);
}
EXPORT_SYMBOL_GPL(extdst_pixengcfg_div);

void extdst_pixengcfg_syncmode_master(struct dpu_extdst *ed, bool enable)
{
	struct dpu_soc *dpu = ed->dpu;
	u32 val;

	if (!dpu->devtype->has_syncmode_fixup)
		return;

	mutex_lock(&ed->mutex);
	val = dpu_pec_ed_read(ed, PIXENGCFG_STATIC);
	if (enable)
		val |= BIT(16);
	else
		val &= ~BIT(16);
	dpu_pec_ed_write(ed, val, PIXENGCFG_STATIC);
	mutex_unlock(&ed->mutex);
}
EXPORT_SYMBOL_GPL(extdst_pixengcfg_syncmode_master);

int extdst_pixengcfg_src_sel(struct dpu_extdst *ed, extdst_src_sel_t src)
{
	struct dpu_soc *dpu = ed->dpu;
	const unsigned int *block_id_map = dpu->devtype->sw2hw_block_id_map;
	u32 mapped_src;

	mapped_src = block_id_map ? block_id_map[src] : src;
	if (WARN_ON(mapped_src == NA))
		return -EINVAL;

	if (dpu_ed_is_safety_stream(ed) && dpu_ed_src_sel_is_extsrc(src)) {
		dev_err(dpu->dev, "ExtDst%d source cannot be ExtSrc\n", ed->id);
		return -EINVAL;
	}

	mutex_lock(&ed->mutex);
	dpu_pec_ed_write(ed, mapped_src, PIXENGCFG_DYNAMIC);
	mutex_unlock(&ed->mutex);

	return 0;
}
EXPORT_SYMBOL_GPL(extdst_pixengcfg_src_sel);

void extdst_pixengcfg_sel_shdldreq(struct dpu_extdst *ed)
{
	u32 val;

	mutex_lock(&ed->mutex);
	val = dpu_pec_ed_read(ed, PIXENGCFG_REQUEST);
	val |= SEL_SHDLDREQ;
	dpu_pec_ed_write(ed, val, PIXENGCFG_REQUEST);
	mutex_unlock(&ed->mutex);
}
EXPORT_SYMBOL_GPL(extdst_pixengcfg_sel_shdldreq);

void extdst_pixengcfg_shdldreq(struct dpu_extdst *ed, u32 req_mask)
{
	u32 val;

	mutex_lock(&ed->mutex);
	val = dpu_pec_ed_read(ed, PIXENGCFG_REQUEST);
	val |= req_mask;
	dpu_pec_ed_write(ed, val, PIXENGCFG_REQUEST);
	mutex_unlock(&ed->mutex);
}
EXPORT_SYMBOL_GPL(extdst_pixengcfg_shdldreq);

void extdst_pixengcfg_sync_trigger(struct dpu_extdst *ed)
{
	mutex_lock(&ed->mutex);
	dpu_pec_ed_write(ed, SYNC_TRIGGER, PIXENGCFG_TRIGGER);
	mutex_unlock(&ed->mutex);
}
EXPORT_SYMBOL_GPL(extdst_pixengcfg_sync_trigger);

void extdst_pixengcfg_trigger_sequence_complete(struct dpu_extdst *ed)
{
	mutex_lock(&ed->mutex);
	dpu_pec_ed_write(ed, TRIGGER_SEQUENCE_COMPLETE, PIXENGCFG_TRIGGER);
	mutex_unlock(&ed->mutex);
}
EXPORT_SYMBOL_GPL(extdst_pixengcfg_trigger_sequence_complete);

bool extdst_pixengcfg_is_sync_busy(struct dpu_extdst *ed)
{
	u32 val;

	mutex_lock(&ed->mutex);
	val = dpu_pec_ed_read(ed, PIXENGCFG_STATUS);
	mutex_unlock(&ed->mutex);

	return val & SYNC_BUSY;
}
EXPORT_SYMBOL_GPL(extdst_pixengcfg_is_sync_busy);

ed_pipeline_status_t extdst_pixengcfg_pipeline_status(struct dpu_extdst *ed)
{
	u32 val;

	mutex_lock(&ed->mutex);
	val = dpu_pec_ed_read(ed, PIXENGCFG_STATUS);
	mutex_unlock(&ed->mutex);

	return val & 0x3;
}
EXPORT_SYMBOL_GPL(extdst_pixengcfg_pipeline_status);

void extdst_shden(struct dpu_extdst *ed, bool enable)
{
	u32 val;

	mutex_lock(&ed->mutex);
	val = dpu_ed_read(ed, STATICCONTROL);
	if (enable)
		val |= SHDEN;
	else
		val &= ~SHDEN;
	dpu_ed_write(ed, val, STATICCONTROL);
	mutex_unlock(&ed->mutex);
}
EXPORT_SYMBOL_GPL(extdst_shden);

void extdst_kick_mode(struct dpu_extdst *ed, ed_kick_mode_t mode)
{
	u32 val;

	mutex_lock(&ed->mutex);
	val = dpu_ed_read(ed, STATICCONTROL);
	val &= ~KICK_MODE;
	val |= mode;
	dpu_ed_write(ed, val, STATICCONTROL);
	mutex_unlock(&ed->mutex);
}
EXPORT_SYMBOL_GPL(extdst_kick_mode);

void extdst_perfcountmode(struct dpu_extdst *ed, bool enable)
{
	u32 val;

	mutex_lock(&ed->mutex);
	val = dpu_ed_read(ed, STATICCONTROL);
	if (enable)
		val |= PERFCOUNTMODE;
	else
		val &= ~PERFCOUNTMODE;
	dpu_ed_write(ed, val, STATICCONTROL);
	mutex_unlock(&ed->mutex);
}
EXPORT_SYMBOL_GPL(extdst_perfcountmode);

void extdst_gamma_apply_enable(struct dpu_extdst *ed, bool enable)
{
	u32 val;

	mutex_lock(&ed->mutex);
	val = dpu_ed_read(ed, CONTROL);
	if (enable)
		val |= GAMMAAPPLYENABLE;
	else
		val &= ~GAMMAAPPLYENABLE;
	dpu_ed_write(ed, val, CONTROL);
	mutex_unlock(&ed->mutex);
}
EXPORT_SYMBOL_GPL(extdst_gamma_apply_enable);

void extdst_kick(struct dpu_extdst *ed)
{
	mutex_lock(&ed->mutex);
	dpu_ed_write(ed, KICK, SOFTWAREKICK);
	mutex_unlock(&ed->mutex);
}
EXPORT_SYMBOL_GPL(extdst_kick);

void extdst_cnt_err_clear(struct dpu_extdst *ed)
{
	mutex_lock(&ed->mutex);
	dpu_ed_write(ed, CNT_ERR_STS, STATUS);
	mutex_unlock(&ed->mutex);
}
EXPORT_SYMBOL_GPL(extdst_cnt_err_clear);

bool extdst_cnt_err_status(struct dpu_extdst *ed)
{
	u32 val;

	mutex_lock(&ed->mutex);
	val = dpu_ed_read(ed, STATUS);
	mutex_unlock(&ed->mutex);

	return val & CNT_ERR_STS;
}
EXPORT_SYMBOL_GPL(extdst_cnt_err_status);

u32 extdst_last_control_word(struct dpu_extdst *ed)
{
	u32 val;

	mutex_lock(&ed->mutex);
	val = dpu_ed_read(ed, CONTROLWORD);
	mutex_unlock(&ed->mutex);

	return val;
}
EXPORT_SYMBOL_GPL(extdst_last_control_word);

void extdst_pixel_cnt(struct dpu_extdst *ed, u16 *x, u16 *y)
{
	u32 val;

	mutex_lock(&ed->mutex);
	val = dpu_ed_read(ed, CURPIXELCNT);
	mutex_unlock(&ed->mutex);

	*x = get_xval(val);
	*y = get_yval(val);
}
EXPORT_SYMBOL_GPL(extdst_pixel_cnt);

void extdst_last_pixel_cnt(struct dpu_extdst *ed, u16 *x, u16 *y)
{
	u32 val;

	mutex_lock(&ed->mutex);
	val = dpu_ed_read(ed, LASTPIXELCNT);
	mutex_unlock(&ed->mutex);

	*x = get_xval(val);
	*y = get_yval(val);
}
EXPORT_SYMBOL_GPL(extdst_last_pixel_cnt);

u32 extdst_perfresult(struct dpu_extdst *ed)
{
	u32 val;

	mutex_lock(&ed->mutex);
	val = dpu_ed_read(ed, PERFCOUNTER);
	mutex_unlock(&ed->mutex);

	return val;
}
EXPORT_SYMBOL_GPL(extdst_perfresult);

bool extdst_is_master(struct dpu_extdst *ed)
{
	const struct dpu_devtype *devtype = ed->dpu->devtype;

	return ed->id == devtype->master_stream_id;
}
EXPORT_SYMBOL_GPL(extdst_is_master);

struct dpu_extdst *dpu_ed_get(struct dpu_soc *dpu, int id)
{
	struct dpu_extdst *ed;
	int i;

	for (i = 0; i < ARRAY_SIZE(ed_ids); i++)
		if (ed_ids[i] == id)
			break;

	if (i == ARRAY_SIZE(ed_ids))
		return ERR_PTR(-EINVAL);

	ed = dpu->ed_priv[i];

	mutex_lock(&ed->mutex);

	if (ed->inuse) {
		mutex_unlock(&ed->mutex);
		return ERR_PTR(-EBUSY);
	}

	ed->inuse = true;

	mutex_unlock(&ed->mutex);

	return ed;
}
EXPORT_SYMBOL_GPL(dpu_ed_get);

void dpu_ed_put(struct dpu_extdst *ed)
{
	mutex_lock(&ed->mutex);

	ed->inuse = false;

	mutex_unlock(&ed->mutex);
}
EXPORT_SYMBOL_GPL(dpu_ed_put);

struct dpu_extdst *dpu_aux_ed_peek(struct dpu_extdst *ed)
{
	unsigned int aux_id = ed->id ^ 1;
	int i;

	for (i = 0; i < ARRAY_SIZE(ed_ids); i++)
		if (ed_ids[i] == aux_id)
			return ed->dpu->ed_priv[i];

	return NULL;
}
EXPORT_SYMBOL_GPL(dpu_aux_ed_peek);

void _dpu_ed_init(struct dpu_soc *dpu, unsigned int id)
{
	struct dpu_extdst *ed;
	int i;

	for (i = 0; i < ARRAY_SIZE(ed_ids); i++)
		if (ed_ids[i] == id)
			break;

	if (WARN_ON(i == ARRAY_SIZE(ed_ids)))
		return;

	ed = dpu->ed_priv[i];

	extdst_pixengcfg_src_sel(ed, ED_SRC_DISABLE);
	extdst_pixengcfg_shden(ed, true);
	extdst_pixengcfg_powerdown(ed, false);
	extdst_pixengcfg_sync_mode(ed, SINGLE);
	extdst_pixengcfg_reset(ed, false);
	extdst_pixengcfg_div(ed, DIV_RESET);
	extdst_shden(ed, true);
	extdst_perfcountmode(ed, false);
	extdst_kick_mode(ed, EXTERNAL);
}

int dpu_ed_init(struct dpu_soc *dpu, unsigned int id,
		unsigned long pec_base, unsigned long base)
{
	struct dpu_extdst *ed;
	int ret, i;

	ed = devm_kzalloc(dpu->dev, sizeof(*ed), GFP_KERNEL);
	if (!ed)
		return -ENOMEM;

	for (i = 0; i < ARRAY_SIZE(ed_ids); i++)
		if (ed_ids[i] == id)
			break;

	if (i == ARRAY_SIZE(ed_ids))
		return -EINVAL;

	dpu->ed_priv[i] = ed;

	ed->pec_base = devm_ioremap(dpu->dev, pec_base, SZ_32);
	if (!ed->pec_base)
		return -ENOMEM;

	ed->base = devm_ioremap(dpu->dev, base, SZ_64);
	if (!ed->base)
		return -ENOMEM;

	ed->dpu = dpu;
	ed->id = id;
	mutex_init(&ed->mutex);

	ret = extdst_pixengcfg_src_sel(ed, ED_SRC_DISABLE);
	if (ret < 0)
		return ret;

	_dpu_ed_init(dpu, id);

	return 0;
}
