// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright 2015 Toradex, Inc.
 *
 * Based on vf610twr:
 * Copyright 2013 Freescale Semiconductor, Inc.
 */

#include <asm/io.h>
#include <asm/arch/imx-regs.h>
#include <asm/arch/iomux-vf610.h>
#include <asm/arch/ddrmc-vf610.h>

void ddrmc_setup_iomux(const iomux_v3_cfg_t *pads, int pads_count)
{
	static const iomux_v3_cfg_t default_pads[] = {
		VF610_PAD_DDR_A15__DDR_A_15,
		VF610_PAD_DDR_A14__DDR_A_14,
		VF610_PAD_DDR_A13__DDR_A_13,
		VF610_PAD_DDR_A12__DDR_A_12,
		VF610_PAD_DDR_A11__DDR_A_11,
		VF610_PAD_DDR_A10__DDR_A_10,
		VF610_PAD_DDR_A9__DDR_A_9,
		VF610_PAD_DDR_A8__DDR_A_8,
		VF610_PAD_DDR_A7__DDR_A_7,
		VF610_PAD_DDR_A6__DDR_A_6,
		VF610_PAD_DDR_A5__DDR_A_5,
		VF610_PAD_DDR_A4__DDR_A_4,
		VF610_PAD_DDR_A3__DDR_A_3,
		VF610_PAD_DDR_A2__DDR_A_2,
		VF610_PAD_DDR_A1__DDR_A_1,
		VF610_PAD_DDR_A0__DDR_A_0,
		VF610_PAD_DDR_BA2__DDR_BA_2,
		VF610_PAD_DDR_BA1__DDR_BA_1,
		VF610_PAD_DDR_BA0__DDR_BA_0,
		VF610_PAD_DDR_CAS__DDR_CAS_B,
		VF610_PAD_DDR_CKE__DDR_CKE_0,
		VF610_PAD_DDR_CLK__DDR_CLK_0,
		VF610_PAD_DDR_CS__DDR_CS_B_0,
		VF610_PAD_DDR_D15__DDR_D_15,
		VF610_PAD_DDR_D14__DDR_D_14,
		VF610_PAD_DDR_D13__DDR_D_13,
		VF610_PAD_DDR_D12__DDR_D_12,
		VF610_PAD_DDR_D11__DDR_D_11,
		VF610_PAD_DDR_D10__DDR_D_10,
		VF610_PAD_DDR_D9__DDR_D_9,
		VF610_PAD_DDR_D8__DDR_D_8,
		VF610_PAD_DDR_D7__DDR_D_7,
		VF610_PAD_DDR_D6__DDR_D_6,
		VF610_PAD_DDR_D5__DDR_D_5,
		VF610_PAD_DDR_D4__DDR_D_4,
		VF610_PAD_DDR_D3__DDR_D_3,
		VF610_PAD_DDR_D2__DDR_D_2,
		VF610_PAD_DDR_D1__DDR_D_1,
		VF610_PAD_DDR_D0__DDR_D_0,
		VF610_PAD_DDR_DQM1__DDR_DQM_1,
		VF610_PAD_DDR_DQM0__DDR_DQM_0,
		VF610_PAD_DDR_DQS1__DDR_DQS_1,
		VF610_PAD_DDR_DQS0__DDR_DQS_0,
		VF610_PAD_DDR_RAS__DDR_RAS_B,
		VF610_PAD_DDR_WE__DDR_WE_B,
		VF610_PAD_DDR_ODT1__DDR_ODT_0,
		VF610_PAD_DDR_ODT0__DDR_ODT_1,
		VF610_PAD_DDR_RESETB,
	};

	if ((pads == NULL) || (pads_count == 0)) {
		pads = default_pads;
		pads_count = ARRAY_SIZE(default_pads);
	}

	imx_iomux_v3_setup_multiple_pads(pads, pads_count);
}

static struct ddrmc_phy_setting default_phy_settings[] = {
	{ DDRMC_PHY_DQ_TIMING,  0 },
	{ DDRMC_PHY_DQ_TIMING, 16 },
	{ DDRMC_PHY_DQ_TIMING, 32 },

	{ DDRMC_PHY_DQS_TIMING,  1 },
	{ DDRMC_PHY_DQS_TIMING, 17 },

	{ DDRMC_PHY_CTRL,  2 },
	{ DDRMC_PHY_CTRL, 18 },
	{ DDRMC_PHY_CTRL, 34 },

	{ DDRMC_PHY_MASTER_CTRL,  3 },
	{ DDRMC_PHY_MASTER_CTRL, 19 },
	{ DDRMC_PHY_MASTER_CTRL, 35 },

