// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2015 Google, Inc
 * Copyright 2014 Rockchip Inc.
 */

#include <common.h>
#include <clk.h>
#include <display.h>
#include <dm.h>
#include <dm/device_compat.h>
#include <edid.h>
#include <log.h>
#include <regmap.h>
#include <reset.h>
#include <syscon.h>
#include <video.h>
#include <asm/global_data.h>
#include <asm/gpio.h>
#include <asm/io.h>
#include <asm/arch-rockchip/clock.h>
#include <asm/arch-rockchip/edp_rk3288.h>
#include <asm/arch-rockchip/vop_rk3288.h>
#include <dm/device-internal.h>
#include <dm/uclass-internal.h>
#include <efi.h>
#include <efi_loader.h>
#include <linux/bitops.h>
#include <linux/err.h>
#include <power/regulator.h>
#include "rk_vop.h"

DECLARE_GLOBAL_DATA_PTR;

enum vop_pol {
	HSYNC_POSITIVE = 0,
	VSYNC_POSITIVE = 1,
	DEN_NEGATIVE   = 2,
	DCLK_INVERT    = 3
};

static void rkvop_enable(struct udevice *dev, ulong fbbase,
			 int fb_bits_per_pixel,
			 const struct display_timing *edid,
			 struct reset_ctl *dclk_rst)
{
	struct rk_vop_priv *priv = dev_get_priv(dev);
	struct rk3288_vop *regs = priv->regs;
	struct rk3288_vop *win_regs = priv->regs + priv->win_offset;
	u32 lb_mode;
	u32 rgb_mode;
	u32 hactive = edid->hactive.typ;
	u32 vactive = edid->vactive.typ;
	int ret;

	writel(V_ACT_WIDTH(hactive - 1) | V_ACT_HEIGHT(vactive - 1),
	       &win_regs->win0_act_info);

	writel(V_DSP_XST(edid->hsync_len.typ + edid->hback_porch.typ) |
	       V_DSP_YST(edid->vsync_len.typ + edid->vback_porch.typ),
	       &win_regs->win0_dsp_st);

	writel(V_DSP_WIDTH(hactive - 1) |
		V_DSP_HEIGHT(vactive - 1),
		&win_regs->win0_dsp_info);

	clrsetbits_le32(&win_regs->win0_color_key, M_WIN0_KEY_EN | M_WIN0_KEY_COLOR,
			V_WIN0_KEY_EN(0) | V_WIN0_KEY_COLOR(0));

	switch (fb_bits_per_pixel) {
	case 16:
		rgb_mode = RGB565;
		writel(V_RGB565_VIRWIDTH(hactive), &win_regs->win0_vir);
		break;
	case 24:
		rgb_mode = RGB888;
		writel(V_RGB888_VIRWIDTH(hactive), &win_regs->win0_vir);
		break;
	case 32:
	default:
		rgb_mode = ARGB8888;
		writel(V_ARGB888_VIRWIDTH(hactive), &win_regs->win0_vir);
		break;
	}

	if (hactive > 2560)
		lb_mode = LB_RGB_3840X2;
	else if (hactive > 1920)
		lb_mode = LB_RGB_2560X4;
	else if (hactive > 1280)
		lb_mode = LB_RGB_1920X5;
	else
		lb_mode = LB_RGB_1280X8;

	clrsetbits_le32(&win_regs->win0_ctrl0,
			M_WIN0_LB_MODE | M_WIN0_DATA_FMT | M_WIN0_EN,
			V_WIN0_LB_MODE(lb_mode) | V_WIN0_DATA_FMT(rgb_mode) |
			V_WIN0_EN(1));

	writel(fbbase, &win_regs->win0_yrgb_mst);
	writel(0x01, &regs->reg_cfg_done); /* enable reg config */

	ret = reset_assert(dclk_rst);
	if (ret) {
		dev_warn(dev, "failed to assert dclk reset (ret=%d)\n", ret);
		return;
	}
	udelay(20);

	ret = reset_deassert(dclk_rst);
	if (ret)
		dev_warn(dev, "failed to deassert dclk reset (ret=%d)\n", ret);

}

static void rkvop_set_pin_polarity(struct udevice *dev,
				   enum vop_modes mode, u32 polarity)
{
	struct rkvop_driverdata *ops =
		(struct rkvop_driverdata *)dev_get_driver_data(dev);

	if (ops->set_pin_polarity)
		ops->set_pin_polarity(dev, mode, polarity);
}

