int get_clocks()

in arch/powerpc/cpu/mpc83xx/speed.c [79:477]


int get_clocks(void)
{
	volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
	u32 pci_sync_in;
	u8 spmf;
	u8 clkin_div;
	u32 sccr;
	u32 corecnf_tab_index;
	u8 corepll;
	u32 lcrr;

	u32 csb_clk;
#if defined(CONFIG_ARCH_MPC8308) || defined(CONFIG_ARCH_MPC831X) || \
	defined(CONFIG_ARCH_MPC834X) || defined(CONFIG_ARCH_MPC837X)
	u32 tsec1_clk;
	u32 tsec2_clk;
	u32 usbdr_clk;
#elif defined(CONFIG_ARCH_MPC8309)
	u32 usbdr_clk;
#endif
#ifdef CONFIG_ARCH_MPC834X
	u32 usbmph_clk;
#endif
	u32 core_clk;
	u32 i2c1_clk;
#if !defined(CONFIG_ARCH_MPC832X)
	u32 i2c2_clk;
#endif
#if defined(CONFIG_FSL_ESDHC)
	u32 sdhc_clk;
#endif
#if !defined(CONFIG_ARCH_MPC8309)
	u32 enc_clk;
#endif
	u32 lbiu_clk;
	u32 lclk_clk;
	u32 mem_clk;
#if defined(CONFIG_ARCH_MPC8360)
	u32 mem_sec_clk;
#endif
#if defined(CONFIG_QE)
	u32 qepmf;
	u32 qepdf;
	u32 qe_clk;
	u32 brg_clk;
#endif
#if defined(CONFIG_ARCH_MPC8308) || defined(CONFIG_ARCH_MPC831X) || \
	defined(CONFIG_ARCH_MPC837X)
	u32 pciexp1_clk;
	u32 pciexp2_clk;
#endif
#if defined(CONFIG_ARCH_MPC837X)
	u32 sata_clk;
#endif

	if ((im->sysconf.immrbar & IMMRBAR_BASE_ADDR) != (u32) im)
		return -1;

	clkin_div = ((im->clk.spmr & SPMR_CKID) >> SPMR_CKID_SHIFT);

	if (im->reset.rcwh & HRCWH_PCI_HOST) {
#if defined(CONFIG_SYS_CLK_FREQ)
		pci_sync_in = CONFIG_SYS_CLK_FREQ / (1 + clkin_div);
#else
		pci_sync_in = 0xDEADBEEF;
#endif
	} else {
#if defined(CONFIG_83XX_PCICLK)
		pci_sync_in = CONFIG_83XX_PCICLK;
#else
		pci_sync_in = 0xDEADBEEF;
#endif
	}

	spmf = (im->clk.spmr & SPMR_SPMF) >> SPMR_SPMF_SHIFT;
	csb_clk = pci_sync_in * (1 + clkin_div) * spmf;

	sccr = im->clk.sccr;

#if defined(CONFIG_ARCH_MPC8308) || defined(CONFIG_ARCH_MPC831X) || \
	defined(CONFIG_ARCH_MPC834X) || defined(CONFIG_ARCH_MPC837X)
	switch ((sccr & SCCR_TSEC1CM) >> SCCR_TSEC1CM_SHIFT) {
	case 0:
		tsec1_clk = 0;
		break;
	case 1:
		tsec1_clk = csb_clk;
		break;
	case 2:
		tsec1_clk = csb_clk / 2;
		break;
	case 3:
		tsec1_clk = csb_clk / 3;
		break;
	default:
		/* unknown SCCR_TSEC1CM value */
		return -2;
	}
#endif

#if defined(CONFIG_ARCH_MPC830X) || defined(CONFIG_ARCH_MPC831X) || \
	defined(CONFIG_ARCH_MPC834X) || defined(CONFIG_ARCH_MPC837X)
	switch ((sccr & SCCR_USBDRCM) >> SCCR_USBDRCM_SHIFT) {
	case 0:
		usbdr_clk = 0;
		break;
	case 1:
		usbdr_clk = csb_clk;
		break;
	case 2:
		usbdr_clk = csb_clk / 2;
		break;
	case 3:
		usbdr_clk = csb_clk / 3;
		break;
	default:
		/* unknown SCCR_USBDRCM value */
		return -3;
	}
#endif

#if defined(CONFIG_ARCH_MPC8308) || defined(CONFIG_ARCH_MPC834X) || \
	defined(CONFIG_ARCH_MPC837X)
	switch ((sccr & SCCR_TSEC2CM) >> SCCR_TSEC2CM_SHIFT) {
	case 0:
		tsec2_clk = 0;
		break;
	case 1:
		tsec2_clk = csb_clk;
		break;
	case 2:
		tsec2_clk = csb_clk / 2;
		break;
	case 3:
		tsec2_clk = csb_clk / 3;
		break;
	default:
		/* unknown SCCR_TSEC2CM value */
		return -4;
	}
#elif defined(CONFIG_ARCH_MPC8313)
	tsec2_clk = tsec1_clk;

	if (!(sccr & SCCR_TSEC1ON))
		tsec1_clk = 0;
	if (!(sccr & SCCR_TSEC2ON))
		tsec2_clk = 0;
#endif

#if defined(CONFIG_ARCH_MPC834X)
	switch ((sccr & SCCR_USBMPHCM) >> SCCR_USBMPHCM_SHIFT) {
	case 0:
		usbmph_clk = 0;
		break;
	case 1:
		usbmph_clk = csb_clk;
		break;
	case 2:
		usbmph_clk = csb_clk / 2;
		break;
	case 3:
		usbmph_clk = csb_clk / 3;
		break;
	default:
		/* unknown SCCR_USBMPHCM value */
		return -5;
	}

	if (usbmph_clk != 0 && usbdr_clk != 0 && usbmph_clk != usbdr_clk) {
		/* if USB MPH clock is not disabled and
		 * USB DR clock is not disabled then
		 * USB MPH & USB DR must have the same rate
		 */
		return -6;
	}
#endif
#if !defined(CONFIG_ARCH_MPC8309)
	switch ((sccr & SCCR_ENCCM) >> SCCR_ENCCM_SHIFT) {
	case 0:
		enc_clk = 0;
		break;
	case 1:
		enc_clk = csb_clk;
		break;
	case 2:
		enc_clk = csb_clk / 2;
		break;
	case 3:
		enc_clk = csb_clk / 3;
		break;
	default:
		/* unknown SCCR_ENCCM value */
		return -7;
	}
#endif

#if defined(CONFIG_FSL_ESDHC)
	switch ((sccr & SCCR_SDHCCM) >> SCCR_SDHCCM_SHIFT) {
	case 0:
		sdhc_clk = 0;
		break;
	case 1:
		sdhc_clk = csb_clk;
		break;
	case 2:
		sdhc_clk = csb_clk / 2;
		break;
	case 3:
		sdhc_clk = csb_clk / 3;
		break;
	default:
		/* unknown SCCR_SDHCCM value */
		return -8;
	}
#endif

#if defined(CONFIG_ARCH_MPC834X)
	i2c1_clk = tsec2_clk;
#elif defined(CONFIG_ARCH_MPC8360)
	i2c1_clk = csb_clk;
#elif defined(CONFIG_ARCH_MPC832X)
	i2c1_clk = enc_clk;
#elif defined(CONFIG_ARCH_MPC8308) || defined(CONFIG_ARCH_MPC831X)
	i2c1_clk = enc_clk;
#elif defined(CONFIG_FSL_ESDHC)
	i2c1_clk = sdhc_clk;
#elif defined(CONFIG_ARCH_MPC837X)
	i2c1_clk = enc_clk;
#elif defined(CONFIG_ARCH_MPC8309)
	i2c1_clk = csb_clk;
#endif
#if !defined(CONFIG_ARCH_MPC832X)
	i2c2_clk = csb_clk; /* i2c-2 clk is equal to csb clk */
#endif

#if defined(CONFIG_ARCH_MPC8308) || defined(CONFIG_ARCH_MPC831X) || \
	defined(CONFIG_ARCH_MPC837X)
	switch ((sccr & SCCR_PCIEXP1CM) >> SCCR_PCIEXP1CM_SHIFT) {
	case 0:
		pciexp1_clk = 0;
		break;
	case 1:
		pciexp1_clk = csb_clk;
		break;
	case 2:
		pciexp1_clk = csb_clk / 2;
		break;
	case 3:
		pciexp1_clk = csb_clk / 3;
		break;
	default:
		/* unknown SCCR_PCIEXP1CM value */
		return -9;
	}

	switch ((sccr & SCCR_PCIEXP2CM) >> SCCR_PCIEXP2CM_SHIFT) {
	case 0:
		pciexp2_clk = 0;
		break;
	case 1:
		pciexp2_clk = csb_clk;
		break;
	case 2:
		pciexp2_clk = csb_clk / 2;
		break;
	case 3:
		pciexp2_clk = csb_clk / 3;
		break;
	default:
		/* unknown SCCR_PCIEXP2CM value */
		return -10;
	}
#endif

#if defined(CONFIG_ARCH_MPC837X)
	switch ((sccr & SCCR_SATA1CM) >> SCCR_SATA1CM_SHIFT) {
	case 0:
		sata_clk = 0;
		break;
	case 1:
		sata_clk = csb_clk;
		break;
	case 2:
		sata_clk = csb_clk / 2;
		break;
	case 3:
		sata_clk = csb_clk / 3;
		break;
	default:
		/* unknown SCCR_SATA1CM value */
		return -11;
	}
#endif

	lbiu_clk = csb_clk *
		   (1 + ((im->clk.spmr & SPMR_LBIUCM) >> SPMR_LBIUCM_SHIFT));
	lcrr = (im->im_lbc.lcrr & LCRR_CLKDIV) >> LCRR_CLKDIV_SHIFT;
	switch (lcrr) {
	case 2:
	case 4:
	case 8:
		lclk_clk = lbiu_clk / lcrr;
		break;
	default:
		/* unknown lcrr */
		return -12;
	}

	mem_clk = csb_clk *
		  (1 + ((im->clk.spmr & SPMR_DDRCM) >> SPMR_DDRCM_SHIFT));
	corepll = (im->clk.spmr & SPMR_COREPLL) >> SPMR_COREPLL_SHIFT;

#if defined(CONFIG_ARCH_MPC8360)
	mem_sec_clk = csb_clk * (1 +
		       ((im->clk.spmr & SPMR_LBIUCM) >> SPMR_LBIUCM_SHIFT));
#endif

	corecnf_tab_index = ((corepll & 0x1F) << 2) | ((corepll & 0x60) >> 5);
	if (corecnf_tab_index > (ARRAY_SIZE(corecnf_tab))) {
		/* corecnf_tab_index is too high, possibly wrong value */
		return -11;
	}
	switch (corecnf_tab[corecnf_tab_index].core_csb_ratio) {
	case _byp:
	case _x1:
	case _1x:
		core_clk = csb_clk;
		break;
	case _1_5x:
		core_clk = (3 * csb_clk) / 2;
		break;
	case _2x:
		core_clk = 2 * csb_clk;
		break;
	case _2_5x:
		core_clk = (5 * csb_clk) / 2;
		break;
	case _3x:
		core_clk = 3 * csb_clk;
		break;
	default:
		/* unknown core to csb ratio */
		return -13;
	}

#if defined(CONFIG_QE)
	qepmf = (im->clk.spmr & SPMR_CEPMF) >> SPMR_CEPMF_SHIFT;
	qepdf = (im->clk.spmr & SPMR_CEPDF) >> SPMR_CEPDF_SHIFT;
	qe_clk = (pci_sync_in * qepmf) / (1 + qepdf);
	brg_clk = qe_clk / 2;
#endif

	gd->arch.csb_clk = csb_clk;
#if defined(CONFIG_ARCH_MPC8308) || defined(CONFIG_ARCH_MPC831X) || \
	defined(CONFIG_ARCH_MPC834X) || defined(CONFIG_ARCH_MPC837X)
	gd->arch.tsec1_clk = tsec1_clk;
	gd->arch.tsec2_clk = tsec2_clk;
	gd->arch.usbdr_clk = usbdr_clk;
#elif defined(CONFIG_ARCH_MPC8309)
	gd->arch.usbdr_clk = usbdr_clk;
#endif
#if defined(CONFIG_ARCH_MPC834X)
	gd->arch.usbmph_clk = usbmph_clk;
#endif
#if defined(CONFIG_FSL_ESDHC)
	gd->arch.sdhc_clk = sdhc_clk;
#endif
	gd->arch.core_clk = core_clk;
	gd->arch.i2c1_clk = i2c1_clk;
#if !defined(CONFIG_ARCH_MPC832X)
	gd->arch.i2c2_clk = i2c2_clk;
#endif
#if !defined(CONFIG_ARCH_MPC8309)
	gd->arch.enc_clk = enc_clk;
#endif
	gd->arch.lbiu_clk = lbiu_clk;
	gd->arch.lclk_clk = lclk_clk;
	gd->mem_clk = mem_clk;
#if defined(CONFIG_ARCH_MPC8360)
	gd->arch.mem_sec_clk = mem_sec_clk;
#endif
#if defined(CONFIG_QE)
	gd->arch.qe_clk = qe_clk;
	gd->arch.brg_clk = brg_clk;
#endif
#if defined(CONFIG_ARCH_MPC8308) || defined(CONFIG_ARCH_MPC831X) || \
	defined(CONFIG_ARCH_MPC837X)
	gd->arch.pciexp1_clk = pciexp1_clk;
	gd->arch.pciexp2_clk = pciexp2_clk;
#endif
#if defined(CONFIG_ARCH_MPC837X)
	gd->arch.sata_clk = sata_clk;
#endif
	gd->pci_clk = pci_sync_in;
	gd->cpu_clk = gd->arch.core_clk;
	gd->bus_clk = gd->arch.csb_clk;
	return 0;

}