/*
 * Copyright 2004 Freescale Semiconductor.
 * Jeff Brown
 * Srikanth Srinivasan (srikanth.srinivasan@freescale.com)
 *
 * (C) Copyright 2000-2002
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 *
 * SPDX-License-Identifier:	GPL-2.0+ 
 */

#include <common.h>
#include <mpc86xx.h>
#include <asm/processor.h>
#include <asm/io.h>

DECLARE_GLOBAL_DATA_PTR;

/* used in some defintiions of CONFIG_SYS_CLK_FREQ */
extern unsigned long get_board_sys_clk(unsigned long dummy);

void get_sys_info(sys_info_t *sys_info)
{
	volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
	volatile ccsr_gur_t *gur = &immap->im_gur;
	uint plat_ratio, e600_ratio;
	uint lcrr_div;

	plat_ratio = (gur->porpllsr) & 0x0000003e;
	plat_ratio >>= 1;

	switch (plat_ratio) {
	case 0x0:
		sys_info->freq_systembus = 16 * CONFIG_SYS_CLK_FREQ;
		break;
	case 0x02:
	case 0x03:
	case 0x04:
	case 0x05:
	case 0x06:
	case 0x08:
	case 0x09:
	case 0x0a:
	case 0x0c:
	case 0x10:
		sys_info->freq_systembus = plat_ratio * CONFIG_SYS_CLK_FREQ;
		break;
	default:
		sys_info->freq_systembus = 0;
		break;
	}

	e600_ratio = (gur->porpllsr) & 0x003f0000;
	e600_ratio >>= 16;

	switch (e600_ratio) {
	case 0x10:
		sys_info->freq_processor = 2 * sys_info->freq_systembus;
		break;
	case 0x19:
		sys_info->freq_processor = 5 * sys_info->freq_systembus / 2;
		break;
	case 0x20:
		sys_info->freq_processor = 3 * sys_info->freq_systembus;
		break;
	case 0x39:
		sys_info->freq_processor = 7 * sys_info->freq_systembus / 2;
		break;
	case 0x28:
		sys_info->freq_processor = 4 * sys_info->freq_systembus;
		break;
	case 0x1d:
		sys_info->freq_processor = 9 * sys_info->freq_systembus / 2;
		break;
	default:
		sys_info->freq_processor = e600_ratio +
						sys_info->freq_systembus;
		break;
	}

#if defined(CONFIG_SYS_LBC_LCRR)
	/* We will program LCRR to this value later */
	lcrr_div = CONFIG_SYS_LBC_LCRR & LCRR_CLKDIV;
#else
	lcrr_div = in_be32(&immap->im_lbc.lcrr) & LCRR_CLKDIV;
#endif
	if (lcrr_div == 2 || lcrr_div == 4 || lcrr_div == 8) {
		sys_info->freq_localbus = sys_info->freq_systembus
							/ (lcrr_div * 2);
	} else {
		/* In case anyone cares what the unknown value is */
		sys_info->freq_localbus = lcrr_div;
	}
}


/*
 * Measure CPU clock speed (core clock GCLK1, GCLK2)
 * (Approx. GCLK frequency in Hz)
 */

int get_clocks(void)
{
	sys_info_t sys_info;

	get_sys_info(&sys_info);
	gd->cpu_clk = sys_info.freq_processor;
	gd->bus_clk = sys_info.freq_systembus;
	gd->arch.lbc_clk = sys_info.freq_localbus;

	/*
	 * The base clock for I2C depends on the actual SOC.  Unfortunately,
	 * there is no pattern that can be used to determine the frequency, so
	 * the only choice is to look up the actual SOC number and use the value
	 * for that SOC. This information is taken from application note
	 * AN2919.
	 */
#ifdef CONFIG_MPC8610
	gd->arch.i2c1_clk = sys_info.freq_systembus;
#else
	gd->arch.i2c1_clk = sys_info.freq_systembus / 2;
#endif
	gd->arch.i2c2_clk = gd->arch.i2c1_clk;

	if (gd->cpu_clk != 0)
		return 0;
	else
		return 1;
}


/*
 * get_bus_freq
 *	Return system bus freq in Hz
 */

ulong get_bus_freq(ulong dummy)
{
	ulong val;
	sys_info_t sys_info;

	get_sys_info(&sys_info);
	val = sys_info.freq_systembus;

	return val;
}
