diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/gpio/Makefile | 47 | ||||
| -rw-r--r-- | drivers/gpio/pca953x.c | 227 | ||||
| -rw-r--r-- | drivers/mtd/nand/fsl_elbc_nand.c | 6 | ||||
| -rw-r--r-- | drivers/mtd/nand/nand_base.c | 2 | ||||
| -rw-r--r-- | drivers/pci/fsl_pci_init.c | 29 | ||||
| -rw-r--r-- | drivers/serial/serial_sh.c | 81 | 
6 files changed, 349 insertions, 43 deletions
| diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile new file mode 100644 index 000000000..dd618ed71 --- /dev/null +++ b/drivers/gpio/Makefile @@ -0,0 +1,47 @@ +# +# Copyright 2000-2008 +# 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 $(TOPDIR)/config.mk + +LIB 	:= $(obj)libgpio.a + +COBJS-$(CONFIG_PCA953X)	+= pca953x.o + +COBJS	:= $(COBJS-y) +SRCS 	:= $(COBJS:.o=.c) +OBJS 	:= $(addprefix $(obj),$(COBJS)) + +all:	$(LIB) + +$(LIB):	$(obj).depend $(OBJS) +	$(AR) $(ARFLAGS) $@ $(OBJS) + + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################## diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c new file mode 100644 index 000000000..390d99ad3 --- /dev/null +++ b/drivers/gpio/pca953x.c @@ -0,0 +1,227 @@ +/* + * Copyright 2008 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 + * Version 2 as published by the Free Software Foundation. + * + * 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 + */ + +/* + * Driver for NXP's 4 and 8 bit I2C gpio expanders (eg pca9537, pca9557, etc) + * TODO: support additional devices with more than 8-bits GPIO + */ + +#include <common.h> +#include <i2c.h> +#include <pca953x.h> + +/* Default to an address that hopefully won't corrupt other i2c devices */ +#ifndef CONFIG_SYS_I2C_PCA953X_ADDR +#define CONFIG_SYS_I2C_PCA953X_ADDR	(~0) +#endif + +enum { +	PCA953X_CMD_INFO, +	PCA953X_CMD_DEVICE, +	PCA953X_CMD_OUTPUT, +	PCA953X_CMD_INPUT, +	PCA953X_CMD_INVERT, +}; + +/* + * Modify masked bits in register + */ +static int pca953x_reg_write(uint8_t chip, uint addr, uint mask, uint data) +{ +	uint8_t val; + +	if (i2c_read(chip, addr, 1, &val, 1)) +		return -1; + +	val &= ~mask; +	val |= data; + +	return i2c_write(chip, addr, 1, &val, 1); +} + +/* + * Set output value of IO pins in 'mask' to corresponding value in 'data' + * 0 = low, 1 = high + */ +int pca953x_set_val(uint8_t chip, uint mask, uint data) +{ +	return pca953x_reg_write(chip, PCA953X_OUT, mask, data); +} + +/* + * Set read polarity of IO pins in 'mask' to corresponding value in 'data' + * 0 = read pin value, 1 = read inverted pin value + */ +int pca953x_set_pol(uint8_t chip, uint mask, uint data) +{ +	return pca953x_reg_write(chip, PCA953X_POL, mask, data); +} + +/* + * Set direction of IO pins in 'mask' to corresponding value in 'data' + * 0 = output, 1 = input + */ +int pca953x_set_dir(uint8_t chip, uint mask, uint data) +{ +	return pca953x_reg_write(chip, PCA953X_CONF, mask, data); +} + +/* + * Read current logic level of all IO pins + */ +int pca953x_get_val(uint8_t chip) +{ +	uint8_t val; + +	if (i2c_read(chip, 0, 1, &val, 1)) +		return -1; + +	return (int)val; +} + +#ifdef CONFIG_CMD_PCA953X +#ifdef CONFIG_CMD_PCA953X_INFO +/* + * Display pca953x information + */ +static int pca953x_info(uint8_t chip) +{ +	int i; +	uint8_t data; + +	printf("pca953x@ 0x%x:\n\n", chip); +	printf("gpio pins: 76543210\n"); +	printf("-------------------\n"); + +	if (i2c_read(chip, PCA953X_CONF, 1, &data, 1)) +		return -1; +	printf("conf:      "); +	for (i = 7; i >= 0; i--) +		printf("%c", data & (1 << i) ? 'i' : 'o'); +	printf("\n"); + +	if (i2c_read(chip, PCA953X_POL, 1, &data, 1)) +		return -1; +	printf("invert:    "); +	for (i = 7; i >= 0; i--) +		printf("%c", data & (1 << i) ? '1' : '0'); +	printf("\n"); + +	if (i2c_read(chip, PCA953X_IN, 1, &data, 1)) +		return -1; +	printf("input:     "); +	for (i = 7; i >= 0; i--) +		printf("%c", data & (1 << i) ? '1' : '0'); +	printf("\n"); + +	if (i2c_read(chip, PCA953X_OUT, 1, &data, 1)) +		return -1; +	printf("output:    "); +	for (i = 7; i >= 0; i--) +		printf("%c", data & (1 << i) ? '1' : '0'); +	printf("\n"); + +	return 0; +} +#endif /* CONFIG_CMD_PCA953X_INFO */ + +cmd_tbl_t cmd_pca953x[] = { +	U_BOOT_CMD_MKENT(device, 3, 0, (void *)PCA953X_CMD_DEVICE, "", ""), +	U_BOOT_CMD_MKENT(output, 4, 0, (void *)PCA953X_CMD_OUTPUT, "", ""), +	U_BOOT_CMD_MKENT(input, 3, 0, (void *)PCA953X_CMD_INPUT, "", ""), +	U_BOOT_CMD_MKENT(invert, 4, 0, (void *)PCA953X_CMD_INVERT, "", ""), +#ifdef CONFIG_CMD_PCA953X_INFO +	U_BOOT_CMD_MKENT(info, 2, 0, (void *)PCA953X_CMD_INFO, "", ""), +#endif +}; + +int do_pca953x(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ +	static uint8_t chip = CONFIG_SYS_I2C_PCA953X_ADDR; +	int val; +	ulong ul_arg2 = 0; +	ulong ul_arg3 = 0; +	cmd_tbl_t *c; + +	c = find_cmd_tbl(argv[1], cmd_pca953x, ARRAY_SIZE(cmd_pca953x)); + +	/* All commands but "device" require 'maxargs' arguments */ +	if (!c || !((argc == (c->maxargs)) || +		(((int)c->cmd == PCA953X_CMD_DEVICE) && +		 (argc == (c->maxargs - 1))))) { +		printf("Usage:\n%s\n", cmdtp->usage); +		return 1; +	} + +	/* arg2 used as chip number or pin number */ +	if (argc > 2) +		ul_arg2 = simple_strtoul(argv[2], NULL, 16); + +	/* arg3 used as pin or invert value */ +	if (argc > 3) +		ul_arg3 = simple_strtoul(argv[3], NULL, 16) & 0x1; + +	switch ((int)c->cmd) { +#ifdef CONFIG_CMD_PCA953X_INFO +	case PCA953X_CMD_INFO: +		return pca953x_info(chip); +#endif +	case PCA953X_CMD_DEVICE: +		if (argc == 3) +			chip = (uint8_t)ul_arg2; +		printf("Current device address: 0x%x\n", chip); +		return 0; +	case PCA953X_CMD_INPUT: +		pca953x_set_dir(chip, (1 << ul_arg2), +				PCA953X_DIR_IN << ul_arg2); +		val = (pca953x_get_val(chip) & (1 << ul_arg2)) != 0; + +		printf("chip 0x%02x, pin 0x%lx = %d\n", chip, ul_arg2, val); +		return val; +	case PCA953X_CMD_OUTPUT: +		pca953x_set_dir(chip, (1 << ul_arg2), +				(PCA953X_DIR_OUT << ul_arg2)); +		return pca953x_set_val(chip, (1 << ul_arg2), +					(ul_arg3 << ul_arg2)); +	case PCA953X_CMD_INVERT: +		return pca953x_set_pol(chip, (1 << ul_arg2), +					(ul_arg3 << ul_arg2)); +	default: +		/* We should never get here */ +		return 1; +	} +} + +U_BOOT_CMD( +	pca953x,	5,	1,	do_pca953x, +	"pca953x	- pca953x gpio access\n", +	"device [dev]\n" +	"	- show or set current device address\n" +#ifdef CONFIG_CMD_PCA953X_INFO +	"pca953x info\n" +	"	- display info for current chip\n" +#endif +	"pca953x output pin 0|1\n" +	"	- set pin as output and drive low or high\n" +	"pca953x invert pin 0|1\n" +	"	- disable/enable polarity inversion for reads\n" +	"pca953x intput pin\n" +	"	- set pin as input and read value\n" +); + +#endif /* CONFIG_CMD_PCA953X */ diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index 367c7d7fc..3f318e02e 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c @@ -718,7 +718,7 @@ static void fsl_elbc_ctrl_init(void)  int board_nand_init(struct nand_chip *nand)  {  	struct fsl_elbc_mtd *priv; -	uint32_t br, or; +	uint32_t br = 0, or = 0;  	if (!elbc_ctrl) {  		fsl_elbc_ctrl_init(); @@ -737,11 +737,13 @@ int board_nand_init(struct nand_chip *nand)  	 * if we could pass more than one datum to the NAND driver...  	 */  	for (priv->bank = 0; priv->bank < MAX_BANKS; priv->bank++) { +		phys_addr_t base_addr = virt_to_phys(nand->IO_ADDR_R); +  		br = in_be32(&elbc_ctrl->regs->bank[priv->bank].br);  		or = in_be32(&elbc_ctrl->regs->bank[priv->bank].or);  		if ((br & BR_V) && (br & BR_MSEL) == BR_MS_FCM && -		    (br & or & BR_BA) == (phys_addr_t)nand->IO_ADDR_R) +		    (br & or & BR_BA) == BR_PHYS_ADDR(base_addr))  			break;  	} diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index ba05b762e..94a65d4e7 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -460,8 +460,8 @@ static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip,  	struct nand_chip *chip = mtd->priv;  	if (!(chip->options & NAND_BBT_SCANNED)) { -		chip->scan_bbt(mtd);  		chip->options |= NAND_BBT_SCANNED; +		chip->scan_bbt(mtd);  	}  	if (!chip->bbt) diff --git a/drivers/pci/fsl_pci_init.c b/drivers/pci/fsl_pci_init.c index 1db42fd8d..db68f2600 100644 --- a/drivers/pci/fsl_pci_init.c +++ b/drivers/pci/fsl_pci_init.c @@ -37,6 +37,11 @@ DECLARE_GLOBAL_DATA_PTR;  #include <pci.h>  #include <asm/immap_fsl_pci.h> +/* Freescale-specific PCI config registers */ +#define FSL_PCI_PBFR		0x44 +#define FSL_PCIE_CAP_ID		0x4c +#define FSL_PCIE_CFG_RDY	0x4b0 +  void pciauto_prescan_setup_bridge(struct pci_controller *hose,  				pci_dev_t dev, int sub_bus);  void pciauto_postscan_setup_bridge(struct pci_controller *hose, @@ -306,6 +311,30 @@ void fsl_pci_init(struct pci_controller *hose)  	}  } +/* Enable inbound PCI config cycles for agent/endpoint interface */ +void fsl_pci_config_unlock(struct pci_controller *hose) +{ +	pci_dev_t dev = PCI_BDF(hose->first_busno,0,0); +	u8 agent; +	u8 pcie_cap; +	u16 pbfr; + +	pci_hose_read_config_byte(hose, dev, PCI_CLASS_PROG, &agent); +	if (!agent) +		return; + +	pci_hose_read_config_byte(hose, dev, FSL_PCIE_CAP_ID, &pcie_cap); +	if (pcie_cap != 0x0) { +		/* PCIe - set CFG_READY bit of Configuration Ready Register */ +		pci_hose_write_config_byte(hose, dev, FSL_PCIE_CFG_RDY, 0x1); +	} else { +		/* PCI - clear ACL bit of PBFR */ +		pci_hose_read_config_word(hose, dev, FSL_PCI_PBFR, &pbfr); +		pbfr &= ~0x20; +		pci_hose_write_config_word(hose, dev, FSL_PCI_PBFR, pbfr); +	} +} +  #ifdef CONFIG_OF_BOARD_SETUP  #include <libfdt.h>  #include <fdt_support.h> diff --git a/drivers/serial/serial_sh.c b/drivers/serial/serial_sh.c index 1d76a194a..bfdb2ce77 100644 --- a/drivers/serial/serial_sh.c +++ b/drivers/serial/serial_sh.c @@ -18,6 +18,7 @@   */  #include <common.h> +#include <asm/io.h>  #include <asm/processor.h>  #if defined(CONFIG_CONS_SCIF0) @@ -49,7 +50,7 @@  # define SCFRDR	(vu_char  *)(SCIF_BASE + 0x24)  #else  # define SCFTDR (vu_char  *)(SCIF_BASE + 0xC) -# define SCFSR 	(vu_short *)(SCIF_BASE + 0x10) +# define SCFSR	(vu_short *)(SCIF_BASE + 0x10)  # define SCFRDR (vu_char  *)(SCIF_BASE + 0x14)  #endif @@ -64,7 +65,7 @@  #elif defined(CONFIG_CPU_SH7763)  # if defined(CONFIG_CONS_SCIF2)  # define SCSPTR	(vu_short *)(SCIF_BASE + 0x20) -# define SCLSR 	(vu_short *)(SCIF_BASE + 0x24) +# define SCLSR	(vu_short *)(SCIF_BASE + 0x24)  # define LSR_ORER	1  # define FIFOLEVEL_MASK	0x1F  # else @@ -90,7 +91,7 @@  	defined(CONFIG_CPU_SH7722) || \  	defined(CONFIG_CPU_SH7203)  # define SCSPTR	(vu_short *)(SCIF_BASE + 0x20) -# define SCLSR 	(vu_short *)(SCIF_BASE + 0x24) +# define SCLSR	(vu_short *)(SCIF_BASE + 0x24)  # define LSR_ORER	1  # define FIFOLEVEL_MASK	0x1F  #elif defined(CONFIG_CPU_SH7720) @@ -106,42 +107,43 @@  /* SCBRR register value setting */  #if defined(CONFIG_CPU_SH7720) -# define SCBRR_VALUE(bps, clk) (((clk*2)+16*bps)/(32*bps)-1) +# define SCBRR_VALUE(bps, clk) (((clk * 2) + 16 * bps) / (32 * bps) - 1)  #elif defined(CONFIG_CPU_SH7723) && defined(CONFIG_SCIF_A)  /* SH7723 SCIFA use bus clock. So clock *2 */ -# define SCBRR_VALUE(bps, clk) (((clk*2*2)+16*bps)/(32*bps)-1) +# define SCBRR_VALUE(bps, clk) (((clk * 2 * 2) + 16 * bps) / (32 * bps) - 1)  #else /* Generic SuperH */ -# define SCBRR_VALUE(bps, clk) ((clk+16*bps)/(32*bps)-1) +# define SCBRR_VALUE(bps, clk) ((clk + 16 * bps) / (32 * bps) - 1)  #endif -#define SCR_RE 		(1 << 4) -#define SCR_TE 		(1 << 5) +#define SCR_RE		(1 << 4) +#define SCR_TE		(1 << 5)  #define FCR_RFRST	(1 << 1)	/* RFCL */  #define FCR_TFRST	(1 << 2)	/* TFCL */ -#define FSR_DR   	(1 << 0) -#define FSR_RDF  	(1 << 1) -#define FSR_FER  	(1 << 3) -#define FSR_BRK  	(1 << 4) -#define FSR_FER  	(1 << 3) -#define FSR_TEND 	(1 << 6) -#define FSR_ER   	(1 << 7) +#define FSR_DR		(1 << 0) +#define FSR_RDF		(1 << 1) +#define FSR_FER		(1 << 3) +#define FSR_BRK		(1 << 4) +#define FSR_FER		(1 << 3) +#define FSR_TEND	(1 << 6) +#define FSR_ER		(1 << 7)  /*----------------------------------------------------------------------*/  void serial_setbrg(void)  {  	DECLARE_GLOBAL_DATA_PTR; -	*SCBRR = SCBRR_VALUE(gd->baudrate, CONFIG_SYS_CLK_FREQ); + +	writeb(SCBRR_VALUE(gd->baudrate, CONFIG_SYS_CLK_FREQ), SCBRR);  }  int serial_init(void)  { -	*SCSCR = (SCR_RE | SCR_TE); -	*SCSMR = 0; -	*SCSMR = 0; -	*SCFCR = (FCR_RFRST | FCR_TFRST); -	*SCFCR; -	*SCFCR = 0; +	writew((SCR_RE | SCR_TE), SCSCR); +	writew(0, SCSMR); +	writew(0, SCSMR); +	writew((FCR_RFRST | FCR_TFRST), SCFCR); +	readw(SCFCR); +	writew(0, SCFCR);  	serial_setbrg();  	return 0; @@ -150,9 +152,9 @@ int serial_init(void)  static int serial_rx_fifo_level(void)  {  #if defined(SCRFDR) -	return (*SCRFDR >> 0) & FIFOLEVEL_MASK; +	return (readw(SCRFDR) >> 0) & FIFOLEVEL_MASK;  #else -	return (*SCFDR >> 0) & FIFOLEVEL_MASK; +	return (readw(SCFDR) >> 0) & FIFOLEVEL_MASK;  #endif  } @@ -161,15 +163,15 @@ void serial_raw_putc(const char c)  	unsigned int fsr_bits_to_clear;  	while (1) { -		if (*SCFSR & FSR_TEND) {	/* Tx fifo is empty */ +		if (readw(SCFSR) & FSR_TEND) { /* Tx fifo is empty */  			fsr_bits_to_clear = FSR_TEND;  			break;  		}  	} -	*SCFTDR = c; +	writeb(c, SCFTDR);  	if (fsr_bits_to_clear != 0) -		*SCFSR &= ~fsr_bits_to_clear; +		writew(readw(SCFSR) & ~fsr_bits_to_clear, SCFSR);  }  void serial_putc(const char c) @@ -191,26 +193,25 @@ int serial_tstc(void)  	return serial_rx_fifo_level() ? 1 : 0;  } -#define FSR_ERR_CLEAR   0x0063 -#define RDRF_CLEAR      0x00fc +#define FSR_ERR_CLEAR	0x0063 +#define RDRF_CLEAR		0x00fc  void handle_error(void)  { - -	(void)*SCFSR; -	*SCFSR = FSR_ERR_CLEAR; -	(void)*SCLSR; -	*SCLSR = 0x00; +	readw(SCFSR); +	writew(FSR_ERR_CLEAR, SCFSR); +	readw(SCLSR); +	writew(0x00, SCLSR);  }  int serial_getc_check(void)  {  	unsigned short status; -	status = *SCFSR; +	status = readw(SCFSR);  	if (status & (FSR_FER | FSR_ER | FSR_BRK))  		handle_error(); -	if (*SCLSR & LSR_ORER) +	if (readw(SCLSR) & LSR_ORER)  		handle_error();  	return status & (FSR_DR | FSR_RDF);  } @@ -223,15 +224,15 @@ int serial_getc(void)  	while (!serial_getc_check())  		; -	ch = *SCFRDR; -	status = *SCFSR; +	ch = readb(SCFRDR); +	status = readw(SCFSR); -	*SCFSR = RDRF_CLEAR; +	writew(RDRF_CLEAR, SCFSR);  	if (status & (FSR_FER | FSR_FER | FSR_ER | FSR_BRK))  		handle_error(); -	if (*SCLSR & LSR_ORER) +	if (readw(SCLSR) & LSR_ORER)  		handle_error();  	return ch; |