/*
 * Copyright 2014 Rockchip Electronics Co., Ltd.
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#include <arch/io.h>
#include <libpayload.h>

#include "drivers/storage/dw_mmc.h"
#include "drivers/gpio/rockchip.h"

struct rk3288_cru_reg {
	u32 cru_apll_con[4];
	u32 cru_dpll_con[4];
	u32 cru_cpll_con[4];
	u32 cru_gpll_con[4];
	u32 cru_npll_con[4];
	u32 cru_mode_con;
	u32 reserved0[3];
	u32 cru_clksel_con[43];
	u32 reserved1[21];
	u32 cru_clkgate_con[19];
	u32 reserved2;
	u32 cru_glb_srst_fst_value;
	u32 cru_glb_srst_snd_value;
	u32 cru_softrst_con[12];
	u32 cru_misc_con;
	u32 cru_glb_cnt_th;
	u32 cru_glb_rst_con;
	u32 reserved3;
	u32 cru_glb_rst_st;
	u32 reserved4;
	u32 cru_sdmmc_con[2];
	u32 cru_sdio0_con[2];
	u32 cru_sdio1_con[2];
	u32 cru_emmc_con[2];
};

static struct rk3288_cru_reg *cru_ptr = (void *)0xff760000;

#define RK_CLRSETBITS(clr, set) ((((clr) | (set)) << 16) | set)

void rkclk_configure_emmc(DwmciHost *host, unsigned int freq)
{
	int src_clk_div;

	dwmci_writel(host, DWMCI_CLKDIV, 0);
	src_clk_div = ALIGN_UP(host->src_hz / 2, freq) / freq;

	if (src_clk_div > 0x3f) {
		src_clk_div = (24000000 / 2 + freq - 1) / freq;
		writel(RK_CLRSETBITS(0xff << 8 , 2 << 14 |
				((src_clk_div - 1) << 8)),
				&cru_ptr->cru_clksel_con[12]);
	} else
		writel(RK_CLRSETBITS(0xff << 8 , 1 << 14 |
				((src_clk_div - 1) << 8)),
				&cru_ptr->cru_clksel_con[12]);
}

void rkclk_configure_sdmmc(DwmciHost *host, unsigned int freq)
{
	int src_clk_div;

	dwmci_writel(host, DWMCI_CLKDIV, 0);
	src_clk_div = ALIGN_UP(host->src_hz / 2, freq) / freq;

	if (src_clk_div > 0x3f) {
		src_clk_div = (24000000 / 2 + freq - 1) / freq;
		writel(RK_CLRSETBITS(0xff, 2 << 6 | (src_clk_div - 1)),
				     &cru_ptr->cru_clksel_con[11]);
	} else
		writel(RK_CLRSETBITS(0xff, 1 << 6 | (src_clk_div - 1)),
				     &cru_ptr->cru_clksel_con[11]);
}

DwmciHost *new_rkdwmci_host(uintptr_t ioaddr, uint32_t src_hz,
				int bus_width, int removable,
				GpioOps *card_detect)
{
	DwmciHost *mmc;

	mmc = new_dwmci_host(ioaddr, src_hz, bus_width, removable,
			     card_detect, 0);
	if(removable)
		mmc->set_clk = &rkclk_configure_sdmmc;
	else
		mmc->set_clk = &rkclk_configure_emmc;
	return mmc;
}