static void rkvop_enable_output(struct udevice *dev, enum vop_modes mode)
{
	struct rk_vop_priv *priv = dev_get_priv(dev);
	struct rk3288_vop *regs = priv->regs;

	/* remove from standby */
	clrbits_le32(&regs->sys_ctrl, V_STANDBY_EN(1));

	switch (mode) {
	case VOP_MODE_HDMI:
		clrsetbits_le32(&regs->sys_ctrl, M_ALL_OUT_EN,
				V_HDMI_OUT_EN(1));
		break;

	case VOP_MODE_EDP:
		clrsetbits_le32(&regs->sys_ctrl, M_ALL_OUT_EN,
				V_EDP_OUT_EN(1));
		break;

#if defined(CONFIG_ROCKCHIP_RK3288)
	case VOP_MODE_LVDS:
		clrsetbits_le32(&regs->sys_ctrl, M_ALL_OUT_EN,
				V_RGB_OUT_EN(1));
		break;
#endif

	case VOP_MODE_MIPI:
		clrsetbits_le32(&regs->sys_ctrl, M_ALL_OUT_EN,
				V_MIPI_OUT_EN(1));
		break;

	default:
		debug("%s: unsupported output mode %x\n", __func__, mode);
	}
}

static void rkvop_mode_set(struct udevice *dev,
			   const struct display_timing *edid,
			   enum vop_modes mode)
{
	struct rk_vop_priv *priv = dev_get_priv(dev);
	struct rk3288_vop *regs = priv->regs;
	struct rk3288_vop *dsp_regs = priv->regs + priv->dsp_offset;
	struct rkvop_driverdata *data =
		(struct rkvop_driverdata *)dev_get_driver_data(dev);

	u32 hactive = edid->hactive.typ;
	u32 vactive = edid->vactive.typ;
	u32 hsync_len = edid->hsync_len.typ;
	u32 hback_porch = edid->hback_porch.typ;
	u32 vsync_len = edid->vsync_len.typ;
	u32 vback_porch = edid->vback_porch.typ;
	u32 hfront_porch = edid->hfront_porch.typ;
	u32 vfront_porch = edid->vfront_porch.typ;
	int mode_flags;
	u32 pin_polarity;

	pin_polarity = BIT(DCLK_INVERT);
	if (edid->flags & DISPLAY_FLAGS_HSYNC_HIGH)
		pin_polarity |= BIT(HSYNC_POSITIVE);
	if (edid->flags & DISPLAY_FLAGS_VSYNC_HIGH)
		pin_polarity |= BIT(VSYNC_POSITIVE);

	rkvop_set_pin_polarity(dev, mode, pin_polarity);
	rkvop_enable_output(dev, mode);

	mode_flags = 0;  /* RGB888 */
	if ((data->features & VOP_FEATURE_OUTPUT_10BIT) &&
	    (mode == VOP_MODE_HDMI || mode == VOP_MODE_EDP))
		mode_flags = 15;  /* RGBaaa */

	clrsetbits_le32(&regs->dsp_ctrl0, M_DSP_OUT_MODE,
			V_DSP_OUT_MODE(mode_flags));

	writel(V_HSYNC(hsync_len) |
	       V_HORPRD(hsync_len + hback_porch + hactive + hfront_porch),
			&dsp_regs->dsp_htotal_hs_end);

	writel(V_HEAP(hsync_len + hback_porch + hactive) |
	       V_HASP(hsync_len + hback_porch),
	       &dsp_regs->dsp_hact_st_end);

	writel(V_VSYNC(vsync_len) |
	       V_VERPRD(vsync_len + vback_porch + vactive + vfront_porch),
	       &dsp_regs->dsp_vtotal_vs_end);

	writel(V_VAEP(vsync_len + vback_porch + vactive)|
	       V_VASP(vsync_len + vback_porch),
	       &dsp_regs->dsp_vact_st_end);

	writel(V_HEAP(hsync_len + hback_porch + hactive) |
	       V_HASP(hsync_len + hback_porch),
	       &dsp_regs->post_dsp_hact_info);

	writel(V_VAEP(vsync_len + vback_porch + vactive)|
	       V_VASP(vsync_len + vback_porch),
	       &dsp_regs->post_dsp_vact_info);

	writel(0x01, &regs->reg_cfg_done); /* enable reg config */
}

