Skip to content
Snippets Groups Projects
cpu_init.c 26.1 KiB
Newer Older
 * Copyright 2007-2011 Freescale Semiconductor, Inc.
 * (C) Copyright 2003 Motorola Inc.
 * Modified by Xianghua Xiao, X.Xiao@motorola.com
 *
 * (C) Copyright 2000
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <watchdog.h>
#include <asm/processor.h>
#include <ioports.h>
#include <asm/io.h>
#include <asm/cache.h>
#include <asm/mmu.h>
#include <fsl_errata.h>
#include <asm/fsl_law.h>
#include <asm/fsl_srio.h>
#include <hwconfig.h>
#ifdef CONFIG_CHAIN_OF_TRUST
#include <fsl_validate.h>
#endif
#ifdef CONFIG_FSL_CAAM
#include <fsl_sec.h>
#endif
#ifdef CONFIG_SYS_QE_FMAN_FW_IN_NAND
#include <nand.h>
#include <errno.h>
#endif
#include "../../../../drivers/block/fsl_sata.h"
Zhao Qiang's avatar
Zhao Qiang committed
#ifdef CONFIG_U_QE
#include "../../../../drivers/qe/qe.h"
#endif
#ifdef CONFIG_SYS_FSL_SINGLE_SOURCE_CLK
/*
 * For deriving usb clock from 100MHz sysclk, reference divisor is set
 * to a value of 5, which gives an intermediate value 20(100/5). The
 * multiplication factor integer is set to 24, which when multiplied to
 * above intermediate value provides clock for usb ip.
 */
void usb_single_source_clk_configure(struct ccsr_usb_phy *usb_phy)
{
	sys_info_t sysinfo;

	get_sys_info(&sysinfo);
	if (sysinfo.diff_sysclk == 1) {
		clrbits_be32(&usb_phy->pllprg[1],
			     CONFIG_SYS_FSL_USB_PLLPRG2_MFI);
		setbits_be32(&usb_phy->pllprg[1],
			     CONFIG_SYS_FSL_USB_PLLPRG2_REF_DIV_INTERNAL_CLK |
			     CONFIG_SYS_FSL_USB_PLLPRG2_MFI_INTERNAL_CLK |
			     CONFIG_SYS_FSL_USB_INTERNAL_SOC_CLK_EN);
		}
}
#endif

#ifdef CONFIG_SYS_FSL_ERRATUM_A006261
void fsl_erratum_a006261_workaround(struct ccsr_usb_phy __iomem *usb_phy)
{
#ifdef CONFIG_SYS_FSL_USB_DUAL_PHY_ENABLE
	u32 xcvrprg = in_be32(&usb_phy->port1.xcvrprg);

	/* Increase Disconnect Threshold by 50mV */
	xcvrprg &= ~CONFIG_SYS_FSL_USB_XCVRPRG_HS_DCNT_PROG_MASK |
						INC_DCNT_THRESHOLD_50MV;
	/* Enable programming of USB High speed Disconnect threshold */
	xcvrprg |= CONFIG_SYS_FSL_USB_XCVRPRG_HS_DCNT_PROG_EN;
	out_be32(&usb_phy->port1.xcvrprg, xcvrprg);

	xcvrprg = in_be32(&usb_phy->port2.xcvrprg);
	/* Increase Disconnect Threshold by 50mV */
	xcvrprg &= ~CONFIG_SYS_FSL_USB_XCVRPRG_HS_DCNT_PROG_MASK |
						INC_DCNT_THRESHOLD_50MV;
	/* Enable programming of USB High speed Disconnect threshold */
	xcvrprg |= CONFIG_SYS_FSL_USB_XCVRPRG_HS_DCNT_PROG_EN;
	out_be32(&usb_phy->port2.xcvrprg, xcvrprg);
#else

	u32 temp = 0;
	u32 status = in_be32(&usb_phy->status1);

	u32 squelch_prog_rd_0_2 =
		(status >> CONFIG_SYS_FSL_USB_SQUELCH_PROG_RD_0)
			& CONFIG_SYS_FSL_USB_SQUELCH_PROG_MASK;

	u32 squelch_prog_rd_3_5 =
		(status >> CONFIG_SYS_FSL_USB_SQUELCH_PROG_RD_3)
			& CONFIG_SYS_FSL_USB_SQUELCH_PROG_MASK;

	setbits_be32(&usb_phy->config1,
		     CONFIG_SYS_FSL_USB_HS_DISCNCT_INC);
	setbits_be32(&usb_phy->config2,
		     CONFIG_SYS_FSL_USB_RX_AUTO_CAL_RD_WR_SEL);

	temp = squelch_prog_rd_0_2 << CONFIG_SYS_FSL_USB_SQUELCH_PROG_WR_0;
	out_be32(&usb_phy->config2, in_be32(&usb_phy->config2) | temp);

	temp = squelch_prog_rd_3_5 << CONFIG_SYS_FSL_USB_SQUELCH_PROG_WR_3;
	out_be32(&usb_phy->config2, in_be32(&usb_phy->config2) | temp);
#endif
}
#endif


