/* SPDX-License-Identifier: GPL-2.0-only */

#include <device/mmio.h>
#include <console/console.h>
#include <delay.h>
#include <device/device.h>
#include <edid.h>
#include <gpio.h>
#include <string.h>
#include <soc/addressmap.h>
#include <soc/clock.h>
#include <soc/display.h>
#include <soc/mipi.h>
#include <soc/soc.h>
#include <types.h>
#include <timer.h>

static struct rk_mipi_dsi rk_mipi[2] = {
	{ .mipi_regs = (void *)MIPI0_BASE},
	{ .mipi_regs = (void *)MIPI1_BASE}
};

/*
 * The controller should generate 2 frames before
 * preparing the peripheral.
 */
static void rk_mipi_dsi_wait_for_two_frames(struct rk_mipi_dsi *dsi,
					    const struct edid *edid)
{
	int two_frames;
	unsigned int refresh = edid->mode.refresh;

	two_frames = DIV_ROUND_UP(MSECS_PER_SEC * 2, refresh);
	mdelay(two_frames);
}

static const struct dphy_pll_parameter_map dppa_map[] = {
	{  89, 0x00, CP_CURRENT_3UA, LPF_RESISTORS_13KOHM},
	{  99, 0x10, CP_CURRENT_3UA, LPF_RESISTORS_13KOHM},
	{ 109, 0x20, CP_CURRENT_3UA, LPF_RESISTORS_13KOHM},
	{ 129, 0x01, CP_CURRENT_3UA, LPF_RESISTORS_15_5KOHM},
	{ 139, 0x11, CP_CURRENT_3UA, LPF_RESISTORS_15_5KOHM},
	{ 149, 0x21, CP_CURRENT_3UA, LPF_RESISTORS_15_5KOHM},
	{ 169, 0x02, CP_CURRENT_6UA, LPF_RESISTORS_13KOHM},
	{ 179, 0x12, CP_CURRENT_6UA, LPF_RESISTORS_13KOHM},
	{ 199, 0x22, CP_CURRENT_6UA, LPF_RESISTORS_13KOHM},
	{ 219, 0x03, CP_CURRENT_4_5UA, LPF_RESISTORS_13KOHM},
	{ 239, 0x13, CP_CURRENT_4_5UA, LPF_RESISTORS_13KOHM},
	{ 249, 0x23, CP_CURRENT_4_5UA, LPF_RESISTORS_13KOHM},
	{ 269, 0x04, CP_CURRENT_6UA, LPF_RESISTORS_11_5KOHM},
	{ 299, 0x14, CP_CURRENT_6UA, LPF_RESISTORS_11_5KOHM},
	{ 329, 0x05, CP_CURRENT_3UA, LPF_RESISTORS_15_5KOHM},
	{ 359, 0x15, CP_CURRENT_3UA, LPF_RESISTORS_15_5KOHM},
	{ 399, 0x25, CP_CURRENT_3UA, LPF_RESISTORS_15_5KOHM},
	{ 449, 0x06, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM},
	{ 499, 0x16, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM},
	{ 549, 0x07, CP_CURRENT_7_5UA, LPF_RESISTORS_10_5KOHM},
	{ 599, 0x17, CP_CURRENT_7_5UA, LPF_RESISTORS_10_5KOHM},
	{ 649, 0x08, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM},
	{ 699, 0x18, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM},
	{ 749, 0x09, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM},
	{ 799, 0x19, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM},
	{ 849, 0x29, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM},
	{ 899, 0x39, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM},
	{ 949, 0x0a, CP_CURRENT_12UA, LPF_RESISTORS_8KOHM},
	{ 999, 0x1a, CP_CURRENT_12UA, LPF_RESISTORS_8KOHM},
	{1049, 0x2a, CP_CURRENT_12UA, LPF_RESISTORS_8KOHM},
	{1099, 0x3a, CP_CURRENT_12UA, LPF_RESISTORS_8KOHM},
	{1149, 0x0b, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM},
	{1199, 0x1b, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM},
	{1249, 0x2b, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM},
	{1299, 0x3b, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM},
	{1349, 0x0c, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM},
	{1399, 0x1c, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM},
	{1449, 0x2c, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM},
	{1500, 0x3c, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM}
};

