mirror of
https://git.codelinaro.org/clo/qsdk/oss/boot/u-boot-2016.git
synced 2025-12-10 07:44:53 +01:00
As 52Mhz clk does not have 50% dutycycle, setting 48MHz clk for mmc data transfer mode Change-Id: Id9c0ce07fe652df7d575c5ea11f1d83eab0fb24c Signed-off-by: Rajkumar Ayyasamy <arajkuma@codeaurora.org>
611 lines
15 KiB
C
611 lines
15 KiB
C
/*
|
|
* Copyright (c) 2012 - 2014 The Linux Foundation. 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 version 2 and
|
|
* only version 2 as published by the Free Software Foundation.
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
#include <common.h>
|
|
#include <asm/io.h>
|
|
|
|
#include <asm/arch-ipq806x/clk.h>
|
|
|
|
#define MSM_CLK_CTL_BASE 0x00900000
|
|
#define GSBIn_UART_APPS_MD_REG(n) (MSM_CLK_CTL_BASE + 0x29D0 + (0x20*((n)-1)))
|
|
#define GSBIn_UART_APPS_NS_REG(n) (MSM_CLK_CTL_BASE + 0x29D4 + (0x20*((n)-1)))
|
|
#define GSBIn_HCLK_CTL_REG(n) (MSM_CLK_CTL_BASE + 0x29C0 + (0x20*((n)-1)))
|
|
#define BB_PLL_ENA_SC0_REG (MSM_CLK_CTL_BASE + 0x34C0)
|
|
#define PLL_LOCK_DET_STATUS_REG (MSM_CLK_CTL_BASE + 0x03420)
|
|
|
|
#define MN_MODE_DUAL_EDGE 0x2
|
|
|
|
#define BM(m, l) (((((unsigned int)-1) << (31-m)) >> (31-m+l)) << l)
|
|
#define BVAL(m, l, val) (((val) << l) & BM(m, l))
|
|
|
|
#define Uart_clk_ns_mask (BM(31, 16) | BM(6, 0))
|
|
#define Uart_en_mask BIT(11)
|
|
#define MD16(m, n) (BVAL(31, 16, m) | BVAL(15, 0, ~(n)))
|
|
|
|
/* NS Registers */
|
|
#define NS(n_msb, n_lsb, n, m, mde_lsb, d_msb, d_lsb, d, s_msb, s_lsb, s) \
|
|
(BVAL(n_msb, n_lsb, ~(n-m)) \
|
|
| (BVAL((mde_lsb+1), mde_lsb, MN_MODE_DUAL_EDGE) * !!(n)) \
|
|
| BVAL(d_msb, d_lsb, (d-1)) | BVAL(s_msb, s_lsb, s))
|
|
|
|
#ifdef CONFIG_IPQ806X_I2C
|
|
unsigned int gsbi_port = 4;
|
|
unsigned int GSBI_I2C_CLK_M = 1;
|
|
unsigned int GSBI_I2C_CLK_N = 4;
|
|
unsigned int GSBI_I2C_CLK_D = 2;
|
|
#endif
|
|
|
|
/**
|
|
* uart_pll_vote_clk_enable - enables PLL8
|
|
*/
|
|
void uart_pll_vote_clk_enable(void)
|
|
{
|
|
setbits_le32(BB_PLL_ENA_SC0_REG, BIT(8));
|
|
|
|
while((readl(PLL_LOCK_DET_STATUS_REG) & BIT(8)) == 0);
|
|
}
|
|
#ifdef CONFIG_USB_XHCI_IPQ
|
|
/**
|
|
* usb_pll_vote_clk_enable - enables PLL8
|
|
*/
|
|
void usb_pll_vote_clk_enable(void)
|
|
{
|
|
setbits_le32(BB_PLL_ENA_SC0_REG, BIT(0));
|
|
|
|
while((readl(PLL_LOCK_DET_STATUS_REG) & BIT(0)) == 0);
|
|
}
|
|
#endif
|
|
/**
|
|
* uart_set_rate_mnd - configures divider M and D values
|
|
*
|
|
* Sets the M, D parameters of the divider to generate the GSBI UART
|
|
* apps clock.
|
|
*/
|
|
static void uart_set_rate_mnd(unsigned int gsbi_port, unsigned int m,
|
|
unsigned int n)
|
|
{
|
|
/* Assert MND reset. */
|
|
setbits_le32(GSBIn_UART_APPS_NS_REG(gsbi_port), BIT(7));
|
|
/* Program M and D values. */
|
|
writel(MD16(m, n), GSBIn_UART_APPS_MD_REG(gsbi_port));
|
|
/* Deassert MND reset. */
|
|
clrbits_le32(GSBIn_UART_APPS_NS_REG(gsbi_port), BIT(7));
|
|
}
|
|
|
|
#ifdef CONFIG_USB_XHCI_IPQ
|
|
/**
|
|
* usb_set_rate_mnd - configures divider M and D values
|
|
*
|
|
* Sets the M, D parameters of the divider to generate the USB
|
|
* apps clock.
|
|
*/
|
|
static void usb_set_rate_mnd(unsigned int usb_port, unsigned int m,
|
|
unsigned int n)
|
|
{
|
|
/* Assert MND reset. */
|
|
setbits_le32(USB30_MASTER_CLK_NS, BIT(7));
|
|
/* Program M and D values. */
|
|
writel(MD8(16, m, 0, n), USB30_MASTER_CLK_MD);
|
|
/* Deassert MND reset. */
|
|
clrbits_le32(USB30_MASTER_CLK_NS, BIT(7));
|
|
}
|
|
|
|
static void usb_set_rate_mnd_utmi(unsigned int usb_port, unsigned int m,
|
|
unsigned int n)
|
|
{
|
|
/* Assert MND reset. */
|
|
setbits_le32(USB30_MOC_UTMI_CLK_NS, BIT(7));
|
|
/* Program M and D values. */
|
|
writel(MD8(16, m, 0, n), USB30_MOC_UTMI_CLK_MD);
|
|
/* Deassert MND reset. */
|
|
clrbits_le32(USB30_MOC_UTMI_CLK_NS, BIT(7));
|
|
}
|
|
#endif
|
|
/**
|
|
* uart_branch_clk_enable_reg - enables branch clock
|
|
*
|
|
* Enables branch clock for GSBI UART port.
|
|
*/
|
|
static void uart_branch_clk_enable_reg(unsigned int gsbi_port)
|
|
{
|
|
setbits_le32(GSBIn_UART_APPS_NS_REG(gsbi_port), BIT(9));
|
|
}
|
|
|
|
#ifdef CONFIG_USB_XHCI_IPQ
|
|
/**
|
|
* usb_local_clock_enable - configures N value and enables root clocks
|
|
*
|
|
* Sets the N parameter of the divider and enables root clock and
|
|
* branch clocks for USB port.
|
|
*/
|
|
static void usb_utmi_local_clock_enable(unsigned int usb_port, unsigned int n,
|
|
unsigned int m)
|
|
{
|
|
unsigned int reg_val, usb_ns_val;
|
|
void *const reg = (void *)USB30_MOC_UTMI_CLK_NS;
|
|
|
|
/*
|
|
* Program the NS register, if applicable. NS registers are not
|
|
* set in the set_rate path because power can be saved by deferring
|
|
* the selection of a clocked source until the clock is enabled.
|
|
*/
|
|
reg_val = readl(reg);
|
|
reg_val &= ~(USB_clk_ns_mask);
|
|
usb_ns_val = NS(23,16,n,m, 5, 4, 3, 1, 2, 0,3);
|
|
reg_val |= (usb_ns_val & USB_clk_ns_mask);
|
|
writel(reg_val,reg);
|
|
|
|
/* enable MNCNTR_EN */
|
|
reg_val = readl(reg);
|
|
reg_val |= BIT(8);
|
|
writel(reg_val, reg);
|
|
|
|
/* set source to PLL8 running @384MHz */
|
|
reg_val = readl(reg);
|
|
reg_val |= 0x2;
|
|
writel(reg_val, reg);
|
|
|
|
/* Enable root. */
|
|
reg_val = readl(reg);
|
|
reg_val |= USB_en_mask;
|
|
writel(reg_val, reg);
|
|
}
|
|
|
|
/**
|
|
* usb_local_clock_enable - configures N value and enables root clocks
|
|
*
|
|
* Sets the N parameter of the divider and enables root clock and
|
|
* branch clocks for USB port.
|
|
*/
|
|
static void usb_local_clock_enable(unsigned int usb_port, unsigned int n,
|
|
unsigned int m)
|
|
{
|
|
unsigned int reg_val, usb_ns_val;
|
|
void *const reg = (void *)USB30_MASTER_CLK_NS;
|
|
|
|
/*
|
|
* Program the NS register, if applicable. NS registers are not
|
|
* set in the set_rate path because power can be saved by deferring
|
|
* the selection of a clocked source until the clock is enabled.
|
|
*/
|
|
reg_val = readl(reg);
|
|
reg_val &= ~(USB_clk_ns_mask);
|
|
usb_ns_val = NS(23,16,n,m, 5, 4, 3, 1, 2, 0,3);
|
|
reg_val |= (usb_ns_val & USB_clk_ns_mask);
|
|
writel(reg_val,reg);
|
|
|
|
/* enable MNCNTR_EN */
|
|
reg_val = readl(reg);
|
|
reg_val |= BIT(8);
|
|
writel(reg_val, reg);
|
|
|
|
/* set source to PLL8 running @384MHz */
|
|
reg_val = readl(reg);
|
|
reg_val |= 0x2;
|
|
writel(reg_val, reg);
|
|
|
|
/* Enable root. */
|
|
reg_val = readl(reg);
|
|
reg_val |= USB_en_mask;
|
|
writel(reg_val, reg);
|
|
}
|
|
|
|
/*
|
|
* usb_set_master_clk - enables MASTER CLK for USB port
|
|
*/
|
|
static void usb_set_master_clk(unsigned int usb_port)
|
|
{
|
|
setbits_le32(USB30_MASTER_CLK_CTL, BIT(4));
|
|
}
|
|
|
|
/**
|
|
* usb_set_master_1_clk - enables MASTER_1 CLK for USB port
|
|
*/
|
|
static void usb_set_master_1_clk(unsigned int usb_port)
|
|
{
|
|
setbits_le32(USB30_MASTER_1_CLK_CTL, BIT(4));
|
|
}
|
|
|
|
/**
|
|
* usb_set_utmi_clk - enables utmi branch port
|
|
*/
|
|
static void usb_set_utmi_clk(unsigned int usb_port)
|
|
{
|
|
setbits_le32(USB30_MOC_UTMI_CLK_CTL, BIT(4));
|
|
}
|
|
|
|
/**
|
|
* usb_set_utmi_1_clk - enables utmi branch port
|
|
*/
|
|
static void usb_set_utmi_1_clk(unsigned int usb_port)
|
|
{
|
|
setbits_le32(USB30_MOC_1_UTMI_CLK_CTL, BIT(4));
|
|
}
|
|
#endif
|
|
|
|
/**
|
|
* uart_local_clock_enable - configures N value and enables root clocks
|
|
*
|
|
* Sets the N parameter of the divider and enables root clock and
|
|
* branch clocks for GSBI UART port.
|
|
*/
|
|
static void uart_local_clock_enable(unsigned int gsbi_port, unsigned int n,
|
|
unsigned int m)
|
|
{
|
|
unsigned int reg_val, uart_ns_val;
|
|
void *const reg = (void *)GSBIn_UART_APPS_NS_REG(gsbi_port);
|
|
|
|
/*
|
|
* Program the NS register, if applicable. NS registers are not
|
|
* set in the set_rate path because power can be saved by deferring
|
|
* the selection of a clocked source until the clock is enabled.
|
|
*/
|
|
reg_val = readl(reg); // REG(0x29D4+(0x20*((n)-1)))
|
|
reg_val &= ~(Uart_clk_ns_mask);
|
|
uart_ns_val = NS(31,16,n,m, 5, 4, 3, 1, 2, 0,3);
|
|
reg_val |= (uart_ns_val & Uart_clk_ns_mask);
|
|
writel(reg_val,reg);
|
|
|
|
/* enable MNCNTR_EN */
|
|
reg_val = readl(reg);
|
|
reg_val |= BIT(8);
|
|
writel(reg_val, reg);
|
|
|
|
/* set source to PLL8 running @384MHz */
|
|
reg_val = readl(reg);
|
|
reg_val |= 0x3;
|
|
writel(reg_val, reg);
|
|
|
|
/* Enable root. */
|
|
reg_val |= Uart_en_mask;
|
|
writel(reg_val, reg);
|
|
uart_branch_clk_enable_reg(gsbi_port);
|
|
}
|
|
|
|
/**
|
|
* uart_set_gsbi_clk - enables HCLK for UART GSBI port
|
|
*/
|
|
static void uart_set_gsbi_clk(unsigned int gsbi_port)
|
|
{
|
|
setbits_le32(GSBIn_HCLK_CTL_REG(gsbi_port), BIT(4));
|
|
}
|
|
|
|
#ifdef CONFIG_USB_XHCI_IPQ
|
|
/**
|
|
*
|
|
* USB_clock_config - configures USB3.0 clocks
|
|
*
|
|
* Configures USB dividers, enable root and branch clocks.
|
|
*/
|
|
void usb_ss_core_clock_config(unsigned int usb_port, unsigned int m,
|
|
unsigned int n, unsigned int d)
|
|
{
|
|
usb_set_rate_mnd(usb_port, m, n);
|
|
usb_pll_vote_clk_enable();
|
|
usb_local_clock_enable(usb_port, n, m);
|
|
usb_set_master_clk(usb_port);
|
|
usb_set_master_1_clk(usb_port);
|
|
}
|
|
|
|
void usb_ss_utmi_clock_config(unsigned int usb_port, unsigned int m,
|
|
unsigned int n, unsigned int d)
|
|
{
|
|
usb_set_rate_mnd_utmi(usb_port, m, n);
|
|
usb_utmi_local_clock_enable(usb_port, n, m);
|
|
usb_set_utmi_clk(usb_port);
|
|
usb_set_utmi_1_clk(usb_port);
|
|
}
|
|
#endif
|
|
|
|
/**
|
|
* uart_clock_config - configures UART clocks
|
|
*
|
|
* Configures GSBI UART dividers, enable root and branch clocks.
|
|
*/
|
|
void uart_clock_config(unsigned int gsbi_port, unsigned int m,
|
|
unsigned int n, unsigned int d)
|
|
{
|
|
uart_set_rate_mnd(gsbi_port, m, d);
|
|
uart_pll_vote_clk_enable();
|
|
uart_local_clock_enable(gsbi_port, n, m);
|
|
uart_set_gsbi_clk(gsbi_port);
|
|
}
|
|
|
|
#ifdef CONFIG_IPQ806X_I2C
|
|
/**
|
|
* i2c_set_rate_mnd - configures divider M and D values
|
|
*
|
|
* Sets the M, D parameters of the divider to generate the GSBI QUP
|
|
* apps clock.
|
|
*/
|
|
static void i2c_set_rate_mnd(void)
|
|
{
|
|
/* Assert MND reset. */
|
|
setbits_le32(GSBIn_QUP_APPS_NS_REG(gsbi_port), BIT(7));
|
|
/* Program M and D values. */
|
|
writel(MD16(GSBI_I2C_CLK_M, GSBI_I2C_CLK_D), GSBIn_QUP_APPS_MD_REG(gsbi_port));
|
|
/* Deassert MND reset. */
|
|
clrbits_le32(GSBIn_QUP_APPS_NS_REG(gsbi_port), BIT(7));
|
|
}
|
|
|
|
/**
|
|
* i2c_pll_vote_clk_enable - enables PLL8
|
|
*/
|
|
void i2c_pll_vote_clk_enable(void)
|
|
{
|
|
setbits_le32(BB_PLL_ENA_SC0_REG, BIT(8));
|
|
|
|
while((readl(PLL_LOCK_DET_STATUS_REG) & BIT(8)) == 0);
|
|
}
|
|
|
|
/**
|
|
* i2c_branch_clk_enable_reg - enables branch clock
|
|
*
|
|
* Enables branch clock for GSBI I2C port.
|
|
*/
|
|
static void i2c_branch_clk_enable_reg(void)
|
|
{
|
|
setbits_le32(GSBIn_QUP_APPS_NS_REG(gsbi_port), BIT(9));
|
|
}
|
|
|
|
/**
|
|
* i2c_local_clock_enable - configures N value and enables root clocks
|
|
*
|
|
* Sets the N parameter of the divider and enables root clock and
|
|
* branch clocks for GSBI I2C port.
|
|
*/
|
|
static void i2c_local_clock_enable(void)
|
|
{
|
|
unsigned int reg_val, i2c_ns_val;
|
|
void *const reg = (void *)GSBIn_QUP_APPS_NS_REG(gsbi_port);
|
|
|
|
/*
|
|
* Program the NS register, if applicable. NS registers are not
|
|
* set in the set_rate path because power can be saved by deferring
|
|
* the selection of a clocked source until the clock is enabled.
|
|
*/
|
|
reg_val = readl(reg);
|
|
reg_val &= ~(I2C_clk_ns_mask);
|
|
i2c_ns_val = NS(23,16,GSBI_I2C_CLK_N, GSBI_I2C_CLK_M, 5, 4, 3, 4, 2, 0, 3);
|
|
reg_val |= (i2c_ns_val & I2C_clk_ns_mask);
|
|
writel(reg_val,reg);
|
|
|
|
/* enable MNCNTR_EN */
|
|
reg_val = readl(reg);
|
|
reg_val |= BIT(8);
|
|
writel(reg_val, reg);
|
|
|
|
/* set source to PLL8 running @384MHz */
|
|
reg_val = readl(reg);
|
|
reg_val |= 0x3;
|
|
writel(reg_val, reg);
|
|
|
|
/* Enable root. */
|
|
reg_val |= I2C_en_mask;
|
|
writel(reg_val, reg);
|
|
i2c_branch_clk_enable_reg();
|
|
}
|
|
|
|
/**
|
|
* i2c_set_gsbi_clk - enables HCLK for I2C GSBI port
|
|
*/
|
|
static void i2c_set_gsbi_clk(void)
|
|
{
|
|
setbits_le32(GSBIn_HCLK_CTL_REG(gsbi_port), BIT(4));
|
|
}
|
|
|
|
/**
|
|
* i2c_clock_config - configures I2C clocks
|
|
*
|
|
* Configures GSBI I2C dividers, enable root and branch clocks.
|
|
*/
|
|
void i2c_clock_config(void)
|
|
{
|
|
i2c_set_rate_mnd();
|
|
i2c_pll_vote_clk_enable();
|
|
i2c_local_clock_enable();
|
|
i2c_set_gsbi_clk();
|
|
}
|
|
#endif
|
|
|
|
#ifdef CONFIG_IPQ_NAND
|
|
/**
|
|
* nand_clock_config - configure NAND controller clocks
|
|
*
|
|
* Enable clocks to EBI2. Must be invoked before touching EBI2
|
|
* registers.
|
|
*/
|
|
void nand_clock_config(void)
|
|
{
|
|
writel(CLK_BRANCH_ENA(1) | ALWAYS_ON_CLK_BRANCH_ENA(1),
|
|
EBI2_CLK_CTL_REG);
|
|
|
|
/* Wait for clock to stabilize. */
|
|
udelay(10);
|
|
}
|
|
#endif
|
|
|
|
void pcie_clock_shutdown(pci_clk_offset_t *pci_clk)
|
|
{
|
|
/* PCIE_ALT_REF_CLK_NS */
|
|
writel(0x0, pci_clk->alt_ref_clk_ns);
|
|
|
|
/* PCIE20_PARF_PHY_REFCLK */
|
|
writel(0x1019, pci_clk->parf_phy_refclk);
|
|
|
|
/* PCIE_ACLK_CTL */
|
|
writel(0x0, pci_clk->aclk_ctl);
|
|
|
|
/* PCIE_PCLK_CTL */
|
|
writel(0x0, pci_clk->pclk_ctl);
|
|
|
|
/* PCIE_HCLK_CTL */
|
|
writel(0x0, pci_clk->hclk_ctl);
|
|
|
|
/* PCIE_AUX_CLK_CTL */
|
|
writel(0x0, pci_clk->aux_clk_ctl);
|
|
}
|
|
|
|
void pcie_clock_config(pci_clk_offset_t *pci_clk)
|
|
{
|
|
/* PCIE_ALT_REF_CLK_NS */
|
|
writel(0x0A59, pci_clk->alt_ref_clk_ns);
|
|
|
|
|
|
/* PCIE_ACLK_FS */
|
|
writel(0x4F, pci_clk->aclk_fs);
|
|
|
|
/* PCIE_PCLK_FS */
|
|
writel(0x4F, pci_clk->pclk_fs);
|
|
|
|
/* PCIE_ACLK_CTL */
|
|
writel(0x10, pci_clk->aclk_ctl);
|
|
|
|
/* PCIE_PCLK_CTL */
|
|
writel(0x10, pci_clk->pclk_ctl);
|
|
|
|
/* PCIE_HCLK_CTL */
|
|
writel(0x10, pci_clk->hclk_ctl);
|
|
|
|
/* PCIE_AUX_CLK_CTL */
|
|
writel(0x10, pci_clk->aux_clk_ctl);
|
|
}
|
|
|
|
#ifdef CONFIG_QCA_MMC
|
|
void emmc_pll_vote_clk_enable(void)
|
|
{
|
|
setbits_le32(BB_PLL_ENA_SC0_REG, BIT(8));
|
|
|
|
while((readl(PLL_LOCK_DET_STATUS_REG) & BIT(8)) == 0);
|
|
}
|
|
|
|
static void emmc_set_rate_mnd( unsigned int m, unsigned int n)
|
|
{
|
|
/* Assert MND reset. */
|
|
setbits_le32(SDC1_APPS_CLK_NS, BIT(7));
|
|
/* Program M and D values. */
|
|
writel(MD8(16, m, 0, n), SDC1_APPS_CLK_MD);
|
|
/* Deassert MND reset. */
|
|
clrbits_le32(SDC1_APPS_CLK_NS, BIT(7));
|
|
}
|
|
|
|
static void emmc_set_iface_clk(void)
|
|
{
|
|
setbits_le32(SDC1_HCLK_CTL, BIT(4));
|
|
}
|
|
|
|
static void emmc_local_clock_enable(unsigned int m, unsigned int n,
|
|
unsigned int d, unsigned int mux, unsigned int pll)
|
|
{
|
|
unsigned int reg_val, emmc_ns_val;
|
|
void *const reg = (void *)SDC1_APPS_CLK_NS;
|
|
|
|
/*
|
|
* Program the NS register, if applicable. NS registers are not
|
|
* set in the set_rate path because power can be saved by deferring
|
|
* the selection of a clocked source until the clock is enabled.
|
|
*/
|
|
reg_val = readl(reg);
|
|
reg_val &= ~(emmc_clk_ns_mask);
|
|
emmc_ns_val = NS(23, 16, n, m, 5, 4, 3, d, 2, 0, mux);
|
|
reg_val |= (emmc_ns_val & emmc_clk_ns_mask);
|
|
writel(reg_val,reg);
|
|
|
|
|
|
reg_val = readl(reg);
|
|
reg_val |= pll;
|
|
writel(reg_val, reg);
|
|
|
|
/* Enable MNCNTR_EN */
|
|
reg_val = readl(reg);
|
|
reg_val |= BIT(8);
|
|
writel(reg_val, reg);
|
|
|
|
/* Enable root. */
|
|
reg_val = readl(reg);
|
|
reg_val |= emmc_en_mask;
|
|
writel(reg_val, reg);
|
|
|
|
/* Enable branch*/
|
|
reg_val = readl(reg);
|
|
reg_val |= BIT(9);
|
|
writel(reg_val, reg);
|
|
}
|
|
|
|
void emmc_clock_disable(void)
|
|
{
|
|
unsigned int reg_val, emmc_ns_val;
|
|
void *const reg = (void *)SDC1_APPS_CLK_NS;
|
|
emmc_ns_val = NS(23, 16, 240, 1, 5, 4, 3, 4, 2, 0, 3);
|
|
|
|
/* Assert MND reset. */
|
|
setbits_le32(SDC1_APPS_CLK_NS, BIT(7));
|
|
/* Program M and D values. */
|
|
writel(0, SDC1_APPS_CLK_MD);
|
|
/* Deassert MND reset. */
|
|
clrbits_le32(SDC1_APPS_CLK_NS, BIT(7));
|
|
|
|
/* Disable branch*/
|
|
reg_val = readl(reg);
|
|
reg_val &= ~BIT(9);
|
|
writel(reg_val, reg);
|
|
|
|
/* Disable root. */
|
|
reg_val = readl(reg);
|
|
reg_val &= ~emmc_en_mask;
|
|
writel(reg_val, reg);
|
|
|
|
/* Disable MNCNTR_EN */
|
|
reg_val = readl(reg);
|
|
reg_val &= ~BIT(8);
|
|
writel(reg_val, reg);
|
|
|
|
reg_val = readl(reg);
|
|
reg_val &= ~(emmc_clk_ns_mask);
|
|
reg_val |= emmc_ns_val & emmc_clk_ns_mask;
|
|
writel(reg_val, reg);
|
|
}
|
|
|
|
void emmc_clock_reset(void)
|
|
{
|
|
/*APPS CLK Assert*/
|
|
writel(0x1, SDC1_RESET);
|
|
/*APPS CLK Dessert*/
|
|
writel(0x0, SDC1_RESET);
|
|
}
|
|
|
|
void emmc_clock_config(int mode)
|
|
{
|
|
emmc_clock_disable();
|
|
udelay(10);
|
|
|
|
emmc_set_iface_clk();
|
|
|
|
if (mode == MMC_IDENTIFY_MODE) {
|
|
/*400 KHz pll8*/
|
|
emmc_set_rate_mnd(1, 240);
|
|
emmc_pll_vote_clk_enable();
|
|
emmc_local_clock_enable(1, 240, 4, 3, 3);
|
|
emmc_clock_reset();
|
|
udelay(10);
|
|
}
|
|
if (mode == MMC_DATA_TRANSFER_MODE) {
|
|
/*48 MHz pll8 */
|
|
emmc_set_rate_mnd(1, 8);
|
|
emmc_pll_vote_clk_enable();
|
|
emmc_local_clock_enable(1, 8, 1, 3, 3);
|
|
emmc_clock_reset();
|
|
udelay(10);
|
|
}
|
|
}
|
|
#endif
|