
/*
 * arch/arm/cpu/armv8/txl/sdio.c
 *
 * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
 *
 * 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.,
 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

#include <config.h>
#include <asm/arch/io.h>
#include <asm/arch/cpu_sdio.h>
#include <asm/arch/secure_apb.h>
#include <asm/cpu_id.h>
#include <common.h>

void  cpu_sd_emmc_pwr_prepare(unsigned port)
{
//    switch(port)
//    {
//        case SDIO_PORT_A:
//            clrbits_le32(P_PREG_PAD_GPIO4_EN_N,0x30f);
//            clrbits_le32(P_PREG_PAD_GPIO4_O   ,0x30f);
//            clrbits_le32(P_PERIPHS_PIN_MUX_8,0x3f);
//            break;
//        case SDIO_PORT_B:
//            clrbits_le32(P_PREG_PAD_GPIO5_EN_N,0x3f<<23);
//            clrbits_le32(P_PREG_PAD_GPIO5_O   ,0x3f<<23);
//            clrbits_le32(P_PERIPHS_PIN_MUX_2,0x3f<<10);
//            break;
//        case SDIO_PORT_C:
//            //clrbits_le32(P_PREG_PAD_GPIO3_EN_N,0xc0f);
//            //clrbits_le32(P_PREG_PAD_GPIO3_O   ,0xc0f);
//            //clrbits_le32(P_PERIPHS_PIN_MUX_6,(0x3f<<24));break;
//            break;
//    }

    /**
        do nothing here
    */
}
unsigned sd_debug_board_1bit_flag = 0;
int cpu_sd_emmc_init(unsigned port)
{
	cpu_id_t cpuid = get_cpu_id();

	switch (port)
	{
	case SDIO_PORT_A:
		clrsetbits_le32(P_PERIPHS_PIN_MUX_3,
						0xFFFFFF, 0x111111);
		break;
	case SDIO_PORT_B:
		if (cpuid.chip_rev == 0xA)
			clrsetbits_le32(P_PAD_DS_REG1A, 0xFFFF, 0x5555);
		else if (cpuid.chip_rev == 0xB) {
			clrsetbits_le32(P_PAD_DS_REG1A, 0xFFFF, 0x5555);
			//setbits_le32(P_PAD_DS_REG1A, 0xFFFF);
			/* pullup & pullupen */
			setbits_le32(P_PAD_PULL_UP_EN_REG1, 0x7F);
			setbits_le32(P_PAD_PULL_UP_REG1, 0x7F);
			clrbits_le32(P_PREG_PAD_GPIO5_O, 1<<17);
		}

		if (sd_debug_board_1bit_flag == 1)
			clrsetbits_le32(P_PERIPHS_PIN_MUX_9,
						((0xFF << 16) | 0xF), ((0x11 << 16) | 0x1));
		else
			clrsetbits_le32(P_PERIPHS_PIN_MUX_9,
						0xFFFFFF, 0x111111);
		break;
	case SDIO_PORT_C:
		/* set driver strength */
		if (cpuid.chip_rev == 0xA)
			writel(0x55555555, P_PAD_DS_REG0A);
		else if (cpuid.chip_rev == 0xB)
			writel(0xFFFFFFFF, P_PAD_DS_REG0A);
		/* pull up data by default */
		setbits_le32(P_PAD_PULL_UP_EN_REG0, 0x35ff);
		setbits_le32(P_PAD_PULL_UP_REG0, 0x35ff);
		/* set pinmux */
		writel(0x11111111, P_PERIPHS_PIN_MUX_0);
		clrsetbits_le32(P_PERIPHS_PIN_MUX_1,
						((0xFF << 16) | (0xF << 8) | 0xF),
						((0x1 << 20) | (0x1 << 8) | 0x1));
		/* hardware reset with pull boot12 */
		clrbits_le32(P_PREG_PAD_GPIO0_EN_N, 1<<12);
		clrbits_le32(P_PREG_PAD_GPIO0_O, 1<<12);
		udelay(10);
		setbits_le32(P_PREG_PAD_GPIO0_O, 1<<12);
		break;
	default:
		return -1;
	}
	return 0;
}

/* return:
	0: insert
	1: not insert
 */
__weak int  sd_emmc_detect(unsigned port)
{
	int ret = 0;
	unsigned pinmux_9;

    switch (port) {

	case SDIO_PORT_A:
		break;
	case SDIO_PORT_B:
		pinmux_9 = readl(P_PERIPHS_PIN_MUX_9);
		clrbits_le32(P_PERIPHS_PIN_MUX_9, 0xF << 24);
		setbits_le32(P_PREG_PAD_GPIO1_EN_N, 1 << 6);
		setbits_le32(P_PAD_PULL_UP_EN_REG1, 1 << 6);
		setbits_le32(P_PAD_PULL_UP_REG1, 1 << 6);

		ret = readl(P_PREG_PAD_GPIO1_I) & (1 << 6);
		printf("%s\n", ret ? "card out" : "card in");
		if (!ret) {
			clrbits_le32(P_PERIPHS_PIN_MUX_9, 0xF << 12);
			setbits_le32(P_PREG_PAD_GPIO1_EN_N, 1 << 3);
			setbits_le32(P_PAD_PULL_UP_EN_REG1, 1 << 3);
			setbits_le32(P_PAD_PULL_UP_REG1, 1 << 3);
			/* debug board in when D3 is low */
			if (!(readl(P_PREG_PAD_GPIO1_I) & (1 << 3))) {
				/* switch uart to GPIOC(Card) */
				clrbits_le32(P_AO_RTI_PINMUX_REG0, 0xFF);
				clrsetbits_le32(P_PERIPHS_PIN_MUX_9, 0xFF << 8, 0x22 << 8);
				clrsetbits_le32(P_PERIPHS_PIN_MUX_9,
						((0xFF << 16) | 0xF), ((0x11 << 16) | 0x1));
				printf("sdio debug board detected\n");
				sd_debug_board_1bit_flag = 1;
			} else {
				//4bit card
				writel(pinmux_9, P_PERIPHS_PIN_MUX_9);
				sd_debug_board_1bit_flag = 0;
			}

		}
		break;
	default:
		break;
	}
	return ret;
}