static int max_mbps_to_parameter(unsigned int max_mbps)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(dppa_map); i++) {
		if (dppa_map[i].max_mbps >= max_mbps)
			return i;
	}

	return -1;
}

static void rk_mipi_dsi_phy_write(struct rk_mipi_dsi *dsi,
				  u8 test_code,
				  u8 test_data)
{
	/*
	 * With the falling edge on TESTCLK, the TESTDIN[7:0] signal content
	 * is latched internally as the current test code. Test data is
	 * programmed internally by rising edge on TESTCLK.
	 */
	write32(&dsi->mipi_regs->dsi_phy_tst_ctrl0,
		PHY_TESTCLK | PHY_UNTESTCLR);

	write32(&dsi->mipi_regs->dsi_phy_tst_ctrl1,
		PHY_TESTEN | PHY_TESTDOUT(0) | PHY_TESTDIN(test_code));

	write32(&dsi->mipi_regs->dsi_phy_tst_ctrl0,
		PHY_UNTESTCLK | PHY_UNTESTCLR);

	write32(&dsi->mipi_regs->dsi_phy_tst_ctrl1,
		PHY_UNTESTEN | PHY_TESTDOUT(0) | PHY_TESTDIN(test_data));

	write32(&dsi->mipi_regs->dsi_phy_tst_ctrl0,
		PHY_TESTCLK | PHY_UNTESTCLR);
}

/* bytes_per_ns - Nanoseconds to byte clock cycles */
static inline unsigned int bytes_per_ns(struct rk_mipi_dsi *dsi, int ns)
{
	return DIV_ROUND_UP((u64)ns * dsi->lane_bps, (u64)8 * NSECS_PER_SEC);
}

 /* bits_per_ns - Nanoseconds to bit time periods */
static inline unsigned int bits_per_ns(struct rk_mipi_dsi *dsi, int ns)
{
	return DIV_ROUND_UP((u64)ns * dsi->lane_bps, NSECS_PER_SEC);
}

static int rk_mipi_dsi_wait_phy_lock(struct rk_mipi_dsi *dsi)
{
	struct stopwatch sw;
	int val;

	stopwatch_init_msecs_expire(&sw, 20);
	do {
		val = read32(&dsi->mipi_regs->dsi_phy_status);
		if (val & LOCK)
			return 0;
	} while (!stopwatch_expired(&sw));

	return -1;
}