/**
 * rk_display_init() - Try to enable the given display device
 *
 * This function performs many steps:
 * - Finds the display device being referenced by @ep_node
 * - Puts the VOP's ID into its uclass platform data
 * - Probes the device to set it up
 * - Reads the EDID timing information
 * - Sets up the VOP clocks, etc. for the selected pixel clock and display mode
 * - Enables the display (the display device handles this and will do different
 *     things depending on the display type)
 * - Tells the uclass about the display resolution so that the console will
 *     appear correctly
 *
 * @dev:	VOP device that we want to connect to the display
 * @fbbase:	Frame buffer address
 * @ep_node:	Device tree node to process - this is the offset of an endpoint
 *		node within the VOP's 'port' list.
 * Return: 0 if OK, -ve if something went wrong
 */
static int rk_display_init(struct udevice *dev, ulong fbbase, ofnode ep_node)
{
	struct video_priv *uc_priv = dev_get_uclass_priv(dev);
	int vop_id, remote_vop_id;
	struct display_timing timing;
	struct udevice *disp;
	int ret;
	u32 remote_phandle;
	struct display_plat *disp_uc_plat;
	struct clk clk;
	enum video_log2_bpp l2bpp;
	ofnode remote;
	const char *compat;
	struct reset_ctl dclk_rst;

	debug("%s(%s, 0x%lx, %s)\n", __func__,
	      dev_read_name(dev), fbbase, ofnode_get_name(ep_node));

	ret = ofnode_read_u32(ep_node, "remote-endpoint", &remote_phandle);
	if (ret)
		return ret;

	remote = ofnode_get_by_phandle(remote_phandle);
	if (!ofnode_valid(remote))
		return -EINVAL;
	remote_vop_id = ofnode_read_u32_default(remote, "reg", -1);
	debug("remote vop_id=%d\n", remote_vop_id);

	/*
	 * The remote-endpoint references into a subnode of the encoder
	 * (i.e. HDMI, MIPI, etc.) with the DTS looking something like
	 * the following (assume 'hdmi_in_vopl' to be referenced):
	 *
	 * hdmi: hdmi@ff940000 {
	 *   ports {
	 *     hdmi_in: port {
	 *       hdmi_in_vopb: endpoint@0 { ... };
	 *       hdmi_in_vopl: endpoint@1 { ... };
	 *     }
	 *   }
	 * }
	 *
	 * The original code had 3 steps of "walking the parent", but
	 * a much better (as in: less likely to break if the DTS
	 * changes) way of doing this is to "find the enclosing device
	 * of UCLASS_DISPLAY".
	 */
	while (ofnode_valid(remote)) {
		remote = ofnode_get_parent(remote);
		if (!ofnode_valid(remote)) {
			debug("%s(%s): no UCLASS_DISPLAY for remote-endpoint\n",
			      __func__, dev_read_name(dev));
			return -EINVAL;
		}

		uclass_find_device_by_ofnode(UCLASS_DISPLAY, remote, &disp);
		if (disp)
			break;
	};
	compat = ofnode_get_property(remote, "compatible", NULL);
	if (!compat) {
		debug("%s(%s): Failed to find compatible property\n",
		      __func__, dev_read_name(dev));
		return -EINVAL;
	}
	if (strstr(compat, "edp") ||
	    strstr(compat, "rk3288-dp")) {
		vop_id = VOP_MODE_EDP;
	} else if (strstr(compat, "mipi")) {
		vop_id = VOP_MODE_MIPI;
	} else if (strstr(compat, "hdmi")) {
		vop_id = VOP_MODE_HDMI;
	} else if (strstr(compat, "cdn-dp")) {
		vop_id = VOP_MODE_DP;
	} else if (strstr(compat, "lvds")) {
		vop_id = VOP_MODE_LVDS;
	} else {
		debug("%s(%s): Failed to find vop mode for %s\n",
		      __func__, dev_read_name(dev), compat);
		return -EINVAL;
	}
	debug("vop_id=%d\n", vop_id);

	disp_uc_plat = dev_get_uclass_plat(disp);
	debug("Found device '%s', disp_uc_priv=%p\n", disp->name, disp_uc_plat);
	if (display_in_use(disp)) {
		debug("   - device in use\n");
		return -EBUSY;
	}

	disp_uc_plat->source_id = remote_vop_id;
	disp_uc_plat->src_dev = dev;

	ret = device_probe(disp);
	if (ret) {
		debug("%s: device '%s' display won't probe (ret=%d)\n",
		      __func__, dev->name, ret);
		return ret;
	}

	ret = display_read_timing(disp, &timing);
	if (ret) {
		debug("%s: Failed to read timings\n", __func__);
		return ret;
	}

	ret = clk_get_by_index(dev, 1, &clk);
	if (!ret)
		ret = clk_set_rate(&clk, timing.pixelclock.typ);
	if (IS_ERR_VALUE(ret)) {
		debug("%s: Failed to set pixel clock: ret=%d\n", __func__, ret);
		return ret;
	}

	/* Set bitwidth for vop display according to vop mode */
	switch (vop_id) {
	case VOP_MODE_EDP:
#if defined(CONFIG_ROCKCHIP_RK3288)
	case VOP_MODE_LVDS:
#endif
		l2bpp = VIDEO_BPP16;
		break;
	case VOP_MODE_HDMI:
	case VOP_MODE_MIPI:
		l2bpp = VIDEO_BPP32;
		break;
	default:
		l2bpp = VIDEO_BPP16;
	}

	rkvop_mode_set(dev, &timing, vop_id);

	ret = reset_get_by_name(dev, "dclk", &dclk_rst);
	if (ret) {
		dev_err(dev, "failed to get dclk reset (ret=%d)\n", ret);
		return ret;
	}

	rkvop_enable(dev, fbbase, 1 << l2bpp, &timing, &dclk_rst);

	ret = display_enable(disp, 1 << l2bpp, &timing);
	if (ret)
		return ret;

	uc_priv->xsize = timing.hactive.typ;
	uc_priv->ysize = timing.vactive.typ;
	uc_priv->bpix = l2bpp;
	debug("fb=%lx, size=%d %d\n", fbbase, uc_priv->xsize, uc_priv->ysize);

	return 0;
}