	{ DDRMC_PHY_SLAVE_CTRL,  4 },
	{ DDRMC_PHY_SLAVE_CTRL, 20 },
	{ DDRMC_PHY_SLAVE_CTRL, 36 },

	/* LPDDR2 only parameter */
	{ DDRMC_PHY_OFF, 49 },

	{ DDRMC_PHY50_DDR3_MODE | DDRMC_PHY50_EN_SW_HALF_CYCLE, 50 },

	/* Processor Pad ODT settings */
	{ DDRMC_PHY_PROC_PAD_ODT, 52 },

	/* end marker */
	{ 0, -1 }
};

void ddrmc_ctrl_init_ddr3(struct ddr3_jedec_timings const *timings,
			  struct ddrmc_cr_setting *board_cr_settings,
			  struct ddrmc_phy_setting *board_phy_settings,
			  int col_diff, int row_diff)
{
	struct ddrmr_regs *ddrmr = (struct ddrmr_regs *)DDR_BASE_ADDR;
	struct ddrmc_cr_setting *cr_setting;
	struct ddrmc_phy_setting *phy_setting;

	writel(DDRMC_CR00_DRAM_CLASS_DDR3, &ddrmr->cr[0]);
	writel(DDRMC_CR02_DRAM_TINIT(timings->tinit), &ddrmr->cr[2]);
	writel(DDRMC_CR10_TRST_PWRON(timings->trst_pwron), &ddrmr->cr[10]);

	writel(DDRMC_CR11_CKE_INACTIVE(timings->cke_inactive), &ddrmr->cr[11]);
	writel(DDRMC_CR12_WRLAT(timings->wrlat) |
		   DDRMC_CR12_CASLAT_LIN(timings->caslat_lin), &ddrmr->cr[12]);
	writel(DDRMC_CR13_TRC(timings->trc) | DDRMC_CR13_TRRD(timings->trrd) |
		   DDRMC_CR13_TCCD(timings->tccd) |
		   DDRMC_CR13_TBST_INT_INTERVAL(timings->tbst_int_interval),
		   &ddrmr->cr[13]);
	writel(DDRMC_CR14_TFAW(timings->tfaw) | DDRMC_CR14_TRP(timings->trp) |
		   DDRMC_CR14_TWTR(timings->twtr) |
		   DDRMC_CR14_TRAS_MIN(timings->tras_min), &ddrmr->cr[14]);
	writel(DDRMC_CR16_TMRD(timings->tmrd) |
		   DDRMC_CR16_TRTP(timings->trtp), &ddrmr->cr[16]);
	writel(DDRMC_CR17_TRAS_MAX(timings->tras_max) |
		   DDRMC_CR17_TMOD(timings->tmod), &ddrmr->cr[17]);
	writel(DDRMC_CR18_TCKESR(timings->tckesr) |
		   DDRMC_CR18_TCKE(timings->tcke), &ddrmr->cr[18]);

	writel(DDRMC_CR20_AP_EN, &ddrmr->cr[20]);
	writel(DDRMC_CR21_TRCD_INT(timings->trcd_int) | DDRMC_CR21_CCMAP_EN |
		   DDRMC_CR21_TRAS_LOCKOUT(timings->tras_lockout),
		   &ddrmr->cr[21]);

	writel(DDRMC_CR22_TDAL(timings->tdal), &ddrmr->cr[22]);
	writel(DDRMC_CR23_BSTLEN(timings->bstlen) |
		   DDRMC_CR23_TDLL(timings->tdll), &ddrmr->cr[23]);
	writel(DDRMC_CR24_TRP_AB(timings->trp_ab), &ddrmr->cr[24]);

	writel(DDRMC_CR25_TREF_EN, &ddrmr->cr[25]);
	writel(DDRMC_CR26_TREF(timings->tref) |
		   DDRMC_CR26_TRFC(timings->trfc), &ddrmr->cr[26]);
	writel(DDRMC_CR28_TREF_INT(timings->tref_int), &ddrmr->cr[28]);
	writel(DDRMC_CR29_TPDEX(timings->tpdex), &ddrmr->cr[29]);

	writel(DDRMC_CR30_TXPDLL(timings->txpdll), &ddrmr->cr[30]);
	writel(DDRMC_CR31_TXSNR(timings->txsnr) |
		   DDRMC_CR31_TXSR(timings->txsr), &ddrmr->cr[31]);
	writel(DDRMC_CR33_EN_QK_SREF, &ddrmr->cr[33]);
	writel(DDRMC_CR34_CKSRX(timings->cksrx) |
		   DDRMC_CR34_CKSRE(timings->cksre), &ddrmr->cr[34]);

	writel(DDRMC_CR38_FREQ_CHG_EN(timings->freq_chg_en), &ddrmr->cr[38]);
	writel(DDRMC_CR39_PHY_INI_COM(1024) | DDRMC_CR39_PHY_INI_STA(16) |
		   DDRMC_CR39_FRQ_CH_DLLOFF(2), &ddrmr->cr[39]);

	writel(DDRMC_CR41_PHY_INI_STRT_INI_DIS, &ddrmr->cr[41]);
	writel(DDRMC_CR48_MR1_DA_0(70) |
		   DDRMC_CR48_MR0_DA_0(1056), &ddrmr->cr[48]);

	writel(DDRMC_CR66_ZQCL(timings->zqcl) |
		   DDRMC_CR66_ZQINIT(timings->zqinit), &ddrmr->cr[66]);
	writel(DDRMC_CR67_ZQCS(timings->zqcs), &ddrmr->cr[67]);
	writel(DDRMC_CR69_ZQ_ON_SREF_EX(2), &ddrmr->cr[69]);

	writel(DDRMC_CR70_REF_PER_ZQ(timings->ref_per_zq), &ddrmr->cr[70]);
	writel(DDRMC_CR72_ZQCS_ROTATE(timings->zqcs_rotate), &ddrmr->cr[72]);

	writel(DDRMC_CR73_APREBIT(timings->aprebit) |
		   DDRMC_CR73_COL_DIFF(col_diff) |
		   DDRMC_CR73_ROW_DIFF(row_diff), &ddrmr->cr[73]);
	writel(DDRMC_CR74_BANKSPLT_EN | DDRMC_CR74_ADDR_CMP_EN |
		   DDRMC_CR74_CMD_AGE_CNT(timings->cmd_age_cnt) |
		   DDRMC_CR74_AGE_CNT(timings->age_cnt),
		   &ddrmr->cr[74]);
	writel(DDRMC_CR75_RW_PG_EN | DDRMC_CR75_RW_EN | DDRMC_CR75_PRI_EN |
		   DDRMC_CR75_PLEN, &ddrmr->cr[75]);
	writel(DDRMC_CR76_NQENT_ACTDIS(3) | DDRMC_CR76_D_RW_G_BKCN(3) |
		   DDRMC_CR76_W2R_SPLT_EN, &ddrmr->cr[76]);
	writel(DDRMC_CR77_CS_MAP | DDRMC_CR77_DI_RD_INTLEAVE |
		   DDRMC_CR77_SWAP_EN, &ddrmr->cr[77]);
	writel(DDRMC_CR78_Q_FULLNESS(timings->q_fullness) |
		   DDRMC_CR78_BUR_ON_FLY_BIT(12), &ddrmr->cr[78]);
	writel(DDRMC_CR79_CTLUPD_AREF(0), &ddrmr->cr[79]);

	writel(DDRMC_CR82_INT_MASK, &ddrmr->cr[82]);

	writel(DDRMC_CR87_ODT_RD_MAPCS0(timings->odt_rd_mapcs0) |
		   DDRMC_CR87_ODT_WR_MAPCS0(timings->odt_wr_mapcs0),
		   &ddrmr->cr[87]);
	writel(DDRMC_CR88_TODTL_CMD(4), &ddrmr->cr[88]);
	writel(DDRMC_CR89_AODT_RWSMCS(2), &ddrmr->cr[89]);

	writel(DDRMC_CR91_R2W_SMCSDL(2), &ddrmr->cr[91]);
	writel(DDRMC_CR96_WLMRD(timings->wlmrd) |
		   DDRMC_CR96_WLDQSEN(timings->wldqsen), &ddrmr->cr[96]);

	/* execute custom CR setting sequence (may be NULL) */
	cr_setting = board_cr_settings;
	if (cr_setting != NULL)
		while (cr_setting->cr_rnum >= 0) {
			writel(cr_setting->setting,
			       &ddrmr->cr[cr_setting->cr_rnum]);
			cr_setting++;
		}

	/* perform default PHY settings (may be overridden by custom settings */
	phy_setting = default_phy_settings;
	while (phy_setting->phy_rnum >= 0) {
		writel(phy_setting->setting,
		       &ddrmr->phy[phy_setting->phy_rnum]);
		phy_setting++;
	}

	/* execute custom PHY setting sequence (may be NULL) */
	phy_setting = board_phy_settings;
	if (phy_setting != NULL)
		while (phy_setting->phy_rnum >= 0) {
			writel(phy_setting->setting,
			       &ddrmr->phy[phy_setting->phy_rnum]);
			phy_setting++;
		}

	/* all inits done, start the DDR controller */
	writel(DDRMC_CR00_DRAM_CLASS_DDR3 | DDRMC_CR00_START, &ddrmr->cr[0]);

	while (!(readl(&ddrmr->cr[80]) && 0x100))
		udelay(10);
}