static int rk_mipi_dsi_phy_init(struct rk_mipi_dsi *dsi)
{
	int i, vco, val;
	int lane_mbps = DIV_ROUND_UP(dsi->lane_bps, USECS_PER_SEC);
	struct stopwatch sw;

	vco = (lane_mbps < 200) ? 0 : (lane_mbps + 100) / 200;

	i = max_mbps_to_parameter(lane_mbps);
	if (i < 0) {
		printk(BIOS_DEBUG,
		       "failed to get parameter for %dmbps clock\n", lane_mbps);
		return i;
	}

	/* Start by clearing PHY state */
	write32(&dsi->mipi_regs->dsi_phy_tst_ctrl0, PHY_UNTESTCLR);
	write32(&dsi->mipi_regs->dsi_phy_tst_ctrl0, PHY_TESTCLR);
	write32(&dsi->mipi_regs->dsi_phy_tst_ctrl0, PHY_UNTESTCLR);

	rk_mipi_dsi_phy_write(dsi, PLL_BIAS_CUR_SEL_CAP_VCO_CONTROL,
			      BYPASS_VCO_RANGE |
			      VCO_RANGE_CON_SEL(vco) |
			      VCO_IN_CAP_CON_LOW |
			      REF_BIAS_CUR_SEL);

	rk_mipi_dsi_phy_write(dsi, PLL_CP_CONTROL_PLL_LOCK_BYPASS,
			      CP_CURRENT_SEL(dppa_map[i].icpctrl));
	rk_mipi_dsi_phy_write(dsi, PLL_LPF_AND_CP_CONTROL,
			      CP_PROGRAM_EN |
			      LPF_PROGRAM_EN |
			      LPF_RESISTORS_SEL(dppa_map[i].lpfctrl));
	rk_mipi_dsi_phy_write(dsi, HS_RX_CONTROL_OF_LANE_0,
			      HSFREQRANGE_SEL(dppa_map[i].hsfreqrange));

	rk_mipi_dsi_phy_write(dsi, PLL_INPUT_DIVIDER_RATIO,
			      INPUT_DIVIDER(dsi->input_div));
	rk_mipi_dsi_phy_write(dsi, PLL_LOOP_DIVIDER_RATIO,
			      LOOP_DIV_LOW_SEL(dsi->feedback_div) |
			      LOW_PROGRAM_EN);

	/*
	 * we need set divider control register immediately to make
	 * the configured LSB effective according to IP simulation
	 * and lab test results. Only in this way can we get correct
	 * mipi phy pll frequency.
	 */
	rk_mipi_dsi_phy_write(dsi, PLL_INPUT_AND_LOOP_DIVIDER_RATIOS_CONTROL,
			      PLL_LOOP_DIV_EN | PLL_INPUT_DIV_EN);
	rk_mipi_dsi_phy_write(dsi, PLL_LOOP_DIVIDER_RATIO,
			      LOOP_DIV_HIGH_SEL(dsi->feedback_div) |
			      HIGH_PROGRAM_EN);
	rk_mipi_dsi_phy_write(dsi, PLL_INPUT_AND_LOOP_DIVIDER_RATIOS_CONTROL,
			      PLL_LOOP_DIV_EN | PLL_INPUT_DIV_EN);
	rk_mipi_dsi_phy_write(dsi, AFE_BIAS_BANDGAP_ANALOG_PROGRAMMABILITY,
			      LOW_PROGRAM_EN |
			      BIASEXTR_SEL(BIASEXTR_127_7));
	rk_mipi_dsi_phy_write(dsi, AFE_BIAS_BANDGAP_ANALOG_PROGRAMMABILITY,
			      HIGH_PROGRAM_EN |
			      BANDGAP_SEL(BANDGAP_96_10));
	rk_mipi_dsi_phy_write(dsi, BANDGAP_AND_BIAS_CONTROL,
			      POWER_CONTROL | INTERNAL_REG_CURRENT |
			      BIAS_BLOCK_ON | BANDGAP_ON);
	rk_mipi_dsi_phy_write(dsi, TERMINATION_RESISTER_CONTROL,
			      TER_RESISTOR_LOW | TER_CAL_DONE |
			      SETRD_MAX | TER_RESISTORS_ON);
	rk_mipi_dsi_phy_write(dsi, TERMINATION_RESISTER_CONTROL,
			      TER_RESISTOR_HIGH | LEVEL_SHIFTERS_ON |
			      SETRD_MAX | POWER_MANAGE |
			      TER_RESISTORS_ON);
	rk_mipi_dsi_phy_write(dsi, HS_TX_CLOCK_LANE_REQUEST_STATE_TIME_CONTROL,
			      TLP_PROGRAM_EN | bytes_per_ns(dsi, 500));
	rk_mipi_dsi_phy_write(dsi, HS_TX_CLOCK_LANE_PREPARE_STATE_TIME_CONTROL,
			      THS_PRE_PROGRAM_EN | bits_per_ns(dsi, 40));
	rk_mipi_dsi_phy_write(dsi, HS_TX_CLOCK_LANE_HS_ZERO_STATE_TIME_CONTROL,
			      THS_ZERO_PROGRAM_EN | bytes_per_ns(dsi, 300));
	rk_mipi_dsi_phy_write(dsi, HS_TX_CLOCK_LANE_TRAIL_STATE_TIME_CONTROL,
			      THS_PRE_PROGRAM_EN | bits_per_ns(dsi, 100));
	rk_mipi_dsi_phy_write(dsi, HS_TX_CLOCK_LANE_EXIT_STATE_TIME_CONTROL,
			      BIT(5) | bytes_per_ns(dsi, 100));
	rk_mipi_dsi_phy_write(dsi, HS_TX_CLOCK_LANE_POST_TIME_CONTROL,
			      BIT(5) | (bytes_per_ns(dsi, 60) + 7));
	rk_mipi_dsi_phy_write(dsi, HS_TX_DATA_LANE_REQUEST_STATE_TIME_CONTROL,
			      TLP_PROGRAM_EN | bytes_per_ns(dsi, 500));
	rk_mipi_dsi_phy_write(dsi, HS_TX_DATA_LANE_PREPARE_STATE_TIME_CONTROL,
			      THS_PRE_PROGRAM_EN | (bits_per_ns(dsi, 50) + 5));
	rk_mipi_dsi_phy_write(dsi, HS_TX_DATA_LANE_HS_ZERO_STATE_TIME_CONTROL,
				   THS_ZERO_PROGRAM_EN |
				   (bytes_per_ns(dsi, 140) + 2));
	rk_mipi_dsi_phy_write(dsi, HS_TX_DATA_LANE_TRAIL_STATE_TIME_CONTROL,
			      THS_PRE_PROGRAM_EN | (bits_per_ns(dsi, 60) + 8));
	rk_mipi_dsi_phy_write(dsi, HS_TX_DATA_LANE_EXIT_STATE_TIME_CONTROL,
			      BIT(5) | bytes_per_ns(dsi, 100));

	write32(&dsi->mipi_regs->dsi_phy_rstz,
				PHY_ENFORCEPLL | PHY_ENABLECLK |
				PHY_UNRSTZ | PHY_UNSHUTDOWNZ);

	if (rk_mipi_dsi_wait_phy_lock(dsi)) {
		printk(BIOS_ERR, "failed to wait for phy lock state\n");
		return -1;
	}

	stopwatch_init_msecs_expire(&sw, 20);
	do {
		val = read32(&dsi->mipi_regs->dsi_phy_status);
		if (val & STOP_STATE_CLK_LANE)
			return 0;
	} while (!stopwatch_expired(&sw));

	printk(BIOS_ERR, "failed to wait for phy clk lane stop state");
	return -1;
}

