diff --git a/arch/powerpc/cpu/mpc512x/fixed_sdram.c b/arch/powerpc/cpu/mpc512x/fixed_sdram.c index 6451ea9a4aa5abef6712cc1359ca2db9a052e33f..68c5f8a27b31097cef00a8c52dee40cd6063a2fb 100644 --- a/arch/powerpc/cpu/mpc512x/fixed_sdram.c +++ b/arch/powerpc/cpu/mpc512x/fixed_sdram.c @@ -70,7 +70,7 @@ long int fixed_sdram(ddr512x_config_t *mddrc_config, mddrc_config = &default_mddrc_config; if (dram_init_seq == NULL) { dram_init_seq = default_init_seq; - seq_sz = sizeof(default_init_seq)/sizeof(u32); + seq_sz = ARRAY_SIZE(default_init_seq); } /* Initialize IO Control */ diff --git a/arch/powerpc/cpu/mpc8260/cpu_init.c b/arch/powerpc/cpu/mpc8260/cpu_init.c index a9bb5adeb2095493613da12c449218167279df65..55130f7831ef7ff7a4b5a2aa35c40fbce6918b90 100644 --- a/arch/powerpc/cpu/mpc8260/cpu_init.c +++ b/arch/powerpc/cpu/mpc8260/cpu_init.c @@ -253,7 +253,7 @@ int prt_8260_rsr (void) RSR_ESRS, "External Soft"}, { RSR_EHRS, "External Hard"} }; - static int n = sizeof bits / sizeof bits[0]; + static int n = ARRAY_SIZE(bits); ulong rsr = gd->arch.reset_status; int i; char *sep; diff --git a/arch/powerpc/cpu/mpc8260/ether_fcc.c b/arch/powerpc/cpu/mpc8260/ether_fcc.c index 9bb395e6a2621d317439fe5be68ebb4247874af2..a11ad1e9d06be650266fc48ee1d1402c853f15e8 100644 --- a/arch/powerpc/cpu/mpc8260/ether_fcc.c +++ b/arch/powerpc/cpu/mpc8260/ether_fcc.c @@ -362,7 +362,7 @@ int fec_initialize(bd_t *bis) struct eth_device* dev; int i; - for (i = 0; i < sizeof(ether_fcc_info) / sizeof(ether_fcc_info[0]); i++) + for (i = 0; i < ARRAY_SIZE(ether_fcc_info); i++) { dev = (struct eth_device*) malloc(sizeof *dev); memset(dev, 0, sizeof *dev); @@ -432,7 +432,7 @@ static elbt_prdesc rxeacc_descs[] = { { offsetof(elbt_rxeacc, badlen), "Bad Frame Length" }, { offsetof(elbt_rxeacc, badbit), "Data Compare Errors" }, }; -static int rxeacc_ndesc = sizeof (rxeacc_descs) / sizeof (rxeacc_descs[0]); +static int rxeacc_ndesc = ARRAY_SIZE(rxeacc_descs); typedef struct { @@ -449,7 +449,7 @@ static elbt_prdesc txeacc_descs[] = { { offsetof(elbt_txeacc, un), "Underrun" }, { offsetof(elbt_txeacc, csl), "Carrier Sense Lost" }, }; -static int txeacc_ndesc = sizeof (txeacc_descs) / sizeof (txeacc_descs[0]); +static int txeacc_ndesc = ARRAY_SIZE(txeacc_descs); typedef struct { @@ -500,7 +500,7 @@ static elbt_prdesc epram_descs[] = { { offsetof(fcc_enet_t, fen_p512c), "512-1023 Octet Frames" }, { offsetof(fcc_enet_t, fen_p1024c), "1024-1518 Octet Frames"}, }; -static int epram_ndesc = sizeof (epram_descs) / sizeof (epram_descs[0]); +static int epram_ndesc = ARRAY_SIZE(epram_descs); /* * given an elbt_prdesc array and an array of base addresses, print diff --git a/arch/powerpc/cpu/mpc83xx/cpu_init.c b/arch/powerpc/cpu/mpc83xx/cpu_init.c index 0791043ee174e5ec4a38dda05ef2edb4bf3d171a..f911275b25f92e7c698dfc4c9238d816065a480a 100644 --- a/arch/powerpc/cpu/mpc83xx/cpu_init.c +++ b/arch/powerpc/cpu/mpc83xx/cpu_init.c @@ -484,7 +484,7 @@ int prt_83xx_rsr(void) RSR_SRS, "External/Internal Soft"}, { RSR_HRS, "External/Internal Hard"} }; - static int n = sizeof bits / sizeof bits[0]; + static int n = ARRAY_SIZE(bits); ulong rsr = gd->arch.reset_status; int i; char *sep; diff --git a/arch/powerpc/cpu/mpc83xx/speed.c b/arch/powerpc/cpu/mpc83xx/speed.c index 2e91f51fcee9e7ce9e77dffbdaedf7cb7513543d..5498c19e253d84e3a53b67a6f6fc7d2ec0af6206 100644 --- a/arch/powerpc/cpu/mpc83xx/speed.c +++ b/arch/powerpc/cpu/mpc83xx/speed.c @@ -412,7 +412,7 @@ int get_clocks(void) #endif corecnf_tab_index = ((corepll & 0x1F) << 2) | ((corepll & 0x60) >> 5); - if (corecnf_tab_index > (sizeof(corecnf_tab) / sizeof(corecnf_t))) { + if (corecnf_tab_index > (ARRAY_SIZE(corecnf_tab))) { /* corecnf_tab_index is too high, possibly wrong value */ return -11; } diff --git a/arch/powerpc/cpu/mpc85xx/ether_fcc.c b/arch/powerpc/cpu/mpc85xx/ether_fcc.c index 14358aeb03d8f3f6f7751aa6f4d57bc0e7650dd0..51f1beef5196a21f70067b1c3ae8a06c844ed9f6 100644 --- a/arch/powerpc/cpu/mpc85xx/ether_fcc.c +++ b/arch/powerpc/cpu/mpc85xx/ether_fcc.c @@ -424,7 +424,7 @@ int fec_initialize(bd_t *bis) struct eth_device* dev; int i; - for (i = 0; i < sizeof(ether_fcc_info) / sizeof(ether_fcc_info[0]); i++) + for (i = 0; i < ARRAY_SIZE(ether_fcc_info); i++) { dev = (struct eth_device*) malloc(sizeof *dev); memset(dev, 0, sizeof *dev); diff --git a/arch/powerpc/cpu/mpc8xx/fec.c b/arch/powerpc/cpu/mpc8xx/fec.c index ea4ab3a04237837b4cb76480be9f79782e8d0e9c..f1ae3584660b33c39fa9802d53537b577ecbafef 100644 --- a/arch/powerpc/cpu/mpc8xx/fec.c +++ b/arch/powerpc/cpu/mpc8xx/fec.c @@ -137,7 +137,7 @@ int fec_initialize(bd_t *bis) struct ether_fcc_info_s *efis; int i; - for (i = 0; i < sizeof(ether_fcc_info) / sizeof(ether_fcc_info[0]); i++) { + for (i = 0; i < ARRAY_SIZE(ether_fcc_info); i++) { dev = malloc(sizeof(*dev)); if (dev == NULL) @@ -879,7 +879,7 @@ void mii_init (void) /* Setup the pin configuration of the FEC(s) */ - for (i = 0; i < sizeof(ether_fcc_info) / sizeof(ether_fcc_info[0]); i++) + for (i = 0; i < ARRAY_SIZE(ether_fcc_info); i++) fec_pin_init(ether_fcc_info[i].ether_index); } diff --git a/arch/powerpc/cpu/ppc4xx/reginfo.c b/arch/powerpc/cpu/ppc4xx/reginfo.c index 339d38aa998f522a1c059479e456809364de0931..a42327eb3dab7045e1ecc89105a33f2d21bc2aff 100644 --- a/arch/powerpc/cpu/ppc4xx/reginfo.c +++ b/arch/powerpc/cpu/ppc4xx/reginfo.c @@ -321,7 +321,7 @@ void ppc4xx_reginfo(void) PRINT_DCR(OPB2PLB40_BCTRL); PRINT_DCR(P4P3BO0_CFG); #endif - n = sizeof(ppc4xx_reg) / sizeof(ppc4xx_reg[0]); + n = ARRAY_SIZE(ppc4xx_reg); for (i = 0; i < n; i++) { value = 0; type = ppc4xx_reg[i].type; diff --git a/arch/powerpc/cpu/ppc4xx/sdram.c b/arch/powerpc/cpu/ppc4xx/sdram.c index d4ef36d39ffc6f335e34ff7a2ec5c9089326579d..cd63456e700a32e5b532115f719638fba6954089 100644 --- a/arch/powerpc/cpu/ppc4xx/sdram.c +++ b/arch/powerpc/cpu/ppc4xx/sdram.c @@ -33,7 +33,7 @@ sdram_conf_t mb0cf[] = { sdram_conf_t mb0cf[] = CONFIG_SYS_SDRAM_TABLE; #endif -#define N_MB0CF (sizeof(mb0cf) / sizeof(mb0cf[0])) +#define N_MB0CF (ARRAY_SIZE(mb0cf)) #ifdef CONFIG_SYS_SDRAM_CASL static ulong ns2clks(ulong ns) @@ -266,7 +266,7 @@ sdram_conf_t mb0cf[] = CONFIG_SYS_SDRAM_TABLE; #define CONFIG_SYS_SDRAM0_CFG0 0x82000000 /* DCEN=1, PMUD=0, 64-bit */ #endif -#define N_MB0CF (sizeof(mb0cf) / sizeof(mb0cf[0])) +#define N_MB0CF (ARRAY_SIZE(mb0cf)) #define NUM_TRIES 64 #define NUM_READS 10 diff --git a/arch/powerpc/include/asm/arch-mpc85xx/gpio.h b/arch/powerpc/include/asm/arch-mpc85xx/gpio.h index da7352abb27a67a2d4677e01d7afaa247e78e7d2..41b6677bba38836bc4a29381f0f193380f66266a 100644 --- a/arch/powerpc/include/asm/arch-mpc85xx/gpio.h +++ b/arch/powerpc/include/asm/arch-mpc85xx/gpio.h @@ -14,6 +14,8 @@ #ifndef __ASM_ARCH_MX85XX_GPIO_H #define __ASM_ARCH_MX85XX_GPIO_H +#ifndef CONFIG_MPC85XX_GPIO #include <asm/mpc85xx_gpio.h> +#endif #endif diff --git a/arch/powerpc/include/asm/immap_85xx.h b/arch/powerpc/include/asm/immap_85xx.h index 07d2adf71f1d8777107ee57bdaca84e39246a46e..c045a24d1aba15471434c22abfc6cae2fb56f66a 100644 --- a/arch/powerpc/include/asm/immap_85xx.h +++ b/arch/powerpc/include/asm/immap_85xx.h @@ -265,6 +265,7 @@ typedef struct ccsr_pcix { #define PIWAR_WRITE_SNOOP 0x00005000 #define PIWAR_MEM_2G 0x0000001e +#ifndef CONFIG_MPC85XX_GPIO typedef struct ccsr_gpio { u32 gpdir; u32 gpodr; @@ -273,6 +274,7 @@ typedef struct ccsr_gpio { u32 gpimr; u32 gpicr; } ccsr_gpio_t; +#endif /* L2 Cache Registers */ typedef struct ccsr_l2cache { diff --git a/arch/sandbox/include/asm/gpio.h b/arch/sandbox/include/asm/gpio.h index 8317db1ad3d896a5f7ddefea6b9dd8dfe2a4dae3..427af2c97018d6627a84a869d7a2f4f5f8b9eca6 100644 --- a/arch/sandbox/include/asm/gpio.h +++ b/arch/sandbox/include/asm/gpio.h @@ -40,6 +40,26 @@ int sandbox_gpio_get_value(struct udevice *dev, unsigned int offset); */ int sandbox_gpio_set_value(struct udevice *dev, unsigned int offset, int value); +/** + * Set or reset the simulated open drain mode of a GPIO (used only in sandbox + * test code) + * + * @param gp GPIO number + * @param value value to set (0 for enabled open drain mode, non-zero for + * disabled) + * @return -1 on error, 0 if ok + */ +int sandbox_gpio_set_open_drain(struct udevice *dev, unsigned offset, int value); + +/** + * Return the state of the simulated open drain mode of a GPIO (used only in + * sandbox test code) + * + * @param gp GPIO number + * @return -1 on error, 0 if GPIO is input, >0 if output + */ +int sandbox_gpio_get_open_drain(struct udevice *dev, unsigned offset); + /** * Return the simulated direction of a GPIO (used only in sandbox test code) * diff --git a/board/freescale/b4860qds/Makefile b/board/freescale/b4860qds/Makefile index 0acd2a9aa4a02e3ad2b495ecb80e61610f644aff..673d2ea56ae5a1e62bb296982f4c4ff1f1cf2f5a 100644 --- a/board/freescale/b4860qds/Makefile +++ b/board/freescale/b4860qds/Makefile @@ -5,11 +5,11 @@ # ifdef CONFIG_SPL_BUILD -obj-y += spl.o +obj-y += spl.o else obj-y += b4860qds.o -obj-$(CONFIG_B4860QDS)+= eth_b4860qds.o -obj-$(CONFIG_PCI) += pci.o +obj-$(CONFIG_B4860QDS) += eth_b4860qds.o +obj-$(CONFIG_PCI) += pci.o endif obj-y += ddr.o diff --git a/board/freescale/b4860qds/ddr.c b/board/freescale/b4860qds/ddr.c index eb10a6f364af2e9842084ded5993f82976b5245a..31b186ea8ce9c51aaf35ed26dfc32d0a763ee764 100644 --- a/board/freescale/b4860qds/ddr.c +++ b/board/freescale/b4860qds/ddr.c @@ -179,15 +179,13 @@ phys_size_t initdram(int board_type) #if defined(CONFIG_SPL_BUILD) || !defined(CONFIG_RAMBOOT_PBL) puts("Initializing....using SPD\n"); - dram_size = fsl_ddr_sdram(); - - dram_size = setup_ddr_tlbs(dram_size / 0x100000); - dram_size *= 0x100000; - #else dram_size = fsl_ddr_sdram_size(); #endif + dram_size = setup_ddr_tlbs(dram_size / 0x100000); + dram_size *= 0x100000; + return dram_size; } diff --git a/board/freescale/b4860qds/spl.c b/board/freescale/b4860qds/spl.c index 3f7cc03581afe07258b8fbf0bf8202e83869b7a0..fabc78301a05b522525c1fcbdfa705d6b04bac0d 100644 --- a/board/freescale/b4860qds/spl.c +++ b/board/freescale/b4860qds/spl.c @@ -91,6 +91,7 @@ void board_init_r(gd_t *gd, ulong dest_addr) get_clocks(); mem_malloc_init(CONFIG_SPL_RELOC_MALLOC_ADDR, CONFIG_SPL_RELOC_MALLOC_SIZE); + gd->flags |= GD_FLG_FULL_MALLOC_INIT; #ifndef CONFIG_SPL_NAND_BOOT env_init(); diff --git a/board/freescale/bsc9131rdb/Makefile b/board/freescale/bsc9131rdb/Makefile index b26d3a1e63d62a24d10d3a855fab685ecdfb50fe..8027750efbda1470e6ad3141a4bfbe0db80c9e65 100644 --- a/board/freescale/bsc9131rdb/Makefile +++ b/board/freescale/bsc9131rdb/Makefile @@ -13,15 +13,11 @@ endif endif ifdef MINIMAL - -obj-y += spl_minimal.o tlb.o law.o - +obj-y += spl_minimal.o else - -obj-y += bsc9131rdb.o -obj-y += ddr.o -obj-y += law.o -obj-y += tlb.o -#obj-y += bsc9131rdb_mux.o - +obj-y += bsc9131rdb.o +obj-y += ddr.o endif + +obj-y += law.o +obj-y += tlb.o diff --git a/board/freescale/bsc9132qds/Makefile b/board/freescale/bsc9132qds/Makefile index 2e4170f512f667b464259db351163f0206af5e54..54193350afd36b74fe1ea14075d0249e3c78c28a 100644 --- a/board/freescale/bsc9132qds/Makefile +++ b/board/freescale/bsc9132qds/Makefile @@ -13,14 +13,11 @@ endif endif ifdef MINIMAL - -obj-y += spl_minimal.o tlb.o law.o - +obj-y += spl_minimal.o else - obj-y += bsc9132qds.o obj-y += ddr.o +endif + obj-y += law.o obj-y += tlb.o - -endif diff --git a/board/freescale/c29xpcie/Makefile b/board/freescale/c29xpcie/Makefile index 818484a57dc8ca49b1887340b8e7504054ef0a70..93b3cba03181dd4a098b0d723523a5abce247a43 100644 --- a/board/freescale/c29xpcie/Makefile +++ b/board/freescale/c29xpcie/Makefile @@ -11,15 +11,15 @@ endif endif ifdef MINIMAL -obj-y += spl_minimal.o tlb.o law.o +obj-y += spl_minimal.o else ifdef CONFIG_SPL_BUILD obj-y += spl.o endif - obj-y += c29xpcie.o obj-y += cpld.o obj-y += ddr.o +endif + obj-y += law.o obj-y += tlb.o -endif diff --git a/board/freescale/c29xpcie/spl.c b/board/freescale/c29xpcie/spl.c index 3d31d41a4f6de59b70628ac8e2ca78e4f897e216..d8d73c70b8e8e31a7b99b94947e87800780d761a 100644 --- a/board/freescale/c29xpcie/spl.c +++ b/board/freescale/c29xpcie/spl.c @@ -57,6 +57,7 @@ void board_init_r(gd_t *gd, ulong dest_addr) get_clocks(); mem_malloc_init(CONFIG_SPL_RELOC_MALLOC_ADDR, CONFIG_SPL_RELOC_MALLOC_SIZE); + gd->flags |= GD_FLG_FULL_MALLOC_INIT; /* relocate environment function pointers etc. */ nand_spl_load_image(CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, diff --git a/board/freescale/p1010rdb/Makefile b/board/freescale/p1010rdb/Makefile index 660d1bbc2aaf7671b72bbca2dc50070c937aae55..86eb6946dd12744fcb74deef9b0208fe11327d6e 100644 --- a/board/freescale/p1010rdb/Makefile +++ b/board/freescale/p1010rdb/Makefile @@ -13,18 +13,14 @@ endif endif ifdef MINIMAL - -obj-y += spl_minimal.o tlb.o law.o - +obj-y += spl_minimal.o else - ifdef CONFIG_SPL_BUILD -obj-y += spl.o +obj-y += spl.o endif - obj-y += p1010rdb.o obj-y += ddr.o +endif + obj-y += law.o obj-y += tlb.o - -endif diff --git a/board/freescale/p1010rdb/spl.c b/board/freescale/p1010rdb/spl.c index eb8e567554c8840bdfb14d2dce541621692dcbd9..f8584084ce5cc9b7421736cc249093c060e8e42e 100644 --- a/board/freescale/p1010rdb/spl.c +++ b/board/freescale/p1010rdb/spl.c @@ -72,6 +72,7 @@ void board_init_r(gd_t *gd, ulong dest_addr) get_clocks(); mem_malloc_init(CONFIG_SPL_RELOC_MALLOC_ADDR, CONFIG_SPL_RELOC_MALLOC_SIZE); + gd->flags |= GD_FLG_FULL_MALLOC_INIT; #ifndef CONFIG_SPL_NAND_BOOT env_init(); diff --git a/board/freescale/p1022ds/Makefile b/board/freescale/p1022ds/Makefile index a5821277ef7be0536cf6b16ba81c5063ed373235..9793853463c67f5b6d210f2bdd69dbfef52027a9 100644 --- a/board/freescale/p1022ds/Makefile +++ b/board/freescale/p1022ds/Makefile @@ -13,17 +13,15 @@ endif endif ifdef MINIMAL - -obj-y += spl_minimal.o tlb.o law.o - +obj-y += spl_minimal.o else ifdef CONFIG_SPL_BUILD -obj-y += spl.o +obj-y += spl.o endif obj-y += p1022ds.o obj-y += ddr.o -obj-y += law.o -obj-y += tlb.o - obj-$(CONFIG_FSL_DIU_FB) += diu.o endif + +obj-y += law.o +obj-y += tlb.o diff --git a/board/freescale/p1022ds/spl.c b/board/freescale/p1022ds/spl.c index 89ef95aab891735ac1c0e80cf42ef3b731c32ff8..04db767f9810468e67c2a95fc1a95038e7c7e1e0 100644 --- a/board/freescale/p1022ds/spl.c +++ b/board/freescale/p1022ds/spl.c @@ -86,6 +86,7 @@ void board_init_r(gd_t *gd, ulong dest_addr) get_clocks(); mem_malloc_init(CONFIG_SPL_RELOC_MALLOC_ADDR, CONFIG_SPL_RELOC_MALLOC_SIZE); + gd->flags |= GD_FLG_FULL_MALLOC_INIT; #ifndef CONFIG_SPL_NAND_BOOT env_init(); #endif diff --git a/board/freescale/p1_p2_rdb_pc/Makefile b/board/freescale/p1_p2_rdb_pc/Makefile index a2a1f92ce86adf2165677c0bd58538a6ac405f11..045d4093aecd0e307da0c2eada300946fa4a2d80 100644 --- a/board/freescale/p1_p2_rdb_pc/Makefile +++ b/board/freescale/p1_p2_rdb_pc/Makefile @@ -13,17 +13,14 @@ endif endif ifdef MINIMAL - -obj-y += spl_minimal.o tlb.o law.o - +obj-y += spl_minimal.o else ifdef CONFIG_SPL_BUILD -obj-y += spl.o +obj-y += spl.o endif - -obj-y += p1_p2_rdb_pc.o -obj-y += ddr.o -obj-y += law.o -obj-y += tlb.o - +obj-y += p1_p2_rdb_pc.o +obj-y += ddr.o endif + +obj-y += law.o +obj-y += tlb.o diff --git a/board/freescale/p1_p2_rdb_pc/spl.c b/board/freescale/p1_p2_rdb_pc/spl.c index 0142746c84211a0dea7da0133091b4d3b97ea467..76a3cf47cc68ba5be19129f26f94e7f312f1a492 100644 --- a/board/freescale/p1_p2_rdb_pc/spl.c +++ b/board/freescale/p1_p2_rdb_pc/spl.c @@ -83,6 +83,7 @@ void board_init_r(gd_t *gd, ulong dest_addr) get_clocks(); mem_malloc_init(CONFIG_SPL_RELOC_MALLOC_ADDR, CONFIG_SPL_RELOC_MALLOC_SIZE); + gd->flags |= GD_FLG_FULL_MALLOC_INIT; #ifndef CONFIG_SPL_NAND_BOOT env_init(); diff --git a/board/freescale/p2041rdb/Makefile b/board/freescale/p2041rdb/Makefile index c74f4c62f86142db60c880bfd4b0099dd7339fc1..a335ec65fafed89a9c68d5fc720a8463d53bb4bb 100644 --- a/board/freescale/p2041rdb/Makefile +++ b/board/freescale/p2041rdb/Makefile @@ -7,6 +7,6 @@ # obj-y += p2041rdb.o -obj-y += cpld.o +obj-y += cpld.o obj-y += ddr.o obj-y += eth.o diff --git a/board/freescale/t102xqds/Makefile b/board/freescale/t102xqds/Makefile index d94f2307d9b50802b080155317c6748b34c206ce..afbc9146ed805d153826ef83b1b1867589870116 100644 --- a/board/freescale/t102xqds/Makefile +++ b/board/freescale/t102xqds/Makefile @@ -5,7 +5,7 @@ # ifdef CONFIG_SPL_BUILD -obj-y += spl.o +obj-y += spl.o else obj-y += t102xqds.o obj-y += eth_t102xqds.o diff --git a/board/freescale/t102xqds/ddr.c b/board/freescale/t102xqds/ddr.c index 912d6a950f8c4653e222797c599f2e8b91a54020..c26f3503b99192bf009010fe0df981c9a5f9c005 100644 --- a/board/freescale/t102xqds/ddr.c +++ b/board/freescale/t102xqds/ddr.c @@ -172,14 +172,13 @@ phys_size_t initdram(int board_type) #if defined(CONFIG_SPL_BUILD) || !defined(CONFIG_RAMBOOT_PBL) puts("Initializing....using SPD\n"); - dram_size = fsl_ddr_sdram(); - dram_size = setup_ddr_tlbs(dram_size / 0x100000); - dram_size *= 0x100000; #else /* DDR has been initialised by first stage boot loader */ dram_size = fsl_ddr_sdram_size(); #endif + dram_size = setup_ddr_tlbs(dram_size / 0x100000); + dram_size *= 0x100000; #if defined(CONFIG_DEEP_SLEEP) && !defined(CONFIG_SPL_BUILD) fsl_dp_resume(); diff --git a/board/freescale/t102xqds/spl.c b/board/freescale/t102xqds/spl.c index 073ff2dcde1cf893ad33f0a56c54021624cbe702..d59d3431ec1fd02cb4b771834c2ca92ef030da42 100644 --- a/board/freescale/t102xqds/spl.c +++ b/board/freescale/t102xqds/spl.c @@ -120,6 +120,7 @@ void board_init_r(gd_t *gd, ulong dest_addr) get_clocks(); mem_malloc_init(CONFIG_SPL_RELOC_MALLOC_ADDR, CONFIG_SPL_RELOC_MALLOC_SIZE); + gd->flags |= GD_FLG_FULL_MALLOC_INIT; #ifdef CONFIG_SPL_NAND_BOOT nand_spl_load_image(CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, diff --git a/board/freescale/t102xrdb/Makefile b/board/freescale/t102xrdb/Makefile index 052006610e6d3b211d317a517930bef02bd9e9a7..64528656aca8bd821093ebec25c93370682532f7 100644 --- a/board/freescale/t102xrdb/Makefile +++ b/board/freescale/t102xrdb/Makefile @@ -5,7 +5,7 @@ # ifdef CONFIG_SPL_BUILD -obj-y += spl.o +obj-y += spl.o else obj-y += t102xrdb.o obj-$(CONFIG_T1024RDB) += cpld.o diff --git a/board/freescale/t102xrdb/ddr.c b/board/freescale/t102xrdb/ddr.c index 60ab9ff8ade08a6d775656842098d9d0903ce0a4..edfbdbf3a814e65b1fe3fd246b51f2fa38c9f5fd 100644 --- a/board/freescale/t102xrdb/ddr.c +++ b/board/freescale/t102xrdb/ddr.c @@ -234,12 +234,12 @@ phys_size_t initdram(int board_type) puts("Initializing....using SPD\n"); #endif dram_size = fsl_ddr_sdram(); - dram_size = setup_ddr_tlbs(dram_size / 0x100000); - dram_size *= 0x100000; #else /* DDR has been initialised by first stage boot loader */ dram_size = fsl_ddr_sdram_size(); #endif + dram_size = setup_ddr_tlbs(dram_size / 0x100000); + dram_size *= 0x100000; #if defined(CONFIG_DEEP_SLEEP) && !defined(CONFIG_SPL_BUILD) fsl_dp_resume(); diff --git a/board/freescale/t102xrdb/spl.c b/board/freescale/t102xrdb/spl.c index da97c440c48bf845d6a274d976fb7611b6c6339b..bd3cbbf11c97a6c214bb06ad6335479a1f8d9394 100644 --- a/board/freescale/t102xrdb/spl.c +++ b/board/freescale/t102xrdb/spl.c @@ -107,6 +107,7 @@ void board_init_r(gd_t *gd, ulong dest_addr) get_clocks(); mem_malloc_init(CONFIG_SPL_RELOC_MALLOC_ADDR, CONFIG_SPL_RELOC_MALLOC_SIZE); + gd->flags |= GD_FLG_FULL_MALLOC_INIT; #ifdef CONFIG_SPL_NAND_BOOT nand_spl_load_image(CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, diff --git a/board/freescale/t104xrdb/ddr.c b/board/freescale/t104xrdb/ddr.c index cf79d2ddb2d462b7051ee473cbfc5909952f22e7..22d6a5f617693c71bca2050627aa46788a4b66a3 100644 --- a/board/freescale/t104xrdb/ddr.c +++ b/board/freescale/t104xrdb/ddr.c @@ -124,15 +124,12 @@ phys_size_t initdram(int board_type) #if defined(CONFIG_SPL_BUILD) || !defined(CONFIG_RAMBOOT_PBL) puts("Initializing....using SPD\n"); - dram_size = fsl_ddr_sdram(); - - dram_size = setup_ddr_tlbs(dram_size / 0x100000); - dram_size *= 0x100000; - #else dram_size = fsl_ddr_sdram_size(); #endif + dram_size = setup_ddr_tlbs(dram_size / 0x100000); + dram_size *= 0x100000; #if defined(CONFIG_DEEP_SLEEP) && !defined(CONFIG_SPL_BUILD) fsl_dp_resume(); diff --git a/board/freescale/t104xrdb/spl.c b/board/freescale/t104xrdb/spl.c index 81f48c4c3010a7f71c740f3d736dc087c86e7a56..4b35af63f65d6f421d88ff910167854889ce8802 100644 --- a/board/freescale/t104xrdb/spl.c +++ b/board/freescale/t104xrdb/spl.c @@ -98,6 +98,7 @@ void board_init_r(gd_t *gd, ulong dest_addr) get_clocks(); mem_malloc_init(CONFIG_SPL_RELOC_MALLOC_ADDR, CONFIG_SPL_RELOC_MALLOC_SIZE); + gd->flags |= GD_FLG_FULL_MALLOC_INIT; #ifdef CONFIG_SPL_MMC_BOOT mmc_initialize(bd); diff --git a/board/freescale/t208xqds/Makefile b/board/freescale/t208xqds/Makefile index 6cb72c9fd5dce24158f1930079ba692002a7192e..ef04a26463f9f6ff07d7beedc66559659ca0f031 100644 --- a/board/freescale/t208xqds/Makefile +++ b/board/freescale/t208xqds/Makefile @@ -7,10 +7,8 @@ ifdef CONFIG_SPL_BUILD obj-y += spl.o else -obj-$(CONFIG_T2080QDS) += t208xqds.o -obj-$(CONFIG_T2080QDS) += eth_t208xqds.o -obj-$(CONFIG_T2081QDS) += t208xqds.o -obj-$(CONFIG_T2081QDS) += eth_t208xqds.o +obj-$(CONFIG_T2080QDS) += t208xqds.o eth_t208xqds.o +obj-$(CONFIG_T2081QDS) += t208xqds.o eth_t208xqds.o obj-$(CONFIG_PCI) += pci.o endif diff --git a/board/freescale/t208xqds/ddr.c b/board/freescale/t208xqds/ddr.c index f1aff5481e49aeeb8a4c7d549ac7709cfaadc5aa..f96470f0206b551d2351369e784cca665040fc2b 100644 --- a/board/freescale/t208xqds/ddr.c +++ b/board/freescale/t208xqds/ddr.c @@ -108,13 +108,12 @@ phys_size_t initdram(int board_type) #if defined(CONFIG_SPL_BUILD) || !defined(CONFIG_RAMBOOT_PBL) puts("Initializing....using SPD\n"); dram_size = fsl_ddr_sdram(); - - dram_size = setup_ddr_tlbs(dram_size / 0x100000); - dram_size *= 0x100000; #else /* DDR has been initialised by first stage boot loader */ dram_size = fsl_ddr_sdram_size(); #endif + dram_size = setup_ddr_tlbs(dram_size / 0x100000); + dram_size *= 0x100000; return dram_size; } diff --git a/board/freescale/t208xqds/spl.c b/board/freescale/t208xqds/spl.c index 55a0f8fdce5bea1cdfd51f4c058eb2270a733d2e..bb02dab2f1539fdd103aee35c42d5abab37aa2d7 100644 --- a/board/freescale/t208xqds/spl.c +++ b/board/freescale/t208xqds/spl.c @@ -106,6 +106,7 @@ void board_init_r(gd_t *gd, ulong dest_addr) get_clocks(); mem_malloc_init(CONFIG_SPL_RELOC_MALLOC_ADDR, CONFIG_SPL_RELOC_MALLOC_SIZE); + gd->flags |= GD_FLG_FULL_MALLOC_INIT; #ifdef CONFIG_SPL_NAND_BOOT nand_spl_load_image(CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, diff --git a/board/freescale/t208xrdb/Makefile b/board/freescale/t208xrdb/Makefile index 9605f8b606c5e27927befe14b2b25c4ce2922ba6..cd8fe096d82426d48f1aa7eb9b9bebbf9cc62a1e 100644 --- a/board/freescale/t208xrdb/Makefile +++ b/board/freescale/t208xrdb/Makefile @@ -5,11 +5,9 @@ # ifdef CONFIG_SPL_BUILD -obj-y += spl.o +obj-y += spl.o else -obj-$(CONFIG_T2080RDB) += t208xrdb.o -obj-$(CONFIG_T2080RDB) += eth_t208xrdb.o -obj-$(CONFIG_T2080RDB) += cpld.o +obj-$(CONFIG_T2080RDB) += t208xrdb.o eth_t208xrdb.o cpld.o obj-$(CONFIG_PCI) += pci.o endif diff --git a/board/freescale/t208xrdb/ddr.c b/board/freescale/t208xrdb/ddr.c index 053f128e5b2286d84f727d022151839f36c2d8c5..f6c8ca30ac44388f35d2579e37cb2fb8c3c91098 100644 --- a/board/freescale/t208xrdb/ddr.c +++ b/board/freescale/t208xrdb/ddr.c @@ -101,12 +101,12 @@ phys_size_t initdram(int board_type) #if defined(CONFIG_SPL_BUILD) || !defined(CONFIG_RAMBOOT_PBL) puts("Initializing....using SPD\n"); dram_size = fsl_ddr_sdram(); - - dram_size = setup_ddr_tlbs(dram_size / 0x100000); - dram_size *= 0x100000; #else /* DDR has been initialised by first stage boot loader */ dram_size = fsl_ddr_sdram_size(); #endif + dram_size = setup_ddr_tlbs(dram_size / 0x100000); + dram_size *= 0x100000; + return dram_size; } diff --git a/board/freescale/t208xrdb/spl.c b/board/freescale/t208xrdb/spl.c index f63366bb0e6336614c73fd0d4b9d7ba5b30ec6ac..2ff05a29f507dae081ed7233d209a3bbc6994d1d 100644 --- a/board/freescale/t208xrdb/spl.c +++ b/board/freescale/t208xrdb/spl.c @@ -76,6 +76,7 @@ void board_init_r(gd_t *gd, ulong dest_addr) get_clocks(); mem_malloc_init(CONFIG_SPL_RELOC_MALLOC_ADDR, CONFIG_SPL_RELOC_MALLOC_SIZE); + gd->flags |= GD_FLG_FULL_MALLOC_INIT; #ifdef CONFIG_SPL_NAND_BOOT nand_spl_load_image(CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, diff --git a/board/freescale/t4qds/Makefile b/board/freescale/t4qds/Makefile index bd2c1f16222a1bd0a226cbed457b690936bfa4e8..731ccb0b295c1fcc255b38408f6b982f04391bd8 100644 --- a/board/freescale/t4qds/Makefile +++ b/board/freescale/t4qds/Makefile @@ -5,12 +5,12 @@ # ifdef CONFIG_SPL_BUILD -obj-y += spl.o +obj-y += spl.o else -obj-$(CONFIG_T4240QDS) += t4240qds.o -obj-$(CONFIG_T4240QDS)+= eth.o +obj-$(CONFIG_T4240QDS) += t4240qds.o eth.o obj-$(CONFIG_PCI) += pci.o endif + obj-y += ddr.o obj-y += law.o obj-y += tlb.o diff --git a/board/freescale/t4qds/ddr.c b/board/freescale/t4qds/ddr.c index 62d58c5b1f10c183c628ecdfa59f812a04977966..d533924a0dd38ac76860870ba388e99d5b6383a2 100644 --- a/board/freescale/t4qds/ddr.c +++ b/board/freescale/t4qds/ddr.c @@ -117,13 +117,12 @@ phys_size_t initdram(int board_type) #if defined(CONFIG_SPL_BUILD) || !defined(CONFIG_RAMBOOT_PBL) dram_size = fsl_ddr_sdram(); - - dram_size = setup_ddr_tlbs(dram_size / 0x100000); - dram_size *= 0x100000; - #else /* DDR has been initialised by first stage boot loader */ dram_size = fsl_ddr_sdram_size(); #endif + dram_size = setup_ddr_tlbs(dram_size / 0x100000); + dram_size *= 0x100000; + return dram_size; } diff --git a/board/freescale/t4qds/spl.c b/board/freescale/t4qds/spl.c index d52059a145330eff991256e1a32bbd91a684760c..6ca0f03ffe837b6ec886107b1248b5cb31d0c131 100644 --- a/board/freescale/t4qds/spl.c +++ b/board/freescale/t4qds/spl.c @@ -116,6 +116,7 @@ void board_init_r(gd_t *gd, ulong dest_addr) get_clocks(); mem_malloc_init(CONFIG_SPL_RELOC_MALLOC_ADDR, CONFIG_SPL_RELOC_MALLOC_SIZE); + gd->flags |= GD_FLG_FULL_MALLOC_INIT; #ifdef CONFIG_SPL_NAND_BOOT nand_spl_load_image(CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, diff --git a/board/freescale/t4rdb/Makefile b/board/freescale/t4rdb/Makefile index 83b55ee193460f4ad2bce1a6640ad05a312e7ece..4f29eea0f45985da2f263ae5bdb74183347dd980 100644 --- a/board/freescale/t4rdb/Makefile +++ b/board/freescale/t4rdb/Makefile @@ -5,13 +5,14 @@ # ifdef CONFIG_SPL_BUILD -obj-y += spl.o +obj-y += spl.o else -obj-$(CONFIG_T4240RDB) += t4240rdb.o -obj-y += cpld.o -obj-y += eth.o +obj-$(CONFIG_T4240RDB) += t4240rdb.o +obj-y += cpld.o +obj-y += eth.o obj-$(CONFIG_PCI) += pci.o endif + obj-y += ddr.o obj-y += law.o obj-y += tlb.o diff --git a/board/freescale/t4rdb/ddr.c b/board/freescale/t4rdb/ddr.c index 27b37b5cc42284c2bedc732da48bed95bcc601e8..230f031a3bf8d9319869f6d22f8bc8709a2f3504 100644 --- a/board/freescale/t4rdb/ddr.c +++ b/board/freescale/t4rdb/ddr.c @@ -110,13 +110,12 @@ phys_size_t initdram(int board_type) #if defined(CONFIG_SPL_BUILD) || !defined(CONFIG_RAMBOOT_PBL) dram_size = fsl_ddr_sdram(); - - dram_size = setup_ddr_tlbs(dram_size / 0x100000); - dram_size *= 0x100000; #else /* DDR has been initialised by first stage boot loader */ dram_size = fsl_ddr_sdram_size(); #endif + dram_size = setup_ddr_tlbs(dram_size / 0x100000); + dram_size *= 0x100000; return dram_size; } diff --git a/board/freescale/t4rdb/spl.c b/board/freescale/t4rdb/spl.c index 4c1e0cc8d0e83ad2b127a0e406d2f3203896d5f1..b148a7fd1fad974269307032d8788e30cc13831b 100644 --- a/board/freescale/t4rdb/spl.c +++ b/board/freescale/t4rdb/spl.c @@ -80,6 +80,7 @@ void board_init_r(gd_t *gd, ulong dest_addr) get_clocks(); mem_malloc_init(CONFIG_SPL_RELOC_MALLOC_ADDR, CONFIG_SPL_RELOC_MALLOC_SIZE); + gd->flags |= GD_FLG_FULL_MALLOC_INIT; mmc_initialize(bd); mmc_spl_load_image(CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 32219ed478899dfb997f01c7b66de261e36d9051..73b862dc0b219b1a5e5445fb113f10d83e554c0a 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -188,4 +188,30 @@ config DM_PCA953X Now, max 24 bits chips and PCA953X compatible chips are supported + +config MPC85XX_GPIO + bool "Freescale MPC85XX GPIO driver" + depends on DM_GPIO + help + This driver supports the built-in GPIO controller of MPC85XX CPUs. + Each GPIO bank is identified by its own entry in the device tree, + i.e. + + gpio-controller@fc00 { + #gpio-cells = <2>; + compatible = "fsl,pq3-gpio"; + reg = <0xfc00 0x100> + } + + By default, each bank is assumed to have 32 GPIOs, but the ngpios + setting is honored, so the number of GPIOs for each bank is + configurable to match the actual GPIO count of the SoC (e.g. the + 32/32/23 banks of the P1022 SoC). + + Aside from the standard functions of input/output mode, and output + value setting, the open-drain feature, which can configure individual + GPIOs to work as open-drain outputs, is supported. + + The driver has been tested on MPC85XX, but it is likely that other + PowerQUICC III devices will work as well. endmenu diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 3c4310176d1d86bf8807e604ba0aa515a5f6724c..792d19186aadf19a4a0a6a63efcccb759d24188a 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -36,6 +36,7 @@ obj-$(CONFIG_DA8XX_GPIO) += da8xx_gpio.o obj-$(CONFIG_DM644X_GPIO) += da8xx_gpio.o obj-$(CONFIG_ALTERA_PIO) += altera_pio.o obj-$(CONFIG_MPC83XX_GPIO) += mpc83xx_gpio.o +obj-$(CONFIG_MPC85XX_GPIO) += mpc85xx_gpio.o obj-$(CONFIG_SH_GPIO_PFC) += sh_pfc.o obj-$(CONFIG_OMAP_GPIO) += omap_gpio.o obj-$(CONFIG_DB8500_GPIO) += db8500_gpio.o diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c index 732b6c2afa12ac8b99b66ee97465971defeb1f73..4559739d619c637d79495e349290b7ae93646de9 100644 --- a/drivers/gpio/gpio-uclass.c +++ b/drivers/gpio/gpio-uclass.c @@ -367,6 +367,38 @@ int dm_gpio_set_value(const struct gpio_desc *desc, int value) return 0; } +int dm_gpio_get_open_drain(struct gpio_desc *desc) +{ + struct dm_gpio_ops *ops = gpio_get_ops(desc->dev); + int ret; + + ret = check_reserved(desc, "get_open_drain"); + if (ret) + return ret; + + if (ops->set_open_drain) + return ops->get_open_drain(desc->dev, desc->offset); + else + return -ENOSYS; +} + +int dm_gpio_set_open_drain(struct gpio_desc *desc, int value) +{ + struct dm_gpio_ops *ops = gpio_get_ops(desc->dev); + int ret; + + ret = check_reserved(desc, "set_open_drain"); + if (ret) + return ret; + + if (ops->set_open_drain) + ret = ops->set_open_drain(desc->dev, desc->offset, value); + else + return 0; /* feature not supported -> ignore setting */ + + return ret; +} + int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags) { struct udevice *dev = desc->dev; diff --git a/drivers/gpio/mpc85xx_gpio.c b/drivers/gpio/mpc85xx_gpio.c new file mode 100644 index 0000000000000000000000000000000000000000..04773e2b31c3074e322dff41debfb5bc63522f4f --- /dev/null +++ b/drivers/gpio/mpc85xx_gpio.c @@ -0,0 +1,228 @@ +/* + * (C) Copyright 2016 + * Mario Six, Guntermann & Drunck GmbH, six@gdsys.de + * + * based on arch/powerpc/include/asm/mpc85xx_gpio.h, which is + * + * Copyright 2010 eXMeritus, A Boeing Company + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <asm/gpio.h> +#include <mapmem.h> + +DECLARE_GLOBAL_DATA_PTR; + +struct ccsr_gpio { + u32 gpdir; + u32 gpodr; + u32 gpdat; + u32 gpier; + u32 gpimr; + u32 gpicr; +}; + +struct mpc85xx_gpio_data { + /* The bank's register base in memory */ + struct ccsr_gpio __iomem *base; + /* The address of the registers; used to identify the bank */ + ulong addr; + /* The GPIO count of the bank */ + uint gpio_count; + /* The GPDAT register cannot be used to determine the value of output + * pins on MPC8572/MPC8536, so we shadow it and use the shadowed value + * for output pins */ + u32 dat_shadow; +}; + +inline u32 gpio_mask(unsigned gpio) { + return (1U << (31 - (gpio))); +} + +static inline u32 mpc85xx_gpio_get_val(struct ccsr_gpio *base, u32 mask) +{ + return in_be32(&base->gpdat) & mask; +} + +static inline u32 mpc85xx_gpio_get_dir(struct ccsr_gpio *base, u32 mask) +{ + return in_be32(&base->gpdir) & mask; +} + +static inline void mpc85xx_gpio_set_in(struct ccsr_gpio *base, u32 gpios) +{ + clrbits_be32(&base->gpdat, gpios); + /* GPDIR register 0 -> input */ + clrbits_be32(&base->gpdir, gpios); +} + +static inline void mpc85xx_gpio_set_low(struct ccsr_gpio *base, u32 gpios) +{ + clrbits_be32(&base->gpdat, gpios); + /* GPDIR register 1 -> output */ + setbits_be32(&base->gpdir, gpios); +} + +static inline void mpc85xx_gpio_set_high(struct ccsr_gpio *base, u32 gpios) +{ + setbits_be32(&base->gpdat, gpios); + /* GPDIR register 1 -> output */ + setbits_be32(&base->gpdir, gpios); +} + +static inline int mpc85xx_gpio_open_drain_val(struct ccsr_gpio *base, u32 mask) +{ + return in_be32(&base->gpodr) & mask; +} + +static inline void mpc85xx_gpio_open_drain_on(struct ccsr_gpio *base, u32 + gpios) +{ + /* GPODR register 1 -> open drain on */ + setbits_be32(&base->gpodr, gpios); +} + +static inline void mpc85xx_gpio_open_drain_off(struct ccsr_gpio *base, + u32 gpios) +{ + /* GPODR register 0 -> open drain off (actively driven) */ + clrbits_be32(&base->gpodr, gpios); +} + +static int mpc85xx_gpio_direction_input(struct udevice *dev, unsigned gpio) +{ + struct mpc85xx_gpio_data *data = dev_get_priv(dev); + + mpc85xx_gpio_set_in(data->base, gpio_mask(gpio)); + return 0; +} + +static int mpc85xx_gpio_set_value(struct udevice *dev, unsigned gpio, + int value) +{ + struct mpc85xx_gpio_data *data = dev_get_priv(dev); + + if (value) { + data->dat_shadow |= gpio_mask(gpio); + mpc85xx_gpio_set_high(data->base, gpio_mask(gpio)); + } else { + data->dat_shadow &= ~gpio_mask(gpio); + mpc85xx_gpio_set_low(data->base, gpio_mask(gpio)); + } + return 0; +} + +static int mpc85xx_gpio_direction_output(struct udevice *dev, unsigned gpio, + int value) +{ + return mpc85xx_gpio_set_value(dev, gpio, value); +} + +static int mpc85xx_gpio_get_value(struct udevice *dev, unsigned gpio) +{ + struct mpc85xx_gpio_data *data = dev_get_priv(dev); + + if (!!mpc85xx_gpio_get_dir(data->base, gpio_mask(gpio))) { + /* Output -> use shadowed value */ + return !!(data->dat_shadow & gpio_mask(gpio)); + } else { + /* Input -> read value from GPDAT register */ + return !!mpc85xx_gpio_get_val(data->base, gpio_mask(gpio)); + } +} + +static int mpc85xx_gpio_get_open_drain(struct udevice *dev, unsigned gpio) +{ + struct mpc85xx_gpio_data *data = dev_get_priv(dev); + + return !!mpc85xx_gpio_open_drain_val(data->base, gpio_mask(gpio)); +} + +static int mpc85xx_gpio_set_open_drain(struct udevice *dev, unsigned gpio, + int value) +{ + struct mpc85xx_gpio_data *data = dev_get_priv(dev); + + if (value) { + mpc85xx_gpio_open_drain_on(data->base, gpio_mask(gpio)); + } else { + mpc85xx_gpio_open_drain_off(data->base, gpio_mask(gpio)); + } + return 0; +} + +static int mpc85xx_gpio_get_function(struct udevice *dev, unsigned gpio) +{ + struct mpc85xx_gpio_data *data = dev_get_priv(dev); + int dir; + + dir = !!mpc85xx_gpio_get_dir(data->base, gpio_mask(gpio)); + return dir ? GPIOF_OUTPUT : GPIOF_INPUT; +} + +static int mpc85xx_gpio_ofdata_to_platdata(struct udevice *dev) { + struct mpc85xx_gpio_data *data = dev_get_priv(dev); + fdt_addr_t addr; + fdt_size_t size; + + addr = fdtdec_get_addr_size_auto_noparent(gd->fdt_blob, dev->of_offset, + "reg", 0, &size); + + data->addr = addr; + data->base = map_sysmem(CONFIG_SYS_IMMR + addr, size); + + if (!data->base) + return -ENOMEM; + + data->gpio_count = fdtdec_get_int(gd->fdt_blob, dev->of_offset, + "ngpios", 32); + data->dat_shadow = 0; + + return 0; +} + +static int mpc85xx_gpio_probe(struct udevice *dev) +{ + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); + struct mpc85xx_gpio_data *data = dev_get_priv(dev); + char name[32], *str; + + snprintf(name, sizeof(name), "MPC@%lx_", data->addr); + str = strdup(name); + + if (!str) + return -ENOMEM; + + uc_priv->bank_name = str; + uc_priv->gpio_count = data->gpio_count; + + return 0; +} + +static const struct dm_gpio_ops gpio_mpc85xx_ops = { + .direction_input = mpc85xx_gpio_direction_input, + .direction_output = mpc85xx_gpio_direction_output, + .get_value = mpc85xx_gpio_get_value, + .set_value = mpc85xx_gpio_set_value, + .get_open_drain = mpc85xx_gpio_get_open_drain, + .set_open_drain = mpc85xx_gpio_set_open_drain, + .get_function = mpc85xx_gpio_get_function, +}; + +static const struct udevice_id mpc85xx_gpio_ids[] = { + { .compatible = "fsl,pq3-gpio" }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(gpio_mpc85xx) = { + .name = "gpio_mpc85xx", + .id = UCLASS_GPIO, + .ops = &gpio_mpc85xx_ops, + .ofdata_to_platdata = mpc85xx_gpio_ofdata_to_platdata, + .of_match = mpc85xx_gpio_ids, + .probe = mpc85xx_gpio_probe, + .priv_auto_alloc_size = sizeof(struct mpc85xx_gpio_data), +}; diff --git a/drivers/gpio/sandbox.c b/drivers/gpio/sandbox.c index a9b1efcd061222220be45b881ec3a119164ab7f8..f6435a0543ba787981a70830d65f6c923f97aa4e 100644 --- a/drivers/gpio/sandbox.c +++ b/drivers/gpio/sandbox.c @@ -15,6 +15,7 @@ DECLARE_GLOBAL_DATA_PTR; /* Flags for each GPIO */ #define GPIOF_OUTPUT (1 << 0) /* Currently set as an output */ #define GPIOF_HIGH (1 << 1) /* Currently set high */ +#define GPIOF_ODR (1 << 2) /* Currently set to open drain mode */ struct gpio_state { const char *label; /* label given by requester */ @@ -70,6 +71,16 @@ int sandbox_gpio_set_value(struct udevice *dev, unsigned offset, int value) return set_gpio_flag(dev, offset, GPIOF_HIGH, value); } +int sandbox_gpio_get_open_drain(struct udevice *dev, unsigned offset) +{ + return get_gpio_flag(dev, offset, GPIOF_ODR); +} + +int sandbox_gpio_set_open_drain(struct udevice *dev, unsigned offset, int value) +{ + return set_gpio_flag(dev, offset, GPIOF_ODR, value); +} + int sandbox_gpio_get_direction(struct udevice *dev, unsigned offset) { return get_gpio_flag(dev, offset, GPIOF_OUTPUT); @@ -124,6 +135,28 @@ static int sb_gpio_set_value(struct udevice *dev, unsigned offset, int value) return sandbox_gpio_set_value(dev, offset, value); } +/* read GPIO ODR value of port 'offset' */ +static int sb_gpio_get_open_drain(struct udevice *dev, unsigned offset) +{ + debug("%s: offset:%u\n", __func__, offset); + + return sandbox_gpio_get_open_drain(dev, offset); +} + +/* write GPIO ODR value to port 'offset' */ +static int sb_gpio_set_open_drain(struct udevice *dev, unsigned offset, int value) +{ + debug("%s: offset:%u, value = %d\n", __func__, offset, value); + + if (!sandbox_gpio_get_direction(dev, offset)) { + printf("sandbox_gpio: error: set_open_drain on input gpio %u\n", + offset); + return -1; + } + + return sandbox_gpio_set_open_drain(dev, offset, value); +} + static int sb_gpio_get_function(struct udevice *dev, unsigned offset) { if (get_gpio_flag(dev, offset, GPIOF_OUTPUT)) @@ -154,6 +187,8 @@ static const struct dm_gpio_ops gpio_sandbox_ops = { .direction_output = sb_gpio_direction_output, .get_value = sb_gpio_get_value, .set_value = sb_gpio_set_value, + .get_open_drain = sb_gpio_get_open_drain, + .set_open_drain = sb_gpio_set_open_drain, .get_function = sb_gpio_get_function, .xlate = sb_gpio_xlate, }; diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index 2500c10450062542b0b9ba2262adb6af6a7a5c6a..4aa0004fab4b2cc67e414b395ca38f9403e950c4 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h @@ -251,6 +251,8 @@ struct dm_gpio_ops { int value); int (*get_value)(struct udevice *dev, unsigned offset); int (*set_value)(struct udevice *dev, unsigned offset, int value); + int (*get_open_drain)(struct udevice *dev, unsigned offset); + int (*set_open_drain)(struct udevice *dev, unsigned offset, int value); /** * get_function() Get the GPIO function * @@ -549,6 +551,38 @@ int dm_gpio_get_value(const struct gpio_desc *desc); int dm_gpio_set_value(const struct gpio_desc *desc, int value); +/** + * dm_gpio_get_open_drain() - Check if open-drain-mode of a GPIO is active + * + * This checks if open-drain-mode for a GPIO is enabled or not. This method is + * optional. + * + * @desc: GPIO description containing device, offset and flags, + * previously returned by gpio_request_by_name() + * @return Value of open drain mode for GPIO (0 for inactive, 1 for active) or + * -ve on error + */ +int dm_gpio_get_open_drain(struct gpio_desc *desc); + +/** + * dm_gpio_set_open_drain() - Switch open-drain-mode of a GPIO on or off + * + * This enables or disables open-drain mode for a GPIO. This method is + * optional; if the driver does not support it, nothing happens when the method + * is called. + * + * In open-drain mode, instead of actively driving the output (Push-pull + * output), the GPIO's pin is connected to the collector (for a NPN transistor) + * or the drain (for a MOSFET) of a transistor, respectively. The pin then + * either forms an open circuit or a connection to ground, depending on the + * state of the transistor. + * + * @desc: GPIO description containing device, offset and flags, + * previously returned by gpio_request_by_name() + * @return 0 if OK, -ve on error + */ +int dm_gpio_set_open_drain(struct gpio_desc *desc, int value); + /** * dm_gpio_set_dir() - Set the direction for a GPIO * diff --git a/test/dm/gpio.c b/test/dm/gpio.c index 727db186903b5d4d324c8b7f979aee48d57ab1bf..b99452340dfcb5135fc9b9ec6106a9ecdded55a3 100644 --- a/test/dm/gpio.c +++ b/test/dm/gpio.c @@ -75,6 +75,13 @@ static int dm_test_gpio(struct unit_test_state *uts) ut_assertok(ops->set_value(dev, offset, 1)); ut_asserteq(1, ops->get_value(dev, offset)); + /* Make it an open drain output, and reset it */ + ut_asserteq(0, sandbox_gpio_get_open_drain(dev, offset)); + ut_assertok(ops->set_open_drain(dev, offset, 1)); + ut_asserteq(1, sandbox_gpio_get_open_drain(dev, offset)); + ut_assertok(ops->set_open_drain(dev, offset, 0)); + ut_asserteq(0, sandbox_gpio_get_open_drain(dev, offset)); + /* Make it an input */ ut_assertok(ops->direction_input(dev, offset)); ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf)));