void rk_vop_probe_regulators(struct udevice *dev,
			     const char * const *names, int cnt)
{
	int i, ret;
	const char *name;
	struct udevice *reg;

	for (i = 0; i < cnt; ++i) {
		name = names[i];
		debug("%s: probing regulator '%s'\n", dev->name, name);

		ret = regulator_autoset_by_name(name, &reg);
		if (!ret)
			ret = regulator_set_enable(reg, true);
	}
}

int rk_vop_probe(struct udevice *dev)
{
	struct video_uc_plat *plat = dev_get_uclass_plat(dev);
	struct rk_vop_priv *priv = dev_get_priv(dev);
	struct rkvop_driverdata *ops =
		(struct rkvop_driverdata *)dev_get_driver_data(dev);
	int ret = 0;
	ofnode port, node;
	struct reset_ctl ahb_rst;

	/* Before relocation we don't need to do anything */
	if (!(gd->flags & GD_FLG_RELOC))
		return 0;

	ret = reset_get_by_name(dev, "ahb", &ahb_rst);
	if (ret) {
		dev_err(dev, "failed to get ahb reset (ret=%d)\n", ret);
		return ret;
	}

	ret = reset_assert(&ahb_rst);
	if (ret) {
		dev_err(dev, "failed to assert ahb reset (ret=%d)\n", ret);
		return ret;
	}
	udelay(20);

	ret = reset_deassert(&ahb_rst);
	if (ret) {
		dev_err(dev, "failed to deassert ahb reset (ret=%d)\n", ret);
		return ret;
	}

#if defined(CONFIG_EFI_LOADER)
	debug("Adding to EFI map %d @ %lx\n", plat->size, plat->base);
	efi_add_memory_map(plat->base, plat->size, EFI_RESERVED_MEMORY_TYPE);
#endif

	priv->regs = dev_read_addr_ptr(dev);
	priv->win_offset = ops->win_offset;
	priv->dsp_offset = ops->dsp_offset;

	/*
	 * Try all the ports until we find one that works. In practice this
	 * tries EDP first if available, then HDMI.
	 *
	 * Note that rockchip_vop_set_clk() always uses NPLL as the source
	 * clock so it is currently not possible to use more than one display
	 * device simultaneously.
	 */
	port = dev_read_subnode(dev, "port");
	if (!ofnode_valid(port)) {
		debug("%s(%s): 'port' subnode not found\n",
		      __func__, dev_read_name(dev));
		return -EINVAL;
	}

	for (node = ofnode_first_subnode(port);
	     ofnode_valid(node);
	     node = dev_read_next_subnode(node)) {
		ret = rk_display_init(dev, plat->base, node);
		if (ret)
			debug("Device failed: ret=%d\n", ret);
		if (!ret)
			break;
	}
	video_set_flush_dcache(dev, 1);

	return ret;
}

int rk_vop_bind(struct udevice *dev)
{
	struct video_uc_plat *plat = dev_get_uclass_plat(dev);

	plat->size = 4 * (CONFIG_VIDEO_ROCKCHIP_MAX_XRES *
			  CONFIG_VIDEO_ROCKCHIP_MAX_YRES);

	return 0;
}