static inline int mipi_dsi_pixel_format_to_bpp(enum mipi_dsi_pixel_format fmt)
{
	switch (fmt) {
	case MIPI_DSI_FMT_RGB888:
	case MIPI_DSI_FMT_RGB666:
		return 24;

	case MIPI_DSI_FMT_RGB666_PACKED:
		return 18;

	case MIPI_DSI_FMT_RGB565:
		return 16;
	}

	return -1;
}

static int rk_mipi_dsi_get_lane_bps(struct rk_mipi_dsi *dsi,
				    const struct edid *edid,
				    const struct mipi_panel_data *panel_data)
{
	u64 pclk, target_bps;
	u32 max_bps = dppa_map[ARRAY_SIZE(dppa_map) - 1].max_mbps * MHz;
	int bpp;
	u64 best_freq = 0;
	u64 fvco_min, fvco_max, fref;
	u32 min_prediv, max_prediv;
	u32 prediv, best_prediv;
	u64 fbdiv, best_fbdiv;
	u32 min_delta;

	bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
	if (bpp < 0) {
		printk(BIOS_DEBUG, "failed to get bpp for pixel format %d\n",
		       dsi->format);
		return bpp;
	}
	pclk = (u64)edid->mode.pixel_clock * MSECS_PER_SEC;

	/* take 1 / 0.8, since mbps must bigger than bandwidth of RGB */
	target_bps = pclk / panel_data->lanes * bpp / 8 * 10;
	if (target_bps >= max_bps) {
		printk(BIOS_DEBUG, "DPHY clock frequency is out of range\n");
		return -1;
	}

	fref = OSC_HZ;

	/* constraint: 5Mhz <= Fref / N <= 40MHz */
	min_prediv = DIV_ROUND_UP(fref, 40 * MHz);
	max_prediv = fref / (5 * MHz);

	/* constraint: 80MHz <= Fvco <= 1500MHz */
	fvco_min = 80 * MHz;
	fvco_max = 1500 * MHz;
	min_delta = 1500 * MHz;

	for (prediv = min_prediv; prediv <= max_prediv; prediv++) {
		u64 freq;
		int delta;

		/* Fvco = Fref * M / N */
		fbdiv = target_bps * prediv / fref;

		/*
		 * Due to the use of a "by 2 pre-scaler", the range of the
		 * feedback multiplication value M is limited to even division
		 * numbers, and m must be in 6 <= m <= 512.
		 */
		fbdiv += fbdiv % 2;
		if (fbdiv < 6 || fbdiv > 512)
			continue;

		freq = (u64)fbdiv * fref / prediv;
		if (freq < fvco_min || freq > fvco_max)
			continue;

		delta = target_bps - freq;
		delta = ABS(delta);
		if (delta >= min_delta)
			continue;

		best_prediv = prediv;
		best_fbdiv = fbdiv;
		min_delta = delta;
		best_freq = freq;
	}

	if (best_freq) {
		dsi->lane_bps = best_freq;
		dsi->input_div = best_prediv;
		dsi->feedback_div = best_fbdiv;
	} else {
		printk(BIOS_ERR, "Can not find best_freq for DPHY\n");
		return -1;
	}

	return 0;
}

