@ -412,17 +412,12 @@ u32 imx_get_fecclk(void)
return decode_pll ( PLL_ENET , MXC_HCLK ) ;
return decode_pll ( PLL_ENET , MXC_HCLK ) ;
}
}
int enable_sata_clock ( void )
static int enable_enet_pll ( uint32_t en )
{
{
u32 reg = 0 ;
s32 timeout = 100000 ;
struct mxc_ccm_reg * const imx_ccm
struct mxc_ccm_reg * const imx_ccm
= ( struct mxc_ccm_reg * ) CCM_BASE_ADDR ;
= ( struct mxc_ccm_reg * ) CCM_BASE_ADDR ;
s32 timeout = 100000 ;
/* Enable sata clock */
u32 reg = 0 ;
reg = readl ( & imx_ccm - > CCGR5 ) ; /* CCGR5 */
reg | = MXC_CCM_CCGR5_SATA_MASK ;
writel ( reg , & imx_ccm - > CCGR5 ) ;
/* Enable PLLs */
/* Enable PLLs */
reg = readl ( & imx_ccm - > analog_pll_enet ) ;
reg = readl ( & imx_ccm - > analog_pll_enet ) ;
@ -437,10 +432,70 @@ int enable_sata_clock(void)
return - EIO ;
return - EIO ;
reg & = ~ BM_ANADIG_PLL_SYS_BYPASS ;
reg & = ~ BM_ANADIG_PLL_SYS_BYPASS ;
writel ( reg , & imx_ccm - > analog_pll_enet ) ;
writel ( reg , & imx_ccm - > analog_pll_enet ) ;
reg | = BM_ANADIG_PLL_ENET_ENABLE_SATA ;
reg | = en ;
writel ( reg , & imx_ccm - > analog_pll_enet ) ;
writel ( reg , & imx_ccm - > analog_pll_enet ) ;
return 0 ;
}
return 0 ;
static void ungate_sata_clock ( void )
{
struct mxc_ccm_reg * const imx_ccm =
( struct mxc_ccm_reg * ) CCM_BASE_ADDR ;
/* Enable SATA clock. */
setbits_le32 ( & imx_ccm - > CCGR5 , MXC_CCM_CCGR5_SATA_MASK ) ;
}
static void ungate_pcie_clock ( void )
{
struct mxc_ccm_reg * const imx_ccm =
( struct mxc_ccm_reg * ) CCM_BASE_ADDR ;
/* Enable PCIe clock. */
setbits_le32 ( & imx_ccm - > CCGR4 , MXC_CCM_CCGR4_PCIE_MASK ) ;
}
int enable_sata_clock ( void )
{
ungate_sata_clock ( ) ;
return enable_enet_pll ( BM_ANADIG_PLL_ENET_ENABLE_SATA ) ;
}
int enable_pcie_clock ( void )
{
struct anatop_regs * anatop_regs =
( struct anatop_regs * ) ANATOP_BASE_ADDR ;
struct mxc_ccm_reg * ccm_regs = ( struct mxc_ccm_reg * ) CCM_BASE_ADDR ;
/*
* Here be dragons !
*
* The register ANATOP_MISC1 is not documented in the Freescale
* MX6RM . The register that is mapped in the ANATOP space and
* marked as ANATOP_MISC1 is actually documented in the PMU section
* of the datasheet as PMU_MISC1 .
*
* Switch LVDS clock source to SATA ( 0xb ) , disable clock INPUT and
* enable clock OUTPUT . This is important for PCI express link that
* is clocked from the i . MX6 .
*/
# define ANADIG_ANA_MISC1_LVDSCLK1_IBEN (1 << 12)
# define ANADIG_ANA_MISC1_LVDSCLK1_OBEN (1 << 10)
# define ANADIG_ANA_MISC1_LVDS1_CLK_SEL_MASK 0x0000001F
clrsetbits_le32 ( & anatop_regs - > ana_misc1 ,
ANADIG_ANA_MISC1_LVDSCLK1_IBEN |
ANADIG_ANA_MISC1_LVDS1_CLK_SEL_MASK ,
ANADIG_ANA_MISC1_LVDSCLK1_OBEN | 0xb ) ;
/* PCIe reference clock sourced from AXI. */
clrbits_le32 ( & ccm_regs - > cbcmr , MXC_CCM_CBCMR_PCIE_AXI_CLK_SEL ) ;
/* Party time! Ungate the clock to the PCIe. */
ungate_sata_clock ( ) ;
ungate_pcie_clock ( ) ;
return enable_enet_pll ( BM_ANADIG_PLL_ENET_ENABLE_SATA |
BM_ANADIG_PLL_ENET_ENABLE_PCIE ) ;
}
}
unsigned int mxc_get_clock ( enum mxc_clock clk )
unsigned int mxc_get_clock ( enum mxc_clock clk )