Zhao Qiang's avatar
Zhao Qiang committed
#if defined(CONFIG_QE) && !defined(CONFIG_U_QE)
extern qe_iop_conf_t qe_iop_conf_tab[];
extern void qe_config_iopin(u8 port, u8 pin, int dir,
				int open_drain, int assign);
extern void qe_init(uint qe_base);
extern void qe_reset(void);

static void config_qe_ioports(void)
{
	u8      port, pin;
	int     dir, open_drain, assign;
	int     i;

	for (i = 0; qe_iop_conf_tab[i].assign != QE_IOP_TAB_END; i++) {
		port		= qe_iop_conf_tab[i].port;
		pin		= qe_iop_conf_tab[i].pin;
		dir		= qe_iop_conf_tab[i].dir;
		open_drain	= qe_iop_conf_tab[i].open_drain;
		assign		= qe_iop_conf_tab[i].assign;
		qe_config_iopin(port, pin, dir, open_drain, assign);
	}
}
#endif
#ifdef CONFIG_CPM2
void config_8560_ioports (volatile ccsr_cpm_t * cpm)
{
	int portnum;

	for (portnum = 0; portnum < 4; portnum++) {
		uint pmsk = 0,
		     ppar = 0,
		     psor = 0,
		     pdir = 0,
		     podr = 0,
		     pdat = 0;
		iop_conf_t *iopc = (iop_conf_t *) & iop_conf_tab[portnum][0];
		iop_conf_t *eiopc = iopc + 32;
		uint msk = 1;

		/*
		 * NOTE:
		 * index 0 refers to pin 31,
		 * index 31 refers to pin 0
		 */
		while (iopc < eiopc) {
			if (iopc->conf) {
				pmsk |= msk;
				if (iopc->ppar)
					ppar |= msk;
				if (iopc->psor)
					psor |= msk;
				if (iopc->pdir)
					pdir |= msk;
				if (iopc->podr)
					podr |= msk;
				if (iopc->pdat)
					pdat |= msk;
			}

			msk <<= 1;
			iopc++;
		}

		if (pmsk != 0) {
			volatile ioport_t *iop = ioport_addr (cpm, portnum);
			uint tpmsk = ~pmsk;

			/*
			 * the (somewhat confused) paragraph at the
			 * bottom of page 35-5 warns that there might
			 * be "unknown behaviour" when programming
			 * PSORx and PDIRx, if PPARx = 1, so I
			 * decided this meant I had to disable the
			 * dedicated function first, and enable it
			 * last.
			 */
			iop->ppar &= tpmsk;
			iop->psor = (iop->psor & tpmsk) | psor;
			iop->podr = (iop->podr & tpmsk) | podr;
			iop->pdat = (iop->pdat & tpmsk) | pdat;
			iop->pdir = (iop->pdir & tpmsk) | pdir;
Loading
Loading full blame...