static void rk_mipi_dsi_dpi_config(struct rk_mipi_dsi *dsi)
{
	u32 color = 0;

	switch (dsi->format) {
	case MIPI_DSI_FMT_RGB888:
		color = DPI_COLOR_CODING_24BIT;
		break;
	case MIPI_DSI_FMT_RGB666:
		color = DPI_COLOR_CODING_18BIT_2 | EN18_LOOSELY;
		break;
	case MIPI_DSI_FMT_RGB666_PACKED:
		color = DPI_COLOR_CODING_18BIT_1;
		break;
	case MIPI_DSI_FMT_RGB565:
		color = DPI_COLOR_CODING_16BIT_1;
		break;
	}

	write32(&dsi->mipi_regs->dsi_dpi_vcid, 0);
	write32(&dsi->mipi_regs->dsi_dpi_color_coding, color);

	write32(&dsi->mipi_regs->dsi_dpi_cfg_pol, 0);

	write32(&dsi->mipi_regs->dsi_dpi_lp_cmd_tim,
		OUTVACT_LPCMD_TIME(4) | INVACT_LPCMD_TIME(4));
}

static void rk_mipi_dsi_packet_handler_config(struct rk_mipi_dsi *dsi)
{
	write32(&dsi->mipi_regs->dsi_pckhdl_cfg,
		EN_CRC_RX | EN_ECC_RX | EN_BTA);
}

static void rk_mipi_dsi_video_mode_config(struct rk_mipi_dsi *dsi)
{
	write32(&dsi->mipi_regs->dsi_vid_mode_cfg,
		VID_MODE_TYPE_BURST_SYNC_PULSES | ENABLE_LOW_POWER);
}

static void rk_mipi_dsi_video_packet_config(struct rk_mipi_dsi *dsi,
			const struct edid *edid,
			const struct mipi_panel_data *panel_data)
{
	int pkt_size;

	if (panel_data->mipi_num > 1)
		pkt_size = VID_PKT_SIZE(edid->mode.ha / 2 + 4);
	else
		pkt_size = VID_PKT_SIZE(edid->mode.ha);

	write32(&dsi->mipi_regs->dsi_vid_pkt_size, pkt_size);
}

static void rk_mipi_dsi_command_mode_config(struct rk_mipi_dsi *dsi)
{
	write32(&dsi->mipi_regs->dsi_to_cnt_cfg,
		HSTX_TO_CNT(1000) | LPRX_TO_CNT(1000));
	write32(&dsi->mipi_regs->dsi_bta_to_cnt, 0xd00);
	write32(&dsi->mipi_regs->dsi_cmd_mode_cfg, CMD_MODE_ALL_LP);
	write32(&dsi->mipi_regs->dsi_mode_cfg, ENABLE_CMD_MODE);
}

