diff options
76 files changed, 6427 insertions, 680 deletions
| diff --git a/MAINTAINERS b/MAINTAINERS index 2f61776e911..b0da631fe19 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -462,10 +462,11 @@ Rune Torgersen <runet@innovsys.com>  Peter Tyser <ptyser@xes-inc.com> -	XPEDITE1000	PPC440GX -	XPEDITE5170	MPC8640 -	XPEDITE5200	MPC8548 -	XPEDITE5370	MPC8572 +	xpedite1000	PPC440GX +	xpedite5170	MPC8640 +	xpedite5200	MPC8548 +	xpedite5370	MPC8572 +	xpedite5500	P2020  David Updegraff <dave@cray.com> @@ -609,31 +609,11 @@ LIST_blackfin="$(boards_by_arch blackfin)  ## SH Systems  ######################################################################### -LIST_sh2="		\ -	rsk7203		\ -" -LIST_sh3="		\ -	mpr2		\ -	ms7720se	\ -" +LIST_sh2="$(boards_by_cpu sh2)" +LIST_sh3="$(boards_by_cpu sh3)" +LIST_sh4="$(boards_by_cpu sh4)" -LIST_sh4="		\ -	ms7750se	\ -	ms7722se	\ -	MigoR		\ -	r7780mp		\ -	r2dplus		\ -	sh7763rdp	\ -	sh7785lcr	\ -	ap325rxa	\ -	espt		\ -" - -LIST_sh="		\ -	${LIST_sh2}	\ -	${LIST_sh3}	\ -	${LIST_sh4}	\ -" +LIST_sh="$(boards_by_arch sh)"  #########################################################################  ## SPARC Systems @@ -1184,88 +1184,6 @@ bf527-ezkit-v2_config	: unconfig  	@$(MKCONFIG) -t BF527_EZKIT_REV_2_1 \  		bf527-ezkit blackfin blackfin bf527-ezkit -#======================================================================== -# SH3 (SuperH) -#======================================================================== - -######################################################################### -## sh2 (Renesas SuperH) -######################################################################### -rsk7203_config: unconfig -	@mkdir -p $(obj)include -	@echo "#define CONFIG_RSK7203 1" > $(obj)include/config.h -	@$(MKCONFIG) -a $@ sh sh2 rsk7203 renesas - -######################################################################### -## sh3 (Renesas SuperH) -######################################################################### - -mpr2_config: unconfig -	@mkdir -p $(obj)include -	@echo "#define CONFIG_MPR2 1" > $(obj)include/config.h -	@$(MKCONFIG) -a $@ sh sh3 mpr2 - -ms7720se_config: unconfig -	@mkdir -p $(obj)include -	@echo "#define CONFIG_MS7720SE 1" > $(obj)include/config.h -	@$(MKCONFIG) -a $@ sh sh3 ms7720se - -######################################################################### -## sh4 (Renesas SuperH) -######################################################################### - -MigoR_config :       unconfig -	@mkdir -p $(obj)include -	@echo "#define CONFIG_MIGO_R 1" > $(obj)include/config.h -	@$(MKCONFIG) -a $@ sh sh4 MigoR renesas - -ms7750se_config: unconfig -	@mkdir -p $(obj)include -	@echo "#define CONFIG_MS7750SE 1" > $(obj)include/config.h -	@$(MKCONFIG) -a $@ sh sh4 ms7750se - -ms7722se_config :	unconfig -	@mkdir -p $(obj)include -	@echo "#define CONFIG_MS7722SE 1" > $(obj)include/config.h -	@$(MKCONFIG) -a $@ sh sh4 ms7722se - -r2dplus_config  :   unconfig -	@mkdir -p $(obj)include -	@echo "#define CONFIG_R2DPLUS 1" > $(obj)include/config.h -	@$(MKCONFIG) -a $@ sh sh4 r2dplus renesas - -r7780mp_config: unconfig -	@mkdir -p $(obj)include -	@echo "#define CONFIG_R7780MP 1" > $(obj)include/config.h -	@$(MKCONFIG) -a $@ sh sh4 r7780mp renesas - -sh7763rdp_config  :   unconfig -	@mkdir -p $(obj)include -	@echo "#define CONFIG_SH7763RDP 1" > $(obj)include/config.h -	@$(MKCONFIG) -a $@ sh sh4 sh7763rdp renesas - -sh7785lcr_32bit_config \ -sh7785lcr_config  :   unconfig -	@mkdir -p $(obj)include -	@mkdir -p $(obj)board/renesas/sh7785lcr -	@echo "#define CONFIG_SH7785LCR 1" > $(obj)include/config.h -	@if [ "$(findstring 32bit, $@)" ] ; then \ -		echo "#define CONFIG_SH_32BIT 1" >> $(obj)include/config.h ; \ -		echo "CONFIG_SYS_TEXT_BASE = 0x8ff80000" > \ -			$(obj)board/renesas/sh7785lcr/config.tmp ; \ -	fi -	@$(MKCONFIG) -n $@ -a sh7785lcr sh sh4 sh7785lcr renesas - -ap325rxa_config  :   unconfig -	@mkdir -p $(obj)include -	@echo "#define CONFIG_AP325RXA 1" > $(obj)include/config.h -	@$(MKCONFIG) -a $@ sh sh4 ap325rxa renesas - -espt_config  :   unconfig -	@mkdir -p $(obj)include -	@echo "#define CONFIG_ESPT 1" > $(obj)include/config.h -	@$(MKCONFIG) -a $@ sh sh4 espt -  #########################################################################  ######################################################################### diff --git a/arch/arm/include/asm/arch-mx5/crm_regs.h b/arch/arm/include/asm/arch-mx5/crm_regs.h index 14aa231a5b0..4ed8eb31c8a 100644 --- a/arch/arm/include/asm/arch-mx5/crm_regs.h +++ b/arch/arm/include/asm/arch-mx5/crm_regs.h @@ -189,4 +189,15 @@ struct mxc_ccm_reg {  #define MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET		0  #define MXC_CCM_CSCDR1_UART_CLK_PODF_MASK		0x7 +/* Define the bits in register CCDR */ +#define MXC_CCM_CCDR_IPU_HS_MASK			(0x1 << 17) + +/* Define the bits in register CCGRx */ +#define MXC_CCM_CCGR_CG_MASK				0x3 + +#define MXC_CCM_CCGR5_CG5_OFFSET			10 + +/* Define the bits in register CLPCR */ +#define MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS                 (0x1 << 18) +  #endif				/* __ARCH_ARM_MACH_MX51_CRM_REGS_H__ */ diff --git a/arch/sh/config.mk b/arch/sh/config.mk index 07ba68f1987..415c9497984 100644 --- a/arch/sh/config.mk +++ b/arch/sh/config.mk @@ -29,6 +29,6 @@ STANDALONE_LOAD_ADDR += -EB  endif  PLATFORM_CPPFLAGS += -DCONFIG_SH -D__SH__ -PLATFORM_LDFLAGS += -e $(CONFIG_SYS_TEXT_BASE) --defsym reloc_dst=$(TEXT_BASE) +PLATFORM_LDFLAGS += -e $(CONFIG_SYS_TEXT_BASE) --defsym reloc_dst=$(CONFIG_SYS_TEXT_BASE)  LDSCRIPT := $(SRCTREE)/$(CPUDIR)/u-boot.lds diff --git a/arch/sh/lib/bootm.c b/arch/sh/lib/bootm.c index 9c58ed7ec8c..f38d0b0e8e3 100644 --- a/arch/sh/lib/bootm.c +++ b/arch/sh/lib/bootm.c @@ -43,6 +43,41 @@ static void hexdump(unsigned char *buf, int len)  }  #endif +#define MOUNT_ROOT_RDONLY	0x000 +#define RAMDISK_FLAGS		0x004 +#define ORIG_ROOT_DEV		0x008 +#define LOADER_TYPE			0x00c +#define INITRD_START		0x010 +#define INITRD_SIZE			0x014 +#define COMMAND_LINE		0x100 + +#define RD_PROMPT	(1<<15) +#define RD_DOLOAD	(1<<14) +#define CMD_ARG_RD_PROMPT	"prompt_ramdisk=" +#define CMD_ARG_RD_DOLOAD	"load_ramdisk=" + +#ifdef CONFIG_SH_SDRAM_OFFSET +#define GET_INITRD_START(initrd, linux) (initrd - linux + CONFIG_SH_SDRAM_OFFSET) +#else +#define GET_INITRD_START(initrd, linux) (initrd - linux) +#endif + +static void set_sh_linux_param(unsigned long param_addr, unsigned long data) +{ +	*(unsigned long *)(param_addr) = data; +} + +static unsigned long sh_check_cmd_arg(char *cmdline, char *key, int base) +{ +	unsigned long val = 0; +	char *p = strstr(cmdline, key); +	if (p) { +		p += strlen(key); +		val = simple_strtol(p, NULL, base); +	} +	return val; +} +  int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *images)  {  	/* Linux kernel load address */ @@ -51,7 +86,7 @@ int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *ima  	unsigned char *param  		= (unsigned char *)image_get_load(images->legacy_hdr_os);  	/* Linux kernel command line */ -	char *cmdline = (char *)param + 0x100; +	char *cmdline = (char *)param + COMMAND_LINE;  	/* PAGE_SIZE */  	unsigned long size = images->ep - (unsigned long)param;  	char *bootargs = getenv("bootargs"); @@ -61,8 +96,37 @@ int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *ima  	/* Setup parameters */  	memset(param, 0, size);	/* Clear zero page */ + +	/* Set commandline */  	strcpy(cmdline, bootargs); +	sh_check_cmd_arg(bootargs, CMD_ARG_RD_DOLOAD, 10); +	/* Initrd */ +	if (images->rd_start || images->rd_end) { +		unsigned long ramdisk_flags = 0; +		int val = sh_check_cmd_arg(bootargs, CMD_ARG_RD_PROMPT, 10); +		if (val == 1) +				ramdisk_flags |= RD_PROMPT; +		else +				ramdisk_flags &= ~RD_PROMPT; +					 +		val = sh_check_cmd_arg(bootargs, CMD_ARG_RD_DOLOAD, 10); +		if (val == 1) +				ramdisk_flags |= RD_DOLOAD; +		else +				ramdisk_flags &= ~RD_DOLOAD; + +		set_sh_linux_param((unsigned long)param + MOUNT_ROOT_RDONLY, 0x0001); +		set_sh_linux_param((unsigned long)param + RAMDISK_FLAGS, ramdisk_flags); +		set_sh_linux_param((unsigned long)param + ORIG_ROOT_DEV, 0x0200); +		set_sh_linux_param((unsigned long)param + LOADER_TYPE, 0x0001); +		set_sh_linux_param((unsigned long)param + INITRD_START, +			GET_INITRD_START(images->rd_start, CONFIG_SYS_SDRAM_BASE)); +		set_sh_linux_param((unsigned long)param + INITRD_SIZE, +			images->rd_end - images->rd_start); +	} + +	/* Boot kernel */  	kernel();  	/* does not return */ diff --git a/board/a4m072/a4m072.c b/board/a4m072/a4m072.c index ae7ccbb4e9d..09a5a5183bf 100644 --- a/board/a4m072/a4m072.c +++ b/board/a4m072/a4m072.c @@ -270,8 +270,6 @@ static u8 display_buf[DISPLAY_BUF_SIZE];  static u8 display_putc_pos;  static u8 display_out_pos; -static u8 display_dot_enable; -  void display_set(int cmd) {  	if (cmd & DISPLAY_CLEAR) { @@ -281,12 +279,6 @@ void display_set(int cmd) {  	if (cmd & DISPLAY_HOME) {  		display_putc_pos = 0;  	} - -	if (cmd & DISPLAY_MARK) { -		display_dot_enable = 1; -	} else { -		display_dot_enable = 0; -	}  }  #define SEG_A    (1<<0) @@ -314,10 +306,12 @@ void display_set(int cmd) {   * A..Z		index 10..35   * -		index 36   * _		index 37 + * .		index 38   */  #define SYMBOL_DASH		(36)  #define SYMBOL_UNDERLINE	(37) +#define SYMBOL_DOT		(38)  static u8 display_char2seg7_tbl[]=  { @@ -337,28 +331,29 @@ static u8 display_char2seg7_tbl[]=  	SEG_B | SEG_C | SEG_D | SEG_E | SEG_G,			/* d */  	SEG_A | SEG_D | SEG_E | SEG_F | SEG_G,			/* E */  	SEG_A | SEG_E | SEG_F | SEG_G,				/* F */ -	SEG_A | SEG_B | SEG_C | SEG_D | SEG_F | SEG_G,		/* g */ +	0,					/* g - not displayed */  	SEG_B | SEG_C | SEG_E | SEG_F | SEG_G,			/* H */ -	SEG_E | SEG_F,						/* I */ -	SEG_B | SEG_C | SEG_D | SEG_E,				/* J */ -	SEG_A,						/* K - special 1 */ +	SEG_B | SEG_C,						/* I */ +	0,					/* J - not displayed */ +	0,					/* K - not displayed */  	SEG_D | SEG_E | SEG_F,					/* L */ -	SEG_B,						/* m - special 2 */ -	SEG_C | SEG_E | SEG_G,					/* n */ -	SEG_C | SEG_D | SEG_E | SEG_G,				/* o */ +	0,					/* m - not displayed */ +	0,					/* n - not displayed */ +	SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F,		/* O */  	SEG_A | SEG_B | SEG_E | SEG_F | SEG_G,			/* P */ -	SEG_A | SEG_B | SEG_C | SEG_F | SEG_G,			/* q */ -	SEG_E | SEG_G,						/* r */ +	0,					/* q - not displayed */ +	0,					/* r - not displayed */  	SEG_A | SEG_C | SEG_D | SEG_F | SEG_G,			/* S */  	SEG_D | SEG_E | SEG_F | SEG_G,				/* t */  	SEG_B | SEG_C | SEG_D | SEG_E | SEG_F,			/* U */ -	SEG_C | SEG_D | SEG_E | SEG_F,				/* V */ -	SEG_C,						/* w - special 3 */ -	SEG_B | SEG_C | SEG_E | SEG_F | SEG_G,			/* X */ +	0,					/* V - not displayed */ +	0,					/* w - not displayed */ +	0,					/* X - not displayed */  	SEG_B | SEG_C | SEG_D | SEG_F | SEG_G,			/* Y */ -	SEG_A | SEG_B | SEG_D | SEG_E | SEG_G,			/* Z */ +	0,					/* Z - not displayed */  	SEG_G,							/* - */ -	SEG_D							/* _ */ +	SEG_D,							/* _ */ +	SEG_P							/* . */  };  /* Convert char to the LED segments representation */ @@ -374,23 +369,20 @@ static u8 display_char2seg7(char c)  		c -= 'A' - 10;  	else if (c == '-')  		c = SYMBOL_DASH; -	else if ((c == '_') || (c == '.')) +	else if (c == '_')  		c = SYMBOL_UNDERLINE; +	else if (c == '.') +		c = SYMBOL_DOT;  	else  		c = ' ';	/* display unsupported symbols as space */  	if (c != ' ')  		val = display_char2seg7_tbl[(int)c]; -	/* Handle DP LED here */ -	if (display_dot_enable) { -		val |= SEG_P; -	} -  	return val;  } -static inline int display_putc_nomark(char c) +int display_putc(char c)  {  	if (display_putc_pos >= DISPLAY_BUF_SIZE)  		return -1; @@ -403,13 +395,6 @@ static inline int display_putc_nomark(char c)  	return c;  } -int display_putc(char c) -{ -	/* Mark the codes from the "display" command with the DP LED */ -	display_set(DISPLAY_MARK); -	return display_putc_nomark(c); -} -  /*   * Flush current symbol to the LED display hardware   */ @@ -493,9 +478,8 @@ void show_boot_progress(int status)  	if (a4m072_status2code(status, buf) < 0)  		return; -	display_set(0);	/* Clear DP Led */ -	display_putc_nomark(buf[0]); -	display_putc_nomark(buf[1]); +	display_putc(buf[0]); +	display_putc(buf[1]);  	display_set(DISPLAY_HOME);  	display_out_pos = 0;	/* reset output position */ diff --git a/board/renesas/sh7785lcr/config.mk b/board/renesas/sh7785lcr/config.mk index 1a9038c7533..6853d2b28be 100644 --- a/board/renesas/sh7785lcr/config.mk +++ b/board/renesas/sh7785lcr/config.mk @@ -24,6 +24,8 @@  #  sinclude $(OBJTREE)/board/$(BOARDDIR)/config.tmp -ifndef CONFIG_SYS_TEXT_BASE +ifdef CONFIG_SH_32BIT +CONFIG_SYS_TEXT_BASE = 0x8FF80000 +else  CONFIG_SYS_TEXT_BASE = 0x0ff80000  endif diff --git a/board/ttcontrol/vision2/vision2.c b/board/ttcontrol/vision2/vision2.c index ce4cb78e981..071dad66c4e 100644 --- a/board/ttcontrol/vision2/vision2.c +++ b/board/ttcontrol/vision2/vision2.c @@ -37,14 +37,34 @@  #include <fsl_esdhc.h>  #include <fsl_pmic.h>  #include <mc13892.h> +#include <linux/fb.h>  DECLARE_GLOBAL_DATA_PTR;  static u32 system_rev; +extern int mx51_fb_init(struct fb_videomode *mode); +  #ifdef CONFIG_HW_WATCHDOG  #include <watchdog.h> +static struct fb_videomode nec_nl6448bc26_09c = { +	"NEC_NL6448BC26-09C", +	60,	/* Refresh */ +	640,	/* xres */ +	480,	/* yres */ +	37650,	/* pixclock = 26.56Mhz */ +	48,	/* left margin */ +	16,	/* right margin */ +	31,	/* upper margin */ +	12,	/* lower margin */ +	96,	/* hsync-len */ +	2,	/* vsync-len */ +	0,	/* sync */ +	FB_VMODE_NONINTERLACED,	/* vmode */ +	0,	/* flag */ +}; +  void hw_watchdog_reset(void)  {  	int val; @@ -423,6 +443,9 @@ static void setup_gpios(void)  	mxc_request_iomux(MX51_PIN_CSPI1_RDY, IOMUX_CONFIG_ALT3);  	mxc_iomux_set_pad(MX51_PIN_CSPI1_RDY, 0x82); +	/* PWM Output GPIO1_2 */ +	mxc_request_iomux(MX51_PIN_GPIO1_2, IOMUX_CONFIG_ALT1); +  	/*  	 * Set GPIO1_4 to high and output; it is used to reset  	 * the system on reboot @@ -630,6 +653,33 @@ int board_early_init_f(void)  	return 0;  } +static void backlight(int on) +{ +	if (on) { +		mxc_gpio_set(65, 1); +		udelay(10000); +		mxc_gpio_set(68, 1); +	} else { +		mxc_gpio_set(65, 0); +		mxc_gpio_set(68, 0); +	} +} + +void lcd_enable(void) +{ +	int ret; + +	mxc_request_iomux(MX51_PIN_DI1_PIN2, IOMUX_CONFIG_ALT0); +	mxc_request_iomux(MX51_PIN_DI1_PIN3, IOMUX_CONFIG_ALT0); + +	mxc_gpio_set(2, 1); +	mxc_request_iomux(MX51_PIN_GPIO1_2, IOMUX_CONFIG_ALT0); + +	ret = mx51_fb_init(&nec_nl6448bc26_09c); +	if (ret) +		puts("LCD cannot be configured\n"); +} +  int board_init(void)  {  #ifdef CONFIG_SYS_ARM_WITHOUT_RELOC @@ -709,3 +759,21 @@ int checkboard(void)  	return 0;  } +int do_vision_lcd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ +	int on; + +	if (argc < 2) +		return cmd_usage(cmdtp); + +	on = (strcmp(argv[1], "on") == 0); +	backlight(on); + +	return 0; +} + +U_BOOT_CMD( +	lcdbl, CONFIG_SYS_MAXARGS, 1, do_vision_lcd, +	"Vision2 Backlight", +	"lcdbl [on|off]\n" +); diff --git a/board/xes/common/Makefile b/board/xes/common/Makefile index d022831830a..16e0b66218a 100644 --- a/board/xes/common/Makefile +++ b/board/xes/common/Makefile @@ -32,7 +32,11 @@ LIB	= $(obj)lib$(VENDOR).a  COBJS-$(CONFIG_FSL_PCI_INIT)	+= fsl_8xxx_pci.o  COBJS-$(CONFIG_MPC8572)		+= fsl_8xxx_clk.o  COBJS-$(CONFIG_MPC86xx)		+= fsl_8xxx_clk.o +COBJS-$(CONFIG_P2020)		+= fsl_8xxx_clk.o  COBJS-$(CONFIG_FSL_DDR2)	+= fsl_8xxx_ddr.o +COBJS-$(CONFIG_FSL_DDR3)	+= fsl_8xxx_ddr.o +COBJS-$(CONFIG_MPC85xx)		+= fsl_8xxx_misc.o board.o +COBJS-$(CONFIG_MPC86xx)		+= fsl_8xxx_misc.o board.o  COBJS-$(CONFIG_NAND_ACTL)	+= actl_nand.o  SRCS	:= $(SOBJS:.o=.S) $(COBJS-y:.o=.c) diff --git a/board/xes/common/board.c b/board/xes/common/board.c new file mode 100644 index 00000000000..738f0a6486b --- /dev/null +++ b/board/xes/common/board.c @@ -0,0 +1,64 @@ +/* + * Copyright 2009 Extreme Engineering Solutions, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + */ + +#include <common.h> +#include "fsl_8xxx_misc.h" + +int checkboard(void) +{ +	char name[] = CONFIG_SYS_BOARD_NAME; +	char *s; + +#ifdef CONFIG_SYS_FORM_CUSTOM +	s = "Custom"; +#elif CONFIG_SYS_FORM_6U_CPCI +	s = "6U CompactPCI"; +#elif CONFIG_SYS_FORM_ATCA_PMC +	s = "ATCA w/PMC"; +#elif CONFIG_SYS_FORM_ATCA_AMC +	s = "ATCA w/AMC"; +#elif CONFIG_SYS_FORM_VME +	s = "VME"; +#elif CONFIG_SYS_FORM_6U_VPX +	s = "6U VPX"; +#elif CONFIG_SYS_FORM_PMC +	s = "PMC"; +#elif CONFIG_SYS_FORM_PCI +	s = "PCI"; +#elif CONFIG_SYS_FORM_3U_CPCI +	s = "3U CompactPCI"; +#elif CONFIG_SYS_FORM_AMC +	s = "AdvancedMC"; +#elif CONFIG_SYS_FORM_XMC +	s = "XMC"; +#elif CONFIG_SYS_FORM_PMC_XMC +	s = "PMC/XMC"; +#elif CONFIG_SYS_FORM_PCI_EXPRESS +	s = "PCI Express"; +#elif CONFIG_SYS_FORM_3U_VPX +	s = "3U VPX"; +#else +#error "Form factor not defined" +#endif + +	name[strlen(name) - 1] += get_board_derivative(); +	printf("Board: X-ES %s %s SBC\n", name, s); + +	/* Display board specific information */ +	puts("       "); +	if ((s = getenv("board_rev"))) +		printf("Rev %s, ", s); +	if ((s = getenv("serial#"))) +		printf("Serial# %s, ", s); +	if ((s = getenv("board_cfg"))) +		printf("Cfg %s", s); +	puts("\n"); + +	return 0; +} diff --git a/board/xes/common/fsl_8xxx_clk.c b/board/xes/common/fsl_8xxx_clk.c index f4a17b78c60..20d0a308b9a 100644 --- a/board/xes/common/fsl_8xxx_clk.c +++ b/board/xes/common/fsl_8xxx_clk.c @@ -38,7 +38,11 @@ unsigned long get_board_sys_clk(ulong dummy)  	if (in_be32(&gur->gpporcr) & 0x10000)  		return 66666666;  	else +#ifdef CONFIG_P2020 +		return 100000000; +#else  		return 50000000; +#endif  }  #ifdef CONFIG_MPC85xx @@ -54,6 +58,13 @@ unsigned long get_board_ddr_clk(ulong dummy)  	if (ddr_ratio == 0x7)  		return get_board_sys_clk(dummy); +#ifdef CONFIG_P2020 +	if (in_be32(&gur->gpporcr) & 0x20000) +		return 66666666; +	else +		return 100000000; +#else  	return 66666666; +#endif  }  #endif diff --git a/board/xes/common/fsl_8xxx_misc.c b/board/xes/common/fsl_8xxx_misc.c new file mode 100644 index 00000000000..b7fa6950b07 --- /dev/null +++ b/board/xes/common/fsl_8xxx_misc.c @@ -0,0 +1,62 @@ +/* + * Copyright 2008 Extreme Engineering Solutions, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/mmu.h> +#ifdef CONFIG_PCA953X +#include <pca953x.h> + +/* + * Determine if a board's flashes are write protected + */ +int board_flash_wp_on(void) +{ +	if (pca953x_get_val(CONFIG_SYS_I2C_PCA953X_ADDR0) & +			CONFIG_SYS_PCA953X_NVM_WP) +		return 1; + +	return 0; +} +#endif + +/* + * Return a board's derivative model number.  For example: + * return 2 for the XPedite5372 and return 1 for the XPedite5201. + */ +uint get_board_derivative(void) +{ +#if defined(CONFIG_MPC85xx) +       volatile ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR; +#elif defined(CONFIG_MPC86xx) +       volatile immap_t *immap = (immap_t *)CONFIG_SYS_CCSRBAR; +       volatile ccsr_gur_t *gur = &immap->im_gur; +#endif + +       /* +        * The top 4 lines of the local bus address are pulled low/high and +        * can be read to determine the least significant digit of a board's +        * model number. +        */ +       return gur->gpporcr >> 28; +} + + diff --git a/board/xes/common/fsl_8xxx_misc.h b/board/xes/common/fsl_8xxx_misc.h new file mode 100644 index 00000000000..ecc70daba13 --- /dev/null +++ b/board/xes/common/fsl_8xxx_misc.h @@ -0,0 +1,28 @@ +/* + * Copyright 2008 Extreme Engineering Solutions, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __FSL_8XXX_MISC_H___ +#define __FSL_8XXX_MISC_H___ + +uint get_board_derivative(void); + +#endif /* __FSL_8XXX_MISC_H__ */ diff --git a/board/xes/common/fsl_8xxx_pci.c b/board/xes/common/fsl_8xxx_pci.c index ece78825778..f425ceedc45 100644 --- a/board/xes/common/fsl_8xxx_pci.c +++ b/board/xes/common/fsl_8xxx_pci.c @@ -25,10 +25,10 @@  #include <pci.h>  #include <asm/fsl_pci.h>  #include <asm/io.h> +#include <linux/compiler.h>  #include <libfdt.h>  #include <fdt_support.h> -int first_free_busno = 0;  #ifdef CONFIG_PCI1  static struct pci_controller pci1_hose; @@ -43,111 +43,6 @@ static struct pci_controller pcie2_hose;  static struct pci_controller pcie3_hose;  #endif -#ifdef CONFIG_MPC8572 -/* Correlate host/agent POR bits to usable info. Table 4-14 */ -struct host_agent_cfg_t { -	uchar pcie_root[3]; -	uchar rio_host; -} host_agent_cfg[8] = { -	{{0, 0, 0}, 0}, -	{{0, 1, 1}, 1}, -	{{1, 0, 1}, 0}, -	{{1, 1, 0}, 1}, -	{{0, 0, 1}, 0}, -	{{0, 1, 0}, 1}, -	{{1, 0, 0}, 0}, -	{{1, 1, 1}, 1} -}; - -/* Correlate port width POR bits to usable info. Table 4-15 */ -struct io_port_cfg_t { -	uchar pcie_width[3]; -	uchar rio_width; -} io_port_cfg[16] = { -	{{0, 0, 0}, 0}, -	{{0, 0, 0}, 0}, -	{{4, 0, 0}, 0}, -	{{4, 4, 0}, 0}, -	{{0, 0, 0}, 0}, -	{{0, 0, 0}, 0}, -	{{0, 0, 0}, 4}, -	{{4, 2, 2}, 0}, -	{{0, 0, 0}, 0}, -	{{0, 0, 0}, 0}, -	{{0, 0, 0}, 0}, -	{{4, 0, 0}, 4}, -	{{4, 0, 0}, 4}, -	{{0, 0, 0}, 4}, -	{{0, 0, 0}, 4}, -	{{8, 0, 0}, 0}, -}; -#elif defined CONFIG_MPC8548 -/* Correlate host/agent POR bits to usable info. Table 4-12 */ -struct host_agent_cfg_t { -	uchar pci_host[2]; -	uchar pcie_root[1]; -	uchar rio_host; -} host_agent_cfg[8] = { -	{{1, 1}, {0}, 0}, -	{{1, 1}, {1}, 0}, -	{{1, 1}, {0}, 1}, -	{{0, 0}, {0}, 0}, /* reserved */ -	{{0, 1}, {1}, 0}, -	{{1, 1}, {1}, 0}, -	{{0, 1}, {1}, 1}, -	{{1, 1}, {1}, 1} -}; - -/* Correlate port width POR bits to usable info. Table 4-13 */ -struct io_port_cfg_t { -	uchar pcie_width[1]; -	uchar rio_width; -} io_port_cfg[8] = { -	{{0}, 0}, -	{{0}, 0}, -	{{0}, 0}, -	{{4}, 4}, -	{{4}, 4}, -	{{0}, 4}, -	{{0}, 4}, -	{{8}, 0}, -}; -#elif defined CONFIG_MPC86xx -/* Correlate host/agent POR bits to usable info. Table 4-17 */ -struct host_agent_cfg_t { -	uchar pcie_root[2]; -	uchar rio_host; -} host_agent_cfg[8] = { -	{{0, 0}, 0}, -	{{1, 0}, 1}, -	{{0, 1}, 0}, -	{{1, 1}, 1} -}; - -/* Correlate port width POR bits to usable info. Table 4-16 */ -struct io_port_cfg_t { -	uchar pcie_width[2]; -	uchar rio_width; -} io_port_cfg[16] = { -	{{0, 0}, 0}, -	{{0, 0}, 0}, -	{{8, 0}, 0}, -	{{8, 8}, 0}, -	{{0, 0}, 0}, -	{{8, 0}, 4}, -	{{8, 0}, 4}, -	{{8, 0}, 4}, -	{{0, 0}, 0}, -	{{0, 0}, 4}, -	{{0, 0}, 4}, -	{{0, 0}, 4}, -	{{0, 0}, 0}, -	{{0, 0}, 0}, -	{{0, 8}, 0}, -	{{8, 8}, 0}, -}; -#endif -  /*   * 85xx and 86xx share naming conventions, but different layout.   * Correlate names to CPU-specific values to share common @@ -173,22 +68,22 @@ struct io_port_cfg_t {  void pci_init_board(void)  { -	struct pci_controller *hose; -	volatile ccsr_fsl_pci_t *pci; -	int width; -	int host; +	struct fsl_pci_info pci_info[3]; +	int first_free_busno = 0; +	int num = 0; +	int pcie_ep; +	__maybe_unused int pcie_configured; +  #if defined(CONFIG_MPC85xx)  	volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);  #elif defined(CONFIG_MPC86xx)  	immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;  	volatile ccsr_gur_t *gur = &immap->im_gur;  #endif -	uint devdisr = in_be32(&gur->devdisr); -	uint io_sel = (in_be32(&gur->pordevsr) & MPC8xxx_PORDEVSR_IO_SEL) >> +	u32 devdisr = in_be32(&gur->devdisr); +	u32 pordevsr = in_be32(&gur->pordevsr); +	__maybe_unused uint io_sel = (pordevsr & MPC8xxx_PORDEVSR_IO_SEL) >>  			MPC8xxx_PORDEVSR_IO_SEL_SHIFT; -	uint host_agent = (in_be32(&gur->porbmsr) & MPC8xxx_PORBMSR_HA) >> -			MPC8xxx_PORBMSR_HA_SHIFT; -	struct pci_region *r;  #ifdef CONFIG_PCI1  	uint pci_spd_norm = in_be32(&gur->pordevsr) & MPC85xx_PORDEVSR_PCI1_SPD; @@ -197,49 +92,19 @@ void pci_init_board(void)  	uint pcix = in_be32(&gur->pordevsr) & MPC85xx_PORDEVSR_PCI1;  	uint freq = CONFIG_SYS_CLK_FREQ / 1000 / 1000; -	width = 0; /* Silence compiler warning... */ -	io_sel &= 0xf; /* Silence compiler warning... */ -	pci = (ccsr_fsl_pci_t *) CONFIG_SYS_PCI1_ADDR; -	hose = &pci1_hose; -	host = host_agent_cfg[host_agent].pci_host[0]; -	r = hose->regions; -  	if (!(devdisr & MPC85xx_DEVDISR_PCI1)) { +		SET_STD_PCI_INFO(pci_info[num], 1); +		pcie_ep = fsl_setup_hose(&pci1_hose, pci_info[num].regs);  		printf("\n    PCI1: %d bit %s, %s %d MHz, %s, %s\n",  			pci_32 ? 32 : 64,  			pcix ? "PCIX" : "PCI",  			pci_spd_norm ? ">=" : "<=",  			pcix ? freq * 2 : freq, -			host ? "host" : "agent", +			pcie_ep ? "agent" : "host",  			pci_arb ? "arbiter" : "external-arbiter"); -		/* outbound memory */ -		pci_set_region(r++, -				CONFIG_SYS_PCI1_MEM_BASE, -				CONFIG_SYS_PCI1_MEM_PHYS, -				CONFIG_SYS_PCI1_MEM_SIZE, -				PCI_REGION_MEM); - -		/* outbound io */ -		pci_set_region(r++, -				CONFIG_SYS_PCI1_IO_BASE, -				CONFIG_SYS_PCI1_IO_PHYS, -				CONFIG_SYS_PCI1_IO_SIZE, -				PCI_REGION_IO); - -		hose->region_count = r - hose->regions; - -		hose->first_busno = first_free_busno; - -		fsl_pci_init(hose, (u32)&pci->cfg_addr, (u32)&pci->cfg_data); - -		/* Unlock inbound PCI configuration cycles */ -		if (!host) -			fsl_pci_config_unlock(hose); - -		first_free_busno = hose->last_busno + 1; -		printf("    PCI1 on bus %02x - %02x\n", -			hose->first_busno, hose->last_busno); +		first_free_busno = fsl_pci_init_port(&pci_info[num++], +					&pci1_hose, first_free_busno);  	} else {  		printf("    PCI1: disabled\n");  	} @@ -247,148 +112,53 @@ void pci_init_board(void)  	/* PCI1 not present on MPC8572 */  	setbits_be32(&gur->devdisr, MPC85xx_DEVDISR_PCI1);  #endif -#ifdef CONFIG_PCIE1 -	pci = (ccsr_fsl_pci_t *) CONFIG_SYS_PCIE1_ADDR; -	hose = &pcie1_hose; -	host = host_agent_cfg[host_agent].pcie_root[0]; -	width = io_port_cfg[io_sel].pcie_width[0]; -	r = hose->regions; - -	if (width && !(devdisr & MPC8xxx_DEVDISR_PCIE1)) { -		printf("\n    PCIE1 connected as %s (x%d)", -			host ? "Root Complex" : "Endpoint", width); -		if (in_be32(&pci->pme_msg_det)) { -			out_be32(&pci->pme_msg_det, 0xffffffff); -			debug(" with errors.  Clearing.  Now 0x%08x", -				in_be32(&pci->pme_msg_det)); -		} -		printf("\n"); - -		/* outbound memory */ -		pci_set_region(r++, -				CONFIG_SYS_PCIE1_MEM_BASE, -				CONFIG_SYS_PCIE1_MEM_PHYS, -				CONFIG_SYS_PCIE1_MEM_SIZE, -				PCI_REGION_MEM); - -		/* outbound io */ -		pci_set_region(r++, -				CONFIG_SYS_PCIE1_IO_BASE, -				CONFIG_SYS_PCIE1_IO_PHYS, -				CONFIG_SYS_PCIE1_IO_SIZE, -				PCI_REGION_IO); - -		hose->region_count = r - hose->regions; - -		hose->first_busno = first_free_busno; - -		fsl_pci_init(hose, (u32)&pci->cfg_addr, (u32)&pci->cfg_data); -		/* Unlock inbound PCI configuration cycles */ -		if (!host) -			fsl_pci_config_unlock(hose); - -		first_free_busno = hose->last_busno + 1; -		printf("    PCIE1 on bus %02x - %02x\n", -				hose->first_busno, hose->last_busno); +#ifdef CONFIG_PCIE1 +	pcie_configured = is_fsl_pci_cfg(LAW_TRGT_IF_PCIE_1, io_sel); + +	if (pcie_configured && !(devdisr & MPC8xxx_DEVDISR_PCIE1)) { +		SET_STD_PCIE_INFO(pci_info[num], 1); +		pcie_ep = fsl_setup_hose(&pcie1_hose, pci_info[num].regs); +		printf("    PCIE1 connected as %s\n", +			pcie_ep ? "Endpoint" : "Root Complex"); +		first_free_busno = fsl_pci_init_port(&pci_info[num++], +					&pcie1_hose, first_free_busno); +	} else { +		printf("    PCIE1: disabled\n");  	}  #else  	setbits_be32(&gur->devdisr, MPC8xxx_DEVDISR_PCIE1);  #endif /* CONFIG_PCIE1 */  #ifdef CONFIG_PCIE2 -	pci = (ccsr_fsl_pci_t *) CONFIG_SYS_PCIE2_ADDR; -	hose = &pcie2_hose; -	host = host_agent_cfg[host_agent].pcie_root[1]; -	width = io_port_cfg[io_sel].pcie_width[1]; -	r = hose->regions; - -	if (width && !(devdisr & MPC8xxx_DEVDISR_PCIE2)) { -		printf("\n    PCIE2 connected as %s (x%d)", -			host ? "Root Complex" : "Endpoint", width); -		if (in_be32(&pci->pme_msg_det)) { -			out_be32(&pci->pme_msg_det, 0xffffffff); -			debug(" with errors.  Clearing.  Now 0x%08x", -				in_be32(&pci->pme_msg_det)); -		} -		printf("\n"); - -		/* outbound memory */ -		pci_set_region(r++, -				CONFIG_SYS_PCIE2_MEM_BASE, -				CONFIG_SYS_PCIE2_MEM_PHYS, -				CONFIG_SYS_PCIE2_MEM_SIZE, -				PCI_REGION_MEM); - -		/* outbound io */ -		pci_set_region(r++, -				CONFIG_SYS_PCIE2_IO_BASE, -				CONFIG_SYS_PCIE2_IO_PHYS, -				CONFIG_SYS_PCIE2_IO_SIZE, -				PCI_REGION_IO); - -		hose->region_count = r - hose->regions; - -		hose->first_busno = first_free_busno; - -		fsl_pci_init(hose, (u32)&pci->cfg_addr, (u32)&pci->cfg_data); - -		/* Unlock inbound PCI configuration cycles */ -		if (!host) -			fsl_pci_config_unlock(hose); - -		first_free_busno = hose->last_busno + 1; -		printf("    PCIE2 on bus %02x - %02x\n", -				hose->first_busno, hose->last_busno); +	pcie_configured = is_fsl_pci_cfg(LAW_TRGT_IF_PCIE_2, io_sel); + +	if (pcie_configured && !(devdisr & MPC8xxx_DEVDISR_PCIE2)) { +		SET_STD_PCIE_INFO(pci_info[num], 2); +		pcie_ep = fsl_setup_hose(&pcie2_hose, pci_info[num].regs); +		printf("    PCIE2 connected as %s\n", +			pcie_ep ? "Endpoint" : "Root Complex"); +		first_free_busno = fsl_pci_init_port(&pci_info[num++], +					&pcie2_hose, first_free_busno); +	} else { +		printf("    PCIE2: disabled\n");  	}  #else  	setbits_be32(&gur->devdisr, MPC8xxx_DEVDISR_PCIE2);  #endif /* CONFIG_PCIE2 */  #ifdef CONFIG_PCIE3 -	pci = (ccsr_fsl_pci_t *) CONFIG_SYS_PCIE3_ADDR; -	hose = &pcie3_hose; -	host = host_agent_cfg[host_agent].pcie_root[2]; -	width = io_port_cfg[io_sel].pcie_width[2]; -	r = hose->regions; - -	if (width && !(devdisr & MPC8xxx_DEVDISR_PCIE3)) { -		printf("\n    PCIE3 connected as %s (x%d)", -			host ? "Root Complex" : "Endpoint", width); -		if (in_be32(&pci->pme_msg_det)) { -			out_be32(&pci->pme_msg_det, 0xffffffff); -			debug(" with errors.  Clearing.  Now 0x%08x", -				in_be32(&pci->pme_msg_det)); -		} -		printf("\n"); - -		/* outbound memory */ -		pci_set_region(r++, -				CONFIG_SYS_PCIE3_MEM_BASE, -				CONFIG_SYS_PCIE3_MEM_PHYS, -				CONFIG_SYS_PCIE3_MEM_SIZE, -				PCI_REGION_MEM); - -		/* outbound io */ -		pci_set_region(r++, -				CONFIG_SYS_PCIE3_IO_BASE, -				CONFIG_SYS_PCIE3_IO_PHYS, -				CONFIG_SYS_PCIE3_IO_SIZE, -				PCI_REGION_IO); - -		hose->region_count = r - hose->regions; - -		hose->first_busno = first_free_busno; - -		fsl_pci_init(hose, (u32)&pci->cfg_addr, (u32)&pci->cfg_data); - -		/* Unlock inbound PCI configuration cycles */ -		if (!host) -			fsl_pci_config_unlock(hose); - -		first_free_busno = hose->last_busno + 1; -		printf("    PCIE3 on bus %02x - %02x\n", -				hose->first_busno, hose->last_busno); +	pcie_configured = is_fsl_pci_cfg(LAW_TRGT_IF_PCIE_3, io_sel); + +	if (pcie_configured && !(devdisr & MPC8xxx_DEVDISR_PCIE3)) { +		SET_STD_PCIE_INFO(pci_info[num], 3); +		pcie_ep = fsl_setup_hose(&pcie3_hose, pci_info[num].regs); +		printf("    PCIE3 connected as %s\n", +			pcie_ep ? "Endpoint" : "Root Complex"); +		first_free_busno = fsl_pci_init_port(&pci_info[num++], +					&pcie3_hose, first_free_busno); +	} else { +		printf("    PCIE3: disabled\n");  	}  #else  	setbits_be32(&gur->devdisr, MPC8xxx_DEVDISR_PCIE3); diff --git a/board/xes/xpedite5170/Makefile b/board/xes/xpedite517x/Makefile index fea6686e699..fea6686e699 100644 --- a/board/xes/xpedite5170/Makefile +++ b/board/xes/xpedite517x/Makefile diff --git a/board/xes/xpedite5170/ddr.c b/board/xes/xpedite517x/ddr.c index 1d57d0909a6..1d57d0909a6 100644 --- a/board/xes/xpedite5170/ddr.c +++ b/board/xes/xpedite517x/ddr.c diff --git a/board/xes/xpedite5170/law.c b/board/xes/xpedite517x/law.c index 0b7d9ef8d18..0b7d9ef8d18 100644 --- a/board/xes/xpedite5170/law.c +++ b/board/xes/xpedite517x/law.c diff --git a/board/xes/xpedite5170/xpedite5170.c b/board/xes/xpedite517x/xpedite517x.c index 58229418f36..0f7fa6c43ab 100644 --- a/board/xes/xpedite5170/xpedite5170.c +++ b/board/xes/xpedite517x/xpedite517x.c @@ -26,30 +26,12 @@  #include <asm/io.h>  #include <fdt_support.h>  #include <pca953x.h> +#include "../common/fsl_8xxx_misc.h"  #if defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_PCI)  extern void ft_board_pci_setup(void *blob, bd_t *bd);  #endif -int checkboard(void) -{ -	char *s; - -	printf("Board: X-ES %s 3U VPX SBC\n", CONFIG_SYS_BOARD_NAME); -	printf("       "); -	s = getenv("board_rev"); -	if (s) -		printf("Rev %s, ", s); -	s = getenv("serial#"); -	if (s) -		printf("Serial# %s, ", s); -	s = getenv("board_cfg"); -	if (s) -		printf("Cfg %s", s); -	printf("\n"); - -	return 0; -}  /*   * Print out which flash was booted from and if booting from the 2nd flash,   * swap flash chip selects to maintain consistent flash numbering/addresses. diff --git a/board/xes/xpedite5200/Makefile b/board/xes/xpedite520x/Makefile index 02fe8fcd2d3..02fe8fcd2d3 100644 --- a/board/xes/xpedite5200/Makefile +++ b/board/xes/xpedite520x/Makefile diff --git a/board/xes/xpedite5200/ddr.c b/board/xes/xpedite520x/ddr.c index c5616d546b8..c5616d546b8 100644 --- a/board/xes/xpedite5200/ddr.c +++ b/board/xes/xpedite520x/ddr.c diff --git a/board/xes/xpedite5200/law.c b/board/xes/xpedite520x/law.c index bbfcb9da83c..bbfcb9da83c 100644 --- a/board/xes/xpedite5200/law.c +++ b/board/xes/xpedite520x/law.c diff --git a/board/xes/xpedite5200/tlb.c b/board/xes/xpedite520x/tlb.c index bd7bff820b6..bd7bff820b6 100644 --- a/board/xes/xpedite5200/tlb.c +++ b/board/xes/xpedite520x/tlb.c diff --git a/board/xes/xpedite5200/xpedite5200.c b/board/xes/xpedite520x/xpedite520x.c index a2627f86736..dc5c9651142 100644 --- a/board/xes/xpedite5200/xpedite5200.c +++ b/board/xes/xpedite520x/xpedite520x.c @@ -36,33 +36,6 @@  extern void ft_board_pci_setup(void *blob, bd_t *bd); -int checkboard(void) -{ -	volatile fsl_lbc_t *lbc = LBC_BASE_ADDR; -	volatile ccsr_local_ecm_t *ecm = (void *)(CONFIG_SYS_MPC85xx_ECM_ADDR); -	char *s; - -	printf("Board: X-ES %s PMC\n", CONFIG_SYS_BOARD_NAME); -	printf("       "); -	s = getenv("board_rev"); -	if (s) -		printf("Rev %s, ", s); -	s = getenv("serial#"); -	if (s) -		printf("Serial# %s, ", s); -	s = getenv("board_cfg"); -	if (s) -		printf("Cfg %s", s); -	printf("\n"); - -	out_be32(&lbc->ltesr, 0xffffffff);	/* Clear LBC error IRQs */ -	out_be32(&lbc->lteir, 0xffffffff);	/* Enable LBC error IRQs */ -	out_be32(&ecm->eedr, 0xffffffff);	/* Clear ecm errors */ -	out_be32(&ecm->eeer, 0xffffffff);	/* Enable ecm errors */ - -	return 0; -} -  static void flash_cs_fixup(void)  {  	int flash_sel; diff --git a/board/xes/xpedite5370/Makefile b/board/xes/xpedite537x/Makefile index 919397c40d5..919397c40d5 100644 --- a/board/xes/xpedite5370/Makefile +++ b/board/xes/xpedite537x/Makefile diff --git a/board/xes/xpedite5370/ddr.c b/board/xes/xpedite537x/ddr.c index 4d3f255d705..4d3f255d705 100644 --- a/board/xes/xpedite5370/ddr.c +++ b/board/xes/xpedite537x/ddr.c diff --git a/board/xes/xpedite5370/law.c b/board/xes/xpedite537x/law.c index daee676c426..daee676c426 100644 --- a/board/xes/xpedite5370/law.c +++ b/board/xes/xpedite537x/law.c diff --git a/board/xes/xpedite5370/tlb.c b/board/xes/xpedite537x/tlb.c index a465ce38600..a465ce38600 100644 --- a/board/xes/xpedite5370/tlb.c +++ b/board/xes/xpedite537x/tlb.c diff --git a/board/xes/xpedite5370/xpedite5370.c b/board/xes/xpedite537x/xpedite537x.c index 2a060c24625..89fa6c78b30 100644 --- a/board/xes/xpedite5370/xpedite5370.c +++ b/board/xes/xpedite537x/xpedite537x.c @@ -36,26 +36,6 @@ DECLARE_GLOBAL_DATA_PTR;  extern void ft_board_pci_setup(void *blob, bd_t *bd); -int checkboard(void) -{ -	char *s; - -	printf("Board: X-ES %s 3U VPX SBC\n", CONFIG_SYS_BOARD_NAME); -	printf("       "); -	s = getenv("board_rev"); -	if (s) -		printf("Rev %s, ", s); -	s = getenv("serial#"); -	if (s) -		printf("Serial# %s, ", s); -	s = getenv("board_cfg"); -	if (s) -		printf("Cfg %s", s); -	printf("\n"); - -	return 0; -} -  static void flash_cs_fixup(void)  {  	int flash_sel; diff --git a/board/xes/xpedite550x/Makefile b/board/xes/xpedite550x/Makefile new file mode 100644 index 00000000000..8980a4b3f6a --- /dev/null +++ b/board/xes/xpedite550x/Makefile @@ -0,0 +1,39 @@ +# +# Copyright 2007-2008 Freescale Semiconductor, Inc. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# + +include $(TOPDIR)/config.mk + +LIB	= $(obj)lib$(BOARD).a + +COBJS-y	+= $(BOARD).o +COBJS-y	+= ddr.o +COBJS-y	+= law.o +COBJS-y	+= tlb.o + +SRCS	:= $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) +OBJS	:= $(addprefix $(obj),$(COBJS-y)) +SOBJS	:= $(addprefix $(obj),$(SOBJS-y)) + +$(LIB):	$(obj).depend $(OBJS) $(SOBJS) +	$(AR) $(ARFLAGS) $@ $(OBJS) + +clean: +	rm -f $(OBJS) $(SOBJS) + +distclean:	clean +	rm -f $(LIB) core *.bak .depend + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/xes/xpedite550x/ddr.c b/board/xes/xpedite550x/ddr.c new file mode 100644 index 00000000000..718cd989bbf --- /dev/null +++ b/board/xes/xpedite550x/ddr.c @@ -0,0 +1,165 @@ +/* + * Copyright 2010 Extreme Engineering Solutions, Inc. + * Copyright 2007-2008 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <i2c.h> + +#include <asm/fsl_ddr_sdram.h> +#include <asm/fsl_ddr_dimm_params.h> + +static void get_spd(ddr3_spd_eeprom_t *spd, unsigned char i2c_address) +{ +	i2c_read(i2c_address, SPD_EEPROM_OFFSET, 2, (uchar *)spd, +		 sizeof(ddr3_spd_eeprom_t)); +} + +void fsl_ddr_get_spd(ddr3_spd_eeprom_t *ctrl_dimms_spd, +		      unsigned int ctrl_num) +{ +	unsigned int i; +	unsigned int i2c_address = 0; + +	for (i = 0; i < CONFIG_DIMM_SLOTS_PER_CTLR; i++) { +		if (ctrl_num == 0 && i == 0) +			i2c_address = SPD_EEPROM_ADDRESS1; +		get_spd(&(ctrl_dimms_spd[i]), i2c_address); +	} +} + +unsigned int fsl_ddr_get_mem_data_rate(void) +{ +	return get_ddr_freq(0); +} + +/* + *     There are traditionally three board-specific SDRAM timing parameters + *     which must be calculated based on the particular PCB artwork.  These are: + *     1.) CPO (Read Capture Delay) + *             - TIMING_CFG_2 register + *             Source: Calculation based on board trace lengths and + *                     chip-specific internal delays. + *     2.) CLK_ADJUST (Clock and Addr/Cmd alignment control) + *             - DDR_SDRAM_CLK_CNTL register + *             Source: Signal Integrity Simulations + *     3.) 2T Timing on Addr/Ctl + *             - TIMING_CFG_2 register + *             Source: Signal Integrity Simulations + *             Usually only needed with heavy load/very high speed (>DDR2-800) + * + *     ====== XPedite550x DDR3-800 read delay calculations ====== + * + *     The P2020 processor provides an autoleveling option. Setting CPO to + *     0x1f enables this auto configuration. + */ + +typedef struct { +	unsigned short datarate_mhz_low; +	unsigned short datarate_mhz_high; +	unsigned char clk_adjust; +	unsigned char cpo; +} board_specific_parameters_t; + +const board_specific_parameters_t board_specific_parameters[][20] = { +	{ +		/* Controller 0 */ +                { +			/* DDR3-600/667 */ +			.datarate_mhz_low	= 500, +			.datarate_mhz_high	= 750, +			.clk_adjust		= 5, +			.cpo			= 31, +		}, +                { +			/* DDR3-800 */ +			.datarate_mhz_low	= 750, +			.datarate_mhz_high	= 850, +			.clk_adjust		= 5, +			.cpo			= 31, +		}, +	}, +}; + +void fsl_ddr_board_options(memctl_options_t *popts, +				dimm_params_t *pdimm, +				unsigned int ctrl_num) +{ +	const board_specific_parameters_t *pbsp = +				&(board_specific_parameters[ctrl_num][0]); +	u32 num_params = sizeof(board_specific_parameters[ctrl_num]) / +				sizeof(board_specific_parameters[0][0]); +	u32 i; +	ulong ddr_freq; + +	/* +	 * Set odt_rd_cfg and odt_wr_cfg. If the there is only one dimm in +	 * that controller, set odt_wr_cfg to 4 for CS0, and 0 to CS1. If +	 * there are two dimms in the controller, set odt_rd_cfg to 3 and +	 * odt_wr_cfg to 3 for the even CS, 0 for the odd CS. +	 */ +	for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { +		if (i&1) {	/* odd CS */ +			popts->cs_local_opts[i].odt_rd_cfg = 0; +			popts->cs_local_opts[i].odt_wr_cfg = 0; +		} else {	/* even CS */ +			if (CONFIG_DIMM_SLOTS_PER_CTLR == 1) { +				popts->cs_local_opts[i].odt_rd_cfg = 0; +				popts->cs_local_opts[i].odt_wr_cfg = 4; +			} else if (CONFIG_DIMM_SLOTS_PER_CTLR == 2) { +				popts->cs_local_opts[i].odt_rd_cfg = 3; +				popts->cs_local_opts[i].odt_wr_cfg = 3; +			} +		} +	} + +	/* +	 * Get clk_adjust, cpo, write_data_delay,2T, according to the board ddr +	 * freqency and n_banks specified in board_specific_parameters table. +	 */ +	ddr_freq = get_ddr_freq(0) / 1000000; + +	for (i = 0; i < num_params; i++) { +		if (ddr_freq >= pbsp->datarate_mhz_low && +		    ddr_freq <= pbsp->datarate_mhz_high) { +			popts->clk_adjust = pbsp->clk_adjust; +			popts->cpo_override = pbsp->cpo; +			popts->twoT_en = 0; +		} +		pbsp++; +	} + +	/* +	 * Factors to consider for half-strength driver enable: +	 *	- number of DIMMs installed +	 */ +	popts->half_strength_driver_enable = 0; + +	/* +	 * Enable on-die termination. +	 * From the Micron Technical Node TN-41-04, RTT_Nom should typically +	 * be 30 to 40 ohms, while RTT_WR should be 120 ohms.  Setting RTT_WR +	 * is handled in the Freescale DDR3 driver.  Set RTT_Nom here. +	 */ +	popts->rtt_override = 1; +	popts->rtt_override_value = 3; +} + diff --git a/board/xes/xpedite550x/law.c b/board/xes/xpedite550x/law.c new file mode 100644 index 00000000000..4d4445d3108 --- /dev/null +++ b/board/xes/xpedite550x/law.c @@ -0,0 +1,54 @@ +/* + * Copyright 2010 Extreme Engineering Solutions, Inc. + * Copyright 2008 Freescale Semiconductor, Inc. + * + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/fsl_law.h> +#include <asm/mmu.h> + +/* + * Notes: + *    CCSRBAR and L2-as-SRAM don't need a configured Local Access Window. + *    If flash is 8M at default position (last 8M), no LAW needed. + */ + +struct law_entry law_table[] = { +	SET_LAW(CONFIG_SYS_FLASH_BASE2, LAW_SIZE_256M, LAW_TRGT_IF_LBC), +	SET_LAW(CONFIG_SYS_NAND_BASE, LAW_SIZE_1M, LAW_TRGT_IF_LBC), +#ifdef CONFIG_SYS_PCIE1_MEM_PHYS +	SET_LAW(CONFIG_SYS_PCIE1_MEM_PHYS, LAW_SIZE_1G, LAW_TRGT_IF_PCIE_1), +	SET_LAW(CONFIG_SYS_PCIE1_IO_PHYS, LAW_SIZE_8M, LAW_TRGT_IF_PCIE_1), +#endif +#ifdef CONFIG_SYS_PCIE2_MEM_PHYS +	SET_LAW(CONFIG_SYS_PCIE2_MEM_PHYS, LAW_SIZE_256M, LAW_TRGT_IF_PCIE_2), +	SET_LAW(CONFIG_SYS_PCIE2_IO_PHYS, LAW_SIZE_8M, LAW_TRGT_IF_PCIE_2), +#endif +#ifdef CONFIG_SYS_PCIE3_MEM_PHYS +	SET_LAW(CONFIG_SYS_PCIE3_MEM_PHYS, LAW_SIZE_256M, LAW_TRGT_IF_PCIE_3), +	SET_LAW(CONFIG_SYS_PCIE3_IO_PHYS, LAW_SIZE_8M, LAW_TRGT_IF_PCIE_3), +#endif +}; + +int num_law_entries = ARRAY_SIZE(law_table); diff --git a/board/xes/xpedite550x/tlb.c b/board/xes/xpedite550x/tlb.c new file mode 100644 index 00000000000..cf3ff4d45f8 --- /dev/null +++ b/board/xes/xpedite550x/tlb.c @@ -0,0 +1,98 @@ +/* + * Copyright 2008 Extreme Engineering Solutions, Inc. + * Copyright 2008 Freescale Semiconductor, Inc. + * + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/mmu.h> + +struct fsl_e_tlb_entry tlb_table[] = { +	/* TLB 0 - for temp stack in cache */ +	SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR, CONFIG_SYS_INIT_RAM_ADDR, +		MAS3_SX|MAS3_SW|MAS3_SR, 0, +		0, 0, BOOKE_PAGESZ_4K, 0), +	SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR + 4 * 1024, +		CONFIG_SYS_INIT_RAM_ADDR + 4 * 1024, +		MAS3_SX|MAS3_SW|MAS3_SR, 0, +		0, 0, BOOKE_PAGESZ_4K, 0), +	SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR + 8 * 1024, +		CONFIG_SYS_INIT_RAM_ADDR + 8 * 1024, +		MAS3_SX|MAS3_SW|MAS3_SR, 0, +		0, 0, BOOKE_PAGESZ_4K, 0), +	SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR + 12 * 1024, +		CONFIG_SYS_INIT_RAM_ADDR + 12 * 1024, +		MAS3_SX|MAS3_SW|MAS3_SR, 0, +		0, 0, BOOKE_PAGESZ_4K, 0), + +	/* W**G* - NOR flashes */ +	/* This will be changed to *I*G* after relocation to RAM. */ +	SET_TLB_ENTRY(1, CONFIG_SYS_FLASH_BASE2, CONFIG_SYS_FLASH_BASE2, +		MAS3_SX|MAS3_SW|MAS3_SR, MAS2_W|MAS2_G, +		0, 0, BOOKE_PAGESZ_256M, 1), + +	/* *I*G* - CCSRBAR */ +	SET_TLB_ENTRY(1, CONFIG_SYS_CCSRBAR, CONFIG_SYS_CCSRBAR_PHYS, +		MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, +		0, 1, BOOKE_PAGESZ_1M, 1), + +	/* *I*G* - NAND flash */ +	SET_TLB_ENTRY(1, CONFIG_SYS_NAND_BASE, CONFIG_SYS_NAND_BASE, +		MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, +		0, 2, BOOKE_PAGESZ_1M, 1), + +	/* **M** - Boot page for secondary processors */ +	SET_TLB_ENTRY(1, CONFIG_BPTR_VIRT_ADDR, CONFIG_BPTR_VIRT_ADDR, +		MAS3_SX|MAS3_SW|MAS3_SR, MAS2_M, +		0, 3, BOOKE_PAGESZ_4K, 1), + +#ifdef CONFIG_PCIE1 +	/* *I*G* - PCIe */ +	SET_TLB_ENTRY(1, CONFIG_SYS_PCIE1_MEM_PHYS, CONFIG_SYS_PCIE1_MEM_PHYS, +		MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, +		0, 4, BOOKE_PAGESZ_1G, 1), +#endif + +#ifdef CONFIG_PCIE2 +	/* *I*G* - PCIe */ +	SET_TLB_ENTRY(1, CONFIG_SYS_PCIE2_MEM_PHYS, CONFIG_SYS_PCIE2_MEM_PHYS, +		MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, +		0, 5, BOOKE_PAGESZ_256M, 1), +#endif + +#ifdef CONFIG_PCIE3 +	/* *I*G* - PCIe */ +	SET_TLB_ENTRY(1, CONFIG_SYS_PCIE3_MEM_PHYS, CONFIG_SYS_PCIE3_MEM_PHYS, +		MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, +		0, 6, BOOKE_PAGESZ_256M, 1), +#endif + +#if defined(CONFIG_PCIE1) || defined(CONFIG_PCIE2) || defined(CONFIG_PCIE3) +	/* *I*G* - PCIe */ +	SET_TLB_ENTRY(1, CONFIG_SYS_PCIE1_IO_PHYS, CONFIG_SYS_PCIE1_IO_PHYS, +		MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, +		0, 7, BOOKE_PAGESZ_64M, 1), +#endif +}; + +int num_tlb_entries = ARRAY_SIZE(tlb_table); diff --git a/board/xes/xpedite550x/xpedite550x.c b/board/xes/xpedite550x/xpedite550x.c new file mode 100644 index 00000000000..2ad30a30f90 --- /dev/null +++ b/board/xes/xpedite550x/xpedite550x.c @@ -0,0 +1,107 @@ +/* + * Copyright 2010 Extreme Engineering Solutions, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <command.h> +#include <asm/processor.h> +#include <asm/mmu.h> +#include <asm/immap_85xx.h> +#include <asm/fsl_pci.h> +#include <asm/io.h> +#include <asm/cache.h> +#include <libfdt.h> +#include <fdt_support.h> +#include <pca953x.h> + +DECLARE_GLOBAL_DATA_PTR; + +extern void ft_board_pci_setup(void *blob, bd_t *bd); + +static void flash_cs_fixup(void) +{ +	int flash_sel; + +	/* +	 * Print boot dev and swap flash flash chip selects if booted from 2nd +	 * flash.  Swapping chip selects presents user with a common memory +	 * map regardless of which flash was booted from. +	 */ +	flash_sel = !((pca953x_get_val(CONFIG_SYS_I2C_PCA953X_ADDR0) & +			CONFIG_SYS_PCA953X_C0_FLASH_PASS_CS)); +	printf("FLASH: Executed from FLASH%d\n", flash_sel ? 2 : 1); + +	if (flash_sel) { +		set_lbc_br(0, CONFIG_SYS_BR1_PRELIM); +		set_lbc_or(0, CONFIG_SYS_OR1_PRELIM); + +		set_lbc_br(1, CONFIG_SYS_BR0_PRELIM); +		set_lbc_or(1, CONFIG_SYS_OR0_PRELIM); +	} +} + +int board_early_init_r(void) +{ +	/* Initialize PCA9557 devices */ +	pca953x_set_pol(CONFIG_SYS_I2C_PCA953X_ADDR0, 0xff, 0); +	pca953x_set_pol(CONFIG_SYS_I2C_PCA953X_ADDR1, 0xff, 0); +	pca953x_set_pol(CONFIG_SYS_I2C_PCA953X_ADDR2, 0xff, 0); +	pca953x_set_pol(CONFIG_SYS_I2C_PCA953X_ADDR3, 0xff, 0); + +	/* +	 * Remap NOR flash region to caching-inhibited +	 * so that flash can be erased/programmed properly. +	 */ + +	/* Flush d-cache and invalidate i-cache of any FLASH data */ +	flush_dcache(); +	invalidate_icache(); + +	/* Invalidate existing TLB entry for NOR flash */ +	disable_tlb(0); +	set_tlb(1, (CONFIG_SYS_FLASH_BASE2 & 0xf0000000), +		(CONFIG_SYS_FLASH_BASE2 & 0xf0000000), +		MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, +		0, 0, BOOKE_PAGESZ_256M, 1); + +	flash_cs_fixup(); + +	return 0; +} + +#if defined(CONFIG_OF_BOARD_SETUP) +void ft_board_setup(void *blob, bd_t *bd) +{ +#ifdef CONFIG_PCI +	ft_board_pci_setup(blob, bd); +#endif +	ft_cpu_setup(blob, bd); +} +#endif + +#ifdef CONFIG_MP +extern void cpu_mp_lmb_reserve(struct lmb *lmb); + +void board_lmb_reserve(struct lmb *lmb) +{ +	cpu_mp_lmb_reserve(lmb); +} +#endif diff --git a/boards.cfg b/boards.cfg index c6880236ee1..4efbff85fd4 100644 --- a/boards.cfg +++ b/boards.cfg @@ -553,8 +553,9 @@ MPC8540ADS	powerpc	mpc85xx		mpc8540ads	freescale  MPC8544DS	powerpc	mpc85xx		mpc8544ds	freescale  MPC8560ADS	powerpc	mpc85xx		mpc8560ads	freescale  MPC8568MDS	powerpc	mpc85xx		mpc8568mds	freescale -XPEDITE5200	powerpc	mpc85xx		xpedite5200	xes -XPEDITE5370	powerpc	mpc85xx		xpedite5370	xes +xpedite520x	powerpc	mpc85xx		-		xes +xpedite537x	powerpc	mpc85xx		-		xes +xpedite550x	powerpc	mpc85xx		-		xes  sbc8540_33	powerpc	mpc85xx		sbc8560		-		-	SBC8540  sbc8540_66	powerpc	mpc85xx		sbc8560		-		-	SBC8540  sbc8548_PCI_33	powerpc	mpc85xx		sbc8548		-		-	sbc8548:PCI,33 @@ -594,7 +595,7 @@ P2020RDB_NAND	powerpc	mpc85xx		p1_p2_rdb	freescale	-	P1_P2_RDB:P2020,NAND  P2020RDB_SDCARD	powerpc	mpc85xx		p1_p2_rdb	freescale	-	P1_P2_RDB:P2020,SDCARD  sbc8641d	powerpc	mpc86xx  MPC8610HPCD	powerpc	mpc86xx		mpc8610hpcd	freescale -XPEDITE5170	powerpc	mpc86xx		xpedite5170	xes +xpedite517x	powerpc	mpc86xx		-		xes  MPC8641HPCN	powerpc	mpc86xx		mpc8641hpcn	freescale	-	MPC8641HPCN  cogent_mpc8xx	powerpc	mpc8xx		cogent  ESTEEM192E	powerpc	mpc8xx		esteem192e @@ -645,7 +646,7 @@ CPCIISER4	powerpc	ppc4xx		cpciiser4	esd  DASA_SIM	powerpc	ppc4xx		dasa_sim	esd  PMC405DE	powerpc	ppc4xx		pmc405de	esd  METROBOX	powerpc	ppc4xx		metrobox	sandburst -XPEDITE1000	powerpc	ppc4xx		xpedite1000	xes +xpedite1000	powerpc	ppc4xx		-		xes  korat_perm	powerpc	ppc4xx		korat		-		-	korat:KORAT_PERMANENT  haleakala	powerpc	ppc4xx		kilauea		amcc		-	kilauea:HALEAKALA  sycamore	powerpc	ppc4xx		walnut		amcc		-	walnut @@ -729,5 +730,18 @@ davinci_dm6467evm arm	arm926ejs	dm6467evm	davinci		davinci  davinci_schmoogie arm	arm926ejs	schmoogie	davinci		davinci  davinci_dm355leopard arm arm926ejs	dm355leopard	davinci		davinci  bf527-ad7160-eval blackfin	blackfin +rsk7203	sh	sh2		rsk7203		renesas		- +mpr2	sh	sh3		mpr2	-	- +ms7720se	sh	sh3	ms7720se	-	- +MigoRsh	sh4	MigoR	renesas	-    +ms7750se	sh	sh4	ms7750se	-	-    +ms7722se	sh	sh4	ms7722se	-	-    +r2dplus	sh	sh4	r2dplus	renesas	-    +r7780mp	sh	sh4	r7780mp	renesas	-    +sh7763rdp	sh	sh4	sh7763rdp	renesas	-    +sh7785lcr	sh	sh4	sh7785lcr	renesas	-    +sh7785lcr_32bit	sh  sh4	sh7785lcr	renesas	-	sh7785lcr:SH_32BIT=1 +ap325rxa	sh	sh4	ap325rxa	renesas	-    +espt	sh	sh4	espt	-	-  # Target	ARCH	CPU		Board name	Vendor		SoC		Options  ############################################################################################### diff --git a/common/cmd_pci.c b/common/cmd_pci.c index 4bde0599118..ccf5adaaad6 100644 --- a/common/cmd_pci.c +++ b/common/cmd_pci.c @@ -497,6 +497,10 @@ int do_pci (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  		if ((bdf = get_pci_dev(argv[2])) == -1)  			return 1;  		break; +#ifdef CONFIG_CMD_PCI_ENUM +	case 'e': +		break; +#endif  	default:		/* scan bus */  		value = 1; /* short listing */  		bdf = 0;   /* bus number  */ @@ -518,6 +522,11 @@ int do_pci (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  		return 0;  	case 'd':		/* display */  		return pci_cfg_display(bdf, addr, size, value); +#ifdef CONFIG_CMD_PCI_ENUM +	case 'e': +		pci_init(); +		return 0; +#endif  	case 'n':		/* next */  		if (argc < 4)  			goto usage; @@ -545,6 +554,10 @@ U_BOOT_CMD(  	"list and access PCI Configuration Space",  	"[bus] [long]\n"  	"    - short or long list of PCI devices on bus 'bus'\n" +#ifdef CONFIG_CMD_PCI_ENUM +	"pci enum\n" +	"    - re-enumerate PCI buses\n" +#endif  	"pci header b.d.f\n"  	"    - show header of PCI device 'bus.device.function'\n"  	"pci display[.b, .w, .l] b.d.f [address] [# of objects]\n" diff --git a/common/usb_storage.c b/common/usb_storage.c index 613c4f0f1f7..1e6cd6af274 100644 --- a/common/usb_storage.c +++ b/common/usb_storage.c @@ -70,7 +70,7 @@  /* direction table -- this indicates the direction of the data   * transfer for each command code -- a 1 indicates input   */ -unsigned char us_direction[256/8] = { +static const unsigned char us_direction[256/8] = {  	0x28, 0x81, 0x14, 0x14, 0x20, 0x01, 0x90, 0x77,  	0x0C, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,  	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, diff --git a/doc/README.LED_display b/doc/README.LED_display index 521746e1291..19977ea7e0d 100644 --- a/doc/README.LED_display +++ b/doc/README.LED_display @@ -14,7 +14,6 @@ This function should control the state of the LED display. Argument is  an ORed combination of the following values:   DISPLAY_CLEAR	-- clear the display   DISPLAY_HOME	-- set the position to the beginning of display - DISPLAY_MARK	-- enable mark (decimal point), if implemented  int display_putc(char c); diff --git a/doc/README.POST b/doc/README.POST index eeb218d39c6..6815d491cf4 100644 --- a/doc/README.POST +++ b/doc/README.POST @@ -659,12 +659,19 @@ not need any modifications for porting them to another board/CPU.  2.2.2.1. I2C test  For verifying the I2C bus, a full I2C bus scanning will be performed -using the i2c_probe() routine. If any I2C device is found, the test -will be considered as passed, otherwise failed. This particular way -will be used because it provides the most common method of testing. -For example, using the internal loopback mode of the CPM I2C -controller for testing would not work on boards where the software -I2C driver (also known as bit-banged driver) is used. +using the i2c_probe() routine. If a board defines +CONFIG_SYS_POST_I2C_ADDRS the I2C test will pass if all devices +listed in CONFIG_SYS_POST_I2C_ADDRS are found, and no additional +devices are detected.  If CONFIG_SYS_POST_I2C_ADDRS is not defined +the test will pass if any I2C device is found. + +The CONFIG_SYS_POST_I2C_IGNORES define can be used to list I2C +devices which may or may not be present when using +CONFIG_SYS_POST_I2C_ADDRS.  The I2C POST test will pass regardless +if the devices in CONFIG_SYS_POST_I2C_IGNORES are found or not. +This is useful in cases when I2C devices are optional (eg on a +daughtercard that may or may not be present) or not critical +to board operation.  2.2.2.2. Watchdog timer test diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c index 798902f3376..c92c7a7a490 100644 --- a/drivers/mtd/cfi_flash.c +++ b/drivers/mtd/cfi_flash.c @@ -85,6 +85,17 @@ static phys_addr_t __cfi_flash_bank_addr(int i)  phys_addr_t cfi_flash_bank_addr(int i)  	__attribute__((weak, alias("__cfi_flash_bank_addr"))); +static unsigned long __cfi_flash_bank_size(int i) +{ +#ifdef CONFIG_SYS_FLASH_BANKS_SIZES +	return ((unsigned long [])CONFIG_SYS_FLASH_BANKS_SIZES)[i]; +#else +	return 0; +#endif +} +unsigned long cfi_flash_bank_size(int i) +	__attribute__((weak, alias("__cfi_flash_bank_size"))); +  static void __flash_write8(u8 value, void *addr)  {  	__raw_writeb(value, addr); @@ -1826,7 +1837,7 @@ static void flash_fixup_stm(flash_info_t *info, struct cfi_qry *qry)   * The following code cannot be run from FLASH!   *   */ -ulong flash_get_size (phys_addr_t base, int banknum) +ulong flash_get_size (phys_addr_t base, int banknum, unsigned long max_size)  {  	flash_info_t *info = &flash_info[banknum];  	int i, j; @@ -1915,6 +1926,13 @@ ulong flash_get_size (phys_addr_t base, int banknum)  		debug ("size_ratio %d port %d bits chip %d bits\n",  		       size_ratio, info->portwidth << CFI_FLASH_SHIFT_WIDTH,  		       info->chipwidth << CFI_FLASH_SHIFT_WIDTH); +		info->size = 1 << qry.dev_size; +		/* multiply the size by the number of chips */ +		info->size *= size_ratio; +		if (max_size && (info->size > max_size)) { +			debug("[truncated from %ldMiB]", info->size >> 20); +			info->size = max_size; +		}  		debug ("found %d erase regions\n", num_erase_regions);  		sect_cnt = 0;  		sector = base; @@ -1935,6 +1953,8 @@ ulong flash_get_size (phys_addr_t base, int banknum)  			debug ("erase_region_count = %d erase_region_size = %d\n",  				erase_region_count, erase_region_size);  			for (j = 0; j < erase_region_count; j++) { +				if (sector - base >= info->size) +					break;  				if (sect_cnt >= CONFIG_SYS_MAX_FLASH_SECT) {  					printf("ERROR: too many flash sectors\n");  					break; @@ -1968,9 +1988,6 @@ ulong flash_get_size (phys_addr_t base, int banknum)  		}  		info->sector_count = sect_cnt; -		info->size = 1 << qry.dev_size; -		/* multiply the size by the number of chips */ -		info->size *= size_ratio;  		info->buffer_size = 1 << le16_to_cpu(qry.max_buf_write_size);  		tmp = 1 << qry.block_erase_timeout_typ;  		info->erase_blk_tout = tmp * @@ -2026,7 +2043,8 @@ unsigned long flash_init (void)  		flash_info[i].flash_id = FLASH_UNKNOWN;  		if (!flash_detect_legacy(cfi_flash_bank_addr(i), i)) -			flash_get_size(cfi_flash_bank_addr(i), i); +			flash_get_size(cfi_flash_bank_addr(i), i, +					cfi_flash_bank_size(i));  		size += flash_info[i].size;  		if (flash_info[i].flash_id == FLASH_UNKNOWN) {  #ifndef CONFIG_SYS_FLASH_QUIET_TEST diff --git a/drivers/pci/fsl_pci_init.c b/drivers/pci/fsl_pci_init.c index 001e6eb9007..1f021036e5f 100644 --- a/drivers/pci/fsl_pci_init.c +++ b/drivers/pci/fsl_pci_init.c @@ -91,6 +91,9 @@ int fsl_setup_hose(struct pci_controller *hose, unsigned long addr)  {  	volatile ccsr_fsl_pci_t *pci = (ccsr_fsl_pci_t *) addr; +	/* Reset hose to make sure its in a clean state */ +	memset(hose, 0, sizeof(struct pci_controller)); +  	pci_setup_indirect(hose, (u32)&pci->cfg_addr, (u32)&pci->cfg_data);  	return fsl_is_pci_agent(hose); diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index cd64a87fc6d..848746f1ed2 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -139,7 +139,7 @@ void *pci_map_bar(pci_dev_t pdev, int bar, int flags)   *   */ -static struct pci_controller* hose_head = NULL; +static struct pci_controller* hose_head;  void pci_register_hose(struct pci_controller* hose)  { @@ -640,6 +640,8 @@ void pci_init(void)  	}  #endif /* CONFIG_PCI_BOOTDELAY */ +	hose_head = NULL; +  	/* now call board specific pci_init()... */  	pci_init_board();  } diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index f44fc4e3c4b..982f96e8b8f 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -205,12 +205,12 @@ static int handshake(uint32_t *ptr, uint32_t mask, uint32_t done, int usec)  	uint32_t result;  	do {  		result = ehci_readl(ptr); +		udelay(5);  		if (result == ~(uint32_t)0)  			return -1;  		result &= mask;  		if (result == done)  			return 0; -		udelay(1);  		usec--;  	} while (usec > 0);  	return -1; diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 047902a0c1c..cff34389295 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -53,6 +53,10 @@ int ehci_hcd_init(void)  	hcor = (struct ehci_hcor *)((uint32_t) hccr +  			HC_LENGTH(ehci_readl(&hccr->cr_capbase))); +	debug("EHCI-PCI init hccr 0x%x and hcor 0x%x hc_length %d\n", +			(uint32_t)hccr, (uint32_t)hcor, +			(uint32_t)HC_LENGTH(ehci_readl(&hccr->cr_capbase))); +  	return 0;  } diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index d3aa55b4a6c..945ab64f951 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -175,7 +175,7 @@ struct qTD {  	uint32_t qt_buffer_hi[5];	/* Appendix B */  	/* pad struct for 32 byte alignment */  	uint32_t unused[3]; -} __attribute__ ((aligned (32))); +};  /* Queue Head (QH). */  struct QH { diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 6fe2c39bce8..545ebf4b502 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -76,7 +76,7 @@ void musb_start(void)   * epinfo	- Pointer to EP configuration table   * cnt		- Number of entries in the EP conf table.   */ -void musb_configure_ep(struct musb_epinfo *epinfo, u8 cnt) +void musb_configure_ep(const struct musb_epinfo *epinfo, u8 cnt)  {  	u16 csr;  	u16 fifoaddr = 64; /* First 64 bytes of FIFO reserved for EP0 */ diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index 8f73876f806..a8adcce00fa 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -357,7 +357,7 @@ extern struct musb_regs		*musbr;  /* exported functions */  extern void musb_start(void); -extern void musb_configure_ep(struct musb_epinfo *epinfo, u8 cnt); +extern void musb_configure_ep(const struct musb_epinfo *epinfo, u8 cnt);  extern void write_fifo(u8 ep, u32 length, void *fifo_data);  extern void read_fifo(u8 ep, u32 length, void *fifo_data); diff --git a/drivers/usb/musb/musb_hcd.c b/drivers/usb/musb/musb_hcd.c index f38b279096c..8b0c61d6426 100644 --- a/drivers/usb/musb/musb_hcd.c +++ b/drivers/usb/musb/musb_hcd.c @@ -29,7 +29,7 @@  #define USB_MSC_BBB_GET_MAX_LUN	0xFE  /* Endpoint configuration information */ -static struct musb_epinfo epinfo[3] = { +static const struct musb_epinfo epinfo[3] = {  	{MUSB_BULK_EP, 1, 512}, /* EP1 - Bluk Out - 512 Bytes */  	{MUSB_BULK_EP, 0, 512}, /* EP1 - Bluk In  - 512 Bytes */  	{MUSB_INTR_EP, 0, 64}   /* EP2 - Interrupt IN - 64 Bytes */ @@ -41,7 +41,7 @@ static int rh_devnum;  static u32 port_status;  /* Device descriptor */ -static u8 root_hub_dev_des[] = { +static const u8 root_hub_dev_des[] = {  	0x12,			/*  __u8  bLength; */  	0x01,			/*  __u8  bDescriptorType; Device */  	0x00,			/*  __u16 bcdUSB; v1.1 */ @@ -63,7 +63,7 @@ static u8 root_hub_dev_des[] = {  };  /* Configuration descriptor */ -static u8 root_hub_config_des[] = { +static const u8 root_hub_config_des[] = {  	0x09,			/*  __u8  bLength; */  	0x02,			/*  __u8  bDescriptorType; Configuration */  	0x19,			/*  __u16 wTotalLength; */ @@ -96,14 +96,14 @@ static u8 root_hub_config_des[] = {  	0xff			/*  __u8  ep_bInterval; 255 ms */  }; -static unsigned char root_hub_str_index0[] = { +static const unsigned char root_hub_str_index0[] = {  	0x04,			/*  __u8  bLength; */  	0x03,			/*  __u8  bDescriptorType; String-descriptor */  	0x09,			/*  __u8  lang ID */  	0x04,			/*  __u8  lang ID */  }; -static unsigned char root_hub_str_index1[] = { +static const unsigned char root_hub_str_index1[] = {  	0x1c,			/*  __u8  bLength; */  	0x03,			/*  __u8  bDescriptorType; String-descriptor */  	'M',			/*  __u8  Unicode */ @@ -557,7 +557,7 @@ static int musb_submit_rh_msg(struct usb_device *dev, unsigned long pipe,  	int len = 0;  	int stat = 0;  	u32 datab[4]; -	u8 *data_buf = (u8 *) datab; +	const u8 *data_buf = (u8 *) datab;  	u16 bmRType_bReq;  	u16 wValue;  	u16 wIndex; @@ -778,25 +778,27 @@ static int musb_submit_rh_msg(struct usb_device *dev, unsigned long pipe,  		break; -	case RH_GET_DESCRIPTOR | RH_CLASS: +	case RH_GET_DESCRIPTOR | RH_CLASS: { +		u8 *_data_buf = (u8 *) datab;  		debug("RH_GET_DESCRIPTOR | RH_CLASS\n"); -		data_buf[0] = 0x09;	/* min length; */ -		data_buf[1] = 0x29; -		data_buf[2] = 0x1;	/* 1 port */ -		data_buf[3] = 0x01;	/* per-port power switching */ -		data_buf[3] |= 0x10;	/* no overcurrent reporting */ +		_data_buf[0] = 0x09;	/* min length; */ +		_data_buf[1] = 0x29; +		_data_buf[2] = 0x1;	/* 1 port */ +		_data_buf[3] = 0x01;	/* per-port power switching */ +		_data_buf[3] |= 0x10;	/* no overcurrent reporting */  		/* Corresponds to data_buf[4-7] */ -		data_buf[4] = 0; -		data_buf[5] = 5; -		data_buf[6] = 0; -		data_buf[7] = 0x02; -		data_buf[8] = 0xff; +		_data_buf[4] = 0; +		_data_buf[5] = 5; +		_data_buf[6] = 0; +		_data_buf[7] = 0x02; +		_data_buf[8] = 0xff;  		len = min_t(unsigned int, leni,  			    min_t(unsigned int, data_buf[0], wLength));  		break; +	}  	case RH_GET_CONFIGURATION:  		debug("RH_GET_CONFIGURATION\n"); diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 4be82e73960..5b7b2612686 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -34,6 +34,7 @@ COBJS-$(CONFIG_VIDEO_CT69000) += ct69000.o videomodes.o  COBJS-$(CONFIG_VIDEO_MB862xx) += mb862xx.o videomodes.o  COBJS-$(CONFIG_VIDEO_MB86R0xGDC) += mb86r0xgdc.o videomodes.o  COBJS-$(CONFIG_VIDEO_MX3) += mx3fb.o +COBJS-$(CONFIG_VIDEO_MX5) += mxc_ipuv3_fb.o ipu_common.o ipu_disp.o  COBJS-$(CONFIG_VIDEO_SED13806) += sed13806.o  COBJS-$(CONFIG_SED156X) += sed156x.o  COBJS-$(CONFIG_VIDEO_SM501) += sm501.o diff --git a/drivers/video/ipu.h b/drivers/video/ipu.h new file mode 100644 index 00000000000..d8bc287d841 --- /dev/null +++ b/drivers/video/ipu.h @@ -0,0 +1,321 @@ +/* + * Porting to u-boot: + * + * (C) Copyright 2010 + * Stefano Babic, DENX Software Engineering, sbabic@denx.de + * + * Linux IPU driver for MX51: + * + * (C) Copyright 2005-2010 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __ASM_ARCH_IPU_H__ +#define __ASM_ARCH_IPU_H__ + +#include <linux/types.h> + +#define IDMA_CHAN_INVALID	0xFF +#define HIGH_RESOLUTION_WIDTH	1024 + +struct clk { +	const char *name; +	int id; +	/* Source clock this clk depends on */ +	struct clk *parent; +	/* Secondary clock to enable/disable with this clock */ +	struct clk *secondary; +	/* Current clock rate */ +	unsigned long rate; +	/* Reference count of clock enable/disable */ +	__s8 usecount; +	/* Register bit position for clock's enable/disable control. */ +	u8 enable_shift; +	/* Register address for clock's enable/disable control. */ +	void *enable_reg; +	u32 flags; +	/* +	 * Function ptr to recalculate the clock's rate based on parent +	 * clock's rate +	 */ +	void (*recalc) (struct clk *); +	/* +	 * Function ptr to set the clock to a new rate. The rate must match a +	 * supported rate returned from round_rate. Leave blank if clock is not +	* programmable +	 */ +	int (*set_rate) (struct clk *, unsigned long); +	/* +	 * Function ptr to round the requested clock rate to the nearest +	 * supported rate that is less than or equal to the requested rate. +	 */ +	unsigned long (*round_rate) (struct clk *, unsigned long); +	/* +	 * Function ptr to enable the clock. Leave blank if clock can not +	 * be gated. +	 */ +	int (*enable) (struct clk *); +	/* +	 * Function ptr to disable the clock. Leave blank if clock can not +	 * be gated. +	 */ +	void (*disable) (struct clk *); +	/* Function ptr to set the parent clock of the clock. */ +	int (*set_parent) (struct clk *, struct clk *); +}; + +/* + * Enumeration of Synchronous (Memory-less) panel types + */ +typedef enum { +	IPU_PANEL_SHARP_TFT, +	IPU_PANEL_TFT, +} ipu_panel_t; + +/*  IPU Pixel format definitions */ +#define fourcc(a, b, c, d)\ +	(((__u32)(a)<<0)|((__u32)(b)<<8)|((__u32)(c)<<16)|((__u32)(d)<<24)) + +/* + * Pixel formats are defined with ASCII FOURCC code. The pixel format codes are + * the same used by V4L2 API. + */ + +#define IPU_PIX_FMT_GENERIC fourcc('I', 'P', 'U', '0') +#define IPU_PIX_FMT_GENERIC_32 fourcc('I', 'P', 'U', '1') +#define IPU_PIX_FMT_LVDS666 fourcc('L', 'V', 'D', '6') +#define IPU_PIX_FMT_LVDS888 fourcc('L', 'V', 'D', '8') + +#define IPU_PIX_FMT_RGB332  fourcc('R', 'G', 'B', '1')	/*<  8  RGB-3-3-2    */ +#define IPU_PIX_FMT_RGB555  fourcc('R', 'G', 'B', 'O')	/*< 16  RGB-5-5-5    */ +#define IPU_PIX_FMT_RGB565  fourcc('R', 'G', 'B', 'P')	/*< 1 6  RGB-5-6-5   */ +#define IPU_PIX_FMT_RGB666  fourcc('R', 'G', 'B', '6')	/*< 18  RGB-6-6-6    */ +#define IPU_PIX_FMT_BGR666  fourcc('B', 'G', 'R', '6')	/*< 18  BGR-6-6-6    */ +#define IPU_PIX_FMT_BGR24   fourcc('B', 'G', 'R', '3')	/*< 24  BGR-8-8-8    */ +#define IPU_PIX_FMT_RGB24   fourcc('R', 'G', 'B', '3')	/*< 24  RGB-8-8-8    */ +#define IPU_PIX_FMT_BGR32   fourcc('B', 'G', 'R', '4')	/*< 32  BGR-8-8-8-8  */ +#define IPU_PIX_FMT_BGRA32  fourcc('B', 'G', 'R', 'A')	/*< 32  BGR-8-8-8-8  */ +#define IPU_PIX_FMT_RGB32   fourcc('R', 'G', 'B', '4')	/*< 32  RGB-8-8-8-8  */ +#define IPU_PIX_FMT_RGBA32  fourcc('R', 'G', 'B', 'A')	/*< 32  RGB-8-8-8-8  */ +#define IPU_PIX_FMT_ABGR32  fourcc('A', 'B', 'G', 'R')	/*< 32  ABGR-8-8-8-8 */ + +/* YUV Interleaved Formats */ +#define IPU_PIX_FMT_YUYV    fourcc('Y', 'U', 'Y', 'V')	/*< 16 YUV 4:2:2 */ +#define IPU_PIX_FMT_UYVY    fourcc('U', 'Y', 'V', 'Y')	/*< 16 YUV 4:2:2 */ +#define IPU_PIX_FMT_Y41P    fourcc('Y', '4', '1', 'P')	/*< 12 YUV 4:1:1 */ +#define IPU_PIX_FMT_YUV444  fourcc('Y', '4', '4', '4')	/*< 24 YUV 4:4:4 */ + +/* two planes -- one Y, one Cb + Cr interleaved  */ +#define IPU_PIX_FMT_NV12    fourcc('N', 'V', '1', '2') /* 12  Y/CbCr 4:2:0  */ + +#define IPU_PIX_FMT_GREY    fourcc('G', 'R', 'E', 'Y')	/*< 8  Greyscale */ +#define IPU_PIX_FMT_YVU410P fourcc('Y', 'V', 'U', '9')	/*< 9  YVU 4:1:0 */ +#define IPU_PIX_FMT_YUV410P fourcc('Y', 'U', 'V', '9')	/*< 9  YUV 4:1:0 */ +#define IPU_PIX_FMT_YVU420P fourcc('Y', 'V', '1', '2')	/*< 12 YVU 4:2:0 */ +#define IPU_PIX_FMT_YUV420P fourcc('I', '4', '2', '0')	/*< 12 YUV 4:2:0 */ +#define IPU_PIX_FMT_YUV420P2 fourcc('Y', 'U', '1', '2')	/*< 12 YUV 4:2:0 */ +#define IPU_PIX_FMT_YVU422P fourcc('Y', 'V', '1', '6')	/*< 16 YVU 4:2:2 */ +#define IPU_PIX_FMT_YUV422P fourcc('4', '2', '2', 'P')	/*< 16 YUV 4:2:2 */ + +/* + * IPU Driver channels definitions. + * Note these are different from IDMA channels + */ +#define IPU_MAX_CH	32 +#define _MAKE_CHAN(num, v_in, g_in, a_in, out) \ +	((num << 24) | (v_in << 18) | (g_in << 12) | (a_in << 6) | out) +#define _MAKE_ALT_CHAN(ch)		(ch | (IPU_MAX_CH << 24)) +#define IPU_CHAN_ID(ch)			(ch >> 24) +#define IPU_CHAN_ALT(ch)		(ch & 0x02000000) +#define IPU_CHAN_ALPHA_IN_DMA(ch)	((uint32_t) (ch >> 6) & 0x3F) +#define IPU_CHAN_GRAPH_IN_DMA(ch)	((uint32_t) (ch >> 12) & 0x3F) +#define IPU_CHAN_VIDEO_IN_DMA(ch)	((uint32_t) (ch >> 18) & 0x3F) +#define IPU_CHAN_OUT_DMA(ch)		((uint32_t) (ch & 0x3F)) +#define NO_DMA 0x3F +#define ALT	1 + +/* + * Enumeration of IPU logical channels. An IPU logical channel is defined as a + * combination of an input (memory to IPU), output (IPU to memory), and/or + * secondary input IDMA channels and in some cases an Image Converter task. + * Some channels consist of only an input or output. + */ +typedef enum { +	CHAN_NONE = -1, + +	MEM_DC_SYNC = _MAKE_CHAN(7, 28, NO_DMA, NO_DMA, NO_DMA), +	MEM_DC_ASYNC = _MAKE_CHAN(8, 41, NO_DMA, NO_DMA, NO_DMA), +	MEM_BG_SYNC = _MAKE_CHAN(9, 23, NO_DMA, 51, NO_DMA), +	MEM_FG_SYNC = _MAKE_CHAN(10, 27, NO_DMA, 31, NO_DMA), + +	MEM_BG_ASYNC0 = _MAKE_CHAN(11, 24, NO_DMA, 52, NO_DMA), +	MEM_FG_ASYNC0 = _MAKE_CHAN(12, 29, NO_DMA, 33, NO_DMA), +	MEM_BG_ASYNC1 = _MAKE_ALT_CHAN(MEM_BG_ASYNC0), +	MEM_FG_ASYNC1 = _MAKE_ALT_CHAN(MEM_FG_ASYNC0), + +	DIRECT_ASYNC0 = _MAKE_CHAN(13, NO_DMA, NO_DMA, NO_DMA, NO_DMA), +	DIRECT_ASYNC1 = _MAKE_CHAN(14, NO_DMA, NO_DMA, NO_DMA, NO_DMA), + +} ipu_channel_t; + +/* + * Enumeration of types of buffers for a logical channel. + */ +typedef enum { +	IPU_OUTPUT_BUFFER = 0,	/*< Buffer for output from IPU */ +	IPU_ALPHA_IN_BUFFER = 1,	/*< Buffer for input to IPU */ +	IPU_GRAPH_IN_BUFFER = 2,	/*< Buffer for input to IPU */ +	IPU_VIDEO_IN_BUFFER = 3,	/*< Buffer for input to IPU */ +	IPU_INPUT_BUFFER = IPU_VIDEO_IN_BUFFER, +	IPU_SEC_INPUT_BUFFER = IPU_GRAPH_IN_BUFFER, +} ipu_buffer_t; + +#define IPU_PANEL_SERIAL		1 +#define IPU_PANEL_PARALLEL		2 + +struct ipu_channel { +	u8 video_in_dma; +	u8 alpha_in_dma; +	u8 graph_in_dma; +	u8 out_dma; +}; + +enum ipu_dmfc_type { +	DMFC_NORMAL = 0, +	DMFC_HIGH_RESOLUTION_DC, +	DMFC_HIGH_RESOLUTION_DP, +	DMFC_HIGH_RESOLUTION_ONLY_DP, +}; + + +/* + * Union of initialization parameters for a logical channel. + */ +typedef union { +	struct { +		uint32_t di; +		unsigned char interlaced; +	} mem_dc_sync; +	struct { +		uint32_t temp; +	} mem_sdc_fg; +	struct { +		uint32_t di; +		unsigned char interlaced; +		uint32_t in_pixel_fmt; +		uint32_t out_pixel_fmt; +		unsigned char alpha_chan_en; +	} mem_dp_bg_sync; +	struct { +		uint32_t temp; +	} mem_sdc_bg; +	struct { +		uint32_t di; +		unsigned char interlaced; +		uint32_t in_pixel_fmt; +		uint32_t out_pixel_fmt; +		unsigned char alpha_chan_en; +	} mem_dp_fg_sync; +} ipu_channel_params_t; + +/* + * Bitfield of Display Interface signal polarities. + */ +typedef struct { +	unsigned datamask_en:1; +	unsigned ext_clk:1; +	unsigned interlaced:1; +	unsigned odd_field_first:1; +	unsigned clksel_en:1; +	unsigned clkidle_en:1; +	unsigned data_pol:1;	/* true = inverted */ +	unsigned clk_pol:1;	/* true = rising edge */ +	unsigned enable_pol:1; +	unsigned Hsync_pol:1;	/* true = active high */ +	unsigned Vsync_pol:1; +} ipu_di_signal_cfg_t; + +typedef enum { +	RGB, +	YCbCr, +	YUV +} ipu_color_space_t; + +/* Common IPU API */ +int32_t ipu_init_channel(ipu_channel_t channel, ipu_channel_params_t *params); +void ipu_uninit_channel(ipu_channel_t channel); + +int32_t ipu_init_channel_buffer(ipu_channel_t channel, ipu_buffer_t type, +				uint32_t pixel_fmt, +				uint16_t width, uint16_t height, +				uint32_t stride, +				dma_addr_t phyaddr_0, dma_addr_t phyaddr_1, +				uint32_t u_offset, uint32_t v_offset); + +int32_t ipu_update_channel_buffer(ipu_channel_t channel, ipu_buffer_t type, +				  uint32_t bufNum, dma_addr_t phyaddr); + +int32_t ipu_is_channel_busy(ipu_channel_t channel); +void ipu_clear_buffer_ready(ipu_channel_t channel, ipu_buffer_t type, +		uint32_t bufNum); +int32_t ipu_enable_channel(ipu_channel_t channel); +int32_t ipu_disable_channel(ipu_channel_t channel); + +int32_t ipu_init_sync_panel(int disp, +			    uint32_t pixel_clk, +			    uint16_t width, uint16_t height, +			    uint32_t pixel_fmt, +			    uint16_t h_start_width, uint16_t h_sync_width, +			    uint16_t h_end_width, uint16_t v_start_width, +			    uint16_t v_sync_width, uint16_t v_end_width, +			    uint32_t v_to_h_sync, ipu_di_signal_cfg_t sig); + +int32_t ipu_disp_set_global_alpha(ipu_channel_t channel, unsigned char enable, +				  uint8_t alpha); +int32_t ipu_disp_set_color_key(ipu_channel_t channel, unsigned char enable, +			       uint32_t colorKey); + +uint32_t bytes_per_pixel(uint32_t fmt); + +void clk_enable(struct clk *clk); +void clk_disable(struct clk *clk); +u32 clk_get_rate(struct clk *clk); +int clk_set_rate(struct clk *clk, unsigned long rate); +long clk_round_rate(struct clk *clk, unsigned long rate); +int clk_set_parent(struct clk *clk, struct clk *parent); +int clk_get_usecount(struct clk *clk); +struct clk *clk_get_parent(struct clk *clk); + +void ipu_dump_registers(void); +int ipu_probe(void); + +void ipu_dmfc_init(int dmfc_type, int first); +void ipu_init_dc_mappings(void); +void ipu_dmfc_set_wait4eot(int dma_chan, int width); +void ipu_dc_init(int dc_chan, int di, unsigned char interlaced); +void ipu_dc_uninit(int dc_chan); +void ipu_dp_dc_enable(ipu_channel_t channel); +int ipu_dp_init(ipu_channel_t channel, uint32_t in_pixel_fmt, +		 uint32_t out_pixel_fmt); +void ipu_dp_uninit(ipu_channel_t channel); +void ipu_dp_dc_disable(ipu_channel_t channel, unsigned char swap); +ipu_color_space_t format_to_colorspace(uint32_t fmt); + +#endif diff --git a/drivers/video/ipu_common.c b/drivers/video/ipu_common.c new file mode 100644 index 00000000000..9d20c864bac --- /dev/null +++ b/drivers/video/ipu_common.c @@ -0,0 +1,1183 @@ +/* + * Porting to u-boot: + * + * (C) Copyright 2010 + * Stefano Babic, DENX Software Engineering, sbabic@denx.de + * + * Linux IPU driver for MX51: + * + * (C) Copyright 2005-2010 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* #define DEBUG */ +#include <common.h> +#include <linux/types.h> +#include <linux/err.h> +#include <asm/io.h> +#include <asm/errno.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/crm_regs.h> +#include "ipu.h" +#include "ipu_regs.h" + +extern struct mxc_ccm_reg *mxc_ccm; +extern u32 *ipu_cpmem_base; + +struct ipu_ch_param_word { +	uint32_t data[5]; +	uint32_t res[3]; +}; + +struct ipu_ch_param { +	struct ipu_ch_param_word word[2]; +}; + +#define ipu_ch_param_addr(ch) (((struct ipu_ch_param *)ipu_cpmem_base) + (ch)) + +#define _param_word(base, w) \ +	(((struct ipu_ch_param *)(base))->word[(w)].data) + +#define ipu_ch_param_set_field(base, w, bit, size, v) { \ +	int i = (bit) / 32; \ +	int off = (bit) % 32; \ +	_param_word(base, w)[i] |= (v) << off; \ +	if (((bit) + (size) - 1) / 32 > i) { \ +		_param_word(base, w)[i + 1] |= (v) >> (off ? (32 - off) : 0); \ +	} \ +} + +#define ipu_ch_param_mod_field(base, w, bit, size, v) { \ +	int i = (bit) / 32; \ +	int off = (bit) % 32; \ +	u32 mask = (1UL << size) - 1; \ +	u32 temp = _param_word(base, w)[i]; \ +	temp &= ~(mask << off); \ +	_param_word(base, w)[i] = temp | (v) << off; \ +	if (((bit) + (size) - 1) / 32 > i) { \ +		temp = _param_word(base, w)[i + 1]; \ +		temp &= ~(mask >> (32 - off)); \ +		_param_word(base, w)[i + 1] = \ +			temp | ((v) >> (off ? (32 - off) : 0)); \ +	} \ +} + +#define ipu_ch_param_read_field(base, w, bit, size) ({ \ +	u32 temp2; \ +	int i = (bit) / 32; \ +	int off = (bit) % 32; \ +	u32 mask = (1UL << size) - 1; \ +	u32 temp1 = _param_word(base, w)[i]; \ +	temp1 = mask & (temp1 >> off); \ +	if (((bit)+(size) - 1) / 32 > i) { \ +		temp2 = _param_word(base, w)[i + 1]; \ +		temp2 &= mask >> (off ? (32 - off) : 0); \ +		temp1 |= temp2 << (off ? (32 - off) : 0); \ +	} \ +	temp1; \ +}) + + +void clk_enable(struct clk *clk) +{ +	if (clk) { +		if (clk->usecount++ == 0) { +			clk->enable(clk); +		} +	} +} + +void clk_disable(struct clk *clk) +{ +	if (clk) { +		if (!(--clk->usecount)) { +			if (clk->disable) +				clk->disable(clk); +		} +	} +} + +int clk_get_usecount(struct clk *clk) +{ +	if (clk == NULL) +		return 0; + +	return clk->usecount; +} + +u32 clk_get_rate(struct clk *clk) +{ +	if (!clk) +		return 0; + +	return clk->rate; +} + +struct clk *clk_get_parent(struct clk *clk) +{ +	if (!clk) +		return 0; + +	return clk->parent; +} + +int clk_set_rate(struct clk *clk, unsigned long rate) +{ +	if (clk && clk->set_rate) +		clk->set_rate(clk, rate); +	return clk->rate; +} + +long clk_round_rate(struct clk *clk, unsigned long rate) +{ +	if (clk == NULL || !clk->round_rate) +		return 0; + +	return clk->round_rate(clk, rate); +} + +int clk_set_parent(struct clk *clk, struct clk *parent) +{ +	clk->parent = parent; +	if (clk->set_parent) +		return clk->set_parent(clk, parent); +	return 0; +} + +static int clk_ipu_enable(struct clk *clk) +{ +	u32 reg; + +	reg = __raw_readl(clk->enable_reg); +	reg |= MXC_CCM_CCGR_CG_MASK << clk->enable_shift; +	__raw_writel(reg, clk->enable_reg); + +	/* Handshake with IPU when certain clock rates are changed. */ +	reg = __raw_readl(&mxc_ccm->ccdr); +	reg &= ~MXC_CCM_CCDR_IPU_HS_MASK; +	__raw_writel(reg, &mxc_ccm->ccdr); + +	/* Handshake with IPU when LPM is entered as its enabled. */ +	reg = __raw_readl(&mxc_ccm->clpcr); +	reg &= ~MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS; +	__raw_writel(reg, &mxc_ccm->clpcr); + +	return 0; +} + +static void clk_ipu_disable(struct clk *clk) +{ +	u32 reg; + +	reg = __raw_readl(clk->enable_reg); +	reg &= ~(MXC_CCM_CCGR_CG_MASK << clk->enable_shift); +	__raw_writel(reg, clk->enable_reg); + +	/* +	 * No handshake with IPU whe dividers are changed +	 * as its not enabled. +	 */ +	reg = __raw_readl(&mxc_ccm->ccdr); +	reg |= MXC_CCM_CCDR_IPU_HS_MASK; +	__raw_writel(reg, &mxc_ccm->ccdr); + +	/* No handshake with IPU when LPM is entered as its not enabled. */ +	reg = __raw_readl(&mxc_ccm->clpcr); +	reg |= MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS; +	__raw_writel(reg, &mxc_ccm->clpcr); +} + + +static struct clk ipu_clk = { +	.name = "ipu_clk", +	.rate = 133000000, +	.enable_reg = (u32 *)(MXC_CCM_BASE + +		offsetof(struct mxc_ccm_reg, CCGR5)), +	.enable_shift = MXC_CCM_CCGR5_CG5_OFFSET, +	.enable = clk_ipu_enable, +	.disable = clk_ipu_disable, +	.usecount = 0, +}; + +/* Globals */ +struct clk *g_ipu_clk; +unsigned char g_ipu_clk_enabled; +struct clk *g_di_clk[2]; +struct clk *g_pixel_clk[2]; +unsigned char g_dc_di_assignment[10]; +uint32_t g_channel_init_mask; +uint32_t g_channel_enable_mask; + +static int ipu_dc_use_count; +static int ipu_dp_use_count; +static int ipu_dmfc_use_count; +static int ipu_di_use_count[2]; + +u32 *ipu_cpmem_base; +u32 *ipu_dc_tmpl_reg; + +/* Static functions */ + +static inline void ipu_ch_param_set_high_priority(uint32_t ch) +{ +	ipu_ch_param_mod_field(ipu_ch_param_addr(ch), 1, 93, 2, 1); +}; + +static inline uint32_t channel_2_dma(ipu_channel_t ch, ipu_buffer_t type) +{ +	return ((uint32_t) ch >> (6 * type)) & 0x3F; +}; + +/* Either DP BG or DP FG can be graphic window */ +static inline int ipu_is_dp_graphic_chan(uint32_t dma_chan) +{ +	return (dma_chan == 23 || dma_chan == 27); +} + +static inline int ipu_is_dmfc_chan(uint32_t dma_chan) +{ +	return ((dma_chan >= 23) && (dma_chan <= 29)); +} + + +static inline void ipu_ch_param_set_buffer(uint32_t ch, int bufNum, +					    dma_addr_t phyaddr) +{ +	ipu_ch_param_mod_field(ipu_ch_param_addr(ch), 1, 29 * bufNum, 29, +			       phyaddr / 8); +}; + +#define idma_is_valid(ch)	(ch != NO_DMA) +#define idma_mask(ch)		(idma_is_valid(ch) ? (1UL << (ch & 0x1F)) : 0) +#define idma_is_set(reg, dma)	(__raw_readl(reg(dma)) & idma_mask(dma)) + +static void ipu_pixel_clk_recalc(struct clk *clk) +{ +	u32 div = __raw_readl(DI_BS_CLKGEN0(clk->id)); +	if (div == 0) +		clk->rate = 0; +	else +		clk->rate = (clk->parent->rate * 16) / div; +} + +static unsigned long ipu_pixel_clk_round_rate(struct clk *clk, +	unsigned long rate) +{ +	u32 div, div1; +	u32 tmp; +	/* +	 * Calculate divider +	 * Fractional part is 4 bits, +	 * so simply multiply by 2^4 to get fractional part. +	 */ +	tmp = (clk->parent->rate * 16); +	div = tmp / rate; + +	if (div < 0x10)            /* Min DI disp clock divider is 1 */ +		div = 0x10; +	if (div & ~0xFEF) +		div &= 0xFF8; +	else { +		div1 = div & 0xFE0; +		if ((tmp/div1 - tmp/div) < rate / 4) +			div = div1; +		else +			div &= 0xFF8; +	} +	return (clk->parent->rate * 16) / div; +} + +static int ipu_pixel_clk_set_rate(struct clk *clk, unsigned long rate) +{ +	u32 div = (clk->parent->rate * 16) / rate; + +	__raw_writel(div, DI_BS_CLKGEN0(clk->id)); + +	/* Setup pixel clock timing */ +	__raw_writel((div / 16) << 16, DI_BS_CLKGEN1(clk->id)); + +	clk->rate = (clk->parent->rate * 16) / div; +	return 0; +} + +static int ipu_pixel_clk_enable(struct clk *clk) +{ +	u32 disp_gen = __raw_readl(IPU_DISP_GEN); +	disp_gen |= clk->id ? DI1_COUNTER_RELEASE : DI0_COUNTER_RELEASE; +	__raw_writel(disp_gen, IPU_DISP_GEN); + +	return 0; +} + +static void ipu_pixel_clk_disable(struct clk *clk) +{ +	u32 disp_gen = __raw_readl(IPU_DISP_GEN); +	disp_gen &= clk->id ? ~DI1_COUNTER_RELEASE : ~DI0_COUNTER_RELEASE; +	__raw_writel(disp_gen, IPU_DISP_GEN); + +} + +static int ipu_pixel_clk_set_parent(struct clk *clk, struct clk *parent) +{ +	u32 di_gen = __raw_readl(DI_GENERAL(clk->id)); + +	if (parent == g_ipu_clk) +		di_gen &= ~DI_GEN_DI_CLK_EXT; +	else if (!IS_ERR(g_di_clk[clk->id]) && parent == g_di_clk[clk->id]) +		di_gen |= DI_GEN_DI_CLK_EXT; +	else +		return -EINVAL; + +	__raw_writel(di_gen, DI_GENERAL(clk->id)); +	ipu_pixel_clk_recalc(clk); +	return 0; +} + +static struct clk pixel_clk[] = { +	{ +	.name = "pixel_clk", +	.id = 0, +	.recalc = ipu_pixel_clk_recalc, +	.set_rate = ipu_pixel_clk_set_rate, +	.round_rate = ipu_pixel_clk_round_rate, +	.set_parent = ipu_pixel_clk_set_parent, +	.enable = ipu_pixel_clk_enable, +	.disable = ipu_pixel_clk_disable, +	.usecount = 0, +	}, +	{ +	.name = "pixel_clk", +	.id = 1, +	.recalc = ipu_pixel_clk_recalc, +	.set_rate = ipu_pixel_clk_set_rate, +	.round_rate = ipu_pixel_clk_round_rate, +	.set_parent = ipu_pixel_clk_set_parent, +	.enable = ipu_pixel_clk_enable, +	.disable = ipu_pixel_clk_disable, +	.usecount = 0, +	}, +}; + +/* + * This function resets IPU + */ +void ipu_reset(void) +{ +	u32 *reg; +	u32 value; + +	reg = (u32 *)SRC_BASE_ADDR; +	value = __raw_readl(reg); +	value = value | SW_IPU_RST; +	__raw_writel(value, reg); +} + +/* + * This function is called by the driver framework to initialize the IPU + * hardware. + * + * @param	dev	The device structure for the IPU passed in by the + *			driver framework. + * + * @return      Returns 0 on success or negative error code on error + */ +int ipu_probe(void) +{ +	unsigned long ipu_base; +	u32 temp; + +	u32 *reg_hsc_mcd = (u32 *)MIPI_HSC_BASE_ADDR; +	u32 *reg_hsc_mxt_conf = (u32 *)(MIPI_HSC_BASE_ADDR + 0x800); + +	 __raw_writel(0xF00, reg_hsc_mcd); + +	/* CSI mode reserved*/ +	temp = __raw_readl(reg_hsc_mxt_conf); +	 __raw_writel(temp | 0x0FF, reg_hsc_mxt_conf); + +	temp = __raw_readl(reg_hsc_mxt_conf); +	__raw_writel(temp | 0x10000, reg_hsc_mxt_conf); + +	ipu_base = IPU_CTRL_BASE_ADDR; +	ipu_cpmem_base = (u32 *)(ipu_base + IPU_CPMEM_REG_BASE); +	ipu_dc_tmpl_reg = (u32 *)(ipu_base + IPU_DC_TMPL_REG_BASE); + +	g_pixel_clk[0] = &pixel_clk[0]; +	g_pixel_clk[1] = &pixel_clk[1]; + +	g_ipu_clk = &ipu_clk; +	debug("ipu_clk = %u\n", clk_get_rate(g_ipu_clk)); + +	ipu_reset(); + +	clk_set_parent(g_pixel_clk[0], g_ipu_clk); +	clk_set_parent(g_pixel_clk[1], g_ipu_clk); +	clk_enable(g_ipu_clk); + +	g_di_clk[0] = NULL; +	g_di_clk[1] = NULL; + +	__raw_writel(0x807FFFFF, IPU_MEM_RST); +	while (__raw_readl(IPU_MEM_RST) & 0x80000000) +		; + +	ipu_init_dc_mappings(); + +	__raw_writel(0, IPU_INT_CTRL(5)); +	__raw_writel(0, IPU_INT_CTRL(6)); +	__raw_writel(0, IPU_INT_CTRL(9)); +	__raw_writel(0, IPU_INT_CTRL(10)); + +	/* DMFC Init */ +	ipu_dmfc_init(DMFC_NORMAL, 1); + +	/* Set sync refresh channels as high priority */ +	__raw_writel(0x18800000L, IDMAC_CHA_PRI(0)); + +	/* Set MCU_T to divide MCU access window into 2 */ +	__raw_writel(0x00400000L | (IPU_MCU_T_DEFAULT << 18), IPU_DISP_GEN); + +	clk_disable(g_ipu_clk); + +	return 0; +} + +void ipu_dump_registers(void) +{ +	debug("IPU_CONF = \t0x%08X\n", __raw_readl(IPU_CONF)); +	debug("IDMAC_CONF = \t0x%08X\n", __raw_readl(IDMAC_CONF)); +	debug("IDMAC_CHA_EN1 = \t0x%08X\n", +	       __raw_readl(IDMAC_CHA_EN(0))); +	debug("IDMAC_CHA_EN2 = \t0x%08X\n", +	       __raw_readl(IDMAC_CHA_EN(32))); +	debug("IDMAC_CHA_PRI1 = \t0x%08X\n", +	       __raw_readl(IDMAC_CHA_PRI(0))); +	debug("IDMAC_CHA_PRI2 = \t0x%08X\n", +	       __raw_readl(IDMAC_CHA_PRI(32))); +	debug("IPU_CHA_DB_MODE_SEL0 = \t0x%08X\n", +	       __raw_readl(IPU_CHA_DB_MODE_SEL(0))); +	debug("IPU_CHA_DB_MODE_SEL1 = \t0x%08X\n", +	       __raw_readl(IPU_CHA_DB_MODE_SEL(32))); +	debug("DMFC_WR_CHAN = \t0x%08X\n", +	       __raw_readl(DMFC_WR_CHAN)); +	debug("DMFC_WR_CHAN_DEF = \t0x%08X\n", +	       __raw_readl(DMFC_WR_CHAN_DEF)); +	debug("DMFC_DP_CHAN = \t0x%08X\n", +	       __raw_readl(DMFC_DP_CHAN)); +	debug("DMFC_DP_CHAN_DEF = \t0x%08X\n", +	       __raw_readl(DMFC_DP_CHAN_DEF)); +	debug("DMFC_IC_CTRL = \t0x%08X\n", +	       __raw_readl(DMFC_IC_CTRL)); +	debug("IPU_FS_PROC_FLOW1 = \t0x%08X\n", +	       __raw_readl(IPU_FS_PROC_FLOW1)); +	debug("IPU_FS_PROC_FLOW2 = \t0x%08X\n", +	       __raw_readl(IPU_FS_PROC_FLOW2)); +	debug("IPU_FS_PROC_FLOW3 = \t0x%08X\n", +	       __raw_readl(IPU_FS_PROC_FLOW3)); +	debug("IPU_FS_DISP_FLOW1 = \t0x%08X\n", +	       __raw_readl(IPU_FS_DISP_FLOW1)); +} + +/* + * This function is called to initialize a logical IPU channel. + * + * @param       channel Input parameter for the logical channel ID to init. + * + * @param       params  Input parameter containing union of channel + *                      initialization parameters. + * + * @return      Returns 0 on success or negative error code on fail + */ +int32_t ipu_init_channel(ipu_channel_t channel, ipu_channel_params_t *params) +{ +	int ret = 0; +	uint32_t ipu_conf; + +	debug("init channel = %d\n", IPU_CHAN_ID(channel)); + +	if (g_ipu_clk_enabled == 0) { +		g_ipu_clk_enabled = 1; +		clk_enable(g_ipu_clk); +	} + + +	if (g_channel_init_mask & (1L << IPU_CHAN_ID(channel))) { +		printf("Warning: channel already initialized %d\n", +			IPU_CHAN_ID(channel)); +	} + +	ipu_conf = __raw_readl(IPU_CONF); + +	switch (channel) { +	case MEM_DC_SYNC: +		if (params->mem_dc_sync.di > 1) { +			ret = -EINVAL; +			goto err; +		} + +		g_dc_di_assignment[1] = params->mem_dc_sync.di; +		ipu_dc_init(1, params->mem_dc_sync.di, +			     params->mem_dc_sync.interlaced); +		ipu_di_use_count[params->mem_dc_sync.di]++; +		ipu_dc_use_count++; +		ipu_dmfc_use_count++; +		break; +	case MEM_BG_SYNC: +		if (params->mem_dp_bg_sync.di > 1) { +			ret = -EINVAL; +			goto err; +		} + +		g_dc_di_assignment[5] = params->mem_dp_bg_sync.di; +		ipu_dp_init(channel, params->mem_dp_bg_sync.in_pixel_fmt, +			     params->mem_dp_bg_sync.out_pixel_fmt); +		ipu_dc_init(5, params->mem_dp_bg_sync.di, +			     params->mem_dp_bg_sync.interlaced); +		ipu_di_use_count[params->mem_dp_bg_sync.di]++; +		ipu_dc_use_count++; +		ipu_dp_use_count++; +		ipu_dmfc_use_count++; +		break; +	case MEM_FG_SYNC: +		ipu_dp_init(channel, params->mem_dp_fg_sync.in_pixel_fmt, +			     params->mem_dp_fg_sync.out_pixel_fmt); + +		ipu_dc_use_count++; +		ipu_dp_use_count++; +		ipu_dmfc_use_count++; +		break; +	default: +		printf("Missing channel initialization\n"); +		break; +	} + +	/* Enable IPU sub module */ +	g_channel_init_mask |= 1L << IPU_CHAN_ID(channel); +	if (ipu_dc_use_count == 1) +		ipu_conf |= IPU_CONF_DC_EN; +	if (ipu_dp_use_count == 1) +		ipu_conf |= IPU_CONF_DP_EN; +	if (ipu_dmfc_use_count == 1) +		ipu_conf |= IPU_CONF_DMFC_EN; +	if (ipu_di_use_count[0] == 1) { +		ipu_conf |= IPU_CONF_DI0_EN; +	} +	if (ipu_di_use_count[1] == 1) { +		ipu_conf |= IPU_CONF_DI1_EN; +	} + +	__raw_writel(ipu_conf, IPU_CONF); + +err: +	return ret; +} + +/* + * This function is called to uninitialize a logical IPU channel. + * + * @param       channel Input parameter for the logical channel ID to uninit. + */ +void ipu_uninit_channel(ipu_channel_t channel) +{ +	uint32_t reg; +	uint32_t in_dma, out_dma = 0; +	uint32_t ipu_conf; + +	if ((g_channel_init_mask & (1L << IPU_CHAN_ID(channel))) == 0) { +		debug("Channel already uninitialized %d\n", +			IPU_CHAN_ID(channel)); +		return; +	} + +	/* +	 * Make sure channel is disabled +	 * Get input and output dma channels +	 */ +	in_dma = channel_2_dma(channel, IPU_OUTPUT_BUFFER); +	out_dma = channel_2_dma(channel, IPU_VIDEO_IN_BUFFER); + +	if (idma_is_set(IDMAC_CHA_EN, in_dma) || +	    idma_is_set(IDMAC_CHA_EN, out_dma)) { +		printf( +			"Channel %d is not disabled, disable first\n", +			IPU_CHAN_ID(channel)); +		return; +	} + +	ipu_conf = __raw_readl(IPU_CONF); + +	/* Reset the double buffer */ +	reg = __raw_readl(IPU_CHA_DB_MODE_SEL(in_dma)); +	__raw_writel(reg & ~idma_mask(in_dma), IPU_CHA_DB_MODE_SEL(in_dma)); +	reg = __raw_readl(IPU_CHA_DB_MODE_SEL(out_dma)); +	__raw_writel(reg & ~idma_mask(out_dma), IPU_CHA_DB_MODE_SEL(out_dma)); + +	switch (channel) { +	case MEM_DC_SYNC: +		ipu_dc_uninit(1); +		ipu_di_use_count[g_dc_di_assignment[1]]--; +		ipu_dc_use_count--; +		ipu_dmfc_use_count--; +		break; +	case MEM_BG_SYNC: +		ipu_dp_uninit(channel); +		ipu_dc_uninit(5); +		ipu_di_use_count[g_dc_di_assignment[5]]--; +		ipu_dc_use_count--; +		ipu_dp_use_count--; +		ipu_dmfc_use_count--; +		break; +	case MEM_FG_SYNC: +		ipu_dp_uninit(channel); +		ipu_dc_use_count--; +		ipu_dp_use_count--; +		ipu_dmfc_use_count--; +		break; +	default: +		break; +	} + +	g_channel_init_mask &= ~(1L << IPU_CHAN_ID(channel)); + +	if (ipu_dc_use_count == 0) +		ipu_conf &= ~IPU_CONF_DC_EN; +	if (ipu_dp_use_count == 0) +		ipu_conf &= ~IPU_CONF_DP_EN; +	if (ipu_dmfc_use_count == 0) +		ipu_conf &= ~IPU_CONF_DMFC_EN; +	if (ipu_di_use_count[0] == 0) { +		ipu_conf &= ~IPU_CONF_DI0_EN; +	} +	if (ipu_di_use_count[1] == 0) { +		ipu_conf &= ~IPU_CONF_DI1_EN; +	} + +	__raw_writel(ipu_conf, IPU_CONF); + +	if (ipu_conf == 0) { +		clk_disable(g_ipu_clk); +		g_ipu_clk_enabled = 0; +	} + +} + +static inline void ipu_ch_param_dump(int ch) +{ +#ifdef DEBUG +	struct ipu_ch_param *p = ipu_ch_param_addr(ch); +	debug("ch %d word 0 - %08X %08X %08X %08X %08X\n", ch, +		 p->word[0].data[0], p->word[0].data[1], p->word[0].data[2], +		 p->word[0].data[3], p->word[0].data[4]); +	debug("ch %d word 1 - %08X %08X %08X %08X %08X\n", ch, +		 p->word[1].data[0], p->word[1].data[1], p->word[1].data[2], +		 p->word[1].data[3], p->word[1].data[4]); +	debug("PFS 0x%x, ", +		 ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 85, 4)); +	debug("BPP 0x%x, ", +		 ipu_ch_param_read_field(ipu_ch_param_addr(ch), 0, 107, 3)); +	debug("NPB 0x%x\n", +		 ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 78, 7)); + +	debug("FW %d, ", +		 ipu_ch_param_read_field(ipu_ch_param_addr(ch), 0, 125, 13)); +	debug("FH %d, ", +		 ipu_ch_param_read_field(ipu_ch_param_addr(ch), 0, 138, 12)); +	debug("Stride %d\n", +		 ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 102, 14)); + +	debug("Width0 %d+1, ", +		 ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 116, 3)); +	debug("Width1 %d+1, ", +		 ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 119, 3)); +	debug("Width2 %d+1, ", +		 ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 122, 3)); +	debug("Width3 %d+1, ", +		 ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 125, 3)); +	debug("Offset0 %d, ", +		 ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 128, 5)); +	debug("Offset1 %d, ", +		 ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 133, 5)); +	debug("Offset2 %d, ", +		 ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 138, 5)); +	debug("Offset3 %d\n", +		 ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 143, 5)); +#endif +} + +static inline void ipu_ch_params_set_packing(struct ipu_ch_param *p, +					      int red_width, int red_offset, +					      int green_width, int green_offset, +					      int blue_width, int blue_offset, +					      int alpha_width, int alpha_offset) +{ +	/* Setup red width and offset */ +	ipu_ch_param_set_field(p, 1, 116, 3, red_width - 1); +	ipu_ch_param_set_field(p, 1, 128, 5, red_offset); +	/* Setup green width and offset */ +	ipu_ch_param_set_field(p, 1, 119, 3, green_width - 1); +	ipu_ch_param_set_field(p, 1, 133, 5, green_offset); +	/* Setup blue width and offset */ +	ipu_ch_param_set_field(p, 1, 122, 3, blue_width - 1); +	ipu_ch_param_set_field(p, 1, 138, 5, blue_offset); +	/* Setup alpha width and offset */ +	ipu_ch_param_set_field(p, 1, 125, 3, alpha_width - 1); +	ipu_ch_param_set_field(p, 1, 143, 5, alpha_offset); +} + +static void ipu_ch_param_init(int ch, +			      uint32_t pixel_fmt, uint32_t width, +			      uint32_t height, uint32_t stride, +			      uint32_t u, uint32_t v, +			      uint32_t uv_stride, dma_addr_t addr0, +			      dma_addr_t addr1) +{ +	uint32_t u_offset = 0; +	uint32_t v_offset = 0; +	struct ipu_ch_param params; + +	memset(¶ms, 0, sizeof(params)); + +	ipu_ch_param_set_field(¶ms, 0, 125, 13, width - 1); + +	if ((ch == 8) || (ch == 9) || (ch == 10)) { +		ipu_ch_param_set_field(¶ms, 0, 138, 12, (height / 2) - 1); +		ipu_ch_param_set_field(¶ms, 1, 102, 14, (stride * 2) - 1); +	} else { +		ipu_ch_param_set_field(¶ms, 0, 138, 12, height - 1); +		ipu_ch_param_set_field(¶ms, 1, 102, 14, stride - 1); +	} + +	ipu_ch_param_set_field(¶ms, 1, 0, 29, addr0 >> 3); +	ipu_ch_param_set_field(¶ms, 1, 29, 29, addr1 >> 3); + +	switch (pixel_fmt) { +	case IPU_PIX_FMT_GENERIC: +		/*Represents 8-bit Generic data */ +		ipu_ch_param_set_field(¶ms, 0, 107, 3, 5);	/* bits/pixel */ +		ipu_ch_param_set_field(¶ms, 1, 85, 4, 6);	/* pix format */ +		ipu_ch_param_set_field(¶ms, 1, 78, 7, 63);	/* burst size */ + +		break; +	case IPU_PIX_FMT_GENERIC_32: +		/*Represents 32-bit Generic data */ +		break; +	case IPU_PIX_FMT_RGB565: +		ipu_ch_param_set_field(¶ms, 0, 107, 3, 3);	/* bits/pixel */ +		ipu_ch_param_set_field(¶ms, 1, 85, 4, 7);	/* pix format */ +		ipu_ch_param_set_field(¶ms, 1, 78, 7, 15);	/* burst size */ + +		ipu_ch_params_set_packing(¶ms, 5, 0, 6, 5, 5, 11, 8, 16); +		break; +	case IPU_PIX_FMT_BGR24: +		ipu_ch_param_set_field(¶ms, 0, 107, 3, 1);	/* bits/pixel */ +		ipu_ch_param_set_field(¶ms, 1, 85, 4, 7);	/* pix format */ +		ipu_ch_param_set_field(¶ms, 1, 78, 7, 19);	/* burst size */ + +		ipu_ch_params_set_packing(¶ms, 8, 0, 8, 8, 8, 16, 8, 24); +		break; +	case IPU_PIX_FMT_RGB24: +	case IPU_PIX_FMT_YUV444: +		ipu_ch_param_set_field(¶ms, 0, 107, 3, 1);	/* bits/pixel */ +		ipu_ch_param_set_field(¶ms, 1, 85, 4, 7);	/* pix format */ +		ipu_ch_param_set_field(¶ms, 1, 78, 7, 19);	/* burst size */ + +		ipu_ch_params_set_packing(¶ms, 8, 16, 8, 8, 8, 0, 8, 24); +		break; +	case IPU_PIX_FMT_BGRA32: +	case IPU_PIX_FMT_BGR32: +		ipu_ch_param_set_field(¶ms, 0, 107, 3, 0);	/* bits/pixel */ +		ipu_ch_param_set_field(¶ms, 1, 85, 4, 7);	/* pix format */ +		ipu_ch_param_set_field(¶ms, 1, 78, 7, 15);	/* burst size */ + +		ipu_ch_params_set_packing(¶ms, 8, 8, 8, 16, 8, 24, 8, 0); +		break; +	case IPU_PIX_FMT_RGBA32: +	case IPU_PIX_FMT_RGB32: +		ipu_ch_param_set_field(¶ms, 0, 107, 3, 0);	/* bits/pixel */ +		ipu_ch_param_set_field(¶ms, 1, 85, 4, 7);	/* pix format */ +		ipu_ch_param_set_field(¶ms, 1, 78, 7, 15);	/* burst size */ + +		ipu_ch_params_set_packing(¶ms, 8, 24, 8, 16, 8, 8, 8, 0); +		break; +	case IPU_PIX_FMT_ABGR32: +		ipu_ch_param_set_field(¶ms, 0, 107, 3, 0);	/* bits/pixel */ +		ipu_ch_param_set_field(¶ms, 1, 85, 4, 7);	/* pix format */ + +		ipu_ch_params_set_packing(¶ms, 8, 0, 8, 8, 8, 16, 8, 24); +		break; +	case IPU_PIX_FMT_UYVY: +		ipu_ch_param_set_field(¶ms, 0, 107, 3, 3);	/* bits/pixel */ +		ipu_ch_param_set_field(¶ms, 1, 85, 4, 0xA);	/* pix format */ +		ipu_ch_param_set_field(¶ms, 1, 78, 7, 15);	/* burst size */ +		break; +	case IPU_PIX_FMT_YUYV: +		ipu_ch_param_set_field(¶ms, 0, 107, 3, 3);	/* bits/pixel */ +		ipu_ch_param_set_field(¶ms, 1, 85, 4, 0x8);	/* pix format */ +		ipu_ch_param_set_field(¶ms, 1, 78, 7, 31);	/* burst size */ +		break; +	case IPU_PIX_FMT_YUV420P2: +	case IPU_PIX_FMT_YUV420P: +		ipu_ch_param_set_field(¶ms, 1, 85, 4, 2);	/* pix format */ + +		if (uv_stride < stride / 2) +			uv_stride = stride / 2; + +		u_offset = stride * height; +		v_offset = u_offset + (uv_stride * height / 2); +		/* burst size */ +		if ((ch == 8) || (ch == 9) || (ch == 10)) { +			ipu_ch_param_set_field(¶ms, 1, 78, 7, 15); +			uv_stride = uv_stride*2; +		} else { +			ipu_ch_param_set_field(¶ms, 1, 78, 7, 31); +		} +		break; +	case IPU_PIX_FMT_YVU422P: +		/* BPP & pixel format */ +		ipu_ch_param_set_field(¶ms, 1, 85, 4, 1);	/* pix format */ +		ipu_ch_param_set_field(¶ms, 1, 78, 7, 31);	/* burst size */ + +		if (uv_stride < stride / 2) +			uv_stride = stride / 2; + +		v_offset = (v == 0) ? stride * height : v; +		u_offset = (u == 0) ? v_offset + v_offset / 2 : u; +		break; +	case IPU_PIX_FMT_YUV422P: +		/* BPP & pixel format */ +		ipu_ch_param_set_field(¶ms, 1, 85, 4, 1);	/* pix format */ +		ipu_ch_param_set_field(¶ms, 1, 78, 7, 31);	/* burst size */ + +		if (uv_stride < stride / 2) +			uv_stride = stride / 2; + +		u_offset = (u == 0) ? stride * height : u; +		v_offset = (v == 0) ? u_offset + u_offset / 2 : v; +		break; +	case IPU_PIX_FMT_NV12: +		/* BPP & pixel format */ +		ipu_ch_param_set_field(¶ms, 1, 85, 4, 4);	/* pix format */ +		ipu_ch_param_set_field(¶ms, 1, 78, 7, 31);	/* burst size */ +		uv_stride = stride; +		u_offset = (u == 0) ? stride * height : u; +		break; +	default: +		puts("mxc ipu: unimplemented pixel format\n"); +		break; +	} + + +	if (uv_stride) +		ipu_ch_param_set_field(¶ms, 1, 128, 14, uv_stride - 1); + +	/* Get the uv offset from user when need cropping */ +	if (u || v) { +		u_offset = u; +		v_offset = v; +	} + +	/* UBO and VBO are 22-bit */ +	if (u_offset/8 > 0x3fffff) +		puts("The value of U offset exceeds IPU limitation\n"); +	if (v_offset/8 > 0x3fffff) +		puts("The value of V offset exceeds IPU limitation\n"); + +	ipu_ch_param_set_field(¶ms, 0, 46, 22, u_offset / 8); +	ipu_ch_param_set_field(¶ms, 0, 68, 22, v_offset / 8); + +	debug("initializing idma ch %d @ %p\n", ch, ipu_ch_param_addr(ch)); +	memcpy(ipu_ch_param_addr(ch), ¶ms, sizeof(params)); +}; + +/* + * This function is called to initialize a buffer for logical IPU channel. + * + * @param       channel         Input parameter for the logical channel ID. + * + * @param       type            Input parameter which buffer to initialize. + * + * @param       pixel_fmt       Input parameter for pixel format of buffer. + *                              Pixel format is a FOURCC ASCII code. + * + * @param       width           Input parameter for width of buffer in pixels. + * + * @param       height          Input parameter for height of buffer in pixels. + * + * @param       stride          Input parameter for stride length of buffer + *                              in pixels. + * + * @param       phyaddr_0       Input parameter buffer 0 physical address. + * + * @param       phyaddr_1       Input parameter buffer 1 physical address. + *                              Setting this to a value other than NULL enables + *                              double buffering mode. + * + * @param       u		private u offset for additional cropping, + *				zero if not used. + * + * @param       v		private v offset for additional cropping, + *				zero if not used. + * + * @return      Returns 0 on success or negative error code on fail + */ +int32_t ipu_init_channel_buffer(ipu_channel_t channel, ipu_buffer_t type, +				uint32_t pixel_fmt, +				uint16_t width, uint16_t height, +				uint32_t stride, +				dma_addr_t phyaddr_0, dma_addr_t phyaddr_1, +				uint32_t u, uint32_t v) +{ +	uint32_t reg; +	uint32_t dma_chan; + +	dma_chan = channel_2_dma(channel, type); +	if (!idma_is_valid(dma_chan)) +		return -EINVAL; + +	if (stride < width * bytes_per_pixel(pixel_fmt)) +		stride = width * bytes_per_pixel(pixel_fmt); + +	if (stride % 4) { +		printf( +			"Stride not 32-bit aligned, stride = %d\n", stride); +		return -EINVAL; +	} +	/* Build parameter memory data for DMA channel */ +	ipu_ch_param_init(dma_chan, pixel_fmt, width, height, stride, u, v, 0, +			   phyaddr_0, phyaddr_1); + +	if (ipu_is_dmfc_chan(dma_chan)) { +		ipu_dmfc_set_wait4eot(dma_chan, width); +	} + +	if (idma_is_set(IDMAC_CHA_PRI, dma_chan)) +		ipu_ch_param_set_high_priority(dma_chan); + +	ipu_ch_param_dump(dma_chan); + +	reg = __raw_readl(IPU_CHA_DB_MODE_SEL(dma_chan)); +	if (phyaddr_1) +		reg |= idma_mask(dma_chan); +	else +		reg &= ~idma_mask(dma_chan); +	__raw_writel(reg, IPU_CHA_DB_MODE_SEL(dma_chan)); + +	/* Reset to buffer 0 */ +	__raw_writel(idma_mask(dma_chan), IPU_CHA_CUR_BUF(dma_chan)); + +	return 0; +} + +/* + * This function enables a logical channel. + * + * @param       channel         Input parameter for the logical channel ID. + * + * @return      This function returns 0 on success or negative error code on + *              fail. + */ +int32_t ipu_enable_channel(ipu_channel_t channel) +{ +	uint32_t reg; +	uint32_t in_dma; +	uint32_t out_dma; + +	if (g_channel_enable_mask & (1L << IPU_CHAN_ID(channel))) { +		printf("Warning: channel already enabled %d\n", +			IPU_CHAN_ID(channel)); +	} + +	/* Get input and output dma channels */ +	out_dma = channel_2_dma(channel, IPU_OUTPUT_BUFFER); +	in_dma = channel_2_dma(channel, IPU_VIDEO_IN_BUFFER); + +	if (idma_is_valid(in_dma)) { +		reg = __raw_readl(IDMAC_CHA_EN(in_dma)); +		__raw_writel(reg | idma_mask(in_dma), IDMAC_CHA_EN(in_dma)); +	} +	if (idma_is_valid(out_dma)) { +		reg = __raw_readl(IDMAC_CHA_EN(out_dma)); +		__raw_writel(reg | idma_mask(out_dma), IDMAC_CHA_EN(out_dma)); +	} + +	if ((channel == MEM_DC_SYNC) || (channel == MEM_BG_SYNC) || +	    (channel == MEM_FG_SYNC)) +		ipu_dp_dc_enable(channel); + +	g_channel_enable_mask |= 1L << IPU_CHAN_ID(channel); + +	return 0; +} + +/* + * This function clear buffer ready for a logical channel. + * + * @param       channel         Input parameter for the logical channel ID. + * + * @param       type            Input parameter which buffer to clear. + * + * @param       bufNum          Input parameter for which buffer number clear + *				ready state. + * + */ +void ipu_clear_buffer_ready(ipu_channel_t channel, ipu_buffer_t type, +		uint32_t bufNum) +{ +	uint32_t dma_ch = channel_2_dma(channel, type); + +	if (!idma_is_valid(dma_ch)) +		return; + +	__raw_writel(0xF0000000, IPU_GPR); /* write one to clear */ +	if (bufNum == 0) { +		if (idma_is_set(IPU_CHA_BUF0_RDY, dma_ch)) { +			__raw_writel(idma_mask(dma_ch), +					IPU_CHA_BUF0_RDY(dma_ch)); +		} +	} else { +		if (idma_is_set(IPU_CHA_BUF1_RDY, dma_ch)) { +			__raw_writel(idma_mask(dma_ch), +					IPU_CHA_BUF1_RDY(dma_ch)); +		} +	} +	__raw_writel(0x0, IPU_GPR); /* write one to set */ +} + +/* + * This function disables a logical channel. + * + * @param       channel         Input parameter for the logical channel ID. + * + * @param       wait_for_stop   Flag to set whether to wait for channel end + *                              of frame or return immediately. + * + * @return      This function returns 0 on success or negative error code on + *              fail. + */ +int32_t ipu_disable_channel(ipu_channel_t channel) +{ +	uint32_t reg; +	uint32_t in_dma; +	uint32_t out_dma; + +	if ((g_channel_enable_mask & (1L << IPU_CHAN_ID(channel))) == 0) { +		debug("Channel already disabled %d\n", +			IPU_CHAN_ID(channel)); +		return 0; +	} + +	/* Get input and output dma channels */ +	out_dma = channel_2_dma(channel, IPU_OUTPUT_BUFFER); +	in_dma = channel_2_dma(channel, IPU_VIDEO_IN_BUFFER); + +	if ((idma_is_valid(in_dma) && +		!idma_is_set(IDMAC_CHA_EN, in_dma)) +		&& (idma_is_valid(out_dma) && +		!idma_is_set(IDMAC_CHA_EN, out_dma))) +		return -EINVAL; + +	if ((channel == MEM_BG_SYNC) || (channel == MEM_FG_SYNC) || +	    (channel == MEM_DC_SYNC)) { +		ipu_dp_dc_disable(channel, 0); +	} + +	/* Disable DMA channel(s) */ +	if (idma_is_valid(in_dma)) { +		reg = __raw_readl(IDMAC_CHA_EN(in_dma)); +		__raw_writel(reg & ~idma_mask(in_dma), IDMAC_CHA_EN(in_dma)); +		__raw_writel(idma_mask(in_dma), IPU_CHA_CUR_BUF(in_dma)); +	} +	if (idma_is_valid(out_dma)) { +		reg = __raw_readl(IDMAC_CHA_EN(out_dma)); +		__raw_writel(reg & ~idma_mask(out_dma), IDMAC_CHA_EN(out_dma)); +		__raw_writel(idma_mask(out_dma), IPU_CHA_CUR_BUF(out_dma)); +	} + +	g_channel_enable_mask &= ~(1L << IPU_CHAN_ID(channel)); + +	/* Set channel buffers NOT to be ready */ +	if (idma_is_valid(in_dma)) { +		ipu_clear_buffer_ready(channel, IPU_VIDEO_IN_BUFFER, 0); +		ipu_clear_buffer_ready(channel, IPU_VIDEO_IN_BUFFER, 1); +	} +	if (idma_is_valid(out_dma)) { +		ipu_clear_buffer_ready(channel, IPU_OUTPUT_BUFFER, 0); +		ipu_clear_buffer_ready(channel, IPU_OUTPUT_BUFFER, 1); +	} + +	return 0; +} + +uint32_t bytes_per_pixel(uint32_t fmt) +{ +	switch (fmt) { +	case IPU_PIX_FMT_GENERIC:	/*generic data */ +	case IPU_PIX_FMT_RGB332: +	case IPU_PIX_FMT_YUV420P: +	case IPU_PIX_FMT_YUV422P: +		return 1; +		break; +	case IPU_PIX_FMT_RGB565: +	case IPU_PIX_FMT_YUYV: +	case IPU_PIX_FMT_UYVY: +		return 2; +		break; +	case IPU_PIX_FMT_BGR24: +	case IPU_PIX_FMT_RGB24: +		return 3; +		break; +	case IPU_PIX_FMT_GENERIC_32:	/*generic data */ +	case IPU_PIX_FMT_BGR32: +	case IPU_PIX_FMT_BGRA32: +	case IPU_PIX_FMT_RGB32: +	case IPU_PIX_FMT_RGBA32: +	case IPU_PIX_FMT_ABGR32: +		return 4; +		break; +	default: +		return 1; +		break; +	} +	return 0; +} + +ipu_color_space_t format_to_colorspace(uint32_t fmt) +{ +	switch (fmt) { +	case IPU_PIX_FMT_RGB666: +	case IPU_PIX_FMT_RGB565: +	case IPU_PIX_FMT_BGR24: +	case IPU_PIX_FMT_RGB24: +	case IPU_PIX_FMT_BGR32: +	case IPU_PIX_FMT_BGRA32: +	case IPU_PIX_FMT_RGB32: +	case IPU_PIX_FMT_RGBA32: +	case IPU_PIX_FMT_ABGR32: +	case IPU_PIX_FMT_LVDS666: +	case IPU_PIX_FMT_LVDS888: +		return RGB; +		break; + +	default: +		return YCbCr; +		break; +	} +	return RGB; +} diff --git a/drivers/video/ipu_disp.c b/drivers/video/ipu_disp.c new file mode 100644 index 00000000000..11cf98d3d5a --- /dev/null +++ b/drivers/video/ipu_disp.c @@ -0,0 +1,1359 @@ +/* + * Porting to u-boot: + * + * (C) Copyright 2010 + * Stefano Babic, DENX Software Engineering, sbabic@denx.de + * + * Linux IPU driver for MX51: + * + * (C) Copyright 2005-2010 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* #define DEBUG */ + +#include <common.h> +#include <linux/types.h> +#include <asm/errno.h> +#include <asm/io.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/sys_proto.h> +#include "ipu.h" +#include "ipu_regs.h" + +enum csc_type_t { +	RGB2YUV = 0, +	YUV2RGB, +	RGB2RGB, +	YUV2YUV, +	CSC_NONE, +	CSC_NUM +}; + +struct dp_csc_param_t { +	int mode; +	void *coeff; +}; + +#define SYNC_WAVE 0 + +/* DC display ID assignments */ +#define DC_DISP_ID_SYNC(di)	(di) +#define DC_DISP_ID_SERIAL	2 +#define DC_DISP_ID_ASYNC	3 + +int dmfc_type_setup; +static int dmfc_size_28, dmfc_size_29, dmfc_size_24, dmfc_size_27, dmfc_size_23; +int g_di1_tvout; + +extern struct clk *g_ipu_clk; +extern struct clk *g_di_clk[2]; +extern struct clk *g_pixel_clk[2]; + +extern unsigned char g_ipu_clk_enabled; +extern unsigned char g_dc_di_assignment[]; + +void ipu_dmfc_init(int dmfc_type, int first) +{ +	u32 dmfc_wr_chan, dmfc_dp_chan; + +	if (first) { +		if (dmfc_type_setup > dmfc_type) +			dmfc_type = dmfc_type_setup; +		else +			dmfc_type_setup = dmfc_type; + +		/* disable DMFC-IC channel*/ +		__raw_writel(0x2, DMFC_IC_CTRL); +	} else if (dmfc_type_setup >= DMFC_HIGH_RESOLUTION_DC) { +		printf("DMFC high resolution has set, will not change\n"); +		return; +	} else +		dmfc_type_setup = dmfc_type; + +	if (dmfc_type == DMFC_HIGH_RESOLUTION_DC) { +		/* 1 - segment 0~3; +		 * 5B - segement 4, 5; +		 * 5F - segement 6, 7; +		 * 1C, 2C and 6B, 6F unused; +		 */ +		debug("IPU DMFC DC HIGH RES: 1(0~3), 5B(4,5), 5F(6,7)\n"); +		dmfc_wr_chan = 0x00000088; +		dmfc_dp_chan = 0x00009694; +		dmfc_size_28 = 256 * 4; +		dmfc_size_29 = 0; +		dmfc_size_24 = 0; +		dmfc_size_27 = 128 * 4; +		dmfc_size_23 = 128 * 4; +	} else if (dmfc_type == DMFC_HIGH_RESOLUTION_DP) { +		/* 1 - segment 0, 1; +		 * 5B - segement 2~5; +		 * 5F - segement 6,7; +		 * 1C, 2C and 6B, 6F unused; +		 */ +		debug("IPU DMFC DP HIGH RES: 1(0,1), 5B(2~5), 5F(6,7)\n"); +		dmfc_wr_chan = 0x00000090; +		dmfc_dp_chan = 0x0000968a; +		dmfc_size_28 = 128 * 4; +		dmfc_size_29 = 0; +		dmfc_size_24 = 0; +		dmfc_size_27 = 128 * 4; +		dmfc_size_23 = 256 * 4; +	} else if (dmfc_type == DMFC_HIGH_RESOLUTION_ONLY_DP) { +		/* 5B - segement 0~3; +		 * 5F - segement 4~7; +		 * 1, 1C, 2C and 6B, 6F unused; +		 */ +		debug("IPU DMFC ONLY-DP HIGH RES: 5B(0~3), 5F(4~7)\n"); +		dmfc_wr_chan = 0x00000000; +		dmfc_dp_chan = 0x00008c88; +		dmfc_size_28 = 0; +		dmfc_size_29 = 0; +		dmfc_size_24 = 0; +		dmfc_size_27 = 256 * 4; +		dmfc_size_23 = 256 * 4; +	} else { +		/* 1 - segment 0, 1; +		 * 5B - segement 4, 5; +		 * 5F - segement 6, 7; +		 * 1C, 2C and 6B, 6F unused; +		 */ +		debug("IPU DMFC NORMAL mode: 1(0~1), 5B(4,5), 5F(6,7)\n"); +		dmfc_wr_chan = 0x00000090; +		dmfc_dp_chan = 0x00009694; +		dmfc_size_28 = 128 * 4; +		dmfc_size_29 = 0; +		dmfc_size_24 = 0; +		dmfc_size_27 = 128 * 4; +		dmfc_size_23 = 128 * 4; +	} +	__raw_writel(dmfc_wr_chan, DMFC_WR_CHAN); +	__raw_writel(0x202020F6, DMFC_WR_CHAN_DEF); +	__raw_writel(dmfc_dp_chan, DMFC_DP_CHAN); +	/* Enable chan 5 watermark set at 5 bursts and clear at 7 bursts */ +	__raw_writel(0x2020F6F6, DMFC_DP_CHAN_DEF); +} + +void ipu_dmfc_set_wait4eot(int dma_chan, int width) +{ +	u32 dmfc_gen1 = __raw_readl(DMFC_GENERAL1); + +	if (width >= HIGH_RESOLUTION_WIDTH) { +		if (dma_chan == 23) +			ipu_dmfc_init(DMFC_HIGH_RESOLUTION_DP, 0); +		else if (dma_chan == 28) +			ipu_dmfc_init(DMFC_HIGH_RESOLUTION_DC, 0); +	} + +	if (dma_chan == 23) { /*5B*/ +		if (dmfc_size_23 / width > 3) +			dmfc_gen1 |= 1UL << 20; +		else +			dmfc_gen1 &= ~(1UL << 20); +	} else if (dma_chan == 24) { /*6B*/ +		if (dmfc_size_24 / width > 1) +			dmfc_gen1 |= 1UL << 22; +		else +			dmfc_gen1 &= ~(1UL << 22); +	} else if (dma_chan == 27) { /*5F*/ +		if (dmfc_size_27 / width > 2) +			dmfc_gen1 |= 1UL << 21; +		else +			dmfc_gen1 &= ~(1UL << 21); +	} else if (dma_chan == 28) { /*1*/ +		if (dmfc_size_28 / width > 2) +			dmfc_gen1 |= 1UL << 16; +		else +			dmfc_gen1 &= ~(1UL << 16); +	} else if (dma_chan == 29) { /*6F*/ +		if (dmfc_size_29 / width > 1) +			dmfc_gen1 |= 1UL << 23; +		else +			dmfc_gen1 &= ~(1UL << 23); +	} + +	__raw_writel(dmfc_gen1, DMFC_GENERAL1); +} + +static void ipu_di_data_wave_config(int di, +				     int wave_gen, +				     int access_size, int component_size) +{ +	u32 reg; +	reg = (access_size << DI_DW_GEN_ACCESS_SIZE_OFFSET) | +	    (component_size << DI_DW_GEN_COMPONENT_SIZE_OFFSET); +	__raw_writel(reg, DI_DW_GEN(di, wave_gen)); +} + +static void ipu_di_data_pin_config(int di, int wave_gen, int di_pin, int set, +				    int up, int down) +{ +	u32 reg; + +	reg = __raw_readl(DI_DW_GEN(di, wave_gen)); +	reg &= ~(0x3 << (di_pin * 2)); +	reg |= set << (di_pin * 2); +	__raw_writel(reg, DI_DW_GEN(di, wave_gen)); + +	__raw_writel((down << 16) | up, DI_DW_SET(di, wave_gen, set)); +} + +static void ipu_di_sync_config(int di, int wave_gen, +				int run_count, int run_src, +				int offset_count, int offset_src, +				int repeat_count, int cnt_clr_src, +				int cnt_polarity_gen_en, +				int cnt_polarity_clr_src, +				int cnt_polarity_trigger_src, +				int cnt_up, int cnt_down) +{ +	u32 reg; + +	if ((run_count >= 0x1000) || (offset_count >= 0x1000) || +		(repeat_count >= 0x1000) || +		(cnt_up >= 0x400) || (cnt_down >= 0x400)) { +		printf("DI%d counters out of range.\n", di); +		return; +	} + +	reg = (run_count << 19) | (++run_src << 16) | +	    (offset_count << 3) | ++offset_src; +	__raw_writel(reg, DI_SW_GEN0(di, wave_gen)); +	reg = (cnt_polarity_gen_en << 29) | (++cnt_clr_src << 25) | +	    (++cnt_polarity_trigger_src << 12) | (++cnt_polarity_clr_src << 9); +	reg |= (cnt_down << 16) | cnt_up; +	if (repeat_count == 0) { +		/* Enable auto reload */ +		reg |= 0x10000000; +	} +	__raw_writel(reg, DI_SW_GEN1(di, wave_gen)); +	reg = __raw_readl(DI_STP_REP(di, wave_gen)); +	reg &= ~(0xFFFF << (16 * ((wave_gen - 1) & 0x1))); +	reg |= repeat_count << (16 * ((wave_gen - 1) & 0x1)); +	__raw_writel(reg, DI_STP_REP(di, wave_gen)); +} + +static void ipu_dc_map_config(int map, int byte_num, int offset, int mask) +{ +	int ptr = map * 3 + byte_num; +	u32 reg; + +	reg = __raw_readl(DC_MAP_CONF_VAL(ptr)); +	reg &= ~(0xFFFF << (16 * (ptr & 0x1))); +	reg |= ((offset << 8) | mask) << (16 * (ptr & 0x1)); +	__raw_writel(reg, DC_MAP_CONF_VAL(ptr)); + +	reg = __raw_readl(DC_MAP_CONF_PTR(map)); +	reg &= ~(0x1F << ((16 * (map & 0x1)) + (5 * byte_num))); +	reg |= ptr << ((16 * (map & 0x1)) + (5 * byte_num)); +	__raw_writel(reg, DC_MAP_CONF_PTR(map)); +} + +static void ipu_dc_map_clear(int map) +{ +	u32 reg = __raw_readl(DC_MAP_CONF_PTR(map)); +	__raw_writel(reg & ~(0xFFFF << (16 * (map & 0x1))), +		     DC_MAP_CONF_PTR(map)); +} + +static void ipu_dc_write_tmpl(int word, u32 opcode, u32 operand, int map, +			       int wave, int glue, int sync) +{ +	u32 reg; +	int stop = 1; + +	reg = sync; +	reg |= (glue << 4); +	reg |= (++wave << 11); +	reg |= (++map << 15); +	reg |= (operand << 20) & 0xFFF00000; +	__raw_writel(reg, ipu_dc_tmpl_reg + word * 2); + +	reg = (operand >> 12); +	reg |= opcode << 4; +	reg |= (stop << 9); +	__raw_writel(reg, ipu_dc_tmpl_reg + word * 2 + 1); +} + +static void ipu_dc_link_event(int chan, int event, int addr, int priority) +{ +	u32 reg; + +	reg = __raw_readl(DC_RL_CH(chan, event)); +	reg &= ~(0xFFFF << (16 * (event & 0x1))); +	reg |= ((addr << 8) | priority) << (16 * (event & 0x1)); +	__raw_writel(reg, DC_RL_CH(chan, event)); +} + +/* Y = R *  1.200 + G *  2.343 + B *  .453 + 0.250; + * U = R * -.672 + G * -1.328 + B *  2.000 + 512.250.; + * V = R *  2.000 + G * -1.672 + B * -.328 + 512.250.; + */ +static const int rgb2ycbcr_coeff[5][3] = { +	{0x4D, 0x96, 0x1D}, +	{0x3D5, 0x3AB, 0x80}, +	{0x80, 0x395, 0x3EB}, +	{0x0000, 0x0200, 0x0200},	/* B0, B1, B2 */ +	{0x2, 0x2, 0x2},	/* S0, S1, S2 */ +}; + +/* R = (1.164 * (Y - 16)) + (1.596 * (Cr - 128)); + * G = (1.164 * (Y - 16)) - (0.392 * (Cb - 128)) - (0.813 * (Cr - 128)); + * B = (1.164 * (Y - 16)) + (2.017 * (Cb - 128); + */ +static const int ycbcr2rgb_coeff[5][3] = { +	{0x095, 0x000, 0x0CC}, +	{0x095, 0x3CE, 0x398}, +	{0x095, 0x0FF, 0x000}, +	{0x3E42, 0x010A, 0x3DD6},	/*B0,B1,B2 */ +	{0x1, 0x1, 0x1},	/*S0,S1,S2 */ +}; + +#define mask_a(a) ((u32)(a) & 0x3FF) +#define mask_b(b) ((u32)(b) & 0x3FFF) + +/* Pls keep S0, S1 and S2 as 0x2 by using this convertion */ +static int rgb_to_yuv(int n, int red, int green, int blue) +{ +	int c; +	c = red * rgb2ycbcr_coeff[n][0]; +	c += green * rgb2ycbcr_coeff[n][1]; +	c += blue * rgb2ycbcr_coeff[n][2]; +	c /= 16; +	c += rgb2ycbcr_coeff[3][n] * 4; +	c += 8; +	c /= 16; +	if (c < 0) +		c = 0; +	if (c > 255) +		c = 255; +	return c; +} + +/* + * Row is for BG:	RGB2YUV YUV2RGB RGB2RGB YUV2YUV CSC_NONE + * Column is for FG:	RGB2YUV YUV2RGB RGB2RGB YUV2YUV CSC_NONE + */ +static struct dp_csc_param_t dp_csc_array[CSC_NUM][CSC_NUM] = { +	{ +		{DP_COM_CONF_CSC_DEF_BOTH, &rgb2ycbcr_coeff}, +		{0, 0}, +		{0, 0}, +		{DP_COM_CONF_CSC_DEF_BG, &rgb2ycbcr_coeff}, +		{DP_COM_CONF_CSC_DEF_BG, &rgb2ycbcr_coeff} +	}, +	{ +		{0, 0}, +		{DP_COM_CONF_CSC_DEF_BOTH, &ycbcr2rgb_coeff}, +		{DP_COM_CONF_CSC_DEF_BG, &ycbcr2rgb_coeff}, +		{0, 0}, +		{DP_COM_CONF_CSC_DEF_BG, &ycbcr2rgb_coeff} +	}, +	{ +		{0, 0}, +		{DP_COM_CONF_CSC_DEF_FG, &ycbcr2rgb_coeff}, +		{0, 0}, +		{0, 0}, +		{0, 0} +	}, +	{ +		{DP_COM_CONF_CSC_DEF_FG, &rgb2ycbcr_coeff}, +		{0, 0}, +		{0, 0}, +		{0, 0}, +		{0, 0} +	}, +	{ +		{DP_COM_CONF_CSC_DEF_FG, &rgb2ycbcr_coeff}, +		{DP_COM_CONF_CSC_DEF_FG, &ycbcr2rgb_coeff}, +		{0, 0}, +		{0, 0}, +		{0, 0} +	} +}; + +static enum csc_type_t fg_csc_type = CSC_NONE, bg_csc_type = CSC_NONE; +static int color_key_4rgb = 1; + +void ipu_dp_csc_setup(int dp, struct dp_csc_param_t dp_csc_param, +			unsigned char srm_mode_update) +{ +	u32 reg; +	const int (*coeff)[5][3]; + +	if (dp_csc_param.mode >= 0) { +		reg = __raw_readl(DP_COM_CONF(dp)); +		reg &= ~DP_COM_CONF_CSC_DEF_MASK; +		reg |= dp_csc_param.mode; +		__raw_writel(reg, DP_COM_CONF(dp)); +	} + +	coeff = dp_csc_param.coeff; + +	if (coeff) { +		__raw_writel(mask_a((*coeff)[0][0]) | +				(mask_a((*coeff)[0][1]) << 16), DP_CSC_A_0(dp)); +		__raw_writel(mask_a((*coeff)[0][2]) | +				(mask_a((*coeff)[1][0]) << 16), DP_CSC_A_1(dp)); +		__raw_writel(mask_a((*coeff)[1][1]) | +				(mask_a((*coeff)[1][2]) << 16), DP_CSC_A_2(dp)); +		__raw_writel(mask_a((*coeff)[2][0]) | +				(mask_a((*coeff)[2][1]) << 16), DP_CSC_A_3(dp)); +		__raw_writel(mask_a((*coeff)[2][2]) | +				(mask_b((*coeff)[3][0]) << 16) | +				((*coeff)[4][0] << 30), DP_CSC_0(dp)); +		__raw_writel(mask_b((*coeff)[3][1]) | ((*coeff)[4][1] << 14) | +				(mask_b((*coeff)[3][2]) << 16) | +				((*coeff)[4][2] << 30), DP_CSC_1(dp)); +	} + +	if (srm_mode_update) { +		reg = __raw_readl(IPU_SRM_PRI2) | 0x8; +		__raw_writel(reg, IPU_SRM_PRI2); +	} +} + +int ipu_dp_init(ipu_channel_t channel, uint32_t in_pixel_fmt, +		 uint32_t out_pixel_fmt) +{ +	int in_fmt, out_fmt; +	int dp; +	int partial = 0; +	uint32_t reg; + +	if (channel == MEM_FG_SYNC) { +		dp = DP_SYNC; +		partial = 1; +	} else if (channel == MEM_BG_SYNC) { +		dp = DP_SYNC; +		partial = 0; +	} else if (channel == MEM_BG_ASYNC0) { +		dp = DP_ASYNC0; +		partial = 0; +	} else { +		return -EINVAL; +	} + +	in_fmt = format_to_colorspace(in_pixel_fmt); +	out_fmt = format_to_colorspace(out_pixel_fmt); + +	if (partial) { +		if (in_fmt == RGB) { +			if (out_fmt == RGB) +				fg_csc_type = RGB2RGB; +			else +				fg_csc_type = RGB2YUV; +		} else { +			if (out_fmt == RGB) +				fg_csc_type = YUV2RGB; +			else +				fg_csc_type = YUV2YUV; +		} +	} else { +		if (in_fmt == RGB) { +			if (out_fmt == RGB) +				bg_csc_type = RGB2RGB; +			else +				bg_csc_type = RGB2YUV; +		} else { +			if (out_fmt == RGB) +				bg_csc_type = YUV2RGB; +			else +				bg_csc_type = YUV2YUV; +		} +	} + +	/* Transform color key from rgb to yuv if CSC is enabled */ +	reg = __raw_readl(DP_COM_CONF(dp)); +	if (color_key_4rgb && (reg & DP_COM_CONF_GWCKE) && +		(((fg_csc_type == RGB2YUV) && (bg_csc_type == YUV2YUV)) || +		((fg_csc_type == YUV2YUV) && (bg_csc_type == RGB2YUV)) || +		((fg_csc_type == YUV2YUV) && (bg_csc_type == YUV2YUV)) || +		((fg_csc_type == YUV2RGB) && (bg_csc_type == YUV2RGB)))) { +		int red, green, blue; +		int y, u, v; +		uint32_t color_key = __raw_readl(DP_GRAPH_WIND_CTRL(dp)) & +			0xFFFFFFL; + +		debug("_ipu_dp_init color key 0x%x need change to yuv fmt!\n", +			color_key); + +		red = (color_key >> 16) & 0xFF; +		green = (color_key >> 8) & 0xFF; +		blue = color_key & 0xFF; + +		y = rgb_to_yuv(0, red, green, blue); +		u = rgb_to_yuv(1, red, green, blue); +		v = rgb_to_yuv(2, red, green, blue); +		color_key = (y << 16) | (u << 8) | v; + +		reg = __raw_readl(DP_GRAPH_WIND_CTRL(dp)) & 0xFF000000L; +		__raw_writel(reg | color_key, DP_GRAPH_WIND_CTRL(dp)); +		color_key_4rgb = 0; + +		debug("_ipu_dp_init color key change to yuv fmt 0x%x!\n", +			color_key); +	} + +	ipu_dp_csc_setup(dp, dp_csc_array[bg_csc_type][fg_csc_type], 1); + +	return 0; +} + +void ipu_dp_uninit(ipu_channel_t channel) +{ +	int dp; +	int partial = 0; + +	if (channel == MEM_FG_SYNC) { +		dp = DP_SYNC; +		partial = 1; +	} else if (channel == MEM_BG_SYNC) { +		dp = DP_SYNC; +		partial = 0; +	} else if (channel == MEM_BG_ASYNC0) { +		dp = DP_ASYNC0; +		partial = 0; +	} else { +		return; +	} + +	if (partial) +		fg_csc_type = CSC_NONE; +	else +		bg_csc_type = CSC_NONE; + +	ipu_dp_csc_setup(dp, dp_csc_array[bg_csc_type][fg_csc_type], 0); +} + +void ipu_dc_init(int dc_chan, int di, unsigned char interlaced) +{ +	u32 reg = 0; + +	if ((dc_chan == 1) || (dc_chan == 5)) { +		if (interlaced) { +			ipu_dc_link_event(dc_chan, DC_EVT_NL, 0, 3); +			ipu_dc_link_event(dc_chan, DC_EVT_EOL, 0, 2); +			ipu_dc_link_event(dc_chan, DC_EVT_NEW_DATA, 0, 1); +		} else { +			if (di) { +				ipu_dc_link_event(dc_chan, DC_EVT_NL, 2, 3); +				ipu_dc_link_event(dc_chan, DC_EVT_EOL, 3, 2); +				ipu_dc_link_event(dc_chan, DC_EVT_NEW_DATA, +					4, 1); +			} else { +				ipu_dc_link_event(dc_chan, DC_EVT_NL, 5, 3); +				ipu_dc_link_event(dc_chan, DC_EVT_EOL, 6, 2); +				ipu_dc_link_event(dc_chan, DC_EVT_NEW_DATA, +					7, 1); +			} +		} +		ipu_dc_link_event(dc_chan, DC_EVT_NF, 0, 0); +		ipu_dc_link_event(dc_chan, DC_EVT_NFIELD, 0, 0); +		ipu_dc_link_event(dc_chan, DC_EVT_EOF, 0, 0); +		ipu_dc_link_event(dc_chan, DC_EVT_EOFIELD, 0, 0); +		ipu_dc_link_event(dc_chan, DC_EVT_NEW_CHAN, 0, 0); +		ipu_dc_link_event(dc_chan, DC_EVT_NEW_ADDR, 0, 0); + +		reg = 0x2; +		reg |= DC_DISP_ID_SYNC(di) << DC_WR_CH_CONF_PROG_DISP_ID_OFFSET; +		reg |= di << 2; +		if (interlaced) +			reg |= DC_WR_CH_CONF_FIELD_MODE; +	} else if ((dc_chan == 8) || (dc_chan == 9)) { +		/* async channels */ +		ipu_dc_link_event(dc_chan, DC_EVT_NEW_DATA_W_0, 0x64, 1); +		ipu_dc_link_event(dc_chan, DC_EVT_NEW_DATA_W_1, 0x64, 1); + +		reg = 0x3; +		reg |= DC_DISP_ID_SERIAL << DC_WR_CH_CONF_PROG_DISP_ID_OFFSET; +	} +	__raw_writel(reg, DC_WR_CH_CONF(dc_chan)); + +	__raw_writel(0x00000000, DC_WR_CH_ADDR(dc_chan)); + +	__raw_writel(0x00000084, DC_GEN); +} + +void ipu_dc_uninit(int dc_chan) +{ +	if ((dc_chan == 1) || (dc_chan == 5)) { +		ipu_dc_link_event(dc_chan, DC_EVT_NL, 0, 0); +		ipu_dc_link_event(dc_chan, DC_EVT_EOL, 0, 0); +		ipu_dc_link_event(dc_chan, DC_EVT_NEW_DATA, 0, 0); +		ipu_dc_link_event(dc_chan, DC_EVT_NF, 0, 0); +		ipu_dc_link_event(dc_chan, DC_EVT_NFIELD, 0, 0); +		ipu_dc_link_event(dc_chan, DC_EVT_EOF, 0, 0); +		ipu_dc_link_event(dc_chan, DC_EVT_EOFIELD, 0, 0); +		ipu_dc_link_event(dc_chan, DC_EVT_NEW_CHAN, 0, 0); +		ipu_dc_link_event(dc_chan, DC_EVT_NEW_ADDR, 0, 0); +	} else if ((dc_chan == 8) || (dc_chan == 9)) { +		ipu_dc_link_event(dc_chan, DC_EVT_NEW_ADDR_W_0, 0, 0); +		ipu_dc_link_event(dc_chan, DC_EVT_NEW_ADDR_W_1, 0, 0); +		ipu_dc_link_event(dc_chan, DC_EVT_NEW_CHAN_W_0, 0, 0); +		ipu_dc_link_event(dc_chan, DC_EVT_NEW_CHAN_W_1, 0, 0); +		ipu_dc_link_event(dc_chan, DC_EVT_NEW_DATA_W_0, 0, 0); +		ipu_dc_link_event(dc_chan, DC_EVT_NEW_DATA_W_1, 0, 0); +		ipu_dc_link_event(dc_chan, DC_EVT_NEW_ADDR_R_0, 0, 0); +		ipu_dc_link_event(dc_chan, DC_EVT_NEW_ADDR_R_1, 0, 0); +		ipu_dc_link_event(dc_chan, DC_EVT_NEW_CHAN_R_0, 0, 0); +		ipu_dc_link_event(dc_chan, DC_EVT_NEW_CHAN_R_1, 0, 0); +		ipu_dc_link_event(dc_chan, DC_EVT_NEW_DATA_R_0, 0, 0); +		ipu_dc_link_event(dc_chan, DC_EVT_NEW_DATA_R_1, 0, 0); +	} +} + +int ipu_chan_is_interlaced(ipu_channel_t channel) +{ +	if (channel == MEM_DC_SYNC) +		return !!(__raw_readl(DC_WR_CH_CONF_1) & +			  DC_WR_CH_CONF_FIELD_MODE); +	else if ((channel == MEM_BG_SYNC) || (channel == MEM_FG_SYNC)) +		return !!(__raw_readl(DC_WR_CH_CONF_5) & +			  DC_WR_CH_CONF_FIELD_MODE); +	return 0; +} + +void ipu_dp_dc_enable(ipu_channel_t channel) +{ +	int di; +	uint32_t reg; +	uint32_t dc_chan; + +	if (channel == MEM_FG_SYNC) +		dc_chan = 5; +	if (channel == MEM_DC_SYNC) +		dc_chan = 1; +	else if (channel == MEM_BG_SYNC) +		dc_chan = 5; +	else +		return; + +	if (channel == MEM_FG_SYNC) { +		/* Enable FG channel */ +		reg = __raw_readl(DP_COM_CONF(DP_SYNC)); +		__raw_writel(reg | DP_COM_CONF_FG_EN, DP_COM_CONF(DP_SYNC)); + +		reg = __raw_readl(IPU_SRM_PRI2) | 0x8; +		__raw_writel(reg, IPU_SRM_PRI2); +		return; +	} + +	di = g_dc_di_assignment[dc_chan]; + +	/* Make sure other DC sync channel is not assigned same DI */ +	reg = __raw_readl(DC_WR_CH_CONF(6 - dc_chan)); +	if ((di << 2) == (reg & DC_WR_CH_CONF_PROG_DI_ID)) { +		reg &= ~DC_WR_CH_CONF_PROG_DI_ID; +		reg |= di ? 0 : DC_WR_CH_CONF_PROG_DI_ID; +		__raw_writel(reg, DC_WR_CH_CONF(6 - dc_chan)); +	} + +	reg = __raw_readl(DC_WR_CH_CONF(dc_chan)); +	reg |= 4 << DC_WR_CH_CONF_PROG_TYPE_OFFSET; +	__raw_writel(reg, DC_WR_CH_CONF(dc_chan)); + +	clk_enable(g_pixel_clk[di]); +} + +static unsigned char dc_swap; + +void ipu_dp_dc_disable(ipu_channel_t channel, unsigned char swap) +{ +	uint32_t reg; +	uint32_t csc; +	uint32_t dc_chan = 0; +	int timeout = 50; + +	dc_swap = swap; + +	if (channel == MEM_DC_SYNC) { +		dc_chan = 1; +	} else if (channel == MEM_BG_SYNC) { +		dc_chan = 5; +	} else if (channel == MEM_FG_SYNC) { +		/* Disable FG channel */ +		dc_chan = 5; + +		reg = __raw_readl(DP_COM_CONF(DP_SYNC)); +		csc = reg & DP_COM_CONF_CSC_DEF_MASK; +		if (csc == DP_COM_CONF_CSC_DEF_FG) +			reg &= ~DP_COM_CONF_CSC_DEF_MASK; + +		reg &= ~DP_COM_CONF_FG_EN; +		__raw_writel(reg, DP_COM_CONF(DP_SYNC)); + +		reg = __raw_readl(IPU_SRM_PRI2) | 0x8; +		__raw_writel(reg, IPU_SRM_PRI2); + +		timeout = 50; + +		/* +		 * Wait for DC triple buffer to empty, +		 * this check is useful for tv overlay. +		 */ +		if (g_dc_di_assignment[dc_chan] == 0) +			while ((__raw_readl(DC_STAT) & 0x00000002) +			       != 0x00000002) { +				udelay(2000); +				timeout -= 2; +				if (timeout <= 0) +					break; +			} +		else if (g_dc_di_assignment[dc_chan] == 1) +			while ((__raw_readl(DC_STAT) & 0x00000020) +			       != 0x00000020) { +				udelay(2000); +				timeout -= 2; +				if (timeout <= 0) +					break; +			} +		return; +	} else { +		return; +	} + +	if (dc_swap) { +		/* Swap DC channel 1 and 5 settings, and disable old dc chan */ +		reg = __raw_readl(DC_WR_CH_CONF(dc_chan)); +		__raw_writel(reg, DC_WR_CH_CONF(6 - dc_chan)); +		reg &= ~DC_WR_CH_CONF_PROG_TYPE_MASK; +		reg ^= DC_WR_CH_CONF_PROG_DI_ID; +		__raw_writel(reg, DC_WR_CH_CONF(dc_chan)); +	} else { +		timeout = 50; + +		/* Wait for DC triple buffer to empty */ +		if (g_dc_di_assignment[dc_chan] == 0) +			while ((__raw_readl(DC_STAT) & 0x00000002) +				!= 0x00000002) { +				udelay(2000); +				timeout -= 2; +				if (timeout <= 0) +					break; +			} +		else if (g_dc_di_assignment[dc_chan] == 1) +			while ((__raw_readl(DC_STAT) & 0x00000020) +				!= 0x00000020) { +				udelay(2000); +				timeout -= 2; +				if (timeout <= 0) +					break; +			} + +		reg = __raw_readl(DC_WR_CH_CONF(dc_chan)); +		reg &= ~DC_WR_CH_CONF_PROG_TYPE_MASK; +		__raw_writel(reg, DC_WR_CH_CONF(dc_chan)); + +		reg = __raw_readl(IPU_DISP_GEN); +		if (g_dc_di_assignment[dc_chan]) +			reg &= ~DI1_COUNTER_RELEASE; +		else +			reg &= ~DI0_COUNTER_RELEASE; +		__raw_writel(reg, IPU_DISP_GEN); + +		/* Clock is already off because it must be done quickly, but +		   we need to fix the ref count */ +		clk_disable(g_pixel_clk[g_dc_di_assignment[dc_chan]]); +	} +} + +void ipu_init_dc_mappings(void) +{ +	/* IPU_PIX_FMT_RGB24 */ +	ipu_dc_map_clear(0); +	ipu_dc_map_config(0, 0, 7, 0xFF); +	ipu_dc_map_config(0, 1, 15, 0xFF); +	ipu_dc_map_config(0, 2, 23, 0xFF); + +	/* IPU_PIX_FMT_RGB666 */ +	ipu_dc_map_clear(1); +	ipu_dc_map_config(1, 0, 5, 0xFC); +	ipu_dc_map_config(1, 1, 11, 0xFC); +	ipu_dc_map_config(1, 2, 17, 0xFC); + +	/* IPU_PIX_FMT_YUV444 */ +	ipu_dc_map_clear(2); +	ipu_dc_map_config(2, 0, 15, 0xFF); +	ipu_dc_map_config(2, 1, 23, 0xFF); +	ipu_dc_map_config(2, 2, 7, 0xFF); + +	/* IPU_PIX_FMT_RGB565 */ +	ipu_dc_map_clear(3); +	ipu_dc_map_config(3, 0, 4, 0xF8); +	ipu_dc_map_config(3, 1, 10, 0xFC); +	ipu_dc_map_config(3, 2, 15, 0xF8); + +	/* IPU_PIX_FMT_LVDS666 */ +	ipu_dc_map_clear(4); +	ipu_dc_map_config(4, 0, 5, 0xFC); +	ipu_dc_map_config(4, 1, 13, 0xFC); +	ipu_dc_map_config(4, 2, 21, 0xFC); +} + +int ipu_pixfmt_to_map(uint32_t fmt) +{ +	switch (fmt) { +	case IPU_PIX_FMT_GENERIC: +	case IPU_PIX_FMT_RGB24: +		return 0; +	case IPU_PIX_FMT_RGB666: +		return 1; +	case IPU_PIX_FMT_YUV444: +		return 2; +	case IPU_PIX_FMT_RGB565: +		return 3; +	case IPU_PIX_FMT_LVDS666: +		return 4; +	} + +	return -1; +} + +/* + * This function is called to adapt synchronous LCD panel to IPU restriction. + */ +void adapt_panel_to_ipu_restricitions(uint32_t *pixel_clk, +				      uint16_t width, uint16_t height, +				      uint16_t h_start_width, +				      uint16_t h_end_width, +				      uint16_t v_start_width, +				      uint16_t *v_end_width) +{ +	if (*v_end_width < 2) { +		uint16_t total_width = width + h_start_width + h_end_width; +		uint16_t total_height_old = height + v_start_width + +			(*v_end_width); +		uint16_t total_height_new = height + v_start_width + 2; +		*v_end_width = 2; +		*pixel_clk = (*pixel_clk) * total_width * total_height_new / +			(total_width * total_height_old); +		printf("WARNING: adapt panel end blank lines\n"); +	} +} + +/* + * This function is called to initialize a synchronous LCD panel. + * + * @param       disp            The DI the panel is attached to. + * + * @param       pixel_clk       Desired pixel clock frequency in Hz. + * + * @param       pixel_fmt       Input parameter for pixel format of buffer. + *                              Pixel format is a FOURCC ASCII code. + * + * @param       width           The width of panel in pixels. + * + * @param       height          The height of panel in pixels. + * + * @param       hStartWidth     The number of pixel clocks between the HSYNC + *                              signal pulse and the start of valid data. + * + * @param       hSyncWidth      The width of the HSYNC signal in units of pixel + *                              clocks. + * + * @param       hEndWidth       The number of pixel clocks between the end of + *                              valid data and the HSYNC signal for next line. + * + * @param       vStartWidth     The number of lines between the VSYNC + *                              signal pulse and the start of valid data. + * + * @param       vSyncWidth      The width of the VSYNC signal in units of lines + * + * @param       vEndWidth       The number of lines between the end of valid + *                              data and the VSYNC signal for next frame. + * + * @param       sig             Bitfield of signal polarities for LCD interface. + * + * @return      This function returns 0 on success or negative error code on + *              fail. + */ + +int32_t ipu_init_sync_panel(int disp, uint32_t pixel_clk, +			    uint16_t width, uint16_t height, +			    uint32_t pixel_fmt, +			    uint16_t h_start_width, uint16_t h_sync_width, +			    uint16_t h_end_width, uint16_t v_start_width, +			    uint16_t v_sync_width, uint16_t v_end_width, +			    uint32_t v_to_h_sync, ipu_di_signal_cfg_t sig) +{ +	uint32_t reg; +	uint32_t di_gen, vsync_cnt; +	uint32_t div, rounded_pixel_clk; +	uint32_t h_total, v_total; +	int map; +	struct clk *di_parent; + +	debug("panel size = %d x %d\n", width, height); + +	if ((v_sync_width == 0) || (h_sync_width == 0)) +		return EINVAL; + +	adapt_panel_to_ipu_restricitions(&pixel_clk, width, height, +					 h_start_width, h_end_width, +					 v_start_width, &v_end_width); +	h_total = width + h_sync_width + h_start_width + h_end_width; +	v_total = height + v_sync_width + v_start_width + v_end_width; + +	/* Init clocking */ +	debug("pixel clk = %d\n", pixel_clk); + +	if (sig.ext_clk) { +		if (!(g_di1_tvout && (disp == 1))) { /*not round div for tvout*/ +			/* +			 * Set the  PLL to be an even multiple +			 * of the pixel clock. +			 */ +			if ((clk_get_usecount(g_pixel_clk[0]) == 0) && +				(clk_get_usecount(g_pixel_clk[1]) == 0)) { +				di_parent = clk_get_parent(g_di_clk[disp]); +				rounded_pixel_clk = +					clk_round_rate(g_pixel_clk[disp], +						pixel_clk); +				div  = clk_get_rate(di_parent) / +					rounded_pixel_clk; +				if (div % 2) +					div++; +				if (clk_get_rate(di_parent) != div * +					rounded_pixel_clk) +					clk_set_rate(di_parent, +						div * rounded_pixel_clk); +				udelay(10000); +				clk_set_rate(g_di_clk[disp], +					2 * rounded_pixel_clk); +				udelay(10000); +			} +		} +		clk_set_parent(g_pixel_clk[disp], g_di_clk[disp]); +	} else { +		if (clk_get_usecount(g_pixel_clk[disp]) != 0) +			clk_set_parent(g_pixel_clk[disp], g_ipu_clk); +	} +	rounded_pixel_clk = clk_round_rate(g_pixel_clk[disp], pixel_clk); +	clk_set_rate(g_pixel_clk[disp], rounded_pixel_clk); +	udelay(5000); +	/* Get integer portion of divider */ +	div = clk_get_rate(clk_get_parent(g_pixel_clk[disp])) / +		rounded_pixel_clk; + +	ipu_di_data_wave_config(disp, SYNC_WAVE, div - 1, div - 1); +	ipu_di_data_pin_config(disp, SYNC_WAVE, DI_PIN15, 3, 0, div * 2); + +	map = ipu_pixfmt_to_map(pixel_fmt); +	if (map < 0) { +		debug("IPU_DISP: No MAP\n"); +		return -EINVAL; +	} + +	di_gen = __raw_readl(DI_GENERAL(disp)); + +	if (sig.interlaced) { +		/* Setup internal HSYNC waveform */ +		ipu_di_sync_config( +				disp,		/* display */ +				1,		/* counter */ +				h_total / 2 - 1,/* run count */ +				DI_SYNC_CLK,	/* run_resolution */ +				0,		/* offset */ +				DI_SYNC_NONE,	/* offset resolution */ +				0,		/* repeat count */ +				DI_SYNC_NONE,	/* CNT_CLR_SEL */ +				0,		/* CNT_POLARITY_GEN_EN */ +				DI_SYNC_NONE,	/* CNT_POLARITY_CLR_SEL */ +				DI_SYNC_NONE,	/* CNT_POLARITY_TRIGGER_SEL */ +				0,		/* COUNT UP */ +				0		/* COUNT DOWN */ +				); + +		/* Field 1 VSYNC waveform */ +		ipu_di_sync_config( +				disp,		/* display */ +				2,		/* counter */ +				h_total - 1,	/* run count */ +				DI_SYNC_CLK,	/* run_resolution */ +				0,		/* offset */ +				DI_SYNC_NONE,	/* offset resolution */ +				0,		/* repeat count */ +				DI_SYNC_NONE,	/* CNT_CLR_SEL */ +				0,		/* CNT_POLARITY_GEN_EN */ +				DI_SYNC_NONE,	/* CNT_POLARITY_CLR_SEL */ +				DI_SYNC_NONE,	/* CNT_POLARITY_TRIGGER_SEL */ +				0,		/* COUNT UP */ +				4		/* COUNT DOWN */ +				); + +		/* Setup internal HSYNC waveform */ +		ipu_di_sync_config( +				disp,		/* display */ +				3,		/* counter */ +				v_total * 2 - 1,/* run count */ +				DI_SYNC_INT_HSYNC,	/* run_resolution */ +				1,		/* offset */ +				DI_SYNC_INT_HSYNC,	/* offset resolution */ +				0,		/* repeat count */ +				DI_SYNC_NONE,	/* CNT_CLR_SEL */ +				0,		/* CNT_POLARITY_GEN_EN */ +				DI_SYNC_NONE,	/* CNT_POLARITY_CLR_SEL */ +				DI_SYNC_NONE,	/* CNT_POLARITY_TRIGGER_SEL */ +				0,		/* COUNT UP */ +				4		/* COUNT DOWN */ +				); + +		/* Active Field ? */ +		ipu_di_sync_config( +				disp,		/* display */ +				4,		/* counter */ +				v_total / 2 - 1,/* run count */ +				DI_SYNC_HSYNC,	/* run_resolution */ +				v_start_width,	/*  offset */ +				DI_SYNC_HSYNC,	/* offset resolution */ +				2,		/* repeat count */ +				DI_SYNC_VSYNC,	/* CNT_CLR_SEL */ +				0,		/* CNT_POLARITY_GEN_EN */ +				DI_SYNC_NONE,	/* CNT_POLARITY_CLR_SEL */ +				DI_SYNC_NONE,	/* CNT_POLARITY_TRIGGER_SEL */ +				0,		/* COUNT UP */ +				0		/* COUNT DOWN */ +				); + +		/* Active Line */ +		ipu_di_sync_config( +				disp,		/* display */ +				5,		/* counter */ +				0,		/* run count */ +				DI_SYNC_HSYNC,	/* run_resolution */ +				0,		/*  offset */ +				DI_SYNC_NONE,	/* offset resolution */ +				height / 2,	/* repeat count */ +				4,		/* CNT_CLR_SEL */ +				0,		/* CNT_POLARITY_GEN_EN */ +				DI_SYNC_NONE,	/* CNT_POLARITY_CLR_SEL */ +				DI_SYNC_NONE,	/* CNT_POLARITY_TRIGGER_SEL */ +				0,		/* COUNT UP */ +				0		/* COUNT DOWN */ +				); + +		/* Field 0 VSYNC waveform */ +		ipu_di_sync_config( +				disp,		/* display */ +				6,		/* counter */ +				v_total - 1,	/* run count */ +				DI_SYNC_HSYNC,	/* run_resolution */ +				0,		/* offset */ +				DI_SYNC_NONE,	/* offset resolution */ +				0,		/* repeat count */ +				DI_SYNC_NONE,	/* CNT_CLR_SEL  */ +				0,		/* CNT_POLARITY_GEN_EN */ +				DI_SYNC_NONE,	/* CNT_POLARITY_CLR_SEL */ +				DI_SYNC_NONE,	/* CNT_POLARITY_TRIGGER_SEL */ +				0,		/* COUNT UP */ +				0		/* COUNT DOWN */ +				); + +		/* DC VSYNC waveform */ +		vsync_cnt = 7; +		ipu_di_sync_config( +				disp,		/* display */ +				7,		/* counter */ +				v_total / 2 - 1,/* run count */ +				DI_SYNC_HSYNC,	/* run_resolution  */ +				9,		/* offset  */ +				DI_SYNC_HSYNC,	/* offset resolution */ +				2,		/* repeat count */ +				DI_SYNC_VSYNC,	/* CNT_CLR_SEL */ +				0,		/* CNT_POLARITY_GEN_EN */ +				DI_SYNC_NONE,	/* CNT_POLARITY_CLR_SEL */ +				DI_SYNC_NONE,	/* CNT_POLARITY_TRIGGER_SEL */ +				0,		/* COUNT UP */ +				0		/* COUNT DOWN */ +				); + +		/* active pixel waveform */ +		ipu_di_sync_config( +				disp,		/* display */ +				8,		/* counter */ +				0,		/* run count  */ +				DI_SYNC_CLK,	/* run_resolution */ +				h_start_width,	/* offset  */ +				DI_SYNC_CLK,	/* offset resolution */ +				width,		/* repeat count  */ +				5,		/* CNT_CLR_SEL  */ +				0,		/* CNT_POLARITY_GEN_EN  */ +				DI_SYNC_NONE,	/* CNT_POLARITY_CLR_SEL */ +				DI_SYNC_NONE,	/* CNT_POLARITY_TRIGGER_SEL  */ +				0,		/* COUNT UP  */ +				0		/* COUNT DOWN */ +				); + +		ipu_di_sync_config( +				disp,		/* display */ +				9,		/* counter */ +				v_total - 1,	/* run count */ +				DI_SYNC_INT_HSYNC,/* run_resolution */ +				v_total / 2,	/* offset  */ +				DI_SYNC_INT_HSYNC,/* offset resolution  */ +				0,		/* repeat count */ +				DI_SYNC_HSYNC,	/* CNT_CLR_SEL */ +				0,		/* CNT_POLARITY_GEN_EN  */ +				DI_SYNC_NONE,	/* CNT_POLARITY_CLR_SEL  */ +				DI_SYNC_NONE,	/* CNT_POLARITY_TRIGGER_SEL */ +				0,		/* COUNT UP */ +				4		/* COUNT DOWN */ +				); + +		/* set gentime select and tag sel */ +		reg = __raw_readl(DI_SW_GEN1(disp, 9)); +		reg &= 0x1FFFFFFF; +		reg |= (3 - 1)<<29 | 0x00008000; +		__raw_writel(reg, DI_SW_GEN1(disp, 9)); + +		__raw_writel(v_total / 2 - 1, DI_SCR_CONF(disp)); + +		/* set y_sel = 1 */ +		di_gen |= 0x10000000; +		di_gen |= DI_GEN_POLARITY_5; +		di_gen |= DI_GEN_POLARITY_8; +	} else { +		/* Setup internal HSYNC waveform */ +		ipu_di_sync_config(disp, 1, h_total - 1, DI_SYNC_CLK, +				0, DI_SYNC_NONE, 0, DI_SYNC_NONE, +				0, DI_SYNC_NONE, +				DI_SYNC_NONE, 0, 0); + +		/* Setup external (delayed) HSYNC waveform */ +		ipu_di_sync_config(disp, DI_SYNC_HSYNC, h_total - 1, +				DI_SYNC_CLK, div * v_to_h_sync, DI_SYNC_CLK, +				0, DI_SYNC_NONE, 1, DI_SYNC_NONE, +				DI_SYNC_CLK, 0, h_sync_width * 2); +		/* Setup VSYNC waveform */ +		vsync_cnt = DI_SYNC_VSYNC; +		ipu_di_sync_config(disp, DI_SYNC_VSYNC, v_total - 1, +				DI_SYNC_INT_HSYNC, 0, DI_SYNC_NONE, 0, +				DI_SYNC_NONE, 1, DI_SYNC_NONE, +				DI_SYNC_INT_HSYNC, 0, v_sync_width * 2); +		__raw_writel(v_total - 1, DI_SCR_CONF(disp)); + +		/* Setup active data waveform to sync with DC */ +		ipu_di_sync_config(disp, 4, 0, DI_SYNC_HSYNC, +				v_sync_width + v_start_width, DI_SYNC_HSYNC, +				height, +				DI_SYNC_VSYNC, 0, DI_SYNC_NONE, +				DI_SYNC_NONE, 0, 0); +		ipu_di_sync_config(disp, 5, 0, DI_SYNC_CLK, +				h_sync_width + h_start_width, DI_SYNC_CLK, +				width, 4, 0, DI_SYNC_NONE, DI_SYNC_NONE, 0, +				0); + +		/* reset all unused counters */ +		__raw_writel(0, DI_SW_GEN0(disp, 6)); +		__raw_writel(0, DI_SW_GEN1(disp, 6)); +		__raw_writel(0, DI_SW_GEN0(disp, 7)); +		__raw_writel(0, DI_SW_GEN1(disp, 7)); +		__raw_writel(0, DI_SW_GEN0(disp, 8)); +		__raw_writel(0, DI_SW_GEN1(disp, 8)); +		__raw_writel(0, DI_SW_GEN0(disp, 9)); +		__raw_writel(0, DI_SW_GEN1(disp, 9)); + +		reg = __raw_readl(DI_STP_REP(disp, 6)); +		reg &= 0x0000FFFF; +		__raw_writel(reg, DI_STP_REP(disp, 6)); +		__raw_writel(0, DI_STP_REP(disp, 7)); +		__raw_writel(0, DI_STP_REP(disp, 9)); + +		/* Init template microcode */ +		if (disp) { +		   ipu_dc_write_tmpl(2, WROD(0), 0, map, SYNC_WAVE, 8, 5); +		   ipu_dc_write_tmpl(3, WROD(0), 0, map, SYNC_WAVE, 4, 5); +		   ipu_dc_write_tmpl(4, WROD(0), 0, map, SYNC_WAVE, 0, 5); +		} else { +		   ipu_dc_write_tmpl(5, WROD(0), 0, map, SYNC_WAVE, 8, 5); +		   ipu_dc_write_tmpl(6, WROD(0), 0, map, SYNC_WAVE, 4, 5); +		   ipu_dc_write_tmpl(7, WROD(0), 0, map, SYNC_WAVE, 0, 5); +		} + +		if (sig.Hsync_pol) +			di_gen |= DI_GEN_POLARITY_2; +		if (sig.Vsync_pol) +			di_gen |= DI_GEN_POLARITY_3; + +		if (sig.clk_pol) +			di_gen |= DI_GEN_POL_CLK; + +	} + +	__raw_writel(di_gen, DI_GENERAL(disp)); + +	__raw_writel((--vsync_cnt << DI_VSYNC_SEL_OFFSET) | +			0x00000002, DI_SYNC_AS_GEN(disp)); + +	reg = __raw_readl(DI_POL(disp)); +	reg &= ~(DI_POL_DRDY_DATA_POLARITY | DI_POL_DRDY_POLARITY_15); +	if (sig.enable_pol) +		reg |= DI_POL_DRDY_POLARITY_15; +	if (sig.data_pol) +		reg |= DI_POL_DRDY_DATA_POLARITY; +	__raw_writel(reg, DI_POL(disp)); + +	__raw_writel(width, DC_DISP_CONF2(DC_DISP_ID_SYNC(disp))); + +	return 0; +} + +/* + * This function sets the foreground and background plane global alpha blending + * modes. This function also sets the DP graphic plane according to the + * parameter of IPUv3 DP channel. + * + * @param	channel		IPUv3 DP channel + * + * @param       enable          Boolean to enable or disable global alpha + *                              blending. If disabled, local blending is used. + * + * @param       alpha           Global alpha value. + * + * @return      Returns 0 on success or negative error code on fail + */ +int32_t ipu_disp_set_global_alpha(ipu_channel_t channel, unsigned char enable, +				  uint8_t alpha) +{ +	uint32_t reg; +	uint32_t flow; + +	unsigned char bg_chan; + +	if (channel == MEM_BG_SYNC || channel == MEM_FG_SYNC) +		flow = DP_SYNC; +	else if (channel == MEM_BG_ASYNC0 || channel == MEM_FG_ASYNC0) +		flow = DP_ASYNC0; +	else if (channel == MEM_BG_ASYNC1 || channel == MEM_FG_ASYNC1) +		flow = DP_ASYNC1; +	else +		return -EINVAL; + +	if (channel == MEM_BG_SYNC || channel == MEM_BG_ASYNC0 || +	    channel == MEM_BG_ASYNC1) +		bg_chan = 1; +	else +		bg_chan = 0; + +	if (!g_ipu_clk_enabled) +		clk_enable(g_ipu_clk); + +	if (bg_chan) { +		reg = __raw_readl(DP_COM_CONF(flow)); +		__raw_writel(reg & ~DP_COM_CONF_GWSEL, DP_COM_CONF(flow)); +	} else { +		reg = __raw_readl(DP_COM_CONF(flow)); +		__raw_writel(reg | DP_COM_CONF_GWSEL, DP_COM_CONF(flow)); +	} + +	if (enable) { +		reg = __raw_readl(DP_GRAPH_WIND_CTRL(flow)) & 0x00FFFFFFL; +		__raw_writel(reg | ((uint32_t) alpha << 24), +			     DP_GRAPH_WIND_CTRL(flow)); + +		reg = __raw_readl(DP_COM_CONF(flow)); +		__raw_writel(reg | DP_COM_CONF_GWAM, DP_COM_CONF(flow)); +	} else { +		reg = __raw_readl(DP_COM_CONF(flow)); +		__raw_writel(reg & ~DP_COM_CONF_GWAM, DP_COM_CONF(flow)); +	} + +	reg = __raw_readl(IPU_SRM_PRI2) | 0x8; +	__raw_writel(reg, IPU_SRM_PRI2); + +	if (!g_ipu_clk_enabled) +		clk_disable(g_ipu_clk); + +	return 0; +} + +/* + * This function sets the transparent color key for SDC graphic plane. + * + * @param       channel         Input parameter for the logical channel ID. + * + * @param       enable          Boolean to enable or disable color key + * + * @param       colorKey        24-bit RGB color for transparent color key. + * + * @return      Returns 0 on success or negative error code on fail + */ +int32_t ipu_disp_set_color_key(ipu_channel_t channel, unsigned char enable, +			       uint32_t color_key) +{ +	uint32_t reg, flow; +	int y, u, v; +	int red, green, blue; + +	if (channel == MEM_BG_SYNC || channel == MEM_FG_SYNC) +		flow = DP_SYNC; +	else if (channel == MEM_BG_ASYNC0 || channel == MEM_FG_ASYNC0) +		flow = DP_ASYNC0; +	else if (channel == MEM_BG_ASYNC1 || channel == MEM_FG_ASYNC1) +		flow = DP_ASYNC1; +	else +		return -EINVAL; + +	if (!g_ipu_clk_enabled) +		clk_enable(g_ipu_clk); + +	color_key_4rgb = 1; +	/* Transform color key from rgb to yuv if CSC is enabled */ +	if (((fg_csc_type == RGB2YUV) && (bg_csc_type == YUV2YUV)) || +		((fg_csc_type == YUV2YUV) && (bg_csc_type == RGB2YUV)) || +		((fg_csc_type == YUV2YUV) && (bg_csc_type == YUV2YUV)) || +		((fg_csc_type == YUV2RGB) && (bg_csc_type == YUV2RGB))) { + +		debug("color key 0x%x need change to yuv fmt\n", color_key); + +		red = (color_key >> 16) & 0xFF; +		green = (color_key >> 8) & 0xFF; +		blue = color_key & 0xFF; + +		y = rgb_to_yuv(0, red, green, blue); +		u = rgb_to_yuv(1, red, green, blue); +		v = rgb_to_yuv(2, red, green, blue); +		color_key = (y << 16) | (u << 8) | v; + +		color_key_4rgb = 0; + +		debug("color key change to yuv fmt 0x%x\n", color_key); +	} + +	if (enable) { +		reg = __raw_readl(DP_GRAPH_WIND_CTRL(flow)) & 0xFF000000L; +		__raw_writel(reg | color_key, DP_GRAPH_WIND_CTRL(flow)); + +		reg = __raw_readl(DP_COM_CONF(flow)); +		__raw_writel(reg | DP_COM_CONF_GWCKE, DP_COM_CONF(flow)); +	} else { +		reg = __raw_readl(DP_COM_CONF(flow)); +		__raw_writel(reg & ~DP_COM_CONF_GWCKE, DP_COM_CONF(flow)); +	} + +	reg = __raw_readl(IPU_SRM_PRI2) | 0x8; +	__raw_writel(reg, IPU_SRM_PRI2); + +	if (!g_ipu_clk_enabled) +		clk_disable(g_ipu_clk); + +	return 0; +} diff --git a/drivers/video/ipu_regs.h b/drivers/video/ipu_regs.h new file mode 100644 index 00000000000..36f07bbee33 --- /dev/null +++ b/drivers/video/ipu_regs.h @@ -0,0 +1,418 @@ +/* + * Porting to u-boot: + * + * (C) Copyright 2010 + * Stefano Babic, DENX Software Engineering, sbabic@denx.de + * + * Linux IPU driver for MX51: + * + * (C) Copyright 2005-2009 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __IPU_REGS_INCLUDED__ +#define __IPU_REGS_INCLUDED__ + +#define IPU_DISP0_BASE		0x00000000 +#define IPU_MCU_T_DEFAULT	8 +#define IPU_DISP1_BASE		(IPU_MCU_T_DEFAULT << 25) +#define IPU_CM_REG_BASE		0x1E000000 +#define IPU_STAT_REG_BASE	0x1E000200 +#define IPU_IDMAC_REG_BASE	0x1E008000 +#define IPU_ISP_REG_BASE	0x1E010000 +#define IPU_DP_REG_BASE		0x1E018000 +#define IPU_IC_REG_BASE		0x1E020000 +#define IPU_IRT_REG_BASE	0x1E028000 +#define IPU_CSI0_REG_BASE	0x1E030000 +#define IPU_CSI1_REG_BASE	0x1E038000 +#define IPU_DI0_REG_BASE	0x1E040000 +#define IPU_DI1_REG_BASE	0x1E048000 +#define IPU_SMFC_REG_BASE	0x1E050000 +#define IPU_DC_REG_BASE		0x1E058000 +#define IPU_DMFC_REG_BASE	0x1E060000 +#define IPU_CPMEM_REG_BASE	0x1F000000 +#define IPU_LUT_REG_BASE	0x1F020000 +#define IPU_SRM_REG_BASE	0x1F040000 +#define IPU_TPM_REG_BASE	0x1F060000 +#define IPU_DC_TMPL_REG_BASE	0x1F080000 +#define IPU_ISP_TBPR_REG_BASE	0x1F0C0000 +#define IPU_VDI_REG_BASE	0x1E068000 + + +extern u32 *ipu_dc_tmpl_reg; + +#define DC_EVT_NF		0 +#define DC_EVT_NL		1 +#define DC_EVT_EOF		2 +#define DC_EVT_NFIELD		3 +#define DC_EVT_EOL		4 +#define DC_EVT_EOFIELD		5 +#define DC_EVT_NEW_ADDR		6 +#define DC_EVT_NEW_CHAN		7 +#define DC_EVT_NEW_DATA		8 + +#define DC_EVT_NEW_ADDR_W_0	0 +#define DC_EVT_NEW_ADDR_W_1	1 +#define DC_EVT_NEW_CHAN_W_0	2 +#define DC_EVT_NEW_CHAN_W_1	3 +#define DC_EVT_NEW_DATA_W_0	4 +#define DC_EVT_NEW_DATA_W_1	5 +#define DC_EVT_NEW_ADDR_R_0	6 +#define DC_EVT_NEW_ADDR_R_1	7 +#define DC_EVT_NEW_CHAN_R_0	8 +#define DC_EVT_NEW_CHAN_R_1	9 +#define DC_EVT_NEW_DATA_R_0	10 +#define DC_EVT_NEW_DATA_R_1	11 + +/* Software reset for ipu */ +#define SW_IPU_RST	8 + +enum { +	IPU_CONF_DP_EN = 0x00000020, +	IPU_CONF_DI0_EN = 0x00000040, +	IPU_CONF_DI1_EN = 0x00000080, +	IPU_CONF_DMFC_EN = 0x00000400, +	IPU_CONF_DC_EN = 0x00000200, + +	DI0_COUNTER_RELEASE = 0x01000000, +	DI1_COUNTER_RELEASE = 0x02000000, + +	DI_DW_GEN_ACCESS_SIZE_OFFSET = 24, +	DI_DW_GEN_COMPONENT_SIZE_OFFSET = 16, + +	DI_GEN_DI_CLK_EXT = 0x100000, +	DI_GEN_POLARITY_1 = 0x00000001, +	DI_GEN_POLARITY_2 = 0x00000002, +	DI_GEN_POLARITY_3 = 0x00000004, +	DI_GEN_POLARITY_4 = 0x00000008, +	DI_GEN_POLARITY_5 = 0x00000010, +	DI_GEN_POLARITY_6 = 0x00000020, +	DI_GEN_POLARITY_7 = 0x00000040, +	DI_GEN_POLARITY_8 = 0x00000080, +	DI_GEN_POL_CLK = 0x20000, + +	DI_POL_DRDY_DATA_POLARITY = 0x00000080, +	DI_POL_DRDY_POLARITY_15 = 0x00000010, +	DI_VSYNC_SEL_OFFSET = 13, + +	DC_WR_CH_CONF_FIELD_MODE = 0x00000200, +	DC_WR_CH_CONF_PROG_TYPE_OFFSET = 5, +	DC_WR_CH_CONF_PROG_TYPE_MASK = 0x000000E0, +	DC_WR_CH_CONF_PROG_DI_ID = 0x00000004, +	DC_WR_CH_CONF_PROG_DISP_ID_OFFSET = 3, +	DC_WR_CH_CONF_PROG_DISP_ID_MASK = 0x00000018, + +	DP_COM_CONF_FG_EN = 0x00000001, +	DP_COM_CONF_GWSEL = 0x00000002, +	DP_COM_CONF_GWAM = 0x00000004, +	DP_COM_CONF_GWCKE = 0x00000008, +	DP_COM_CONF_CSC_DEF_MASK = 0x00000300, +	DP_COM_CONF_CSC_DEF_OFFSET = 8, +	DP_COM_CONF_CSC_DEF_FG = 0x00000300, +	DP_COM_CONF_CSC_DEF_BG = 0x00000200, +	DP_COM_CONF_CSC_DEF_BOTH = 0x00000100, +	DP_COM_CONF_GAMMA_EN = 0x00001000, +	DP_COM_CONF_GAMMA_YUV_EN = 0x00002000, +}; + +enum di_pins { +	DI_PIN11 = 0, +	DI_PIN12 = 1, +	DI_PIN13 = 2, +	DI_PIN14 = 3, +	DI_PIN15 = 4, +	DI_PIN16 = 5, +	DI_PIN17 = 6, +	DI_PIN_CS = 7, + +	DI_PIN_SER_CLK = 0, +	DI_PIN_SER_RS = 1, +}; + +enum di_sync_wave { +	DI_SYNC_NONE = -1, +	DI_SYNC_CLK = 0, +	DI_SYNC_INT_HSYNC = 1, +	DI_SYNC_HSYNC = 2, +	DI_SYNC_VSYNC = 3, +	DI_SYNC_DE = 5, +}; + +struct ipu_cm { +	u32 conf; +	u32 sisg_ctrl0; +	u32 sisg_ctrl1; +	u32 sisg_set[6]; +	u32 sisg_clear[6]; +	u32 int_ctrl[15]; +	u32 sdma_event[10]; +	u32 srm_pri1; +	u32 srm_pri2; +	u32 fs_proc_flow[3]; +	u32 fs_disp_flow[2]; +	u32 skip; +	u32 disp_alt_conf; +	u32 disp_gen; +	u32 disp_alt[4]; +	u32 snoop; +	u32 mem_rst; +	u32 pm; +	u32 gpr; +	u32 reserved0[26]; +	u32 ch_db_mode_sel[2]; +	u32 reserved1[16]; +	u32 alt_ch_db_mode_sel[2]; +	u32 reserved2[2]; +	u32 ch_trb_mode_sel[2]; +}; + +struct ipu_idmac { +	u32 conf; +	u32 ch_en[2]; +	u32 sep_alpha; +	u32 alt_sep_alpha; +	u32 ch_pri[2]; +	u32 wm_en[2]; +	u32 lock_en[2]; +	u32 sub_addr[5]; +	u32 bndm_en[2]; +	u32 sc_cord[2]; +	u32 reserved[45]; +	u32 ch_busy[2]; +}; + +struct ipu_com_async { +	u32 com_conf_async; +	u32 graph_wind_ctrl_async; +	u32 fg_pos_async; +	u32 cur_pos_async; +	u32 cur_map_async; +	u32 gamma_c_async[8]; +	u32 gamma_s_async[4]; +	u32 dp_csca_async[4]; +	u32 dp_csc_async[2]; +}; + +struct ipu_dp { +	u32 com_conf_sync; +	u32 graph_wind_ctrl_sync; +	u32 fg_pos_sync; +	u32 cur_pos_sync; +	u32 cur_map_sync; +	u32 gamma_c_sync[8]; +	u32 gamma_s_sync[4]; +	u32 csca_sync[4]; +	u32 csc_sync[2]; +	u32 cur_pos_alt; +	struct ipu_com_async async[2]; +}; + +struct ipu_di { +	u32 general; +	u32 bs_clkgen0; +	u32 bs_clkgen1; +	u32 sw_gen0[9]; +	u32 sw_gen1[9]; +	u32 sync_as; +	u32 dw_gen[12]; +	u32 dw_set[48]; +	u32 stp_rep[4]; +	u32 stp_rep9; +	u32 ser_conf; +	u32 ssc; +	u32 pol; +	u32 aw0; +	u32 aw1; +	u32 scr_conf; +	u32 stat; +}; + +struct ipu_stat { +	u32 int_stat[15]; +	u32 cur_buf[2]; +	u32 alt_cur_buf_0; +	u32 alt_cur_buf_1; +	u32 srm_stat; +	u32 proc_task_stat; +	u32 disp_task_stat; +	u32 triple_cur_buf[4]; +	u32 ch_buf0_rdy[2]; +	u32 ch_buf1_rdy[2]; +	u32 alt_ch_buf0_rdy[2]; +	u32 alt_ch_buf1_rdy[2]; +	u32 ch_buf2_rdy[2]; +}; + +struct ipu_dc_ch { +	u32 wr_ch_conf; +	u32 wr_ch_addr; +	u32 rl[5]; +}; + +struct ipu_dc { +	struct ipu_dc_ch dc_ch0_1_2[3]; +	u32 cmd_ch_conf_3; +	u32 cmd_ch_conf_4; +	struct ipu_dc_ch dc_ch5_6[2]; +	struct ipu_dc_ch dc_ch8; +	u32 rl6_ch_8; +	struct ipu_dc_ch dc_ch9; +	u32 rl6_ch_9; +	u32 gen; +	u32 disp_conf1[4]; +	u32 disp_conf2[4]; +	u32 di0_conf[2]; +	u32 di1_conf[2]; +	u32 dc_map_ptr[15]; +	u32 dc_map_val[12]; +	u32 udge[16]; +	u32 lla[2]; +	u32 r_lla[2]; +	u32 wr_ch_addr_5_alt; +	u32 stat; +}; + +struct ipu_dmfc { +	u32 rd_chan; +	u32 wr_chan; +	u32 wr_chan_def; +	u32 dp_chan; +	u32 dp_chan_def; +	u32 general[2]; +	u32 ic_ctrl; +	u32 wr_chan_alt; +	u32 wr_chan_def_alt; +	u32 general1_alt; +	u32 stat; +}; + +#define IPU_CM_REG		((struct ipu_cm *)(IPU_CTRL_BASE_ADDR + \ +				IPU_CM_REG_BASE)) +#define IPU_CONF		(&IPU_CM_REG->conf) +#define IPU_SRM_PRI1		(&IPU_CM_REG->srm_pri1) +#define IPU_SRM_PRI2		(&IPU_CM_REG->srm_pri2) +#define IPU_FS_PROC_FLOW1	(&IPU_CM_REG->fs_proc_flow[0]) +#define IPU_FS_PROC_FLOW2	(&IPU_CM_REG->fs_proc_flow[1]) +#define IPU_FS_PROC_FLOW3	(&IPU_CM_REG->fs_proc_flow[2]) +#define IPU_FS_DISP_FLOW1	(&IPU_CM_REG->fs_disp_flow[0]) +#define IPU_DISP_GEN		(&IPU_CM_REG->disp_gen) +#define IPU_MEM_RST		(&IPU_CM_REG->mem_rst) +#define IPU_GPR			(&IPU_CM_REG->gpr) +#define IPU_CHA_DB_MODE_SEL(ch)	(&IPU_CM_REG->ch_db_mode_sel[ch / 32]) + +#define IPU_STAT		((struct ipu_stat *)(IPU_CTRL_BASE_ADDR + \ +				IPU_STAT_REG_BASE)) +#define IPU_CHA_CUR_BUF(ch)	(&IPU_STAT->cur_buf[ch / 32]) +#define IPU_CHA_BUF0_RDY(ch)	(&IPU_STAT->ch_buf0_rdy[ch / 32]) +#define IPU_CHA_BUF1_RDY(ch)	(&IPU_STAT->ch_buf1_rdy[ch / 32]) + +#define IPU_INT_CTRL(n)		(&IPU_CM_REG->int_ctrl[(n) - 1]) + +#define IDMAC_REG		((struct ipu_idmac *)(IPU_CTRL_BASE_ADDR + \ +				IPU_IDMAC_REG_BASE)) +#define IDMAC_CONF		(&IDMAC_REG->conf) +#define IDMAC_CHA_EN(ch)	(&IDMAC_REG->ch_en[ch / 32]) +#define IDMAC_CHA_PRI(ch)	(&IDMAC_REG->ch_pri[ch / 32]) + +#define DI_REG(di)		((struct ipu_di *)(IPU_CTRL_BASE_ADDR + \ +				((di == 1) ? IPU_DI1_REG_BASE : \ +				IPU_DI0_REG_BASE))) +#define DI_GENERAL(di)		(&DI_REG(di)->general) +#define DI_BS_CLKGEN0(di)	(&DI_REG(di)->bs_clkgen0) +#define DI_BS_CLKGEN1(di)	(&DI_REG(di)->bs_clkgen1) + +#define DI_SW_GEN0(di, gen)	(&DI_REG(di)->sw_gen0[gen - 1]) +#define DI_SW_GEN1(di, gen)	(&DI_REG(di)->sw_gen1[gen - 1]) +#define DI_STP_REP(di, gen)	(&DI_REG(di)->stp_rep[(gen - 1) / 2]) +#define DI_SYNC_AS_GEN(di)	(&DI_REG(di)->sync_as) +#define DI_DW_GEN(di, gen)	(&DI_REG(di)->dw_gen[gen]) +#define DI_DW_SET(di, gen, set)	(&DI_REG(di)->dw_set[gen + 12 * set]) +#define DI_POL(di)		(&DI_REG(di)->pol) +#define DI_SCR_CONF(di)		(&DI_REG(di)->scr_conf) + +#define DMFC_REG		((struct ipu_dmfc *)(IPU_CTRL_BASE_ADDR + \ +				IPU_DMFC_REG_BASE)) +#define DMFC_WR_CHAN		(&DMFC_REG->wr_chan) +#define DMFC_WR_CHAN_DEF	(&DMFC_REG->wr_chan_def) +#define DMFC_DP_CHAN		(&DMFC_REG->dp_chan) +#define DMFC_DP_CHAN_DEF	(&DMFC_REG->dp_chan_def) +#define DMFC_GENERAL1		(&DMFC_REG->general[0]) +#define DMFC_IC_CTRL		(&DMFC_REG->ic_ctrl) + + +#define DC_REG			((struct ipu_dc *)(IPU_CTRL_BASE_ADDR + \ +				IPU_DC_REG_BASE)) +#define DC_MAP_CONF_PTR(n)	(&DC_REG->dc_map_ptr[n / 2]) +#define DC_MAP_CONF_VAL(n)	(&DC_REG->dc_map_val[n / 2]) + + +static inline struct ipu_dc_ch *dc_ch_offset(int ch) +{ +	switch (ch) { +	case 0: +	case 1: +	case 2: +		return &DC_REG->dc_ch0_1_2[ch]; +	case 5: +	case 6: +		return &DC_REG->dc_ch5_6[ch - 5]; +	case 8: +		return &DC_REG->dc_ch8; +	case 9: +		return &DC_REG->dc_ch9; +	default: +		printf("%s: invalid channel %d\n", __func__, ch); +		return NULL; +	} + +} + +#define DC_RL_CH(ch, evt)	(&dc_ch_offset(ch)->rl[evt / 2]) + +#define DC_WR_CH_CONF(ch)	(&dc_ch_offset(ch)->wr_ch_conf) +#define DC_WR_CH_ADDR(ch)	(&dc_ch_offset(ch)->wr_ch_addr) + +#define DC_WR_CH_CONF_1		DC_WR_CH_CONF(1) +#define DC_WR_CH_CONF_5		DC_WR_CH_CONF(5) + +#define DC_GEN			(&DC_REG->gen) +#define DC_DISP_CONF2(disp)	(&DC_REG->disp_conf2[disp]) +#define DC_STAT			(&DC_REG->stat) + +#define DP_SYNC 0 +#define DP_ASYNC0 0x60 +#define DP_ASYNC1 0xBC + +#define DP_REG			((struct ipu_dp *)(IPU_CTRL_BASE_ADDR + \ +				IPU_DP_REG_BASE)) +#define DP_COM_CONF(flow)	(&DP_REG->com_conf_sync) +#define DP_GRAPH_WIND_CTRL(flow) (&DP_REG->graph_wind_ctrl_sync) +#define DP_CSC_A_0(flow)	(&DP_REG->csca_sync[0]) +#define DP_CSC_A_1(flow)	(&DP_REG->csca_sync[1]) +#define DP_CSC_A_2(flow)	(&DP_REG->csca_sync[2]) +#define DP_CSC_A_3(flow)	(&DP_REG->csca_sync[3]) + +#define DP_CSC_0(flow)		(&DP_REG->csc_sync[0]) +#define DP_CSC_1(flow)		(&DP_REG->csc_sync[1]) + +/* DC template opcodes */ +#define WROD(lf)		(0x18 | (lf << 1)) + +#endif diff --git a/drivers/video/mxc_ipuv3_fb.c b/drivers/video/mxc_ipuv3_fb.c new file mode 100644 index 00000000000..a66981c27c9 --- /dev/null +++ b/drivers/video/mxc_ipuv3_fb.c @@ -0,0 +1,642 @@ +/* + * Porting to u-boot: + * + * (C) Copyright 2010 + * Stefano Babic, DENX Software Engineering, sbabic@denx.de + * + * MX51 Linux framebuffer: + * + * (C) Copyright 2004-2010 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* #define DEBUG */ +#include <common.h> +#include <asm/errno.h> +#include <linux/string.h> +#include <linux/list.h> +#include <linux/fb.h> +#include <asm/io.h> +#include <malloc.h> +#include <lcd.h> +#include "videomodes.h" +#include "ipu.h" +#include "mxcfb.h" + +DECLARE_GLOBAL_DATA_PTR; + +void *lcd_base;			/* Start of framebuffer memory	*/ +void *lcd_console_address;	/* Start of console buffer	*/ + +int lcd_line_length; +int lcd_color_fg; +int lcd_color_bg; + +short console_col; +short console_row; + +vidinfo_t panel_info; + +static int mxcfb_map_video_memory(struct fb_info *fbi); +static int mxcfb_unmap_video_memory(struct fb_info *fbi); + +void lcd_initcolregs(void) +{ +} + +void lcd_setcolreg(ushort regno, ushort red, ushort green, ushort blue) +{ +} + +void lcd_disable(void) +{ +} + +void lcd_panel_disable(void) +{ +} + +void fb_videomode_to_var(struct fb_var_screeninfo *var, +			 const struct fb_videomode *mode) +{ +	var->xres = mode->xres; +	var->yres = mode->yres; +	var->xres_virtual = mode->xres; +	var->yres_virtual = mode->yres; +	var->xoffset = 0; +	var->yoffset = 0; +	var->pixclock = mode->pixclock; +	var->left_margin = mode->left_margin; +	var->right_margin = mode->right_margin; +	var->upper_margin = mode->upper_margin; +	var->lower_margin = mode->lower_margin; +	var->hsync_len = mode->hsync_len; +	var->vsync_len = mode->vsync_len; +	var->sync = mode->sync; +	var->vmode = mode->vmode & FB_VMODE_MASK; +} + +/* + * Structure containing the MXC specific framebuffer information. + */ +struct mxcfb_info { +	int blank; +	ipu_channel_t ipu_ch; +	int ipu_di; +	u32 ipu_di_pix_fmt; +	unsigned char overlay; +	unsigned char alpha_chan_en; +	dma_addr_t alpha_phy_addr0; +	dma_addr_t alpha_phy_addr1; +	void *alpha_virt_addr0; +	void *alpha_virt_addr1; +	uint32_t alpha_mem_len; +	uint32_t cur_ipu_buf; +	uint32_t cur_ipu_alpha_buf; + +	u32 pseudo_palette[16]; +}; + +enum { +	BOTH_ON, +	SRC_ON, +	TGT_ON, +	BOTH_OFF +}; + +static unsigned long default_bpp = 16; +static unsigned char g_dp_in_use; +static struct fb_info *mxcfb_info[3]; +static int ext_clk_used; + +static uint32_t bpp_to_pixfmt(struct fb_info *fbi) +{ +	uint32_t pixfmt = 0; + +	debug("bpp_to_pixfmt: %d\n", fbi->var.bits_per_pixel); + +	if (fbi->var.nonstd) +		return fbi->var.nonstd; + +	switch (fbi->var.bits_per_pixel) { +	case 24: +		pixfmt = IPU_PIX_FMT_BGR24; +		break; +	case 32: +		pixfmt = IPU_PIX_FMT_BGR32; +		break; +	case 16: +		pixfmt = IPU_PIX_FMT_RGB565; +		break; +	} +	return pixfmt; +} + +/* + * Set fixed framebuffer parameters based on variable settings. + * + * @param       info     framebuffer information pointer + */ +static int mxcfb_set_fix(struct fb_info *info) +{ +	struct fb_fix_screeninfo *fix = &info->fix; +	struct fb_var_screeninfo *var = &info->var; + +	fix->line_length = var->xres_virtual * var->bits_per_pixel / 8; + +	fix->type = FB_TYPE_PACKED_PIXELS; +	fix->accel = FB_ACCEL_NONE; +	fix->visual = FB_VISUAL_TRUECOLOR; +	fix->xpanstep = 1; +	fix->ypanstep = 1; + +	return 0; +} + +static int setup_disp_channel1(struct fb_info *fbi) +{ +	ipu_channel_params_t params; +	struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par; + +	memset(¶ms, 0, sizeof(params)); +	params.mem_dp_bg_sync.di = mxc_fbi->ipu_di; + +	debug("%s called\n", __func__); +	/* +	 * Assuming interlaced means yuv output, below setting also +	 * valid for mem_dc_sync. FG should have the same vmode as BG. +	 */ +	if (fbi->var.vmode & FB_VMODE_INTERLACED) { +		params.mem_dp_bg_sync.interlaced = 1; +		params.mem_dp_bg_sync.out_pixel_fmt = +			IPU_PIX_FMT_YUV444; +	} else { +		if (mxc_fbi->ipu_di_pix_fmt) { +			params.mem_dp_bg_sync.out_pixel_fmt = +				mxc_fbi->ipu_di_pix_fmt; +		} else { +			params.mem_dp_bg_sync.out_pixel_fmt = +				IPU_PIX_FMT_RGB666; +		} +	} +	params.mem_dp_bg_sync.in_pixel_fmt = bpp_to_pixfmt(fbi); +	if (mxc_fbi->alpha_chan_en) +		params.mem_dp_bg_sync.alpha_chan_en = 1; + +	ipu_init_channel(mxc_fbi->ipu_ch, ¶ms); + +	return 0; +} + +static int setup_disp_channel2(struct fb_info *fbi) +{ +	int retval = 0; +	struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par; + +	mxc_fbi->cur_ipu_buf = 1; +	if (mxc_fbi->alpha_chan_en) +		mxc_fbi->cur_ipu_alpha_buf = 1; + +	fbi->var.xoffset = fbi->var.yoffset = 0; + +	debug("%s: %x %d %d %d %lx %lx\n", +		__func__, +		mxc_fbi->ipu_ch, +		fbi->var.xres, +		fbi->var.yres, +		fbi->fix.line_length, +		fbi->fix.smem_start, +		fbi->fix.smem_start + +		(fbi->fix.line_length * fbi->var.yres)); + +	retval = ipu_init_channel_buffer(mxc_fbi->ipu_ch, IPU_INPUT_BUFFER, +					 bpp_to_pixfmt(fbi), +					 fbi->var.xres, fbi->var.yres, +					 fbi->fix.line_length, +					 fbi->fix.smem_start + +					 (fbi->fix.line_length * fbi->var.yres), +					 fbi->fix.smem_start, +					 0, 0); +	if (retval) +		printf("ipu_init_channel_buffer error %d\n", retval); + +	return retval; +} + +/* + * Set framebuffer parameters and change the operating mode. + * + * @param       info     framebuffer information pointer + */ +static int mxcfb_set_par(struct fb_info *fbi) +{ +	int retval = 0; +	u32 mem_len; +	ipu_di_signal_cfg_t sig_cfg; +	struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par; +	uint32_t out_pixel_fmt; + +	ipu_disable_channel(mxc_fbi->ipu_ch); +	ipu_uninit_channel(mxc_fbi->ipu_ch); +	mxcfb_set_fix(fbi); + +	mem_len = fbi->var.yres_virtual * fbi->fix.line_length; +	if (!fbi->fix.smem_start || (mem_len > fbi->fix.smem_len)) { +		if (fbi->fix.smem_start) +			mxcfb_unmap_video_memory(fbi); + +		if (mxcfb_map_video_memory(fbi) < 0) +			return -ENOMEM; +	} + +	setup_disp_channel1(fbi); + +	memset(&sig_cfg, 0, sizeof(sig_cfg)); +	if (fbi->var.vmode & FB_VMODE_INTERLACED) { +		sig_cfg.interlaced = 1; +		out_pixel_fmt = IPU_PIX_FMT_YUV444; +	} else { +		if (mxc_fbi->ipu_di_pix_fmt) +			out_pixel_fmt = mxc_fbi->ipu_di_pix_fmt; +		else +			out_pixel_fmt = IPU_PIX_FMT_RGB666; +	} +	if (fbi->var.vmode & FB_VMODE_ODD_FLD_FIRST) /* PAL */ +		sig_cfg.odd_field_first = 1; +	if ((fbi->var.sync & FB_SYNC_EXT) || ext_clk_used) +		sig_cfg.ext_clk = 1; +	if (fbi->var.sync & FB_SYNC_HOR_HIGH_ACT) +		sig_cfg.Hsync_pol = 1; +	if (fbi->var.sync & FB_SYNC_VERT_HIGH_ACT) +		sig_cfg.Vsync_pol = 1; +	if (!(fbi->var.sync & FB_SYNC_CLK_LAT_FALL)) +		sig_cfg.clk_pol = 1; +	if (fbi->var.sync & FB_SYNC_DATA_INVERT) +		sig_cfg.data_pol = 1; +	if (!(fbi->var.sync & FB_SYNC_OE_LOW_ACT)) +		sig_cfg.enable_pol = 1; +	if (fbi->var.sync & FB_SYNC_CLK_IDLE_EN) +		sig_cfg.clkidle_en = 1; + +	debug("pixclock = %ul Hz\n", +		(u32) (PICOS2KHZ(fbi->var.pixclock) * 1000UL)); + +	if (ipu_init_sync_panel(mxc_fbi->ipu_di, +				(PICOS2KHZ(fbi->var.pixclock)) * 1000UL, +				fbi->var.xres, fbi->var.yres, +				out_pixel_fmt, +				fbi->var.left_margin, +				fbi->var.hsync_len, +				fbi->var.right_margin, +				fbi->var.upper_margin, +				fbi->var.vsync_len, +				fbi->var.lower_margin, +				0, sig_cfg) != 0) { +		puts("mxcfb: Error initializing panel.\n"); +		return -EINVAL; +	} + +	retval = setup_disp_channel2(fbi); +	if (retval) +		return retval; + +	if (mxc_fbi->blank == FB_BLANK_UNBLANK) +		ipu_enable_channel(mxc_fbi->ipu_ch); + +	return retval; +} + +/* + * Check framebuffer variable parameters and adjust to valid values. + * + * @param       var      framebuffer variable parameters + * + * @param       info     framebuffer information pointer + */ +static int mxcfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) +{ +	u32 vtotal; +	u32 htotal; + +	if (var->xres_virtual < var->xres) +		var->xres_virtual = var->xres; +	if (var->yres_virtual < var->yres) +		var->yres_virtual = var->yres; + +	if ((var->bits_per_pixel != 32) && (var->bits_per_pixel != 24) && +	    (var->bits_per_pixel != 16) && (var->bits_per_pixel != 8)) +		var->bits_per_pixel = default_bpp; + +	switch (var->bits_per_pixel) { +	case 8: +		var->red.length = 3; +		var->red.offset = 5; +		var->red.msb_right = 0; + +		var->green.length = 3; +		var->green.offset = 2; +		var->green.msb_right = 0; + +		var->blue.length = 2; +		var->blue.offset = 0; +		var->blue.msb_right = 0; + +		var->transp.length = 0; +		var->transp.offset = 0; +		var->transp.msb_right = 0; +		break; +	case 16: +		var->red.length = 5; +		var->red.offset = 11; +		var->red.msb_right = 0; + +		var->green.length = 6; +		var->green.offset = 5; +		var->green.msb_right = 0; + +		var->blue.length = 5; +		var->blue.offset = 0; +		var->blue.msb_right = 0; + +		var->transp.length = 0; +		var->transp.offset = 0; +		var->transp.msb_right = 0; +		break; +	case 24: +		var->red.length = 8; +		var->red.offset = 16; +		var->red.msb_right = 0; + +		var->green.length = 8; +		var->green.offset = 8; +		var->green.msb_right = 0; + +		var->blue.length = 8; +		var->blue.offset = 0; +		var->blue.msb_right = 0; + +		var->transp.length = 0; +		var->transp.offset = 0; +		var->transp.msb_right = 0; +		break; +	case 32: +		var->red.length = 8; +		var->red.offset = 16; +		var->red.msb_right = 0; + +		var->green.length = 8; +		var->green.offset = 8; +		var->green.msb_right = 0; + +		var->blue.length = 8; +		var->blue.offset = 0; +		var->blue.msb_right = 0; + +		var->transp.length = 8; +		var->transp.offset = 24; +		var->transp.msb_right = 0; +		break; +	} + +	if (var->pixclock < 1000) { +		htotal = var->xres + var->right_margin + var->hsync_len + +		    var->left_margin; +		vtotal = var->yres + var->lower_margin + var->vsync_len + +		    var->upper_margin; +		var->pixclock = (vtotal * htotal * 6UL) / 100UL; +		var->pixclock = KHZ2PICOS(var->pixclock); +		printf("pixclock set for 60Hz refresh = %u ps\n", +			var->pixclock); +	} + +	var->height = -1; +	var->width = -1; +	var->grayscale = 0; + +	return 0; +} + +static int mxcfb_map_video_memory(struct fb_info *fbi) +{ +	if (fbi->fix.smem_len < fbi->var.yres_virtual * fbi->fix.line_length) { +		fbi->fix.smem_len = fbi->var.yres_virtual * +				    fbi->fix.line_length; +	} + +	fbi->screen_base = (char *)lcd_base; +	fbi->fix.smem_start = (unsigned long)lcd_base; +	if (fbi->screen_base == 0) { +		puts("Unable to allocate framebuffer memory\n"); +		fbi->fix.smem_len = 0; +		fbi->fix.smem_start = 0; +		return -EBUSY; +	} + +	debug("allocated fb @ paddr=0x%08X, size=%d.\n", +		(uint32_t) fbi->fix.smem_start, fbi->fix.smem_len); + +	fbi->screen_size = fbi->fix.smem_len; + +	/* Clear the screen */ +	memset((char *)fbi->screen_base, 0, fbi->fix.smem_len); + +	return 0; +} + +static int mxcfb_unmap_video_memory(struct fb_info *fbi) +{ +	fbi->screen_base = 0; +	fbi->fix.smem_start = 0; +	fbi->fix.smem_len = 0; +	return 0; +} + +/* + * Initializes the framebuffer information pointer. After allocating + * sufficient memory for the framebuffer structure, the fields are + * filled with custom information passed in from the configurable + * structures.  This includes information such as bits per pixel, + * color maps, screen width/height and RGBA offsets. + * + * @return      Framebuffer structure initialized with our information + */ +static struct fb_info *mxcfb_init_fbinfo(void) +{ +#define BYTES_PER_LONG 4 +#define PADDING (BYTES_PER_LONG - (sizeof(struct fb_info) % BYTES_PER_LONG)) +	struct fb_info *fbi; +	struct mxcfb_info *mxcfbi; +	char *p; +	int size = sizeof(struct mxcfb_info) + PADDING + +		sizeof(struct fb_info); + +	debug("%s: %d %d %d %d\n", +		__func__, +		PADDING, +		size, +		sizeof(struct mxcfb_info), +		sizeof(struct fb_info)); +	/* +	 * Allocate sufficient memory for the fb structure +	 */ + +	p = malloc(size); +	if (!p) +		return NULL; + +	memset(p, 0, size); + +	fbi = (struct fb_info *)p; +	fbi->par = p + sizeof(struct fb_info) + PADDING; + +	mxcfbi = (struct mxcfb_info *)fbi->par; +	debug("Framebuffer structures at: fbi=0x%x mxcfbi=0x%x\n", +		(unsigned int)fbi, (unsigned int)mxcfbi); + +	fbi->var.activate = FB_ACTIVATE_NOW; + +	fbi->flags = FBINFO_FLAG_DEFAULT; +	fbi->pseudo_palette = mxcfbi->pseudo_palette; + +	return fbi; +} + +/* + * Probe routine for the framebuffer driver. It is called during the + * driver binding process.      The following functions are performed in + * this routine: Framebuffer initialization, Memory allocation and + * mapping, Framebuffer registration, IPU initialization. + * + * @return      Appropriate error code to the kernel common code + */ +static int mxcfb_probe(u32 interface_pix_fmt, struct fb_videomode *mode) +{ +	struct fb_info *fbi; +	struct mxcfb_info *mxcfbi; +	int ret = 0; + +	/* +	 * Initialize FB structures +	 */ +	fbi = mxcfb_init_fbinfo(); +	if (!fbi) { +		ret = -ENOMEM; +		goto err0; +	} +	mxcfbi = (struct mxcfb_info *)fbi->par; + +	if (!g_dp_in_use) { +		mxcfbi->ipu_ch = MEM_BG_SYNC; +		mxcfbi->blank = FB_BLANK_UNBLANK; +	} else { +		mxcfbi->ipu_ch = MEM_DC_SYNC; +		mxcfbi->blank = FB_BLANK_POWERDOWN; +	} + +	mxcfbi->ipu_di = 0; + +	ipu_disp_set_global_alpha(mxcfbi->ipu_ch, 1, 0x80); +	ipu_disp_set_color_key(mxcfbi->ipu_ch, 0, 0); +	strcpy(fbi->fix.id, "DISP3 BG"); + +	g_dp_in_use = 1; + +	mxcfb_info[mxcfbi->ipu_di] = fbi; + +	/* Need dummy values until real panel is configured */ +	fbi->var.xres = 640; +	fbi->var.yres = 480; +	fbi->var.bits_per_pixel = 16; + +	mxcfbi->ipu_di_pix_fmt = interface_pix_fmt; +	fb_videomode_to_var(&fbi->var, mode); + +	mxcfb_check_var(&fbi->var, fbi); + +	/* Default Y virtual size is 2x panel size */ +	fbi->var.yres_virtual = fbi->var.yres * 2; + +	mxcfb_set_fix(fbi); + +	/* alocate fb first */ +	if (mxcfb_map_video_memory(fbi) < 0) +		return -ENOMEM; + +	mxcfb_set_par(fbi); + +	/* Setting panel_info for lcd */ +	panel_info.cmap = NULL; +	panel_info.vl_col = fbi->var.xres; +	panel_info.vl_row = fbi->var.yres; +	panel_info.vl_bpix = LCD_BPP; + +	lcd_line_length = (panel_info.vl_col * NBITS(panel_info.vl_bpix)) / 8; + +	debug("MXC IPUV3 configured\n" +		"XRES = %d YRES = %d BitsXpixel = %d\n", +		panel_info.vl_col, +		panel_info.vl_row, +		panel_info.vl_bpix); + +	ipu_dump_registers(); + +	return 0; + +err0: +	return ret; +} + +int overwrite_console(void) +{ +	/* Keep stdout / stderr on serial, our LCD is for splashscreen only */ +	return 1; +} + +void lcd_ctrl_init(void *lcdbase) +{ +	u32 mem_len = panel_info.vl_col * +		panel_info.vl_row * +		NBITS(panel_info.vl_bpix) / 8; + +	/* +	 * We rely on lcdbase being a physical address, i.e., either MMU off, +	 * or 1-to-1 mapping. Might want to add some virt2phys here. +	 */ +	if (!lcdbase) +		return; + +	memset(lcdbase, 0, mem_len); +} + +int mx51_fb_init(struct fb_videomode *mode) +{ +	int ret; + +	ret = ipu_probe(); +	if (ret) +		puts("Error initializing IPU\n"); + +	lcd_base += 56; + +	debug("Framebuffer at 0x%x\n", (unsigned int)lcd_base); +	ret = mxcfb_probe(IPU_PIX_FMT_RGB666, mode); + +	return ret; +} diff --git a/drivers/video/mxcfb.h b/drivers/video/mxcfb.h new file mode 100644 index 00000000000..d508196603b --- /dev/null +++ b/drivers/video/mxcfb.h @@ -0,0 +1,68 @@ +/* + * Porting to u-boot: + * + * (C) Copyright 2010 + * Stefano Babic, DENX Software Engineering, sbabic@denx.de + * + * Linux IPU driver for MX51: + * + * (C) Copyright 2004-2009 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __ASM_ARCH_MXCFB_H__ +#define __ASM_ARCH_MXCFB_H__ + +#define FB_SYNC_OE_LOW_ACT	0x80000000 +#define FB_SYNC_CLK_LAT_FALL	0x40000000 +#define FB_SYNC_DATA_INVERT	0x20000000 +#define FB_SYNC_CLK_IDLE_EN	0x10000000 +#define FB_SYNC_SHARP_MODE	0x08000000 +#define FB_SYNC_SWAP_RGB	0x04000000 + +struct mxcfb_gbl_alpha { +	int enable; +	int alpha; +}; + +struct mxcfb_loc_alpha { +	int enable; +	int alpha_in_pixel; +	unsigned long alpha_phy_addr0; +	unsigned long alpha_phy_addr1; +}; + +struct mxcfb_color_key { +	int enable; +	__u32 color_key; +}; + +struct mxcfb_pos { +	__u16 x; +	__u16 y; +}; + +struct mxcfb_gamma { +	int enable; +	int constk[16]; +	int slopek[16]; +}; + +#endif diff --git a/include/configs/KUP4K.h b/include/configs/KUP4K.h index 9702d63eb81..c8e0ff287bc 100644 --- a/include/configs/KUP4K.h +++ b/include/configs/KUP4K.h @@ -139,9 +139,9 @@  /* List of I2C addresses to be verified by POST */ -#define I2C_ADDR_LIST	{CONFIG_SYS_I2C_PICIO_ADDR,	\ -			CONFIG_SYS_I2C_RTC_ADDR,	\ -			} +#define CONFIG_SYS_POST_I2C_ADDRS	{CONFIG_SYS_I2C_PICIO_ADDR,	\ +					 CONFIG_SYS_I2C_RTC_ADDR,	\ +					}  #define CONFIG_RTC_PCF8563		/* use Philips PCF8563 RTC	*/ diff --git a/include/configs/KUP4X.h b/include/configs/KUP4X.h index 9613ed9a824..ce731e387d8 100644 --- a/include/configs/KUP4X.h +++ b/include/configs/KUP4X.h @@ -149,9 +149,9 @@  /* List of I2C addresses to be verified by POST */ -#define I2C_ADDR_LIST	{CONFIG_SYS_I2C_PICIO_ADDR,	\ -			CONFIG_SYS_I2C_RTC_ADDR,	\ -			} +#define CONFIG_SYS_POST_I2C_ADDRS	{CONFIG_SYS_I2C_PICIO_ADDR,	\ +					 CONFIG_SYS_I2C_RTC_ADDR,	\ +					}  #define CONFIG_RTC_PCF8563		/* use Philips PCF8563 RTC	*/ diff --git a/include/configs/TB5200.h b/include/configs/TB5200.h index ad86e2e23a3..f336e8d0bc3 100644 --- a/include/configs/TB5200.h +++ b/include/configs/TB5200.h @@ -251,10 +251,10 @@  #define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS	20  /* List of I2C addresses to be verified by POST */ -#undef I2C_ADDR_LIST -#define I2C_ADDR_LIST	{	CONFIG_SYS_I2C_EEPROM_ADDR,	\ -				CONFIG_SYS_I2C_RTC_ADDR,	\ -				CONFIG_SYS_I2C_SLAVE } +#undef CONFIG_SYS_POST_I2C_ADDRS +#define CONFIG_SYS_POST_I2C_ADDRS	{CONFIG_SYS_I2C_EEPROM_ADDR,	\ +					 CONFIG_SYS_I2C_RTC_ADDR,	\ +					 CONFIG_SYS_I2C_SLAVE}  /*   * Flash configuration diff --git a/include/configs/TQM5200.h b/include/configs/TQM5200.h index 2612c7a50ba..794e11b024d 100644 --- a/include/configs/TQM5200.h +++ b/include/configs/TQM5200.h @@ -370,10 +370,10 @@  /* List of I2C addresses to be verified by POST */  #if defined (CONFIG_MINIFAP) -#undef I2C_ADDR_LIST -#define I2C_ADDR_LIST	{	CONFIG_SYS_I2C_EEPROM_ADDR,	\ -				CONFIG_SYS_I2C_HWMON_ADDR,	\ -				CONFIG_SYS_I2C_SLAVE } +#undef CONFIG_SYS_POST_I2C_ADDRS +#define CONFIG_SYS_POST_I2C_ADDRS	{CONFIG_SYS_I2C_EEPROM_ADDR,	\ +					 CONFIG_SYS_I2C_HWMON_ADDR,	\ +					 CONFIG_SYS_I2C_SLAVE}  #endif  /* diff --git a/include/configs/a4m072.h b/include/configs/a4m072.h index 24a04ebefb5..f18bc45c4d1 100644 --- a/include/configs/a4m072.h +++ b/include/configs/a4m072.h @@ -147,27 +147,43 @@  #define CONFIG_PREBOOT				"run try_update"  #define	CONFIG_EXTRA_ENV_SETTINGS					\ -	"bk=run add_mtd ; run add_consolespec ; bootm 200000\0"	\ -	"cf1=diskboot 200000 0:1\0"	\ -	"bootcmd_cf1=run bcf1\0"	\ -	"bcf=setenv bootargs root=/dev/hda3\0"	\ -	"bootcmd_nfs=run bnfs\0"	\ -	"norargs=setenv bootargs root=/dev/mtdblock3 rootfstype=cramfs\0"	\ -	"bootcmd_nor=cp.b ${kernel_addr} 200000 100000; run norargs addip; run bk\0"	\ -	"bnfs=nfs 200000 ${rootpath}/boot/uImage ; run nfsargs addip ; run bk\0"	\ -	"nfsargs=setenv bootargs root=/dev/nfs rw nfsroot=${serverip}:${rootpath}\0"	\ -	"try_update=usb start;sleep 2;usb start;sleep 1;fatload usb 0 2F0000 PCPUUPDT 2FF;usb stop;source 2F0000\0"	\ -	"env_addr=FE060000\0"	\ -	"kernel_addr=FE100000\0"	\ -	"rootfs_addr=FE200000\0"	\ -	"add_mtd=setenv bootargs ${bootargs} mtdparts=phys_mapped_flash:384k(u),640k(e),1m(k),30m(r)\0"	\ -	"bcf1=run cf1; run bcf; run addip; run bk\0"	\ -	"add_consolespec=setenv bootargs ${bootargs} console=/dev/null quiet\0"	\ -	"addip=if test \"${ethaddr}\" != \"00:00:00:00:00:00\" ; then if test -n ${ipaddr}; then setenv bootargs ${bootargs} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}:${netdev}:off panic=1; fi ; fi\0"	\ -	"hostname=CPUP0\0"	\ -	"ethaddr=00:00:00:00:00:00\0"	\ -	"netdev=eth0\0"	\ -	"bootcmd=run bootcmd_nor\0" \ +	"bk=run add_mtd ; run add_consolespec ; bootm 200000\0"		\ +	"cf1=diskboot 200000 0:1\0"					\ +	"bootcmd_cf1=run bcf1\0"					\ +	"bcf=setenv bootargs root=/dev/hda3\0"				\ +	"bootcmd_nfs=run bnfs\0"					\ +	"norargs=setenv bootargs root=/dev/mtdblock3 rootfstype=cramfs "\ +		"panic=1\0"						\ +	"bootcmd_nor=cp.b ${kernel_addr} 200000 100000;"		\ +			"run norargs addip; run bk\0"			\ +	"bnfs=nfs 200000 ${rootpath}/boot/uImage;"			\ +			"run nfsargs addip ; run bk\0"			\ +	"nfsargs=setenv bootargs root=/dev/nfs rw "			\ +				"nfsroot=${serverip}:${rootpath}\0"	\ +	"try_update=usb start;sleep 2;usb start;sleep 1;"		\ +			"fatload usb 0 2F0000 PCPUUPDT 2FF;usb stop;"	\ +			"source 2F0000\0"				\ +	"env_addr=FE060000\0"						\ +	"kernel_addr=FE100000\0"					\ +	"rootfs_addr=FE200000\0"					\ +	"add_mtd=setenv bootargs ${bootargs} mtdparts="			\ +		"phys_mapped_flash:384k(u),640k(e),1m(k),30m(r)\0"	\ +	"bcf1=run cf1; run bcf; run addip; run bk\0"			\ +	"add_consolespec=setenv bootargs ${bootargs} "			\ +				"console=/dev/null quiet\0"		\ +	"addip=if test -n ${ethaddr};"					\ +		"then if test -n ${ipaddr};"				\ +			"then setenv bootargs ${bootargs} "		\ +				"ip=${ipaddr}:${serverip}:${gatewayip}:"\ +				"${netmask}:${hostname}:${netdev}:off;"	\ +			"fi;"						\ +		"else;"							\ +			"setenv bootargs ${bootargs} no_ethaddr;"	\ +		"fi\0"							\ +	"hostname=CPUP0\0"						\ +	"ethaddr=00:00:00:00:00:00\0"					\ +	"netdev=eth0\0"							\ +	"bootcmd=run bootcmd_nor\0" 					\  	""  /*   * IPB Bus clocking configuration. @@ -212,6 +228,7 @@  #define CONFIG_SYS_FLASH_CFI  #define CONFIG_SYS_FLASH_CFI_WIDTH	FLASH_CFI_16BIT  #define CONFIG_SYS_FLASH_BANKS_LIST	{CONFIG_SYS_CS0_START} +#define CONFIG_SYS_FLASH_BANKS_SIZES	{CONFIG_SYS_CS0_SIZE}  /*   * Environment settings diff --git a/include/configs/cm5200.h b/include/configs/cm5200.h index 1b129a2e667..af6769b18d5 100644 --- a/include/configs/cm5200.h +++ b/include/configs/cm5200.h @@ -80,7 +80,9 @@  #define CONFIG_POST		(CONFIG_SYS_POST_MEMORY | CONFIG_SYS_POST_CPU | CONFIG_SYS_POST_I2C)  #define MPC5XXX_SRAM_POST_SIZE	(MPC5XXX_SRAM_SIZE - 4)  /* List of I2C addresses to be verified by POST */ -#define I2C_ADDR_LIST		{ CONFIG_SYS_I2C_SLAVE, CONFIG_SYS_I2C_IO, CONFIG_SYS_I2C_EEPROM } +#define CONFIG_SYS_POST_I2C_ADDRS	{CONFIG_SYS_I2C_SLAVE,	\ +					 CONFIG_SYS_I2C_IO,	\ +					 CONFIG_SYS_I2C_EEPROM}  /* display image timestamps */  #define CONFIG_TIMESTAMP	1 diff --git a/include/configs/corenet_ds.h b/include/configs/corenet_ds.h index 85147d00219..2733fb21e35 100644 --- a/include/configs/corenet_ds.h +++ b/include/configs/corenet_ds.h @@ -213,7 +213,7 @@  #endif  #define CONFIG_SYS_INIT_RAM_END		0x00004000	/* End of used area in RAM */ -#define CONFIG_SYS_GBL_DATA_SIZE	128	/* num bytes initial data */ +#define CONFIG_SYS_GBL_DATA_SIZE	256	/* num bytes initial data */  #define CONFIG_SYS_GBL_DATA_OFFSET	(CONFIG_SYS_INIT_RAM_END - CONFIG_SYS_GBL_DATA_SIZE)  #define CONFIG_SYS_INIT_SP_OFFSET	CONFIG_SYS_GBL_DATA_OFFSET diff --git a/include/configs/lwmon.h b/include/configs/lwmon.h index 1062765f036..9e48857308b 100644 --- a/include/configs/lwmon.h +++ b/include/configs/lwmon.h @@ -349,32 +349,32 @@  /* List of I2C addresses to be verified by POST */  #ifdef CONFIG_USE_FRAM -#define I2C_ADDR_LIST	{  /*	CONFIG_SYS_I2C_AUDIO_ADDR, */	\ -				CONFIG_SYS_I2C_SYSMON_ADDR,	\ -				CONFIG_SYS_I2C_RTC_ADDR,	\ -				CONFIG_SYS_I2C_POWER_A_ADDR,	\ -				CONFIG_SYS_I2C_POWER_B_ADDR,	\ -				CONFIG_SYS_I2C_KEYBD_ADDR,	\ -				CONFIG_SYS_I2C_PICIO_ADDR,	\ -				CONFIG_SYS_I2C_EEPROM_ADDR,	\ -			} +#define CONFIG_SYS_POST_I2C_ADDRS	{/* CONFIG_SYS_I2C_AUDIO_ADDR, */ \ +					 CONFIG_SYS_I2C_SYSMON_ADDR,	\ +					 CONFIG_SYS_I2C_RTC_ADDR,	\ +					 CONFIG_SYS_I2C_POWER_A_ADDR,	\ +					 CONFIG_SYS_I2C_POWER_B_ADDR,	\ +					 CONFIG_SYS_I2C_KEYBD_ADDR,	\ +					 CONFIG_SYS_I2C_PICIO_ADDR,	\ +					 CONFIG_SYS_I2C_EEPROM_ADDR,	\ +					}  #else	/* Use EEPROM - which show up on 8 consequtive addresses */ -#define I2C_ADDR_LIST	{  /*	CONFIG_SYS_I2C_AUDIO_ADDR, */	\ -				CONFIG_SYS_I2C_SYSMON_ADDR,	\ -				CONFIG_SYS_I2C_RTC_ADDR,	\ -				CONFIG_SYS_I2C_POWER_A_ADDR,	\ -				CONFIG_SYS_I2C_POWER_B_ADDR,	\ -				CONFIG_SYS_I2C_KEYBD_ADDR,	\ -				CONFIG_SYS_I2C_PICIO_ADDR,	\ -				CONFIG_SYS_I2C_EEPROM_ADDR+0,	\ -				CONFIG_SYS_I2C_EEPROM_ADDR+1,	\ -				CONFIG_SYS_I2C_EEPROM_ADDR+2,	\ -				CONFIG_SYS_I2C_EEPROM_ADDR+3,	\ -				CONFIG_SYS_I2C_EEPROM_ADDR+4,	\ -				CONFIG_SYS_I2C_EEPROM_ADDR+5,	\ -				CONFIG_SYS_I2C_EEPROM_ADDR+6,	\ -				CONFIG_SYS_I2C_EEPROM_ADDR+7,	\ -			} +#define CONFIG_SYS_POST_I2C_ADDRS	{/* CONFIG_SYS_I2C_AUDIO_ADDR, */ \ +					 CONFIG_SYS_I2C_SYSMON_ADDR,	\ +					 CONFIG_SYS_I2C_RTC_ADDR,	\ +					 CONFIG_SYS_I2C_POWER_A_ADDR,	\ +					 CONFIG_SYS_I2C_POWER_B_ADDR,	\ +					 CONFIG_SYS_I2C_KEYBD_ADDR,	\ +					 CONFIG_SYS_I2C_PICIO_ADDR,	\ +					 CONFIG_SYS_I2C_EEPROM_ADDR+0,	\ +					 CONFIG_SYS_I2C_EEPROM_ADDR+1,	\ +					 CONFIG_SYS_I2C_EEPROM_ADDR+2,	\ +					 CONFIG_SYS_I2C_EEPROM_ADDR+3,	\ +					 CONFIG_SYS_I2C_EEPROM_ADDR+4,	\ +					 CONFIG_SYS_I2C_EEPROM_ADDR+5,	\ +					 CONFIG_SYS_I2C_EEPROM_ADDR+6,	\ +					 CONFIG_SYS_I2C_EEPROM_ADDR+7,	\ +					}  #endif	/* CONFIG_USE_FRAM */  /*----------------------------------------------------------------------- diff --git a/include/configs/lwmon5.h b/include/configs/lwmon5.h index a4e92cce3b7..63e22d400c0 100644 --- a/include/configs/lwmon5.h +++ b/include/configs/lwmon5.h @@ -306,14 +306,13 @@  #define CONFIG_SYS_I2C_KEYBD_ADDR	0x56	/* PIC LWE keyboard		*/  #define CONFIG_SYS_I2C_DSPIC_IO_ADDR	0x57	/* PIC I/O addr               */ -#define I2C_ADDR_LIST	{						\ -			CONFIG_SYS_I2C_RTC_ADDR,			\ -			CONFIG_SYS_I2C_EEPROM_CPU_ADDR,			\ -			CONFIG_SYS_I2C_EEPROM_MB_ADDR,			\ -			CONFIG_SYS_I2C_DSPIC_ADDR,			\ -			CONFIG_SYS_I2C_DSPIC_2_ADDR,			\ -			CONFIG_SYS_I2C_DSPIC_KEYB_ADDR,			\ -			CONFIG_SYS_I2C_DSPIC_IO_ADDR } +#define CONFIG_SYS_POST_I2C_ADDRS	{CONFIG_SYS_I2C_RTC_ADDR,	\ +					 CONFIG_SYS_I2C_EEPROM_CPU_ADDR,\ +					 CONFIG_SYS_I2C_EEPROM_MB_ADDR,	\ +					 CONFIG_SYS_I2C_DSPIC_ADDR,	\ +					 CONFIG_SYS_I2C_DSPIC_2_ADDR,	\ +					 CONFIG_SYS_I2C_DSPIC_KEYB_ADDR,\ +					 CONFIG_SYS_I2C_DSPIC_IO_ADDR }  /*   * Pass open firmware flat tree diff --git a/include/configs/sh7785lcr.h b/include/configs/sh7785lcr.h index 2c18e2f7fdf..6627f99ce30 100644 --- a/include/configs/sh7785lcr.h +++ b/include/configs/sh7785lcr.h @@ -62,8 +62,10 @@  /* MEMORY */  #if defined(CONFIG_SH_32BIT) -#define SH7785LCR_SDRAM_PHYS_BASE	(0x48000000) -#define SH7785LCR_SDRAM_BASE		(0x88000000) +/* 0x40000000 - 0x47FFFFFF does not use */ +#define CONFIG_SH_SDRAM_OFFSET		(0x8000000) +#define SH7785LCR_SDRAM_PHYS_BASE	(0x40000000 + CONFIG_SH_SDRAM_OFFSET) +#define SH7785LCR_SDRAM_BASE		(0x80000000 + CONFIG_SH_SDRAM_OFFSET)  #define SH7785LCR_SDRAM_SIZE		(384 * 1024 * 1024)  #define SH7785LCR_FLASH_BASE_1		(0xa0000000)  #define SH7785LCR_FLASH_BANK_SIZE	(64 * 1024 * 1024) diff --git a/include/configs/spieval.h b/include/configs/spieval.h index b5ac1689b88..880c8a30575 100644 --- a/include/configs/spieval.h +++ b/include/configs/spieval.h @@ -271,10 +271,10 @@  /* List of I2C addresses to be verified by POST */  #if defined (CONFIG_MINIFAP) -#undef I2C_ADDR_LIST -#define I2C_ADDR_LIST	{	CONFIG_SYS_I2C_EEPROM_ADDR,	\ -				CONFIG_SYS_I2C_HWMON_ADDR,	\ -				CONFIG_SYS_I2C_SLAVE } +#undef CONFIG_SYS_POST_I2C_ADDRS +#define CONFIG_SYS_POST_I2C_ADDRS	{CONFIG_SYS_I2C_EEPROM_ADDR,	\ +					 CONFIG_SYS_I2C_HWMON_ADDR,	\ +					 CONFIG_SYS_I2C_SLAVE}  #endif  /* diff --git a/include/configs/vision2.h b/include/configs/vision2.h index a2ecbe50d63..d2d95652476 100644 --- a/include/configs/vision2.h +++ b/include/configs/vision2.h @@ -211,4 +211,18 @@  #define CONFIG_SYS_NO_FLASH +/* + * Framebuffer and LCD + */ +#define CONFIG_PREBOOT +#define CONFIG_LCD +#define CONFIG_VIDEO_MX5 +#define CONFIG_SYS_CONSOLE_ENV_OVERWRITE +#define CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE +#define CONFIG_SYS_CONSOLE_IS_IN_ENV +#define LCD_BPP		LCD_COLOR16 +#define CONFIG_SPLASH_SCREEN +#define CONFIG_CMD_BMP +#define CONFIG_BMP_16BPP +  #endif				/* __CONFIG_H */ diff --git a/include/configs/XPEDITE1000.h b/include/configs/xpedite1000.h index 56058497742..d0f93635333 100644 --- a/include/configs/XPEDITE1000.h +++ b/include/configs/xpedite1000.h @@ -33,6 +33,7 @@  /* High Level Configuration Options */  #define CONFIG_XPEDITE1000	1  #define CONFIG_SYS_BOARD_NAME	"XPedite1000" +#define CONFIG_SYS_FORM_PMC	1  #define CONFIG_4xx		1		/* ... PPC4xx family */  #define CONFIG_440		1  #define CONFIG_440GX		1		/* 440 GX */ @@ -341,8 +342,8 @@ extern void out32(unsigned int, unsigned long);  	"misc_args=ip=on\0"						\  	"set_bootargs=setenv bootargs ${console_args} ${root_args} ${misc_args}\0" \  	"bootfile=/home/user/file\0"					\ -	"osfile=/home/user/uImage-XPedite1000\0"			\ -	"fdtfile=/home/user/xpedite1000.dtb\0"				\ +	"osfile=/home/user/board.uImage\0"				\ +	"fdtfile=/home/user/board.dtb\0"				\  	"ubootfile=/home/user/u-boot.bin\0"				\  	"fdtaddr=c00000\0"						\  	"osaddr=0x1000000\0"						\ diff --git a/include/configs/XPEDITE5170.h b/include/configs/xpedite517x.h index 1851997916c..8df9edd0edf 100644 --- a/include/configs/XPEDITE5170.h +++ b/include/configs/xpedite517x.h @@ -22,7 +22,7 @@   */  /* - * xpedite5170 board configuration file + * xpedite517x board configuration file   */  #ifndef __CONFIG_H  #define __CONFIG_H @@ -34,6 +34,7 @@  #define CONFIG_MPC8641		1	/* MPC8641 specific */  #define CONFIG_XPEDITE5140	1	/* MPC8641HPCN board specific */  #define CONFIG_SYS_BOARD_NAME	"XPedite5170" +#define CONFIG_SYS_FORM_3U_VPX	1  #define CONFIG_LINUX_RESET_VEC	0x100	/* Reset vector used by Linux */  #define CONFIG_BOARD_EARLY_INIT_R	/* Call board_pre_init */  #define CONFIG_BAT_RW		1	/* Use common BAT rw code */ @@ -107,6 +108,21 @@ extern unsigned long get_board_sys_clk(unsigned long dummy);  #define CONFIG_SYS_ALT_MEMTEST  #define CONFIG_SYS_MEMTEST_START	0x10000000  #define CONFIG_SYS_MEMTEST_END		0x20000000 +#define CONFIG_POST			(CONFIG_SYS_POST_MEMORY |\ +					 CONFIG_SYS_POST_I2C) +#define I2C_ADDR_LIST			{CONFIG_SYS_I2C_DS1621_ADDR,	\ +					 CONFIG_SYS_I2C_DS4510_ADDR,	\ +					 CONFIG_SYS_I2C_EEPROM_ADDR,	\ +					 CONFIG_SYS_I2C_LM90_ADDR,	\ +					 CONFIG_SYS_I2C_PCA9553_ADDR,	\ +					 CONFIG_SYS_I2C_PCA953X_ADDR0,	\ +					 CONFIG_SYS_I2C_PCA953X_ADDR1,	\ +					 CONFIG_SYS_I2C_PCA953X_ADDR2,	\ +					 CONFIG_SYS_I2C_PCA953X_ADDR3,	\ +					 CONFIG_SYS_I2C_PEX8518_ADDR,	\ +					 CONFIG_SYS_I2C_RTC_ADDR} +/* The XPedite5170 can host an XMC which has an EEPROM at address 0x50 */ +#define I2C_ADDR_IGNORE_LIST		{0x50}  /*   * Memory map @@ -258,6 +274,7 @@ extern unsigned long get_board_sys_clk(unsigned long dummy);  #define CONFIG_SYS_I2C_DS1621_ADDR	0x48  #define CONFIG_DTT_DS1621  #define CONFIG_DTT_SENSORS		{ 0 } +#define CONFIG_SYS_I2C_LM90_ADDR	0x4c  /* I2C EEPROM - AT24C128B */  #define CONFIG_SYS_I2C_EEPROM_ADDR		0x54 @@ -281,6 +298,7 @@ extern unsigned long get_board_sys_clk(unsigned long dummy);  #define CONFIG_SYS_I2C_PCA953X_ADDR2	0x1e  #define CONFIG_SYS_I2C_PCA953X_ADDR3	0x1f  #define CONFIG_SYS_I2C_PCA953X_ADDR	CONFIG_SYS_I2C_PCA953X_ADDR0 +#define CONFIG_SYS_I2C_PCA9553_ADDR	0x62  /*   * PU = pulled high, PD = pulled low @@ -324,18 +342,18 @@ extern unsigned long get_board_sys_clk(unsigned long dummy);   * Memory space is mapped 1-1, but I/O space must start from 0.   */  /* PCIE1 - PEX8518 */ -#define CONFIG_SYS_PCIE1_MEM_BASE	0x80000000 -#define CONFIG_SYS_PCIE1_MEM_PHYS	CONFIG_SYS_PCIE1_MEM_BASE +#define CONFIG_SYS_PCIE1_MEM_BUS	0x80000000 +#define CONFIG_SYS_PCIE1_MEM_PHYS	CONFIG_SYS_PCIE1_MEM_BUS  #define CONFIG_SYS_PCIE1_MEM_SIZE	0x40000000	/* 1G */ -#define CONFIG_SYS_PCIE1_IO_BASE	0x00000000 +#define CONFIG_SYS_PCIE1_IO_BUS		0x00000000  #define CONFIG_SYS_PCIE1_IO_PHYS	0xe8000000  #define CONFIG_SYS_PCIE1_IO_SIZE	0x00800000	/* 8M */  /* PCIE2 - VPX P1 */ -#define CONFIG_SYS_PCIE2_MEM_BASE	0xc0000000 -#define CONFIG_SYS_PCIE2_MEM_PHYS	CONFIG_SYS_PCIE2_MEM_BASE +#define CONFIG_SYS_PCIE2_MEM_BUS	0xc0000000 +#define CONFIG_SYS_PCIE2_MEM_PHYS	CONFIG_SYS_PCIE2_MEM_BUS  #define CONFIG_SYS_PCIE2_MEM_SIZE	0x10000000	/* 256M */ -#define CONFIG_SYS_PCIE2_IO_BASE	0x00000000 +#define CONFIG_SYS_PCIE2_IO_BUS		0x00000000  #define CONFIG_SYS_PCIE2_IO_PHYS	0xe8800000  #define CONFIG_SYS_PCIE2_IO_SIZE	0x00800000	/* 8M */ @@ -545,6 +563,7 @@ extern unsigned long get_board_sys_clk(unsigned long dummy);  #define CONFIG_CMD_PCA953X  #define CONFIG_CMD_PCA953X_INFO  #define CONFIG_CMD_PCI +#define CONFIG_CMD_PCI_ENUM  #define CONFIG_CMD_PING  #define CONFIG_CMD_REGINFO  #define CONFIG_CMD_SNTP @@ -725,8 +744,8 @@ extern unsigned long get_board_sys_clk(unsigned long dummy);  	"misc_args=ip=on\0"						\  	"set_bootargs=setenv bootargs ${console_args} ${root_args} ${misc_args}\0" \  	"bootfile=/home/user/file\0"					\ -	"osfile=/home/user/uImage-XPedite5170\0"			\ -	"fdtfile=/home/user/xpedite5170.dtb\0"				\ +	"osfile=/home/user/board.uImage\0"				\ +	"fdtfile=/home/user/board.dtb\0"				\  	"ubootfile=/home/user/u-boot.bin\0"				\  	"fdtaddr=c00000\0"						\  	"osaddr=0x1000000\0"						\ diff --git a/include/configs/XPEDITE5200.h b/include/configs/xpedite520x.h index d0e9492b4ed..2f313371c54 100644 --- a/include/configs/XPEDITE5200.h +++ b/include/configs/xpedite520x.h @@ -22,7 +22,7 @@   */  /* - * xpedite5200 board configuration file + * xpedite520x board configuration file   */  #ifndef __CONFIG_H  #define __CONFIG_H @@ -36,6 +36,7 @@  #define CONFIG_MPC8548		1  #define CONFIG_XPEDITE5200	1  #define CONFIG_SYS_BOARD_NAME	"XPedite5200" +#define CONFIG_SYS_FORM_PMC_XMC	1  #define CONFIG_BOARD_EARLY_INIT_R	/* Call board_pre_init */  #ifndef CONFIG_SYS_TEXT_BASE @@ -92,6 +93,13 @@  #define CONFIG_SYS_ALT_MEMTEST  #define CONFIG_SYS_MEMTEST_START	0x10000000  #define CONFIG_SYS_MEMTEST_END		0x20000000 +#define CONFIG_POST			(CONFIG_SYS_POST_MEMORY | \ +					 CONFIG_SYS_POST_I2C) +#define I2C_ADDR_LIST			{CONFIG_SYS_I2C_MAX1237_ADDR,	\ +					 CONFIG_SYS_I2C_EEPROM_ADDR,	\ +					 CONFIG_SYS_I2C_PCA953X_ADDR0,	\ +					 CONFIG_SYS_I2C_PCA953X_ADDR1,	\ +					 CONFIG_SYS_I2C_RTC_ADDR}  /*   * Memory map @@ -250,7 +258,7 @@  #define CONFIG_SYS_PCA953X_BRD_CFG2		0x04  #define CONFIG_SYS_PCA953X_XMC_ROOT0		0x08  #define CONFIG_SYS_PCA953X_FLASH_PASS_CS	0x10 -#define CONFIG_SYS_PCA953X_FLASH_WP		0x20 +#define CONFIG_SYS_PCA953X_NVM_WP		0x20  #define CONFIG_SYS_PCA953X_MONARCH		0x40  #define CONFIG_SYS_PCA953X_EREADY		0x80 @@ -264,14 +272,17 @@  #define CONFIG_SYS_PCA953X_P14_IO6		0x40  #define CONFIG_SYS_PCA953X_P14_IO7		0x80 +/* 12-bit ADC used to measure CPU diode */ +#define CONFIG_SYS_I2C_MAX1237_ADDR		0x34 +  /*   * General PCI   * Memory space is mapped 1-1, but I/O space must start from 0.   */ -#define CONFIG_SYS_PCI1_MEM_BASE	0x80000000 -#define CONFIG_SYS_PCI1_MEM_PHYS	CONFIG_SYS_PCI1_MEM_BASE +#define CONFIG_SYS_PCI1_MEM_BUS		0x80000000 +#define CONFIG_SYS_PCI1_MEM_PHYS	CONFIG_SYS_PCI1_MEM_BUS  #define CONFIG_SYS_PCI1_MEM_SIZE	0x40000000	/* 1G */ -#define CONFIG_SYS_PCI1_IO_BASE		0x00000000 +#define CONFIG_SYS_PCI1_IO_BUS		0x00000000  #define CONFIG_SYS_PCI1_IO_PHYS		0xe8000000  #define CONFIG_SYS_PCI1_IO_SIZE		0x00800000	/* 1M */ @@ -339,6 +350,7 @@  #define CONFIG_CMD_PCA953X  #define CONFIG_CMD_PCA953X_INFO  #define CONFIG_CMD_PCI +#define CONFIG_CMD_PCI_ENUM  #define CONFIG_CMD_PING  #define CONFIG_CMD_SNTP  #define CONFIG_CMD_REGINFO @@ -521,8 +533,8 @@  	"misc_args=ip=on\0"						\  	"set_bootargs=setenv bootargs ${console_args} ${root_args} ${misc_args}\0" \  	"bootfile=/home/user/file\0"					\ -	"osfile=/home/user/uImage-XPedite5200\0"			\ -	"fdtfile=/home/user/xpedite5200.dtb\0"				\ +	"osfile=/home/user/board.uImage\0"				\ +	"fdtfile=/home/user/board.dtb\0"				\  	"ubootfile=/home/user/u-boot.bin\0"				\  	"fdtaddr=c00000\0"						\  	"osaddr=0x1000000\0"						\ diff --git a/include/configs/XPEDITE5370.h b/include/configs/xpedite537x.h index 629dc0d89c6..e7de13a7ccb 100644 --- a/include/configs/XPEDITE5370.h +++ b/include/configs/xpedite537x.h @@ -22,7 +22,7 @@   */  /* - * xpedite5370 board configuration file + * xpedite537x board configuration file   */  #ifndef __CONFIG_H  #define __CONFIG_H @@ -36,6 +36,7 @@  #define CONFIG_MPC8572		1  #define CONFIG_XPEDITE5370	1  #define CONFIG_SYS_BOARD_NAME	"XPedite5370" +#define CONFIG_SYS_FORM_3U_VPX	1  #define CONFIG_BOARD_EARLY_INIT_R	/* Call board_pre_init */  #ifndef CONFIG_SYS_TEXT_BASE @@ -110,6 +111,20 @@ extern unsigned long get_board_ddr_clk(unsigned long dummy);  #define CONFIG_SYS_ALT_MEMTEST  #define CONFIG_SYS_MEMTEST_START	0x10000000  #define CONFIG_SYS_MEMTEST_END		0x20000000 +#define CONFIG_POST			(CONFIG_SYS_POST_MEMORY | \ +					 CONFIG_SYS_POST_I2C) +#define I2C_ADDR_LIST			{CONFIG_SYS_I2C_DS1621_ADDR,	\ +					 CONFIG_SYS_I2C_DS4510_ADDR,	\ +					 CONFIG_SYS_I2C_EEPROM_ADDR,	\ +					 CONFIG_SYS_I2C_LM90_ADDR,	\ +					 CONFIG_SYS_I2C_PCA953X_ADDR0,	\ +					 CONFIG_SYS_I2C_PCA953X_ADDR1,	\ +					 CONFIG_SYS_I2C_PCA953X_ADDR2,	\ +					 CONFIG_SYS_I2C_PCA953X_ADDR3,	\ +					 CONFIG_SYS_I2C_PEX8518_ADDR,	\ +					 CONFIG_SYS_I2C_RTC_ADDR} +/* The XPedite5370 can host an XMC which has an EEPROM at address 0x50 */ +#define I2C_ADDR_IGNORE_LIST		{0x50}  /*   * Memory map @@ -265,6 +280,7 @@ extern unsigned long get_board_ddr_clk(unsigned long dummy);  #define CONFIG_SYS_I2C_DS1621_ADDR	0x48  #define CONFIG_DTT_DS1621  #define CONFIG_DTT_SENSORS		{ 0 } +#define CONFIG_SYS_I2C_LM90_ADDR	0x4c  /* I2C EEPROM - AT24C128B */  #define CONFIG_SYS_I2C_EEPROM_ADDR		0x54 @@ -334,18 +350,18 @@ extern unsigned long get_board_ddr_clk(unsigned long dummy);   * Memory space is mapped 1-1, but I/O space must start from 0.   */  /* PCIE1 - VPX P1 */ -#define CONFIG_SYS_PCIE1_MEM_BASE	0x80000000 -#define CONFIG_SYS_PCIE1_MEM_PHYS	CONFIG_SYS_PCIE1_MEM_BASE +#define CONFIG_SYS_PCIE1_MEM_BUS	0x80000000 +#define CONFIG_SYS_PCIE1_MEM_PHYS	CONFIG_SYS_PCIE1_MEM_BUS  #define CONFIG_SYS_PCIE1_MEM_SIZE	0x40000000	/* 1G */ -#define CONFIG_SYS_PCIE1_IO_BASE	0x00000000 +#define CONFIG_SYS_PCIE1_IO_BUS		0x00000000  #define CONFIG_SYS_PCIE1_IO_PHYS	0xe8000000  #define CONFIG_SYS_PCIE1_IO_SIZE	0x00800000	/* 8M */  /* PCIE2 - PEX8518 */ -#define CONFIG_SYS_PCIE2_MEM_BASE	0xc0000000 -#define CONFIG_SYS_PCIE2_MEM_PHYS	CONFIG_SYS_PCIE2_MEM_BASE +#define CONFIG_SYS_PCIE2_MEM_BUS	0xc0000000 +#define CONFIG_SYS_PCIE2_MEM_PHYS	CONFIG_SYS_PCIE2_MEM_BUS  #define CONFIG_SYS_PCIE2_MEM_SIZE	0x10000000	/* 256M */ -#define CONFIG_SYS_PCIE2_IO_BASE	0x00000000 +#define CONFIG_SYS_PCIE2_IO_BUS		0x00000000  #define CONFIG_SYS_PCIE2_IO_PHYS	0xe8800000  #define CONFIG_SYS_PCIE2_IO_SIZE	0x00800000	/* 8M */ @@ -396,6 +412,7 @@ extern unsigned long get_board_ddr_clk(unsigned long dummy);  #define CONFIG_CMD_PCA953X  #define CONFIG_CMD_PCA953X_INFO  #define CONFIG_CMD_PCI +#define CONFIG_CMD_PCI_ENUM  #define CONFIG_CMD_PING  #define CONFIG_CMD_SAVEENV  #define CONFIG_CMD_SNTP @@ -578,8 +595,8 @@ extern unsigned long get_board_ddr_clk(unsigned long dummy);  	"misc_args=ip=on\0"						\  	"set_bootargs=setenv bootargs ${console_args} ${root_args} ${misc_args}\0" \  	"bootfile=/home/user/file\0"					\ -	"osfile=/home/user/uImage-XPedite5370\0"			\ -	"fdtfile=/home/user/xpedite5370.dtb\0"				\ +	"osfile=/home/user/board.uImage\0"				\ +	"fdtfile=/home/user/board.dtb\0"				\  	"ubootfile=/home/user/u-boot.bin\0"				\  	"fdtaddr=c00000\0"						\  	"osaddr=0x1000000\0"						\ diff --git a/include/configs/xpedite550x.h b/include/configs/xpedite550x.h new file mode 100644 index 00000000000..a849cf93635 --- /dev/null +++ b/include/configs/xpedite550x.h @@ -0,0 +1,607 @@ +/* + * Copyright 2010 Extreme Engineering Solutions, Inc. + * Copyright 2007-2008 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * xpedite550x board configuration file + */ +#ifndef __CONFIG_H +#define __CONFIG_H + +/* + * High Level Configuration Options + */ +#define CONFIG_BOOKE		1	/* BOOKE */ +#define CONFIG_E500		1	/* BOOKE e500 family */ +#define CONFIG_MPC85xx		1	/* MPC8540/60/55/41/48 */ +#define CONFIG_P2020		1 +#define CONFIG_XPEDITE550X	1 +#define CONFIG_SYS_BOARD_NAME	"XPedite5500" +#define CONFIG_SYS_FORM_PMC_XMC	1 +#define CONFIG_PRPMC_PCI_ALIAS	"pci0"	/* Processor PMC interface on pci0 */ +#define CONFIG_BOARD_EARLY_INIT_R	/* Call board_pre_init */ + +#ifndef CONFIG_SYS_TEXT_BASE +#define CONFIG_SYS_TEXT_BASE	0xfff80000 +#endif + +#define CONFIG_PCI		1	/* Enable PCI/PCIE */ +#define CONFIG_PCI_PNP		1	/* do pci plug-and-play */ +#define CONFIG_PCI_SCAN_SHOW	1	/* show pci devices on startup */ +#define CONFIG_PCIE1		1	/* PCIE controler 1 (PEX8112 or XMC) */ +#define CONFIG_FSL_PCI_INIT	1	/* Use common FSL init code */ +#define CONFIG_SYS_PCI_64BIT	1	/* enable 64-bit PCI resources */ +#define CONFIG_FSL_PCIE_RESET	1	/* need PCIe reset errata */ +#define CONFIG_FSL_LAW		1	/* Use common FSL init code */ +#define CONFIG_FSL_ELBC		1 + +/* + * Multicore config + */ +#define CONFIG_MP +#define CONFIG_BPTR_VIRT_ADDR	0xee000000	/* virt boot page address */ +#define CONFIG_MPC8xxx_DISABLE_BPTR		/* Don't leave BPTR enabled */ + +/* + * DDR config + */ +#define CONFIG_FSL_DDR3 +#define CONFIG_SPD_EEPROM		/* Use SPD EEPROM for DDR setup */ +#define CONFIG_DDR_SPD +#define CONFIG_MEM_INIT_VALUE		0xdeadbeef +#define SPD_EEPROM_ADDRESS1			0x54 +#define SPD_EEPROM_OFFSET		0x200	/* OFFSET of SPD in EEPROM */ +#define CONFIG_NUM_DDR_CONTROLLERS	1 +#define CONFIG_DIMM_SLOTS_PER_CTLR	1 +#define CONFIG_CHIP_SELECTS_PER_CTRL 2 +#define CONFIG_DDR_ECC +#define CONFIG_ECC_INIT_VIA_DDRCONTROLLER +#define CONFIG_SYS_DDR_SDRAM_BASE	0x00000000 /* DDR is system memory*/ +#define CONFIG_SYS_SDRAM_BASE		CONFIG_SYS_DDR_SDRAM_BASE +#define CONFIG_VERY_BIG_RAM + +#ifndef __ASSEMBLY__ +extern unsigned long get_board_sys_clk(unsigned long dummy); +extern unsigned long get_board_ddr_clk(unsigned long dummy); +#endif + +#define CONFIG_SYS_CLK_FREQ	get_board_sys_clk(0) /* sysclk for MPC85xx */ +#define CONFIG_DDR_CLK_FREQ	get_board_ddr_clk(0) /* ddrclk for MPC85xx */ + +/* + * These can be toggled for performance analysis, otherwise use default. + */ +#define CONFIG_L2_CACHE			/* toggle L2 cache */ +#define CONFIG_BTB			/* toggle branch predition */ +#define CONFIG_ENABLE_36BIT_PHYS	1 + +/* + * Base addresses -- Note these are effective addresses where the + * actual resources get mapped (not physical addresses) + */ +#define CONFIG_SYS_CCSRBAR_DEFAULT	0xff700000	/* CCSRBAR Default */ +#define CONFIG_SYS_CCSRBAR		0xef000000	/* relocated CCSRBAR */ +#define CONFIG_SYS_CCSRBAR_PHYS	CONFIG_SYS_CCSRBAR	/* physical addr of CCSRBAR */ +#define CONFIG_SYS_IMMR		CONFIG_SYS_CCSRBAR	/* PQII uses CONFIG_SYS_IMMR */ + +/* + * Diagnostics + */ +#define CONFIG_SYS_ALT_MEMTEST +#define CONFIG_SYS_MEMTEST_START	0x10000000 +#define CONFIG_SYS_MEMTEST_END		0x20000000 +#define CONFIG_POST			(CONFIG_SYS_POST_MEMORY | \ +					 CONFIG_SYS_POST_I2C) +#define I2C_ADDR_LIST			{CONFIG_SYS_I2C_EEPROM_ADDR,	\ +					 CONFIG_SYS_I2C_LM75_ADDR,	\ +					 CONFIG_SYS_I2C_LM90_ADDR,	\ +					 CONFIG_SYS_I2C_PCA953X_ADDR0,	\ +					 CONFIG_SYS_I2C_PCA953X_ADDR2,	\ +					 CONFIG_SYS_I2C_PCA953X_ADDR3,	\ +					 CONFIG_SYS_I2C_RTC_ADDR} + +/* + * Memory map + * 0x0000_0000 0x7fff_ffff	DDR			2G Cacheable + * 0x8000_0000 0xbfff_ffff	PCIe1 Mem		1G non-cacheable + * 0xe000_0000 0xe7ff_ffff	SRAM/SSRAM/L1 Cache	128M non-cacheable + * 0xe800_0000 0xe87f_ffff	PCIe1 IO		8M non-cacheable + * 0xee00_0000 0xee00_ffff	Boot page translation	4K non-cacheable + * 0xef00_0000 0xef0f_ffff	CCSR/IMMR		1M non-cacheable + * 0xef80_0000 0xef8f_ffff	NAND Flash		1M non-cacheable + * 0xf000_0000 0xf7ff_ffff	NOR Flash 2		128M non-cacheable + * 0xf800_0000 0xffff_ffff	NOR Flash 1		128M non-cacheable + */ + +#define CONFIG_SYS_LBC_LCRR	(LCRR_CLKDIV_8 | LCRR_EADC_3) + +/* + * NAND flash configuration + */ +#define CONFIG_SYS_NAND_BASE		0xef800000 +#define CONFIG_SYS_NAND_BASE2		0xef840000 /* Unused at this time */ +#define CONFIG_SYS_NAND_BASE_LIST	{CONFIG_SYS_NAND_BASE, \ +					 CONFIG_SYS_NAND_BASE2} +#define CONFIG_SYS_MAX_NAND_DEVICE	2 +#define CONFIG_MTD_NAND_VERIFY_WRITE +#define CONFIG_SYS_NAND_QUIET_TEST	/* 2nd NAND flash not always populated */ +#define CONFIG_NAND_FSL_ELBC + +/* + * NOR flash configuration + */ +#define CONFIG_SYS_FLASH_BASE		0xf8000000 +#define CONFIG_SYS_FLASH_BASE2		0xf0000000 +#define CONFIG_SYS_FLASH_BANKS_LIST	{CONFIG_SYS_FLASH_BASE, CONFIG_SYS_FLASH_BASE2} +#define CONFIG_SYS_MAX_FLASH_BANKS	2		/* number of banks */ +#define CONFIG_SYS_MAX_FLASH_SECT	1024		/* sectors per device */ +#define CONFIG_SYS_FLASH_ERASE_TOUT	60000		/* Flash Erase Timeout (ms) */ +#define CONFIG_SYS_FLASH_WRITE_TOUT	500		/* Flash Write Timeout (ms) */ +#define CONFIG_FLASH_CFI_DRIVER +#define CONFIG_SYS_FLASH_CFI +#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE +#define CONFIG_SYS_FLASH_AUTOPROTECT_LIST	{ {0xfff40000, 0xc0000}, \ +						  {0xf7f40000, 0xc0000} } +#define CONFIG_SYS_MONITOR_BASE	CONFIG_SYS_TEXT_BASE	/* start of monitor */ + +/* + * Chip select configuration + */ +/* NOR Flash 0 on CS0 */ +#define CONFIG_SYS_BR0_PRELIM	(CONFIG_SYS_FLASH_BASE	| \ +				 BR_PS_16		| \ +				 BR_V) +#define CONFIG_SYS_OR0_PRELIM	(OR_AM_128MB		| \ +				 OR_GPCM_CSNT		| \ +				 OR_GPCM_XACS		| \ +				 OR_GPCM_ACS_DIV2	| \ +				 OR_GPCM_SCY_8		| \ +				 OR_GPCM_TRLX		| \ +				 OR_GPCM_EHTR		| \ +				 OR_GPCM_EAD) + +/* NOR Flash 1 on CS1 */ +#define CONFIG_SYS_BR1_PRELIM	(CONFIG_SYS_FLASH_BASE2	| \ +				 BR_PS_16		| \ +				 BR_V) +#define CONFIG_SYS_OR1_PRELIM	CONFIG_SYS_OR0_PRELIM + +/* NAND flash on CS2 */ +#define CONFIG_SYS_BR2_PRELIM	(CONFIG_SYS_NAND_BASE	| \ +				 (2<<BR_DECC_SHIFT)	| \ +				 BR_PS_8		| \ +				 BR_MS_FCM		| \ +				 BR_V) + +/* NAND flash on CS2 */ +#define CONFIG_SYS_OR2_PRELIM	(OR_AM_256KB	| \ +				 OR_FCM_PGS	| \ +				 OR_FCM_CSCT	| \ +				 OR_FCM_CST	| \ +				 OR_FCM_CHT	| \ +				 OR_FCM_SCY_1	| \ +				 OR_FCM_TRLX	| \ +				 OR_FCM_EHTR) + +/* NAND flash on CS3 */ +#define CONFIG_SYS_BR3_PRELIM	(CONFIG_SYS_NAND_BASE2	| \ +				 (2<<BR_DECC_SHIFT)	| \ +				 BR_PS_8		| \ +				 BR_MS_FCM		| \ +				 BR_V) +#define CONFIG_SYS_OR3_PRELIM	CONFIG_SYS_OR2_PRELIM + +/* + * Use L1 as initial stack + */ +#define CONFIG_SYS_INIT_RAM_LOCK	1 +#define CONFIG_SYS_INIT_RAM_ADDR	0xe0000000 +#define CONFIG_SYS_INIT_RAM_END		0x00004000 + +#define CONFIG_SYS_GBL_DATA_SIZE	128	/* num bytes initial data */ +#define CONFIG_SYS_GBL_DATA_OFFSET	(CONFIG_SYS_INIT_RAM_END - CONFIG_SYS_GBL_DATA_SIZE) +#define CONFIG_SYS_INIT_SP_OFFSET	CONFIG_SYS_GBL_DATA_OFFSET + +#define CONFIG_SYS_MONITOR_LEN		(512 * 1024)	/* Reserve 512 KB for Mon */ +#define CONFIG_SYS_MALLOC_LEN		(1024 * 1024)	/* Reserved for malloc */ + +/* + * Serial Port + */ +#define CONFIG_CONS_INDEX		1 +#define CONFIG_SYS_NS16550 +#define CONFIG_SYS_NS16550_SERIAL +#define CONFIG_SYS_NS16550_REG_SIZE	1 +#define CONFIG_SYS_NS16550_CLK		get_bus_freq(0) +#define CONFIG_SYS_NS16550_COM1	(CONFIG_SYS_CCSRBAR+0x4500) +#define CONFIG_SYS_NS16550_COM2	(CONFIG_SYS_CCSRBAR+0x4600) +#define CONFIG_SYS_BAUDRATE_TABLE	\ +	{300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 115200} +#define CONFIG_BAUDRATE			115200 +#define CONFIG_LOADS_ECHO		1	/* echo on for serial download */ +#define CONFIG_SYS_LOADS_BAUD_CHANGE	1	/* allow baudrate change */ + +/* + * Use the HUSH parser + */ +#define CONFIG_SYS_HUSH_PARSER +#define CONFIG_SYS_PROMPT_HUSH_PS2	"> " + +/* + * Pass open firmware flat tree + */ +#define CONFIG_OF_LIBFDT		1 +#define CONFIG_OF_BOARD_SETUP		1 +#define CONFIG_OF_STDOUT_VIA_ALIAS	1 +#define CONFIG_FDT_FIXUP_PCI_IRQ	1 + +/* + * I2C + */ +#define CONFIG_FSL_I2C				/* Use FSL common I2C driver */ +#define CONFIG_HARD_I2C				/* I2C with hardware support */ +#define CONFIG_SYS_I2C_SPEED		400000	/* I2C speed and slave address */ +#define CONFIG_SYS_I2C_SLAVE		0x7F +#define CONFIG_SYS_I2C_OFFSET		0x3000 +#define CONFIG_SYS_I2C2_OFFSET		0x3100 +#define CONFIG_I2C_MULTI_BUS + +/* I2C DS7505 temperature sensor */ +#define CONFIG_DTT_LM75 +#define CONFIG_DTT_SENSORS		{ 0 } +#define CONFIG_SYS_I2C_LM75_ADDR	0x48 + +/* I2C ADT7461 temperature sensor */ +#define CONFIG_SYS_I2C_LM90_ADDR	0x4C + +/* I2C EEPROM - AT24C128B */ +#define CONFIG_SYS_I2C_EEPROM_ADDR		0x54 +#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN		2 +#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS	6	/* 64 byte pages */ +#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS	10	/* take up to 10 msec */ + +/* I2C RTC */ +#define CONFIG_RTC_M41T11		1 +#define CONFIG_SYS_I2C_RTC_ADDR		0x68 +#define CONFIG_SYS_M41T11_BASE_YEAR	2000 + +/* GPIO */ +#define CONFIG_PCA953X +#define CONFIG_SYS_I2C_PCA953X_ADDR0	0x18 +#define CONFIG_SYS_I2C_PCA953X_ADDR1	0x1c +#define CONFIG_SYS_I2C_PCA953X_ADDR2	0x1e +#define CONFIG_SYS_I2C_PCA953X_ADDR3	0x1f +#define CONFIG_SYS_I2C_PCA953X_ADDR	CONFIG_SYS_I2C_PCA953X_ADDR0 + +/* + * GPIO pin definitions, PU = pulled high, PD = pulled low + */ +/* PCA9557 @ 0x18*/ +#define CONFIG_SYS_PCA953X_C0_SER0_EN		0x01 /* PU; UART0 enable (1: enabled) */ +#define CONFIG_SYS_PCA953X_C0_SER0_MODE		0x02 /* PU; UART0 serial mode select (1: RS-485, 0: RS-232) */ +#define CONFIG_SYS_PCA953X_C0_SER1_EN		0x04 /* PU; UART1 enable (1: enabled) */ +#define CONFIG_SYS_PCA953X_C0_SER1_MODE		0x08 /* PU; UART1 serial mode select (1: RS-485, 0: RS-232) */ +#define CONFIG_SYS_PCA953X_C0_FLASH_PASS_CS	0x10 /* PU; Boot flash CS select */ +#define CONFIG_SYS_PCA953X_NVM_WP		0x20 /* PU; Write protection (0: disabled, 1: enabled) */ + +/* PCA9557 @ 0x1e*/ +#define CONFIG_SYS_PCA953X_XMC_GA0		0x01 /* PU; */ +#define CONFIG_SYS_PCA953X_XMC_GA1		0x02 /* PU; */ +#define CONFIG_SYS_PCA953X_XMC_GA2		0x04 /* PU; */ +#define CONFIG_SYS_PCA953X_XMC_WAKE		0x10 /* PU; */ +#define CONFIG_SYS_PCA953X_XMC_BIST		0x20 /* Enable XMC BIST */ +#define CONFIG_SYS_PCA953X_PMC_EREADY		0x40 /* PU; PMC PCI eready */ +#define CONFIG_SYS_PCA953X_PMC_MONARCH		0x80 /* PMC monarch mode enable */ + +/* PCA9557 @ 0x1f */ +#define CONFIG_SYS_PCA953X_MC_GPIO0		0x01 /* PU; */ +#define CONFIG_SYS_PCA953X_MC_GPIO1		0x02 /* PU; */ +#define CONFIG_SYS_PCA953X_MC_GPIO2		0x04 /* PU; */ +#define CONFIG_SYS_PCA953X_MC_GPIO3		0x08 /* PU; */ +#define CONFIG_SYS_PCA953X_MC_GPIO4		0x10 /* PU; */ +#define CONFIG_SYS_PCA953X_MC_GPIO5		0x20 /* PU; */ +#define CONFIG_SYS_PCA953X_MC_GPIO6		0x40 /* PU; */ +#define CONFIG_SYS_PCA953X_MC_GPIO7		0x80 /* PU; */ + +/* + * General PCI + * Memory space is mapped 1-1, but I/O space must start from 0. + */ + +/* controller 1 - PEX8112 or XMC, depending on build option */ +#define CONFIG_SYS_PCIE1_MEM_BUS	0x80000000 +#define CONFIG_SYS_PCIE1_MEM_PHYS	CONFIG_SYS_PCIE1_MEM_BUS +#define CONFIG_SYS_PCIE1_MEM_SIZE	0x40000000	/* 1G */ +#define CONFIG_SYS_PCIE1_IO_BUS		0x00000000 +#define CONFIG_SYS_PCIE1_IO_PHYS	0xe8000000 +#define CONFIG_SYS_PCIE1_IO_SIZE	0x00800000	/* 8M */ + + +/* + * Networking options + */ +#define CONFIG_TSEC_ENET		/* tsec ethernet support */ +#define CONFIG_PHY_GIGE		1	/* Include GbE speed/duplex detection */ +#define CONFIG_NET_MULTI	1 +#define CONFIG_TSEC_TBI +#define CONFIG_MII		1	/* MII PHY management */ +#define CONFIG_MII_DEFAULT_TSEC	1	/* Allow unregistered phys */ +#define CONFIG_ETHPRIME		"eTSEC2" + +#define CONFIG_TSEC1		1 +#define CONFIG_TSEC1_NAME	"eTSEC1" +#define TSEC1_FLAGS		(TSEC_GIGABIT | TSEC_REDUCED) +#define TSEC1_PHY_ADDR		1 +#define TSEC1_PHYIDX		0 +#define CONFIG_HAS_ETH0 + +#define CONFIG_TSEC2		1 +#define CONFIG_TSEC2_NAME	"eTSEC2" +#define TSEC2_FLAGS		(TSEC_GIGABIT | TSEC_REDUCED) +#define TSEC2_PHY_ADDR		2 +#define TSEC2_PHYIDX		0 +#define CONFIG_HAS_ETH1 + +#define CONFIG_TSEC3		1 +#define CONFIG_TSEC3_NAME	"eTSEC3" +#define TSEC3_FLAGS		(TSEC_GIGABIT | TSEC_REDUCED) +#define TSEC3_PHY_ADDR		3 +#define TSEC3_PHYIDX		0 +#define CONFIG_HAS_ETH2 + +/* + * USB + */ +#define CONFIG_USB_STORAGE +#define CONFIG_USB_EHCI +#define CONFIG_USB_EHCI_FSL +#define CONFIG_EHCI_HCD_INIT_AFTER_RESET +#define CONFIG_DOS_PARTITION + +/* + * Command configuration. + */ +#include <config_cmd_default.h> + +#define CONFIG_CMD_ASKENV +#define CONFIG_CMD_DATE +#define CONFIG_CMD_DHCP +#define CONFIG_CMD_DTT +#define CONFIG_CMD_EEPROM +#define CONFIG_CMD_ELF +#define CONFIG_CMD_FLASH +#define CONFIG_CMD_I2C +#define CONFIG_CMD_JFFS2 +#define CONFIG_CMD_MII +#define CONFIG_CMD_NAND +#define CONFIG_CMD_NET +#define CONFIG_CMD_PCA953X +#define CONFIG_CMD_PCA953X_INFO +#define CONFIG_CMD_PCI +#define CONFIG_CMD_PCI_ENUM +#define CONFIG_CMD_PING +#define CONFIG_CMD_REGINFO +#define CONFIG_CMD_SAVEENV +#define CONFIG_CMD_SNTP +#define CONFIG_CMD_USB + +/* + * Miscellaneous configurable options + */ +#define CONFIG_SYS_LONGHELP			/* undef to save memory	*/ +#define CONFIG_SYS_LOAD_ADDR	0x2000000	/* default load address */ +#define CONFIG_SYS_PROMPT	"=> "		/* Monitor Command Prompt */ +#define CONFIG_SYS_CBSIZE	256		/* Console I/O Buffer Size */ +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16) /* Print Buffer Size */ +#define CONFIG_SYS_MAXARGS	16		/* max number of command args */ +#define CONFIG_SYS_BARGSIZE	CONFIG_SYS_CBSIZE	/* Boot Argument Buffer Size */ +#define CONFIG_SYS_HZ		1000		/* decrementer freq: 1ms ticks */ +#define CONFIG_CMDLINE_EDITING	1		/* add command line history	*/ +#define CONFIG_AUTO_COMPLETE	1		/* add autocompletion support */ +#define CONFIG_LOADADDR		0x1000000	/* default location for tftp and bootm */ +#define CONFIG_BOOTDELAY	3		/* -1 disables auto-boot */ +#define CONFIG_PANIC_HANG			/* do not reset board on panic */ +#define CONFIG_PREBOOT				/* enable preboot variable */ +#define CONFIG_FIT		1 +#define CONFIG_FIT_VERBOSE	1 +#define CONFIG_INTEGRITY			/* support booting INTEGRITY OS */ + +/* + * For booting Linux, the board info and command line data + * have to be in the first 16 MB of memory, since this is + * the maximum mapped by the Linux kernel during initialization. + */ +#define CONFIG_SYS_BOOTMAPSZ	(16 << 20)	/* Initial Memory map for Linux*/ +#define CONFIG_SYS_BOOTM_LEN	(16 << 20)	/* Increase max gunzip size */ + +/* + * Boot Flags + */ +#define BOOTFLAG_COLD		0x01		/* Normal Power-On: Boot from FLASH */ +#define BOOTFLAG_WARM		0x02		/* Software reboot */ + +/* + * Environment Configuration + */ +#define CONFIG_ENV_IS_IN_FLASH	1 +#define CONFIG_ENV_SECT_SIZE	0x20000		/* 128k (one sector) for env */ +#define CONFIG_ENV_SIZE		0x8000 +#define CONFIG_ENV_ADDR		(CONFIG_SYS_MONITOR_BASE - (256 * 1024)) + +/* + * Flash memory map: + * fff80000 - ffffffff     Pri U-Boot (512 KB) + * fff40000 - fff7ffff     Pri U-Boot Environment (256 KB) + * fff00000 - fff3ffff     Pri FDT (256KB) + * fef00000 - ffefffff     Pri OS image (16MB) + * f8000000 - feefffff     Pri OS Use/Filesystem (111MB) + * + * f7f80000 - f7ffffff     Sec U-Boot (512 KB) + * f7f40000 - f7f7ffff     Sec U-Boot Environment (256 KB) + * f7f00000 - f7f3ffff     Sec FDT (256KB) + * f6f00000 - f7efffff     Sec OS image (16MB) + * f0000000 - f6efffff     Sec OS Use/Filesystem (111MB) + */ +#define CONFIG_UBOOT1_ENV_ADDR	MK_STR(0xfff80000) +#define CONFIG_UBOOT2_ENV_ADDR	MK_STR(0xf7f80000) +#define CONFIG_FDT1_ENV_ADDR	MK_STR(0xfff00000) +#define CONFIG_FDT2_ENV_ADDR	MK_STR(0xf7f00000) +#define CONFIG_OS1_ENV_ADDR	MK_STR(0xfef00000) +#define CONFIG_OS2_ENV_ADDR	MK_STR(0xf6f00000) + +#define CONFIG_PROG_UBOOT1						\ +	"$download_cmd $loadaddr $ubootfile; "				\ +	"if test $? -eq 0; then "					\ +		"protect off "CONFIG_UBOOT1_ENV_ADDR" +80000; "		\ +		"erase "CONFIG_UBOOT1_ENV_ADDR" +80000; "		\ +		"cp.w $loadaddr "CONFIG_UBOOT1_ENV_ADDR" 40000; "	\ +		"protect on "CONFIG_UBOOT1_ENV_ADDR" +80000; "		\ +		"cmp.b $loadaddr "CONFIG_UBOOT1_ENV_ADDR" 80000; "	\ +		"if test $? -ne 0; then "				\ +			"echo PROGRAM FAILED; "				\ +		"else; "						\ +			"echo PROGRAM SUCCEEDED; "			\ +		"fi; "							\ +	"else; "							\ +		"echo DOWNLOAD FAILED; "				\ +	"fi;" + +#define CONFIG_PROG_UBOOT2						\ +	"$download_cmd $loadaddr $ubootfile; "				\ +	"if test $? -eq 0; then "					\ +		"protect off "CONFIG_UBOOT2_ENV_ADDR" +80000; "		\ +		"erase "CONFIG_UBOOT2_ENV_ADDR" +80000; "		\ +		"cp.w $loadaddr "CONFIG_UBOOT2_ENV_ADDR" 40000; "	\ +		"protect on "CONFIG_UBOOT2_ENV_ADDR" +80000; "		\ +		"cmp.b $loadaddr "CONFIG_UBOOT2_ENV_ADDR" 80000; "	\ +		"if test $? -ne 0; then "				\ +			"echo PROGRAM FAILED; "				\ +		"else; "						\ +			"echo PROGRAM SUCCEEDED; "			\ +		"fi; "							\ +	"else; "							\ +		"echo DOWNLOAD FAILED; "				\ +	"fi;" + +#define CONFIG_BOOT_OS_NET						\ +	"$download_cmd $osaddr $osfile; "				\ +	"if test $? -eq 0; then "					\ +		"if test -n $fdtaddr; then "				\ +			"$download_cmd $fdtaddr $fdtfile; "		\ +			"if test $? -eq 0; then "			\ +				"bootm $osaddr - $fdtaddr; "		\ +			"else; "					\ +				"echo FDT DOWNLOAD FAILED; "		\ +			"fi; "						\ +		"else; "						\ +			"bootm $osaddr; "				\ +		"fi; "							\ +	"else; "							\ +		"echo OS DOWNLOAD FAILED; "				\ +	"fi;" + +#define CONFIG_PROG_OS1							\ +	"$download_cmd $osaddr $osfile; "				\ +	"if test $? -eq 0; then "					\ +		"erase "CONFIG_OS1_ENV_ADDR" +$filesize; "		\ +		"cp.b $osaddr "CONFIG_OS1_ENV_ADDR" $filesize; "	\ +		"cmp.b $osaddr "CONFIG_OS1_ENV_ADDR" $filesize; "	\ +		"if test $? -ne 0; then "				\ +			"echo OS PROGRAM FAILED; "			\ +		"else; "						\ +			"echo OS PROGRAM SUCCEEDED; "			\ +		"fi; "							\ +	"else; "							\ +		"echo OS DOWNLOAD FAILED; "				\ +	"fi;" + +#define CONFIG_PROG_OS2							\ +	"$download_cmd $osaddr $osfile; "				\ +	"if test $? -eq 0; then "					\ +		"erase "CONFIG_OS2_ENV_ADDR" +$filesize; "		\ +		"cp.b $osaddr "CONFIG_OS2_ENV_ADDR" $filesize; "	\ +		"cmp.b $osaddr "CONFIG_OS2_ENV_ADDR" $filesize; "	\ +		"if test $? -ne 0; then "				\ +			"echo OS PROGRAM FAILED; "			\ +		"else; "						\ +			"echo OS PROGRAM SUCCEEDED; "			\ +		"fi; "							\ +	"else; "							\ +		"echo OS DOWNLOAD FAILED; "				\ +	"fi;" + +#define CONFIG_PROG_FDT1						\ +	"$download_cmd $fdtaddr $fdtfile; "				\ +	"if test $? -eq 0; then "					\ +		"erase "CONFIG_FDT1_ENV_ADDR" +$filesize;"		\ +		"cp.b $fdtaddr "CONFIG_FDT1_ENV_ADDR" $filesize; "	\ +		"cmp.b $fdtaddr "CONFIG_FDT1_ENV_ADDR" $filesize; "	\ +		"if test $? -ne 0; then "				\ +			"echo FDT PROGRAM FAILED; "			\ +		"else; "						\ +			"echo FDT PROGRAM SUCCEEDED; "			\ +		"fi; "							\ +	"else; "							\ +		"echo FDT DOWNLOAD FAILED; "				\ +	"fi;" + +#define CONFIG_PROG_FDT2						\ +	"$download_cmd $fdtaddr $fdtfile; "				\ +	"if test $? -eq 0; then "					\ +		"erase "CONFIG_FDT2_ENV_ADDR" +$filesize;"		\ +		"cp.b $fdtaddr "CONFIG_FDT2_ENV_ADDR" $filesize; "	\ +		"cmp.b $fdtaddr "CONFIG_FDT2_ENV_ADDR" $filesize; "	\ +		"if test $? -ne 0; then "				\ +			"echo FDT PROGRAM FAILED; "			\ +		"else; "						\ +			"echo FDT PROGRAM SUCCEEDED; "			\ +		"fi; "							\ +	"else; "							\ +		"echo FDT DOWNLOAD FAILED; "				\ +	"fi;" + +#define CONFIG_EXTRA_ENV_SETTINGS					\ +	"autoload=yes\0"						\ +	"download_cmd=tftp\0"						\ +	"console_args=console=ttyS0,115200\0"				\ +	"root_args=root=/dev/nfs rw\0"					\ +	"misc_args=ip=on\0"						\ +	"set_bootargs=setenv bootargs ${console_args} ${root_args} ${misc_args}\0" \ +	"bootfile=/home/user/file\0"					\ +	"osfile=/home/user/board.uImage\0"				\ +	"fdtfile=/home/user/board.dtb\0"				\ +	"ubootfile=/home/user/u-boot.bin\0"				\ +	"fdtaddr=c00000\0"						\ +	"osaddr=0x1000000\0"						\ +	"loadaddr=0x1000000\0"						\ +	"prog_uboot1="CONFIG_PROG_UBOOT1"\0"				\ +	"prog_uboot2="CONFIG_PROG_UBOOT2"\0"				\ +	"prog_os1="CONFIG_PROG_OS1"\0"					\ +	"prog_os2="CONFIG_PROG_OS2"\0"					\ +	"prog_fdt1="CONFIG_PROG_FDT1"\0"				\ +	"prog_fdt2="CONFIG_PROG_FDT2"\0"				\ +	"bootcmd_net=run set_bootargs; "CONFIG_BOOT_OS_NET"\0"		\ +	"bootcmd_flash1=run set_bootargs; "				\ +		"bootm "CONFIG_OS1_ENV_ADDR" - "CONFIG_FDT1_ENV_ADDR"\0"\ +	"bootcmd_flash2=run set_bootargs; "				\ +		"bootm "CONFIG_OS2_ENV_ADDR" - "CONFIG_FDT2_ENV_ADDR"\0"\ +	"bootcmd=run bootcmd_flash1\0" +#endif	/* __CONFIG_H */ diff --git a/include/led-display.h b/include/led-display.h index 41c37443452..eaa0f406406 100644 --- a/include/led-display.h +++ b/include/led-display.h @@ -29,7 +29,6 @@  /* Display Commands */  #define DISPLAY_CLEAR	0x1 /* Clear the display */  #define DISPLAY_HOME	0x2 /* Set cursor at home position */ -#define DISPLAY_MARK	0x4 /* Enable the decimal point led, if implemented */  void display_set(int cmd);  int display_putc(char c); diff --git a/include/linux/fb.h b/include/linux/fb.h new file mode 100644 index 00000000000..f4ac4bf90e8 --- /dev/null +++ b/include/linux/fb.h @@ -0,0 +1,616 @@ +#ifndef _LINUX_FB_H +#define _LINUX_FB_H + +#include <linux/types.h> + +/* Definitions of frame buffers						*/ + +#define FB_MAX			32	/* sufficient for now */ + +#define FB_TYPE_PACKED_PIXELS		0	/* Packed Pixels	*/ + +#define FB_VISUAL_MONO01		0	/* Monochr. 1=Black 0=White */ +#define FB_VISUAL_MONO10		1	/* Monochr. 1=White 0=Black */ +#define FB_VISUAL_TRUECOLOR		2	/* True color	*/ +#define FB_VISUAL_PSEUDOCOLOR		3	/* Pseudo color (like atari) */ +#define FB_VISUAL_DIRECTCOLOR		4	/* Direct color */ +#define FB_VISUAL_STATIC_PSEUDOCOLOR	5	/* Pseudo color readonly */ + +#define FB_ACCEL_NONE		0	/* no hardware accelerator	*/ + +struct fb_fix_screeninfo { +	char id[16];			/* identification string eg "TT Builtin" */ +	unsigned long smem_start;	/* Start of frame buffer mem */ +					/* (physical address) */ +	__u32 smem_len;			/* Length of frame buffer mem */ +	__u32 type;			/* see FB_TYPE_*		*/ +	__u32 type_aux;			/* Interleave for interleaved Planes */ +	__u32 visual;			/* see FB_VISUAL_*		*/ +	__u16 xpanstep;			/* zero if no hardware panning  */ +	__u16 ypanstep;			/* zero if no hardware panning  */ +	__u16 ywrapstep;		/* zero if no hardware ywrap    */ +	__u32 line_length;		/* length of a line in bytes    */ +	unsigned long mmio_start;	/* Start of Memory Mapped I/O   */ +					/* (physical address) */ +	__u32 mmio_len;			/* Length of Memory Mapped I/O  */ +	__u32 accel;			/* Indicate to driver which	*/ +					/*  specific chip/card we have	*/ +	__u16 reserved[3];		/* Reserved for future compatibility */ +}; + +/* + * Interpretation of offset for color fields: All offsets are from the right, + * inside a "pixel" value, which is exactly 'bits_per_pixel' wide (means: you + * can use the offset as right argument to <<). A pixel afterwards is a bit + * stream and is written to video memory as that unmodified. + * + * For pseudocolor: offset and length should be the same for all color + * components. Offset specifies the position of the least significant bit + * of the pallette index in a pixel value. Length indicates the number + * of available palette entries (i.e. # of entries = 1 << length). + */ +struct fb_bitfield { +	__u32 offset;			/* beginning of bitfield	*/ +	__u32 length;			/* length of bitfield		*/ +	__u32 msb_right; + +}; + +#define FB_NONSTD_HAM		1	/* Hold-And-Modify (HAM)        */ +#define FB_NONSTD_REV_PIX_IN_B	2	/* order of pixels in each byte is reversed */ + +#define FB_ACTIVATE_NOW		0	/* set values immediately (or vbl)*/ +#define FB_ACTIVATE_NXTOPEN	1	/* activate on next open	*/ +#define FB_ACTIVATE_TEST	2	/* don't set, round up impossible */ +#define FB_ACTIVATE_MASK       15 +					/* values			*/ +#define FB_ACTIVATE_VBL	       16	/* activate values on next vbl  */ +#define FB_CHANGE_CMAP_VBL     32	/* change colormap on vbl	*/ +#define FB_ACTIVATE_ALL	       64	/* change all VCs on this fb	*/ +#define FB_ACTIVATE_FORCE     128	/* force apply even when no change*/ +#define FB_ACTIVATE_INV_MODE  256       /* invalidate videomode */ + +#define FB_SYNC_HOR_HIGH_ACT	1	/* horizontal sync high active	*/ +#define FB_SYNC_VERT_HIGH_ACT	2	/* vertical sync high active	*/ +#define FB_SYNC_EXT		4	/* external sync		*/ +#define FB_SYNC_COMP_HIGH_ACT	8	/* composite sync high active   */ +#define FB_SYNC_BROADCAST	16	/* broadcast video timings      */ +					/* vtotal = 144d/288n/576i => PAL  */ +					/* vtotal = 121d/242n/484i => NTSC */ +#define FB_SYNC_ON_GREEN	32	/* sync on green */ + +#define FB_VMODE_NONINTERLACED  0	/* non interlaced */ +#define FB_VMODE_INTERLACED	1	/* interlaced	*/ +#define FB_VMODE_DOUBLE		2	/* double scan */ +#define FB_VMODE_ODD_FLD_FIRST	4	/* interlaced: top line first */ +#define FB_VMODE_MASK		255 + +#define FB_VMODE_YWRAP		256	/* ywrap instead of panning     */ +#define FB_VMODE_SMOOTH_XPAN	512	/* smooth xpan possible (internally used) */ +#define FB_VMODE_CONUPDATE	512	/* don't update x/yoffset	*/ + +/* + * Display rotation support + */ +#define FB_ROTATE_UR      0 +#define FB_ROTATE_CW      1 +#define FB_ROTATE_UD      2 +#define FB_ROTATE_CCW     3 + +#define PICOS2KHZ(a) (1000000000UL/(a)) +#define KHZ2PICOS(a) (1000000000UL/(a)) + +struct fb_var_screeninfo { +	__u32 xres;			/* visible resolution		*/ +	__u32 yres; +	__u32 xres_virtual;		/* virtual resolution		*/ +	__u32 yres_virtual; +	__u32 xoffset;			/* offset from virtual to visible */ +	__u32 yoffset;			/* resolution			*/ + +	__u32 bits_per_pixel;		/* guess what			*/ +	__u32 grayscale;		/* != 0 Graylevels instead of colors */ + +	struct fb_bitfield red;		/* bitfield in fb mem if true color, */ +	struct fb_bitfield green;	/* else only length is significant */ +	struct fb_bitfield blue; +	struct fb_bitfield transp;	/* transparency			*/ + +	__u32 nonstd;			/* != 0 Non standard pixel format */ + +	__u32 activate;			/* see FB_ACTIVATE_*		*/ + +	__u32 height;			/* height of picture in mm    */ +	__u32 width;			/* width of picture in mm     */ + +	__u32 accel_flags;		/* (OBSOLETE) see fb_info.flags */ + +	/* Timing: All values in pixclocks, except pixclock (of course) */ +	__u32 pixclock;			/* pixel clock in ps (pico seconds) */ +	__u32 left_margin;		/* time from sync to picture	*/ +	__u32 right_margin;		/* time from picture to sync	*/ +	__u32 upper_margin;		/* time from sync to picture	*/ +	__u32 lower_margin; +	__u32 hsync_len;		/* length of horizontal sync	*/ +	__u32 vsync_len;		/* length of vertical sync	*/ +	__u32 sync;			/* see FB_SYNC_*		*/ +	__u32 vmode;			/* see FB_VMODE_*		*/ +	__u32 rotate;			/* angle we rotate counter clockwise */ +	__u32 reserved[5];		/* Reserved for future compatibility */ +}; + +struct fb_cmap { +	__u32 start;			/* First entry	*/ +	__u32 len;			/* Number of entries */ +	__u16 *red;			/* Red values	*/ +	__u16 *green; +	__u16 *blue; +	__u16 *transp;			/* transparency, can be NULL */ +}; + +struct fb_con2fbmap { +	__u32 console; +	__u32 framebuffer; +}; + +/* VESA Blanking Levels */ +#define VESA_NO_BLANKING        0 +#define VESA_VSYNC_SUSPEND      1 +#define VESA_HSYNC_SUSPEND      2 +#define VESA_POWERDOWN          3 + + +enum { +	/* screen: unblanked, hsync: on,  vsync: on */ +	FB_BLANK_UNBLANK       = VESA_NO_BLANKING, + +	/* screen: blanked,   hsync: on,  vsync: on */ +	FB_BLANK_NORMAL        = VESA_NO_BLANKING + 1, + +	/* screen: blanked,   hsync: on,  vsync: off */ +	FB_BLANK_VSYNC_SUSPEND = VESA_VSYNC_SUSPEND + 1, + +	/* screen: blanked,   hsync: off, vsync: on */ +	FB_BLANK_HSYNC_SUSPEND = VESA_HSYNC_SUSPEND + 1, + +	/* screen: blanked,   hsync: off, vsync: off */ +	FB_BLANK_POWERDOWN     = VESA_POWERDOWN + 1 +}; + +#define FB_VBLANK_VBLANKING	0x001	/* currently in a vertical blank */ +#define FB_VBLANK_HBLANKING	0x002	/* currently in a horizontal blank */ +#define FB_VBLANK_HAVE_VBLANK	0x004	/* vertical blanks can be detected */ +#define FB_VBLANK_HAVE_HBLANK	0x008	/* horizontal blanks can be detected */ +#define FB_VBLANK_HAVE_COUNT	0x010	/* global retrace counter is available */ +#define FB_VBLANK_HAVE_VCOUNT	0x020	/* the vcount field is valid */ +#define FB_VBLANK_HAVE_HCOUNT	0x040	/* the hcount field is valid */ +#define FB_VBLANK_VSYNCING	0x080	/* currently in a vsync */ +#define FB_VBLANK_HAVE_VSYNC	0x100	/* verical syncs can be detected */ + +struct fb_vblank { +	__u32 flags;			/* FB_VBLANK flags */ +	__u32 count;			/* counter of retraces since boot */ +	__u32 vcount;			/* current scanline position */ +	__u32 hcount;			/* current scandot position */ +	__u32 reserved[4];		/* reserved for future compatibility */ +}; + +/* Internal HW accel */ +#define ROP_COPY 0 +#define ROP_XOR  1 + +struct fb_copyarea { +	__u32 dx; +	__u32 dy; +	__u32 width; +	__u32 height; +	__u32 sx; +	__u32 sy; +}; + +struct fb_fillrect { +	__u32 dx;	/* screen-relative */ +	__u32 dy; +	__u32 width; +	__u32 height; +	__u32 color; +	__u32 rop; +}; + +struct fb_image { +	__u32 dx;		/* Where to place image */ +	__u32 dy; +	__u32 width;		/* Size of image */ +	__u32 height; +	__u32 fg_color;		/* Only used when a mono bitmap */ +	__u32 bg_color; +	__u8  depth;		/* Depth of the image */ +	const char *data;	/* Pointer to image data */ +	struct fb_cmap cmap;	/* color map info */ +}; + +/* + * hardware cursor control + */ + +#define FB_CUR_SETIMAGE 0x01 +#define FB_CUR_SETPOS   0x02 +#define FB_CUR_SETHOT   0x04 +#define FB_CUR_SETCMAP  0x08 +#define FB_CUR_SETSHAPE 0x10 +#define FB_CUR_SETSIZE	0x20 +#define FB_CUR_SETALL   0xFF + +struct fbcurpos { +	__u16 x, y; +}; + +struct fb_cursor { +	__u16 set;		/* what to set */ +	__u16 enable;		/* cursor on/off */ +	__u16 rop;		/* bitop operation */ +	const char *mask;	/* cursor mask bits */ +	struct fbcurpos hot;	/* cursor hot spot */ +	struct fb_image	image;	/* Cursor image */ +}; + +#ifdef CONFIG_FB_BACKLIGHT +/* Settings for the generic backlight code */ +#define FB_BACKLIGHT_LEVELS	128 +#define FB_BACKLIGHT_MAX	0xFF +#endif + +#ifdef __KERNEL__ + +struct vm_area_struct; +struct fb_info; +struct device; +struct file; + +/* Definitions below are used in the parsed monitor specs */ +#define FB_DPMS_ACTIVE_OFF	1 +#define FB_DPMS_SUSPEND		2 +#define FB_DPMS_STANDBY		4 + +#define FB_DISP_DDI		1 +#define FB_DISP_ANA_700_300	2 +#define FB_DISP_ANA_714_286	4 +#define FB_DISP_ANA_1000_400	8 +#define FB_DISP_ANA_700_000	16 + +#define FB_DISP_MONO		32 +#define FB_DISP_RGB		64 +#define FB_DISP_MULTI		128 +#define FB_DISP_UNKNOWN		256 + +#define FB_SIGNAL_NONE		0 +#define FB_SIGNAL_BLANK_BLANK	1 +#define FB_SIGNAL_SEPARATE	2 +#define FB_SIGNAL_COMPOSITE	4 +#define FB_SIGNAL_SYNC_ON_GREEN	8 +#define FB_SIGNAL_SERRATION_ON	16 + +#define FB_MISC_PRIM_COLOR	1 +#define FB_MISC_1ST_DETAIL	2	/* First Detailed Timing is preferred */ +struct fb_chroma { +	__u32 redx;	/* in fraction of 1024 */ +	__u32 greenx; +	__u32 bluex; +	__u32 whitex; +	__u32 redy; +	__u32 greeny; +	__u32 bluey; +	__u32 whitey; +}; + +struct fb_monspecs { +	struct fb_chroma chroma; +	struct fb_videomode *modedb;	/* mode database */ +	__u8  manufacturer[4];		/* Manufacturer */ +	__u8  monitor[14];		/* Monitor String */ +	__u8  serial_no[14];		/* Serial Number */ +	__u8  ascii[14];		/* ? */ +	__u32 modedb_len;		/* mode database length */ +	__u32 model;			/* Monitor Model */ +	__u32 serial;			/* Serial Number - Integer */ +	__u32 year;			/* Year manufactured */ +	__u32 week;			/* Week Manufactured */ +	__u32 hfmin;			/* hfreq lower limit (Hz) */ +	__u32 hfmax;			/* hfreq upper limit (Hz) */ +	__u32 dclkmin;			/* pixelclock lower limit (Hz) */ +	__u32 dclkmax;			/* pixelclock upper limit (Hz) */ +	__u16 input;			/* display type - see FB_DISP_* */ +	__u16 dpms;			/* DPMS support - see FB_DPMS_ */ +	__u16 signal;			/* Signal Type - see FB_SIGNAL_* */ +	__u16 vfmin;			/* vfreq lower limit (Hz) */ +	__u16 vfmax;			/* vfreq upper limit (Hz) */ +	__u16 gamma;			/* Gamma - in fractions of 100 */ +	__u16 gtf	: 1;		/* supports GTF */ +	__u16 misc;			/* Misc flags - see FB_MISC_* */ +	__u8  version;			/* EDID version... */ +	__u8  revision;			/* ...and revision */ +	__u8  max_x;			/* Maximum horizontal size (cm) */ +	__u8  max_y;			/* Maximum vertical size (cm) */ +}; + +struct fb_cmap_user { +	__u32 start;			/* First entry	*/ +	__u32 len;			/* Number of entries */ +	__u16 *red;		/* Red values	*/ +	__u16 *green; +	__u16 *blue; +	__u16 *transp;		/* transparency, can be NULL */ +}; + +struct fb_image_user { +	__u32 dx;			/* Where to place image */ +	__u32 dy; +	__u32 width;			/* Size of image */ +	__u32 height; +	__u32 fg_color;			/* Only used when a mono bitmap */ +	__u32 bg_color; +	__u8  depth;			/* Depth of the image */ +	const char *data;	/* Pointer to image data */ +	struct fb_cmap_user cmap;	/* color map info */ +}; + +struct fb_cursor_user { +	__u16 set;			/* what to set */ +	__u16 enable;			/* cursor on/off */ +	__u16 rop;			/* bitop operation */ +	const char *mask;	/* cursor mask bits */ +	struct fbcurpos hot;		/* cursor hot spot */ +	struct fb_image_user image;	/* Cursor image */ +}; + +/* + * Register/unregister for framebuffer events + */ + +/*	The resolution of the passed in fb_info about to change */ +#define FB_EVENT_MODE_CHANGE		0x01 +/*	The display on this fb_info is beeing suspended, no access to the + *	framebuffer is allowed any more after that call returns + */ +#define FB_EVENT_SUSPEND		0x02 +/*	The display on this fb_info was resumed, you can restore the display + *	if you own it + */ +#define FB_EVENT_RESUME			0x03 +/*      An entry from the modelist was removed */ +#define FB_EVENT_MODE_DELETE            0x04 +/*      A driver registered itself */ +#define FB_EVENT_FB_REGISTERED          0x05 +/*      A driver unregistered itself */ +#define FB_EVENT_FB_UNREGISTERED        0x06 +/*      CONSOLE-SPECIFIC: get console to framebuffer mapping */ +#define FB_EVENT_GET_CONSOLE_MAP        0x07 +/*      CONSOLE-SPECIFIC: set console to framebuffer mapping */ +#define FB_EVENT_SET_CONSOLE_MAP        0x08 +/*      A hardware display blank change occured */ +#define FB_EVENT_BLANK                  0x09 +/*      Private modelist is to be replaced */ +#define FB_EVENT_NEW_MODELIST           0x0A +/*	The resolution of the passed in fb_info about to change and +        all vc's should be changed         */ +#define FB_EVENT_MODE_CHANGE_ALL	0x0B +/*	A software display blank change occured */ +#define FB_EVENT_CONBLANK               0x0C +/*      Get drawing requirements        */ +#define FB_EVENT_GET_REQ                0x0D +/*      Unbind from the console if possible */ +#define FB_EVENT_FB_UNBIND              0x0E + +struct fb_event { +	struct fb_info *info; +	void *data; +}; + +struct fb_blit_caps { +	u32 x; +	u32 y; +	u32 len; +	u32 flags; +}; + +/* + * Pixmap structure definition + * + * The purpose of this structure is to translate data + * from the hardware independent format of fbdev to what + * format the hardware needs. + */ + +#define FB_PIXMAP_DEFAULT 1     /* used internally by fbcon */ +#define FB_PIXMAP_SYSTEM  2     /* memory is in system RAM  */ +#define FB_PIXMAP_IO      4     /* memory is iomapped       */ +#define FB_PIXMAP_SYNC    256   /* set if GPU can DMA       */ + +struct fb_pixmap { +	u8  *addr;		/* pointer to memory			*/ +	u32 size;		/* size of buffer in bytes		*/ +	u32 offset;		/* current offset to buffer		*/ +	u32 buf_align;		/* byte alignment of each bitmap	*/ +	u32 scan_align;		/* alignment per scanline		*/ +	u32 access_align;	/* alignment per read/write (bits)	*/ +	u32 flags;		/* see FB_PIXMAP_*			*/ +	u32 blit_x;             /* supported bit block dimensions (1-32)*/ +	u32 blit_y;             /* Format: blit_x = 1 << (width - 1)    */ +	                        /*         blit_y = 1 << (height - 1)   */ +	                        /* if 0, will be set to 0xffffffff (all)*/ +	/* access methods */ +	void (*writeio)(struct fb_info *info, void *dst, void *src, unsigned int size); +	void (*readio) (struct fb_info *info, void *dst, void *src, unsigned int size); +}; + +#ifdef CONFIG_FB_DEFERRED_IO +struct fb_deferred_io { +	/* delay between mkwrite and deferred handler */ +	unsigned long delay; +	struct mutex lock; /* mutex that protects the page list */ +	struct list_head pagelist; /* list of touched pages */ +	/* callback */ +	void (*deferred_io)(struct fb_info *info, struct list_head *pagelist); +}; +#endif + +/* FBINFO_* = fb_info.flags bit flags */ +#define FBINFO_MODULE		0x0001	/* Low-level driver is a module */ +#define FBINFO_HWACCEL_DISABLED	0x0002 +	/* When FBINFO_HWACCEL_DISABLED is set: +	 *  Hardware acceleration is turned off.  Software implementations +	 *  of required functions (copyarea(), fillrect(), and imageblit()) +	 *  takes over; acceleration engine should be in a quiescent state */ + +/* hints */ +#define FBINFO_PARTIAL_PAN_OK	0x0040 /* otw use pan only for double-buffering */ +#define FBINFO_READS_FAST	0x0080 /* soft-copy faster than rendering */ + +/* + * A driver may set this flag to indicate that it does want a set_par to be + * called every time when fbcon_switch is executed. The advantage is that with + * this flag set you can really be sure that set_par is always called before + * any of the functions dependant on the correct hardware state or altering + * that state, even if you are using some broken X releases. The disadvantage + * is that it introduces unwanted delays to every console switch if set_par + * is slow. It is a good idea to try this flag in the drivers initialization + * code whenever there is a bug report related to switching between X and the + * framebuffer console. + */ +#define FBINFO_MISC_ALWAYS_SETPAR   0x40000 + +/* + * Host and GPU endianness differ. + */ +#define FBINFO_FOREIGN_ENDIAN	0x100000 +/* + * Big endian math. This is the same flags as above, but with different + * meaning, it is set by the fb subsystem depending FOREIGN_ENDIAN flag + * and host endianness. Drivers should not use this flag. + */ +#define FBINFO_BE_MATH  0x100000 + +struct fb_info { +	int node; +	int flags; +	struct fb_var_screeninfo var;	/* Current var */ +	struct fb_fix_screeninfo fix;	/* Current fix */ +	struct fb_monspecs monspecs;	/* Current Monitor specs */ +	struct fb_pixmap pixmap;	/* Image hardware mapper */ +	struct fb_pixmap sprite;	/* Cursor hardware mapper */ +	struct fb_cmap cmap;		/* Current cmap */ +	struct list_head modelist;      /* mode list */ +	struct fb_videomode *mode;	/* current mode */ + +	char *screen_base;	/* Virtual address */ +	unsigned long screen_size;	/* Amount of ioremapped VRAM or 0 */ +	void *pseudo_palette;		/* Fake palette of 16 colors */ +#define FBINFO_STATE_RUNNING	0 +#define FBINFO_STATE_SUSPENDED	1 +	u32 state;			/* Hardware state i.e suspend */ +	void *fbcon_par;                /* fbcon use-only private area */ +	/* From here on everything is device dependent */ +	void *par; +}; + +#define FBINFO_DEFAULT	0 + +#define FBINFO_FLAG_MODULE	FBINFO_MODULE +#define FBINFO_FLAG_DEFAULT	FBINFO_DEFAULT + +// This will go away +#if defined(__sparc__) + +/* We map all of our framebuffers such that big-endian accesses + * are what we want, so the following is sufficient. + */ + +// This will go away +#define fb_readb sbus_readb +#define fb_readw sbus_readw +#define fb_readl sbus_readl +#define fb_readq sbus_readq +#define fb_writeb sbus_writeb +#define fb_writew sbus_writew +#define fb_writel sbus_writel +#define fb_writeq sbus_writeq +#define fb_memset sbus_memset_io + +#elif defined(__i386__) || defined(__alpha__) || defined(__x86_64__) || defined(__hppa__) || defined(__sh__) || defined(__powerpc__) || defined(__avr32__) || defined(__bfin__) + +#define fb_readb __raw_readb +#define fb_readw __raw_readw +#define fb_readl __raw_readl +#define fb_readq __raw_readq +#define fb_writeb __raw_writeb +#define fb_writew __raw_writew +#define fb_writel __raw_writel +#define fb_writeq __raw_writeq +#define fb_memset memset_io + +#else + +#define fb_readb(addr) (*(volatile u8 *) (addr)) +#define fb_readw(addr) (*(volatile u16 *) (addr)) +#define fb_readl(addr) (*(volatile u32 *) (addr)) +#define fb_readq(addr) (*(volatile u64 *) (addr)) +#define fb_writeb(b,addr) (*(volatile u8 *) (addr) = (b)) +#define fb_writew(b,addr) (*(volatile u16 *) (addr) = (b)) +#define fb_writel(b,addr) (*(volatile u32 *) (addr) = (b)) +#define fb_writeq(b,addr) (*(volatile u64 *) (addr) = (b)) +#define fb_memset memset + +#endif + +#define FB_LEFT_POS(p, bpp)          (fb_be_math(p) ? (32 - (bpp)) : 0) +#define FB_SHIFT_HIGH(p, val, bits)  (fb_be_math(p) ? (val) >> (bits) : \ +						      (val) << (bits)) +#define FB_SHIFT_LOW(p, val, bits)   (fb_be_math(p) ? (val) << (bits) : \ +						      (val) >> (bits)) +/* drivers/video/fbmon.c */ +#define FB_MAXTIMINGS		0 +#define FB_VSYNCTIMINGS		1 +#define FB_HSYNCTIMINGS		2 +#define FB_DCLKTIMINGS		3 +#define FB_IGNOREMON		0x100 + +#define FB_MODE_IS_UNKNOWN	0 +#define FB_MODE_IS_DETAILED	1 +#define FB_MODE_IS_STANDARD	2 +#define FB_MODE_IS_VESA		4 +#define FB_MODE_IS_CALCULATED	8 +#define FB_MODE_IS_FIRST	16 +#define FB_MODE_IS_FROM_VAR     32 + + +/* drivers/video/fbcmap.c */ + +extern int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp); +extern void fb_dealloc_cmap(struct fb_cmap *cmap); +extern int fb_copy_cmap(const struct fb_cmap *from, struct fb_cmap *to); +extern int fb_cmap_to_user(const struct fb_cmap *from, struct fb_cmap_user *to); +extern int fb_set_cmap(struct fb_cmap *cmap, struct fb_info *fb_info); +extern int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *fb_info); +extern const struct fb_cmap *fb_default_cmap(int len); +extern void fb_invert_cmaps(void); + +struct fb_videomode { +	const char *name;	/* optional */ +	u32 refresh;		/* optional */ +	u32 xres; +	u32 yres; +	u32 pixclock; +	u32 left_margin; +	u32 right_margin; +	u32 upper_margin; +	u32 lower_margin; +	u32 hsync_len; +	u32 vsync_len; +	u32 sync; +	u32 vmode; +	u32 flag; +}; + +#endif /* __KERNEL__ */ + +#endif /* _LINUX_FB_H */ diff --git a/include/post.h b/include/post.h index daa9047118e..abe47da53bf 100644 --- a/include/post.h +++ b/include/post.h @@ -60,6 +60,10 @@  #include <asm/immap_85xx.h>  #define _POST_WORD_ADDR	(CONFIG_SYS_IMMR + offsetof(ccsr_pic_t, tfrr)) +#elif defined (CONFIG_MPC86xx) +#include <asm/immap_86xx.h> +#define _POST_WORD_ADDR	(CONFIG_SYS_IMMR + offsetof(ccsr_pic_t, tfrr)) +  #elif defined (CONFIG_4xx)  #define _POST_WORD_ADDR \  	(CONFIG_SYS_OCM_DATA_ADDR + CONFIG_SYS_GBL_DATA_OFFSET - 0x4) diff --git a/post/drivers/i2c.c b/post/drivers/i2c.c index b152deaf6ab..3080e81b5bf 100644 --- a/post/drivers/i2c.c +++ b/post/drivers/i2c.c @@ -21,70 +21,89 @@   * MA 02111-1307 USA   */ -#include <common.h> -  /*   * I2C test   *   * For verifying the I2C bus, a full I2C bus scanning is performed.   * - * #ifdef I2C_ADDR_LIST - *   The test is considered as passed if all the devices and - *   only the devices in the list are found. - * #else [ ! I2C_ADDR_LIST ] + * #ifdef CONFIG_SYS_POST_I2C_ADDRS + *   The test is considered as passed if all the devices and only the devices + *   in the list are found. + *   #ifdef CONFIG_SYS_POST_I2C_IGNORES + *     Ignore devices listed in CONFIG_SYS_POST_I2C_IGNORES.  These devices + *     are optional or not vital to board functionality. + *   #endif + * #else [ ! CONFIG_SYS_POST_I2C_ADDRS ]   *   The test is considered as passed if any I2C device is found.   * #endif   */ +#include <common.h>  #include <post.h>  #include <i2c.h>  #if CONFIG_POST & CONFIG_SYS_POST_I2C +static int i2c_ignore_device(unsigned int chip) +{ +#ifdef CONFIG_SYS_POST_I2C_IGNORES +	const unsigned char i2c_ignore_list[] = CONFIG_SYS_POST_I2C_IGNORES; +	int i; + +	for (i = 0; i < sizeof(i2c_ignore_list); i++) +		if (i2c_ignore_list[i] == chip) +			return 1; +#endif + +	return 0; +} +  int i2c_post_test (int flags)  {  	unsigned int i; -	unsigned int good = 0; -#ifdef I2C_ADDR_LIST -	unsigned int bad  = 0; +#ifndef CONFIG_SYS_POST_I2C_ADDRS +	/* Start at address 1, address 0 is the general call address */ +	for (i = 1; i < 128; i++) +		if (i2c_ignore_device(i)) +			continue; +		if (i2c_probe (i) == 0) +			return 0; + +	/* No devices found */ +	return -1; +#else +	unsigned int ret  = 0;  	int j; -	unsigned char i2c_addr_list[] = I2C_ADDR_LIST; -	unsigned char i2c_miss_list[] = I2C_ADDR_LIST; -#endif +	const unsigned char i2c_addr_list[] = CONFIG_SYS_POST_I2C_ADDRS; -	for (i = 0; i < 128; i++) { -		if (i2c_probe (i) == 0) { -#ifndef	I2C_ADDR_LIST -			good++; -#else	/* I2C_ADDR_LIST */ -			for (j=0; j<sizeof(i2c_addr_list); ++j) { -				if (i == i2c_addr_list[j]) { -					good++; -					i2c_miss_list[j] = 0xFF; -					break; -				} -			} -			if (j == sizeof(i2c_addr_list)) { -				bad++; -				post_log ("I2C: addr %02X not expected\n", -						i); +	/* Start at address 1, address 0 is the general call address */ +	for (i = 1; i < 128; i++) { +		if (i2c_ignore_device(i)) +			continue; +		if (i2c_probe(i) != 0) +			continue; + +		for (j = 0; j < sizeof(i2c_addr_list); ++j) { +			if (i == i2c_addr_list[j]) { +				i2c_addr_list[j] = 0xff; +				break;  			} -#endif	/* I2C_ADDR_LIST */  		} -	} -#ifndef	I2C_ADDR_LIST -	return good > 0 ? 0 : -1; -#else	/* I2C_ADDR_LIST */ -	if (good != sizeof(i2c_addr_list)) { -		for (j=0; j<sizeof(i2c_miss_list); ++j) { -			if (i2c_miss_list[j] != 0xFF) { -				post_log ("I2C: addr %02X did not respond\n", -						i2c_miss_list[j]); -			} +		if (j == sizeof(i2c_addr_list)) { +			ret = -1; +			post_log("I2C: addr %02x not expected\n", i);  		}  	} -	return ((good == sizeof(i2c_addr_list)) && (bad == 0)) ? 0 : -1; + +	for (i = 0; i < sizeof(i2c_addr_list); ++i) { +		if (i2c_addr_list[i] == 0xff) +			continue; +		post_log("I2C: addr %02x did not respond\n", i2c_addr_list[i]); +		ret = -1; +	} + +	return ret;  #endif  } | 