/* Get lane byte clock cycles. */
static u32 rk_mipi_dsi_get_hcomponent_lbcc(struct rk_mipi_dsi *dsi,
					   u32 hcomponent,
					   const struct edid *edid)
{
	u32 lbcc;
	u64 lbcc_tmp;

	lbcc_tmp = hcomponent * dsi->lane_bps / (8 * MSECS_PER_SEC);
	lbcc = DIV_ROUND_UP(lbcc_tmp, edid->mode.pixel_clock);

	return lbcc;
}

static void rk_mipi_dsi_line_timer_config(struct rk_mipi_dsi *dsi,
					  const struct edid *edid)
{
	u32 htotal, hsa, hbp, lbcc;

	htotal = edid->mode.ha + edid->mode.hbl;
	hsa = edid->mode.hspw;
	hbp = edid->mode.hbl - edid->mode.hso - edid->mode.hspw;

	lbcc = rk_mipi_dsi_get_hcomponent_lbcc(dsi, htotal, edid);
	write32(&dsi->mipi_regs->dsi_vid_hline_time, lbcc);

	lbcc = rk_mipi_dsi_get_hcomponent_lbcc(dsi, hsa, edid);
	write32(&dsi->mipi_regs->dsi_vid_hsa_time, lbcc);
	lbcc = rk_mipi_dsi_get_hcomponent_lbcc(dsi, hbp, edid);
	write32(&dsi->mipi_regs->dsi_vid_hbp_time, lbcc);
}

static void rk_mipi_dsi_vertical_timing_config(struct rk_mipi_dsi *dsi,
					       const struct edid *edid)
{
	u32 vactive, vsa, vfp, vbp;

	vactive = edid->mode.va;
	vsa = edid->mode.vspw;
	vfp = edid->mode.vso;
	vbp = edid->mode.vbl - edid->mode.vso - edid->mode.vspw;

	write32(&dsi->mipi_regs->dsi_vid_vactive_lines, vactive);
	write32(&dsi->mipi_regs->dsi_vid_vsa_lines, vsa);
	write32(&dsi->mipi_regs->dsi_vid_vfp_lines, vfp);
	write32(&dsi->mipi_regs->dsi_vid_vbp_lines, vbp);
}

static void rk_mipi_dsi_dphy_timing_config(struct rk_mipi_dsi *dsi)
{
	/*
	 * HS-PREPARE: 40ns + 4 * UI ~ 85ns + 6 * UI
	 * HS-EXIT: 100ns
	 */
	write32(&dsi->mipi_regs->dsi_phy_tmr_cfg, PHY_HS2LP_TIME(0x40) |
					     PHY_LP2HS_TIME(0x40) |
					     MAX_RD_TIME(10000));

	write32(&dsi->mipi_regs->dsi_phy_tmr_lpclk_cfg,
		PHY_CLKHS2LP_TIME(0x40) | PHY_CLKLP2HS_TIME(0x40));
}

static void rk_mipi_dsi_clear_err(struct rk_mipi_dsi *dsi)
{
	read32(&dsi->mipi_regs->dsi_int_st0);
	read32(&dsi->mipi_regs->dsi_int_st1);
	write32(&dsi->mipi_regs->dsi_int_msk0, 0);
	write32(&dsi->mipi_regs->dsi_int_msk1, 0);
}

static void rk_mipi_dsi_dphy_interface_config(struct rk_mipi_dsi *dsi)
{
	write32(&dsi->mipi_regs->dsi_phy_if_cfg, PHY_STOP_WAIT_TIME(0x20) |
					    N_LANES(dsi->lanes));
}

static void rk_mipi_dsi_set_mode(struct rk_mipi_dsi *dsi,
				 enum rk_mipi_dsi_mode mode)
{
	write32(&dsi->mipi_regs->dsi_pwr_up, RESET);
	if (mode == MIPI_DSI_CMD_MODE) {
		write32(&dsi->mipi_regs->dsi_mode_cfg, ENABLE_CMD_MODE);
	} else {
		write32(&dsi->mipi_regs->dsi_mode_cfg, ENABLE_VIDEO_MODE);
		rk_mipi_dsi_video_mode_config(dsi);
		write32(&dsi->mipi_regs->dsi_lpclk_ctrl, PHY_TXREQUESTCLKHS);
	}
	write32(&dsi->mipi_regs->dsi_pwr_up, POWERUP);
}

static void rk_mipi_dsi_init(struct rk_mipi_dsi *dsi)
{
	/*
	 * The maximum permitted escape clock is 20MHz and it is derived from
	 * lanebyteclk, which is running at "lane_mbps / 8".  Thus we want:
	 *
	 *     (lane_mbps >> 3) / esc_clk_division < 20
	 * which is:
	 *     (lane_mbps >> 3) / 20 > esc_clk_division
	 */
	u32 esc_clk_division = DIV_ROUND_UP(dsi->lane_bps,
					    8 * 20 * USECS_PER_SEC);

	write32(&dsi->mipi_regs->dsi_pwr_up, RESET);
	write32(&dsi->mipi_regs->dsi_phy_rstz,
		PHY_DISFORCEPLL | PHY_DISABLECLK | PHY_RSTZ | PHY_SHUTDOWNZ);
	write32(&dsi->mipi_regs->dsi_clk_cfg,
		TO_CLK_DIVIDSION(10) |
		TX_ESC_CLK_DIVIDSION(esc_clk_division));
}

static void rk_mipi_message_config(struct rk_mipi_dsi *dsi)
{
	write32(&dsi->mipi_regs->dsi_lpclk_ctrl, 0);
	write32(&dsi->mipi_regs->dsi_cmd_mode_cfg, CMD_MODE_ALL_LP);
}

static int rk_mipi_dsi_check_fifo(struct rk_mipi_dsi *dsi, u32 flag)
{
	struct stopwatch sw;
	int val;

	stopwatch_init_msecs_expire(&sw, 20);
	do {
		val = read32(&dsi->mipi_regs->dsi_cmd_pkt_status);
		if (!(val & flag))
			return 0;
	} while (!stopwatch_expired(&sw));

	return -1;
}

static int rk_mipi_dsi_gen_pkt_hdr_write(struct rk_mipi_dsi *dsi, u32 hdr_val)
{
	int val;
	struct stopwatch sw;
	u32 mask;

	if (rk_mipi_dsi_check_fifo(dsi, GEN_CMD_FULL)) {
		printk(BIOS_ERR, "failed to get available command FIFO\n");
		return -1;
	}

	write32(&dsi->mipi_regs->dsi_gen_hdr, hdr_val);

	mask = GEN_CMD_EMPTY | GEN_PLD_W_EMPTY;
	stopwatch_init_msecs_expire(&sw, 20);
	do {
		val = read32(&dsi->mipi_regs->dsi_cmd_pkt_status);
		if ((val & mask) == mask)
			return 0;
	} while (!stopwatch_expired(&sw));
	printk(BIOS_ERR, "failed to write command FIFO\n");

	return -1;
}

static int rk_mipi_dsi_dcs_cmd(struct rk_mipi_dsi *dsi, u8 cmd)
{
	u32 val;

	rk_mipi_message_config(dsi);

	val = GEN_HDATA(cmd) | GEN_HTYPE(MIPI_DSI_DCS_SHORT_WRITE);

	return rk_mipi_dsi_gen_pkt_hdr_write(dsi, val);
}

static int rk_mipi_dsi_dci_long_write(struct rk_mipi_dsi *dsi,
				      char *data, u32 len)
{
	u32 remainder;
	int ret = 0;

	while (len) {
		if (len < 4) {
			remainder = 0;
			memcpy(&remainder, data, len);
			write32(&dsi->mipi_regs->dsi_gen_pld_data, remainder);
			len = 0;
		} else {
			remainder = *(u32 *)data;
			write32(&dsi->mipi_regs->dsi_gen_pld_data, remainder);
			data += 4;
			len -= 4;
		}

		ret = rk_mipi_dsi_check_fifo(dsi, GEN_PLD_W_FULL);
		if (ret) {
			printk(BIOS_ERR, "Failed to write fifo\n");
			return ret;
		}
	}

	return ret;
}

static int rk_mipi_dsi_write(struct rk_mipi_dsi *dsi, char *data, int len)
{
	u16 buf = 0;
	u32 val;
	int ret = 0;

	rk_mipi_message_config(dsi);

	switch (len) {
	case 0:
		die("not data!");
	case 1:
		val = GEN_HDATA(*data) |
		      GEN_HTYPE(MIPI_DSI_DCS_SHORT_WRITE);
		break;
	case 2:
		buf = *data++;
		buf |= *data << 8;
		val = GEN_HDATA(buf) |
		      GEN_HTYPE(MIPI_DSI_DCS_SHORT_WRITE_PARAM);
		break;
	default:
		ret = rk_mipi_dsi_dci_long_write(dsi, data, len);
		if (ret) {
			printk(BIOS_ERR, "error happened during long write\n");
			return ret;
		}
		val = GEN_HDATA(len) | GEN_HTYPE(MIPI_DSI_DCS_LONG_WRITE);
		break;
	}

	return rk_mipi_dsi_gen_pkt_hdr_write(dsi, val);
}

static void rk_mipi_enable(struct rk_mipi_dsi *dsi,
			   const struct edid *edid,
			   const struct mipi_panel_data *panel_data)
{
	if (rk_mipi_dsi_get_lane_bps(dsi, edid, panel_data) < 0)
		return;

	rk_mipi_dsi_init(dsi);
	rk_mipi_dsi_dpi_config(dsi);
	rk_mipi_dsi_packet_handler_config(dsi);
	rk_mipi_dsi_video_mode_config(dsi);
	rk_mipi_dsi_video_packet_config(dsi, edid, panel_data);
	rk_mipi_dsi_command_mode_config(dsi);
	rk_mipi_dsi_line_timer_config(dsi, edid);
	rk_mipi_dsi_vertical_timing_config(dsi, edid);
	rk_mipi_dsi_dphy_timing_config(dsi);
	rk_mipi_dsi_dphy_interface_config(dsi);
	rk_mipi_dsi_clear_err(dsi);
	if (rk_mipi_dsi_phy_init(dsi) < 0)
		return;
	rk_mipi_dsi_wait_for_two_frames(dsi, edid);

	rk_mipi_dsi_set_mode(dsi, MIPI_DSI_CMD_MODE);
}

void rk_mipi_prepare(const struct edid *edid,
		     const struct mipi_panel_data *panel_data)
{
	int i, num;
	struct panel_init_command *cmds;

	for (i = 0; i < panel_data->mipi_num; i++) {
		rk_mipi[i].lanes = panel_data->lanes / panel_data->mipi_num;
		rk_mipi[i].format = panel_data->format;
		rk_mipi_enable(&rk_mipi[i], edid, panel_data);
	}

	if (panel_data->init_cmd) {
		cmds = panel_data->init_cmd;
		for (num = 0; cmds[num].len != 0; num++) {
			struct panel_init_command *cmd = &cmds[num];
			for (i = 0; i < panel_data->mipi_num; i++) {
				if (rk_mipi_dsi_write(&rk_mipi[i], cmd->data,
						      cmd->len))
					return;

				/* make sure panel picks up the command */
				if (rk_mipi_dsi_dcs_cmd(&rk_mipi[i],
							MIPI_DCS_NOP))
					return;
			}
		}
	}

	for (i = 0; i < panel_data->mipi_num; i++) {
		if (rk_mipi_dsi_dcs_cmd(&rk_mipi[i],
					MIPI_DCS_EXIT_SLEEP_MODE) < 0)
			return;
	}
	udelay(panel_data->display_on_udelay);
	for (i = 0; i < panel_data->mipi_num; i++) {
		if (rk_mipi_dsi_dcs_cmd(&rk_mipi[i],
					MIPI_DCS_SET_DISPLAY_ON) < 0)
			return;
	}
	udelay(panel_data->video_mode_udelay);
	for (i = 0; i < panel_data->mipi_num; i++)
		rk_mipi_dsi_set_mode(&rk_mipi[i], MIPI_DSI_VID_MODE);
}
