config SPL_BUILD
bool
- depends on $KCONFIG_OBJDIR="spl" || $KCONFIG_OBJDIR="tpl"
- default y
+ default y if $KCONFIG_OBJDIR="spl" || $KCONFIG_OBJDIR="tpl"
config TPL_BUILD
bool
depends on FIT
config FIT_SIGNATURE
- bool "Enabel signature verification of FIT uImages"
+ bool "Enable signature verification of FIT uImages"
depends on FIT
+ select RSA
help
This option enables signature verification of FIT uImages,
using a hash signed and verified using RSA.
help
TODO: Move CONFIG_SYS_TEXT_BASE for all the architecture
+ config SYS_CLK_FREQ
+ depends on ARC
+ int "CPU clock frequency"
+ help
+ TODO: Move CONFIG_SYS_CLK_FREQ for all the architecture
+
endmenu # Boot images
source "arch/Kconfig"
source "common/Kconfig"
++source "disk/Kconfig"
++
source "dts/Kconfig"
source "net/Kconfig"
/lib Architecture specific library files
/powerpc Files generic to PowerPC architecture
/cpu CPU specific files
- /74xx_7xx Files specific to Freescale MPC74xx and 7xx CPUs
/mpc5xx Files specific to Freescale MPC5xx CPUs
/mpc5xxx Files specific to Freescale MPC5xxx CPUs
/mpc8xx Files specific to Freescale MPC8xx CPUs
requests. Increasing this will allow U-Boot to accept offers
from a BOOTP client in networks with unusually high latency.
+- BOOTP Random transaction ID:
+ CONFIG_BOOTP_RANDOM_ID
+
+ The standard algorithm to generate a DHCP/BOOTP transaction ID
+ by using the MAC address and the current time stamp may not
+ quite unlikely produce duplicate transaction IDs from different
+ clients in the same network. This option creates a transaction
+ ID using the rand() function. Provided that the RNG has been
+ seeded well, this should guarantee unique transaction IDs
+ always.
+
- DHCP Advanced Options:
You can fine tune the DHCP functionality by defining
CONFIG_BOOTP_* symbols:
This enables the RSA algorithm used for FIT image verification
in U-Boot. See doc/uImage.FIT/signature.txt for more information.
+ The Modular Exponentiation algorithm in RSA is implemented using
+ driver model. So CONFIG_DM needs to be enabled by default for this
+ library to function.
+
The signing part is build into mkimage regardless of this
- option.
+ option. The software based modular exponentiation is built into
+ mkimage irrespective of this option.
- bootcount support:
CONFIG_BOOTCOUNT_LIMIT
option). Given an image built by mkimage, the dumpimage extracts a "data file"
from the image:
- tools/dumpimage -i image -p position data_file
- -i ==> extract from the 'image' a specific 'data_file', \
- indexed by 'position'
+ tools/dumpimage -i image -T type -p position data_file
+ -i ==> extract from the 'image' a specific 'data_file'
+ -T ==> set image type to 'type'
+ -p ==> 'position' (starting at 0) of the 'data_file' inside the 'image'
Installing a Linux Image:
default "sa1100" if CPU_SA1100
default "armv8" if ARM64
+ config SEMIHOSTING
+ bool "support boot from semihosting"
+ help
+ In emulated environments, semihosting is a way for
+ the hosted environment to call out to the emulator to
+ retrieve files from the host machine.
+
choice
prompt "Target select"
select CPU_ARM926EJS
select SUPPORT_SPL
+config TARGET_TX28
+ bool "Support tx28"
+ select CPU_ARM926EJS
+ select SUPPORT_SPL
+
+config TARGET_TX48
+ bool "Support tx48"
+ select CPU_V7
+ select SUPPORT_SPL
+
+config TARGET_TX51
+ bool "Support tx51"
+ select CPU_V7
+
+config TARGET_TX53
+ bool "Support tx53"
+ select CPU_V7
+
+config TARGET_TX6
+ bool "Support tx6"
+ select CPU_V7
+
config TARGET_ZMX25
bool "Support zmx25"
select CPU_ARM926EJS
select CPU_ARM720T if SPL_BUILD
select CPU_V7 if !SPL_BUILD
- config TARGET_VEXPRESS_AEMV8A
+ config TARGET_VEXPRESS64_AEMV8A
bool "Support vexpress_aemv8a"
select ARM64
+ config TARGET_VEXPRESS64_BASE_FVP
+ bool "Support Versatile Express ARMv8a FVP BASE model"
+ select ARM64
+ select SEMIHOSTING
+
+ config TARGET_VEXPRESS64_JUNO
+ bool "Support Versatile Express Juno Development Platform"
+ select ARM64
+
config TARGET_LS2085A_EMU
bool "Support ls2085a_emu"
select ARM64
source "board/isee/igep0033/Kconfig"
source "board/jornada/Kconfig"
source "board/karo/tx25/Kconfig"
+source "board/karo/tx28/Kconfig"
+source "board/karo/tx48/Kconfig"
+source "board/karo/tx51/Kconfig"
+source "board/karo/tx53/Kconfig"
+source "board/karo/tx6/Kconfig"
source "board/kosagi/novena/Kconfig"
source "board/logicpd/imx27lite/Kconfig"
source "board/logicpd/imx31_litekit/Kconfig"
#include <common.h>
#include <command.h>
+#include <lcd.h>
#include <asm/system.h>
static void cache_flush(void);
disable_interrupts ();
+#ifdef CONFIG_LCD
+ {
+ /* switch off LCD panel */
+ lcd_panel_disable();
+ /* disable LCD controller */
+ lcd_disable();
+ }
+#endif
/* turn off I/D-cache */
icache_disable();
/* flush I/D-cache */
static void cache_flush (void)
{
+ #if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF))
unsigned long i = 0;
asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i));
+ #endif
}
#endif
#if defined(CONFIG_OMAP_HSMMC) && !defined(CONFIG_SPL_BUILD)
-int cpu_mmc_init(bd_t *bis)
+int __cpu_mmc_init(bd_t *bis)
{
int ret;
return omap_mmc_init(1, 0, 0, -1, -1);
}
+/* let platform code be able to override this! */
+int cpu_mmc_init(bd_t *bis) __attribute__((weak, alias("__cpu_mmc_init")));
#endif
/* AM33XX has two MUSB controllers which can be host or gadget */
*/
#ifdef CONFIG_NOR_BOOT
enable_norboot_pin_mux();
- #endif
- /*
- * Save the boot parameters passed from romcode.
- * We cannot delay the saving further than this,
- * to prevent overwrites.
- */
- #ifdef CONFIG_SPL_BUILD
- save_omap_boot_params();
#endif
watchdog_disable();
set_uart_mux_conf();
gd->baudrate = CONFIG_BAUDRATE;
serial_init();
gd->have_console = 1;
- #elif defined(CONFIG_SPL_BUILD)
- gd = &gdata;
- preloader_console_init();
#endif
#if defined(CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC)
/* Enable RTC32K clock */
#include <common.h>
#include <command.h>
+#include <lcd.h>
#include <asm/system.h>
#include <asm/cache.h>
#include <asm/armv7.h>
*/
#ifndef CONFIG_SPL_BUILD
disable_interrupts();
-#endif
+#ifdef CONFIG_LCD
+ {
+ /* switch off LCD panel */
+ lcd_panel_disable();
+ /* disable LCD controller */
+ lcd_disable();
+ }
+#endif /* CONFIG_LCD */
+#endif /* CONFIG_SPL_BUILD */
/*
* Turn off I-cache and invalidate it
* After D-cache is flushed and before it is disabled there may
* be some new valid entries brought into the cache. We are sure
* that these lines are not dirty and will not affect our execution.
- * (because unwinding the call-stack and setting a bit in CP15 SCTRL
+ * (because unwinding the call-stack and setting a bit in CP15 SCTLR
* is all we did during this. We have not pushed anything on to the
* stack. Neither have we affected any static data)
* So just invalidate the entire d-cache again to avoid coherency
#ifdef CONFIG_SPL_BUILD
u32 spl_boot_device(void)
{
- return (u32) (gd->arch.omap_boot_params.omap_bootdevice);
+ return gd->arch.omap_boot_params.omap_bootdevice;
}
u32 spl_boot_mode(void)
void spl_board_init(void)
{
+ /*
+ * Save the boot parameters passed from romcode.
+ * We cannot delay the saving further than this,
+ * to prevent overwrites.
+ */
+ save_omap_boot_params();
+
+ /* Prepare console output */
+ preloader_console_init();
+
#ifdef CONFIG_SPL_NAND_SUPPORT
gpmc_init();
#endif
#include <asm/arch/hardware.h>
-#define BIT(x) (1 << x)
-#define CL_BIT(x) (0 << x)
+#define BIT(x) (1 << (x))
+#define CL_BIT(x) (0 << (x))
/* Timer register bits */
#define TCLR_ST BIT(0) /* Start=1 Stop=0 */
#define TCLR_AR BIT(1) /* Auto reload */
#define TCLR_PRE BIT(5) /* Pre-scaler enable */
-#define TCLR_PTV_SHIFT (2) /* Pre-scaler shift value */
+#define TCLR_PTV_SHIFT 2 /* Pre-scaler shift value */
#define TCLR_PRE_DISABLE CL_BIT(5) /* Pre-scalar disable */
#define TCLR_CE BIT(6) /* compare mode enable */
#define TCLR_SCPWM BIT(7) /* pwm outpin behaviour */
#define AM335X_ZCE_600 0x1F9F
/* This gives the status of the boot mode pins on the evm */
-#define SYSBOOT_MASK (BIT(0) | BIT(1) | BIT(2)\
- | BIT(3) | BIT(4))
+#define SYSBOOT_MASK (BIT(0) | BIT(1) | BIT(2) | \
+ BIT(3) | BIT(4))
#define PRM_RSTCTRL_RESET 0x01
#define PRM_RSTST_WARM_RESET_MASK 0x232
unsigned int idlestdpllddr; /* offset 0x34 */
unsigned int resv5[2];
unsigned int clkseldpllddr; /* offset 0x40 */
- unsigned int resv6[4];
+ unsigned int autoidledplldisp; /* offset 0x44 */
+ unsigned int idlestdplldisp; /* offset 0x48 */
+ unsigned int resv6[2];
unsigned int clkseldplldisp; /* offset 0x54 */
unsigned int resv7[1];
unsigned int idlestdpllcore; /* offset 0x5c */
unsigned int resv1;
unsigned int cpgmac0clkctrl; /* offset 0x14 */
unsigned int lcdclkctrl; /* offset 0x18 */
- unsigned int usb0clkctrl; /* offset 0x1C */
+ unsigned int usb0clkctrl; /* offset 0x1c */
unsigned int resv2;
unsigned int tptc0clkctrl; /* offset 0x24 */
unsigned int emifclkctrl; /* offset 0x28 */
unsigned int resv4[2];
unsigned int clklcdcpixelclk; /* offset 0x34 */
};
+
+ struct prm_device_inst {
+ unsigned int prm_rstctrl;
+ unsigned int prm_rsttime;
+ unsigned int prm_rstst;
+ };
#else
/* Encapsulating core pll registers */
struct cm_wkuppll {
unsigned int cm_dll_ctrl;
};
+ struct prm_device_inst {
+ unsigned int prm_rstctrl;
+ unsigned int prm_rstst;
+ };
+
struct cm_dpll {
unsigned int resv1;
unsigned int clktimer2clk; /* offset 0x04 */
unsigned int twpc; /* offset 0x48 */
unsigned int tmar; /* offset 0x4c */
unsigned int tcar1; /* offset 0x50 */
- unsigned int tscir; /* offset 0x54 */
+ unsigned int tsicr; /* offset 0x54 */
unsigned int tcar2; /* offset 0x58 */
};
unsigned int resv1[16];
unsigned int statusreg; /* ofset 0x40 */
unsigned int resv2[51];
- unsigned int secure_emif_sdram_config; /* offset 0x0110 */
+ unsigned int emif_sdram_config; /* offset 0x0110 */
unsigned int resv3[319];
unsigned int dev_attr;
};
#define ECTRL2_PLSL_LOW BIT(10)
#define ECTRL2_SYNC_EN BIT(5)
+#define clk_get_rate(c,p) \
+ __clk_get_rate(readl(&(c)->clkseldpll##p), \
+ readl(&(c)->divm2dpll##p))
+
+unsigned long __clk_get_rate(u32 m_n, u32 div_m2);
+
+unsigned long mpu_clk_rate(void);
+
#endif /* __ASSEMBLY__ */
#endif /* __KERNEL_STRICT_NAMES */
+/* Ethernet MAC ID from EFuse */
+#define MAC_ID0_LO (CTRL_BASE + 0x630)
+#define MAC_ID0_HI (CTRL_BASE + 0x634)
+#define MAC_ID1_LO (CTRL_BASE + 0x638)
+#define MAC_ID1_HI (CTRL_BASE + 0x63c)
+#define MAC_MII_SEL (CTRL_BASE + 0x650)
+
#endif /* _AM33XX_CPU_H */
/* Reg mapping structure */
struct emif_reg_struct {
- u32 emif_mod_id_rev;
- u32 emif_status;
- u32 emif_sdram_config;
- u32 emif_lpddr2_nvm_config;
- u32 emif_sdram_ref_ctrl;
- u32 emif_sdram_ref_ctrl_shdw;
- u32 emif_sdram_tim_1;
- u32 emif_sdram_tim_1_shdw;
- u32 emif_sdram_tim_2;
- u32 emif_sdram_tim_2_shdw;
- u32 emif_sdram_tim_3;
- u32 emif_sdram_tim_3_shdw;
- u32 emif_lpddr2_nvm_tim;
- u32 emif_lpddr2_nvm_tim_shdw;
- u32 emif_pwr_mgmt_ctrl;
- u32 emif_pwr_mgmt_ctrl_shdw;
- u32 emif_lpddr2_mode_reg_data;
- u32 padding1[1];
- u32 emif_lpddr2_mode_reg_data_es2;
- u32 padding11[1];
- u32 emif_lpddr2_mode_reg_cfg;
- u32 emif_l3_config;
- u32 emif_l3_cfg_val_1;
- u32 emif_l3_cfg_val_2;
- u32 emif_iodft_tlgc;
- u32 padding2[7];
- u32 emif_perf_cnt_1;
- u32 emif_perf_cnt_2;
- u32 emif_perf_cnt_cfg;
- u32 emif_perf_cnt_sel;
- u32 emif_perf_cnt_tim;
- u32 padding3;
- u32 emif_read_idlectrl;
- u32 emif_read_idlectrl_shdw;
- u32 padding4;
- u32 emif_irqstatus_raw_sys;
- u32 emif_irqstatus_raw_ll;
- u32 emif_irqstatus_sys;
- u32 emif_irqstatus_ll;
- u32 emif_irqenable_set_sys;
- u32 emif_irqenable_set_ll;
- u32 emif_irqenable_clr_sys;
- u32 emif_irqenable_clr_ll;
- u32 padding5;
- u32 emif_zq_config;
- u32 emif_temp_alert_config;
- u32 emif_l3_err_log;
- u32 emif_rd_wr_lvl_rmp_win;
- u32 emif_rd_wr_lvl_rmp_ctl;
- u32 emif_rd_wr_lvl_ctl;
- u32 padding6[1];
- u32 emif_ddr_phy_ctrl_1;
- u32 emif_ddr_phy_ctrl_1_shdw;
- u32 emif_ddr_phy_ctrl_2;
- u32 padding7[4];
- u32 emif_prio_class_serv_map;
- u32 emif_connect_id_serv_1_map;
- u32 emif_connect_id_serv_2_map;
- u32 padding8[5];
- u32 emif_rd_wr_exec_thresh;
- u32 emif_cos_config;
- u32 padding9[6];
- u32 emif_ddr_phy_status[28];
- u32 padding10[20];
- u32 emif_ddr_ext_phy_ctrl_1;
- u32 emif_ddr_ext_phy_ctrl_1_shdw;
- u32 emif_ddr_ext_phy_ctrl_2;
- u32 emif_ddr_ext_phy_ctrl_2_shdw;
- u32 emif_ddr_ext_phy_ctrl_3;
- u32 emif_ddr_ext_phy_ctrl_3_shdw;
- u32 emif_ddr_ext_phy_ctrl_4;
- u32 emif_ddr_ext_phy_ctrl_4_shdw;
- u32 emif_ddr_ext_phy_ctrl_5;
- u32 emif_ddr_ext_phy_ctrl_5_shdw;
- u32 emif_ddr_ext_phy_ctrl_6;
- u32 emif_ddr_ext_phy_ctrl_6_shdw;
- u32 emif_ddr_ext_phy_ctrl_7;
- u32 emif_ddr_ext_phy_ctrl_7_shdw;
- u32 emif_ddr_ext_phy_ctrl_8;
- u32 emif_ddr_ext_phy_ctrl_8_shdw;
- u32 emif_ddr_ext_phy_ctrl_9;
- u32 emif_ddr_ext_phy_ctrl_9_shdw;
- u32 emif_ddr_ext_phy_ctrl_10;
- u32 emif_ddr_ext_phy_ctrl_10_shdw;
- u32 emif_ddr_ext_phy_ctrl_11;
- u32 emif_ddr_ext_phy_ctrl_11_shdw;
- u32 emif_ddr_ext_phy_ctrl_12;
- u32 emif_ddr_ext_phy_ctrl_12_shdw;
- u32 emif_ddr_ext_phy_ctrl_13;
- u32 emif_ddr_ext_phy_ctrl_13_shdw;
- u32 emif_ddr_ext_phy_ctrl_14;
- u32 emif_ddr_ext_phy_ctrl_14_shdw;
- u32 emif_ddr_ext_phy_ctrl_15;
- u32 emif_ddr_ext_phy_ctrl_15_shdw;
- u32 emif_ddr_ext_phy_ctrl_16;
- u32 emif_ddr_ext_phy_ctrl_16_shdw;
- u32 emif_ddr_ext_phy_ctrl_17;
- u32 emif_ddr_ext_phy_ctrl_17_shdw;
- u32 emif_ddr_ext_phy_ctrl_18;
- u32 emif_ddr_ext_phy_ctrl_18_shdw;
- u32 emif_ddr_ext_phy_ctrl_19;
- u32 emif_ddr_ext_phy_ctrl_19_shdw;
- u32 emif_ddr_ext_phy_ctrl_20;
- u32 emif_ddr_ext_phy_ctrl_20_shdw;
- u32 emif_ddr_ext_phy_ctrl_21;
- u32 emif_ddr_ext_phy_ctrl_21_shdw;
- u32 emif_ddr_ext_phy_ctrl_22;
- u32 emif_ddr_ext_phy_ctrl_22_shdw;
- u32 emif_ddr_ext_phy_ctrl_23;
- u32 emif_ddr_ext_phy_ctrl_23_shdw;
- u32 emif_ddr_ext_phy_ctrl_24;
- u32 emif_ddr_ext_phy_ctrl_24_shdw;
- u32 emif_ddr_ext_phy_ctrl_25;
- u32 emif_ddr_ext_phy_ctrl_25_shdw;
- u32 emif_ddr_ext_phy_ctrl_26;
- u32 emif_ddr_ext_phy_ctrl_26_shdw;
- u32 emif_ddr_ext_phy_ctrl_27;
- u32 emif_ddr_ext_phy_ctrl_27_shdw;
- u32 emif_ddr_ext_phy_ctrl_28;
- u32 emif_ddr_ext_phy_ctrl_28_shdw;
- u32 emif_ddr_ext_phy_ctrl_29;
- u32 emif_ddr_ext_phy_ctrl_29_shdw;
- u32 emif_ddr_ext_phy_ctrl_30;
- u32 emif_ddr_ext_phy_ctrl_30_shdw;
- u32 emif_ddr_ext_phy_ctrl_31;
- u32 emif_ddr_ext_phy_ctrl_31_shdw;
- u32 emif_ddr_ext_phy_ctrl_32;
- u32 emif_ddr_ext_phy_ctrl_32_shdw;
- u32 emif_ddr_ext_phy_ctrl_33;
- u32 emif_ddr_ext_phy_ctrl_33_shdw;
- u32 emif_ddr_ext_phy_ctrl_34;
- u32 emif_ddr_ext_phy_ctrl_34_shdw;
- u32 emif_ddr_ext_phy_ctrl_35;
- u32 emif_ddr_ext_phy_ctrl_35_shdw;
+ u32 emif_mod_id_rev; /* 0x000 */
+ u32 emif_status; /* 0x004 */
+ u32 emif_sdram_config; /* 0x008 */
+ u32 emif_lpddr2_nvm_config; /* 0x00c */
+ u32 emif_sdram_ref_ctrl; /* 0x010 */
+ u32 emif_sdram_ref_ctrl_shdw; /* 0x014 */
+ u32 emif_sdram_tim_1; /* 0x018 */
+ u32 emif_sdram_tim_1_shdw; /* 0x01c */
+ u32 emif_sdram_tim_2; /* 0x020 */
+ u32 emif_sdram_tim_2_shdw; /* 0x024 */
+ u32 emif_sdram_tim_3; /* 0x028 */
+ u32 emif_sdram_tim_3_shdw; /* 0x02c */
+ u32 emif_lpddr2_nvm_tim; /* 0x030 */
+ u32 emif_lpddr2_nvm_tim_shdw; /* 0x034 */
+ u32 emif_pwr_mgmt_ctrl; /* 0x038 */
+ u32 emif_pwr_mgmt_ctrl_shdw; /* 0x03c */
+ u32 emif_lpddr2_mode_reg_data; /* 0x040 */
+ u32 padding1[1]; /* 0x044 */
+ u32 emif_lpddr2_mode_reg_data_es2; /* 0x048 */
+ u32 padding11[1]; /* 0x04c */
+ u32 emif_lpddr2_mode_reg_cfg; /* 0x050 */
+ u32 emif_l3_config; /* 0x054 */
+ u32 emif_l3_cfg_val_1; /* 0x058 */
+ u32 emif_l3_cfg_val_2; /* 0x05c */
+ u32 emif_iodft_tlgc; /* 0x060 */
+ u32 padding2[7]; /* 0x064 */
+ u32 emif_perf_cnt_1; /* 0x080 */
+ u32 emif_perf_cnt_2; /* 0x084 */
+ u32 emif_perf_cnt_cfg; /* 0x088 */
+ u32 emif_perf_cnt_sel; /* 0x08c */
+ u32 emif_perf_cnt_tim; /* 0x090 */
+ u32 padding3; /* 0x094 */
+ u32 emif_read_idlectrl; /* 0x098 */
+ u32 emif_read_idlectrl_shdw; /* 0x09c */
+ u32 padding4; /* 0x0a0 */
+ u32 emif_irqstatus_raw_sys; /* 0x0a4 */
+ u32 emif_irqstatus_raw_ll; /* 0x0a8 */
+ u32 emif_irqstatus_sys; /* 0x0ac */
+ u32 emif_irqstatus_ll; /* 0x0b0 */
+ u32 emif_irqenable_set_sys; /* 0x0b4 */
+ u32 emif_irqenable_set_ll; /* 0x0b8 */
+ u32 emif_irqenable_clr_sys; /* 0x0bc */
+ u32 emif_irqenable_clr_ll; /* 0x0c0 */
+ u32 padding5; /* 0x0c4 */
+ u32 emif_zq_config; /* 0x0c8 */
+ u32 emif_temp_alert_config; /* 0x0cc */
+ u32 emif_l3_err_log; /* 0x0d0 */
+ u32 emif_rd_wr_lvl_rmp_win; /* 0x0d4 */
+ u32 emif_rd_wr_lvl_rmp_ctl; /* 0x0d8 */
+ u32 emif_rd_wr_lvl_ctl; /* 0x0dc */
+ u32 padding6[1]; /* 0x0e0 */
+ u32 emif_ddr_phy_ctrl_1; /* 0x0e4 */
+ u32 emif_ddr_phy_ctrl_1_shdw; /* 0x0e8 */
+ u32 emif_ddr_phy_ctrl_2; /* 0x0ec */
+ u32 padding7[4]; /* 0x0f0 */
+ u32 emif_prio_class_serv_map; /* 0x100 */
+ u32 emif_connect_id_serv_1_map; /* 0x104 */
+ u32 emif_connect_id_serv_2_map; /* 0x108 */
+ u32 padding8[5]; /* 0x10c */
+ u32 emif_rd_wr_exec_thresh; /* 0x120 */
- u32 padding9[6]; /* 0x124 */
- u32 emif_ddr_phy_status[21]; /* 0x13c */
- u32 padding10[27]; /* 0x1fc */
++ u32 emif_cos_config; /* 0x124 */
++ u32 padding9[6]; /* 0x128 */
++ u32 emif_ddr_phy_status[28]; /* 0x140 */
++ u32 padding10[20]; /* 0x1b0 */
+ u32 emif_ddr_ext_phy_ctrl_1; /* 0x200 */
+ u32 emif_ddr_ext_phy_ctrl_1_shdw; /* 0x204 */
+ u32 emif_ddr_ext_phy_ctrl_2; /* 0x248 */
+ u32 emif_ddr_ext_phy_ctrl_2_shdw; /* 0x24c */
+ u32 emif_ddr_ext_phy_ctrl_3; /* 0x200 */
+ u32 emif_ddr_ext_phy_ctrl_3_shdw; /* 0x204 */
+ u32 emif_ddr_ext_phy_ctrl_4; /* 0x208 */
+ u32 emif_ddr_ext_phy_ctrl_4_shdw; /* 0x20c */
+ u32 emif_ddr_ext_phy_ctrl_5; /* 0x210 */
+ u32 emif_ddr_ext_phy_ctrl_5_shdw; /* 0x214 */
+ u32 emif_ddr_ext_phy_ctrl_6; /* 0x218 */
+ u32 emif_ddr_ext_phy_ctrl_6_shdw; /* 0x21c */
+ u32 emif_ddr_ext_phy_ctrl_7; /* 0x220 */
+ u32 emif_ddr_ext_phy_ctrl_7_shdw; /* 0x224 */
+ u32 emif_ddr_ext_phy_ctrl_8; /* 0x228 */
+ u32 emif_ddr_ext_phy_ctrl_8_shdw; /* 0x22c */
+ u32 emif_ddr_ext_phy_ctrl_9; /* 0x230 */
+ u32 emif_ddr_ext_phy_ctrl_9_shdw; /* 0x234 */
+ u32 emif_ddr_ext_phy_ctrl_10; /* 0x238 */
+ u32 emif_ddr_ext_phy_ctrl_10_shdw; /* 0x23c */
+ u32 emif_ddr_ext_phy_ctrl_11; /* 0x240 */
+ u32 emif_ddr_ext_phy_ctrl_11_shdw; /* 0x244 */
+ u32 emif_ddr_ext_phy_ctrl_12; /* 0x248 */
+ u32 emif_ddr_ext_phy_ctrl_12_shdw; /* 0x24c */
+ u32 emif_ddr_ext_phy_ctrl_13; /* 0x250 */
+ u32 emif_ddr_ext_phy_ctrl_13_shdw; /* 0x254 */
+ u32 emif_ddr_ext_phy_ctrl_14; /* 0x258 */
+ u32 emif_ddr_ext_phy_ctrl_14_shdw; /* 0x25c */
+ u32 emif_ddr_ext_phy_ctrl_15; /* 0x260 */
+ u32 emif_ddr_ext_phy_ctrl_15_shdw; /* 0x264 */
+ u32 emif_ddr_ext_phy_ctrl_16; /* 0x268 */
+ u32 emif_ddr_ext_phy_ctrl_16_shdw; /* 0x26c */
+ u32 emif_ddr_ext_phy_ctrl_17; /* 0x270 */
+ u32 emif_ddr_ext_phy_ctrl_17_shdw; /* 0x274 */
+ u32 emif_ddr_ext_phy_ctrl_18; /* 0x278 */
+ u32 emif_ddr_ext_phy_ctrl_18_shdw; /* 0x27c */
+ u32 emif_ddr_ext_phy_ctrl_19; /* 0x280 */
+ u32 emif_ddr_ext_phy_ctrl_19_shdw; /* 0x284 */
+ u32 emif_ddr_ext_phy_ctrl_20; /* 0x288 */
+ u32 emif_ddr_ext_phy_ctrl_20_shdw; /* 0x28c */
+ u32 emif_ddr_ext_phy_ctrl_21; /* 0x290 */
+ u32 emif_ddr_ext_phy_ctrl_21_shdw; /* 0x294 */
+ u32 emif_ddr_ext_phy_ctrl_22; /* 0x298 */
+ u32 emif_ddr_ext_phy_ctrl_22_shdw; /* 0x29c */
+ u32 emif_ddr_ext_phy_ctrl_23; /* 0x2a0 */
+ u32 emif_ddr_ext_phy_ctrl_23_shdw; /* 0x2a4 */
+ u32 emif_ddr_ext_phy_ctrl_24; /* 0x2a8 */
+ u32 emif_ddr_ext_phy_ctrl_24_shdw; /* 0x2ac */
- u32 padding[22]; /* 0x2b0 */
- u32 emif_ddr_fifo_misaligned_clear_1; /* 0x308 */
- u32 emif_ddr_fifo_misaligned_clear_2; /* 0x30c */
++ u32 emif_ddr_ext_phy_ctrl_25; /* 0x2b0 */
++ u32 emif_ddr_ext_phy_ctrl_25_shdw; /* 0x2b4 */
++ u32 emif_ddr_ext_phy_ctrl_26; /* 0x2b8 */
++ u32 emif_ddr_ext_phy_ctrl_26_shdw; /* 0x2bc */
++ u32 emif_ddr_ext_phy_ctrl_27; /* 0x2c0 */
++ u32 emif_ddr_ext_phy_ctrl_27_shdw; /* 0x2c4 */
++ u32 emif_ddr_ext_phy_ctrl_28; /* 0x2c8 */
++ u32 emif_ddr_ext_phy_ctrl_28_shdw; /* 0x2cc */
++ u32 emif_ddr_ext_phy_ctrl_29; /* 0x2d0 */
++ u32 emif_ddr_ext_phy_ctrl_29_shdw; /* 0x2d4 */
++ u32 emif_ddr_ext_phy_ctrl_30; /* 0x2d8 */
++ u32 emif_ddr_ext_phy_ctrl_30_shdw; /* 0x2dc */
++ u32 emif_ddr_ext_phy_ctrl_31; /* 0x2e0 */
++ u32 emif_ddr_ext_phy_ctrl_31_shdw; /* 0x2e4 */
++ u32 emif_ddr_ext_phy_ctrl_32; /* 0x2e8 */
++ u32 emif_ddr_ext_phy_ctrl_32_shdw; /* 0x2ec */
++ u32 emif_ddr_ext_phy_ctrl_33; /* 0x2f0 */
++ u32 emif_ddr_ext_phy_ctrl_33_shdw; /* 0x2f4 */
++ u32 emif_ddr_ext_phy_ctrl_34; /* 0x2f8 */
++ u32 emif_ddr_ext_phy_ctrl_34_shdw; /* 0x2fc */
++ u32 emif_ddr_ext_phy_ctrl_35; /* 0x300 */
++ u32 emif_ddr_ext_phy_ctrl_35_shdw; /* 0x304 */
+ union {
- u32 emif_ddr_ext_phy_ctrl_36;
++ u32 emif_ddr_ext_phy_ctrl_36; /* 0x308 */
+ u32 emif_ddr_fifo_misaligned_clear_1;
+ };
+ union {
- u32 emif_ddr_ext_phy_ctrl_36_shdw;
++ u32 emif_ddr_ext_phy_ctrl_36_shdw; /* 0x30c */
+ u32 emif_ddr_fifo_misaligned_clear_2;
+ };
};
struct dmm_lisa_map_regs {
/* assert macros */
#if defined(DEBUG)
-#define emif_assert(c) ({ if (!(c)) for (;;); })
+#define emif_assert(c) ({ if (!(c)) hang(); })
#else
-#define emif_assert(c) ({ if (0) hang(); })
+#define emif_assert(c) (c)
#endif
#ifdef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS
#endif /* CONFIG_CPU_ARM1136 */
- #ifdef CONFIG_ARM926EJS
+ #ifdef CONFIG_CPU_ARM926EJS
+ #if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF))
- /* test and clean, page 2-23 of arm926ejs manual */
- asm("0: mrc p15, 0, r15, c7, c10, 3\n\t" "bne 0b\n" : : : "memory");
- /* disable write buffer as well (page 2-22) */
- asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
+ asm(
+ /* test and clean, page 2-23 of arm926ejs manual */
+ "0: mrc p15, 0, r15, c7, c10, 3\n\t" "bne 0b\n"
+ /* flush write buffer as well (page 2-22) */
+ "mcr p15, 0, %0, c7, c10, 4" : : "r"(0) : "memory"
+ );
#endif
+ #endif /* CONFIG_CPU_ARM926EJS */
return;
}
--- /dev/null
- KEEP(board/karo/tx53/lowlevel_init.o (.text*))
+/*
+ * (C) Copyright 2012 Lothar Waßmann <LW@KARO-electronics.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
+ */
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+ . = 0x00000000;
+ .text :
+ {
- _end = .;
+ *(.__image_copy_start)
++ *(.vectors)
+ CPUDIR/start.o (.text*)
++ . = 0x400;
++ KEEP(BOARDDIR/lowlevel_init.o (.text*))
+ *(.text*)
+ }
+
++#if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT) || defined(CONFIG_ARMV7_PSCI)
++
++#ifndef CONFIG_ARMV7_SECURE_BASE
++#define CONFIG_ARMV7_SECURE_BASE
++#endif
++
++ .__secure_start : {
++ . = ALIGN(0x1000);
++ *(.__secure_start)
++ }
++
++ .secure_text CONFIG_ARMV7_SECURE_BASE :
++ AT(ADDR(.__secure_start) + SIZEOF(.__secure_start))
++ {
++ *(._secure.text)
++ }
++
++ . = LOADADDR(.__secure_start) +
++ SIZEOF(.__secure_start) +
++ SIZEOF(.secure_text);
++
++ __secure_end_lma = .;
++ .__secure_end : AT(__secure_end_lma) {
++ *(.__secure_end)
++ LONG(0x1d1071c); /* Must output something to reset LMA */
++ }
++#endif
++
+ . = ALIGN(4);
+ .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
+
+ . = ALIGN(4);
+ .data : {
+ *(.data*)
+ }
+
+ . = ALIGN(4);
+ .u_boot_list : {
+ KEEP(*(SORT(.u_boot_list*)));
+ }
+
+ . = ALIGN(4);
+ .image_copy_end :
+ {
+ *(.__image_copy_end)
+ }
+
+ .rel_dyn_start :
+ {
+ *(.__rel_dyn_start)
+ }
+
+ .rel.dyn :
+ {
+ *(.rel*)
+ }
+
+ .rel_dyn_end :
+ {
+ *(.__rel_dyn_end)
+ }
+
+ /* Workaround for an apparent bug in i.MX53 ROM Code,
+ * that skips loading the last block if it doesn't
+ * end on a 4KiB boundary.
+ */
++
+ . = ALIGN(4096);
+ .uboot_img_end :
+ {
+ *(.__uboot_img_end)
+ }
+
-
- /DISCARD/ : { *(.bss*) }
- /DISCARD/ : { *(.dynstr*) }
- /DISCARD/ : { *(.dynsym*) }
- /DISCARD/ : { *(.dynamic*) }
- /DISCARD/ : { *(.hash*) }
- /DISCARD/ : { *(.plt*) }
- /DISCARD/ : { *(.interp*) }
- /DISCARD/ : { *(.gnu*) }
++ _image_binary_end = .;
+
+/*
+ * Compiler-generated __bss_start and __bss_end, see arch/arm/lib/bss.c
+ * __bss_base and __bss_limit are for linker only (overlay ordering)
+ */
+
+ .bss_start __rel_dyn_start (OVERLAY) : {
+ KEEP(*(.__bss_start));
+ __bss_base = .;
+ }
+
+ .bss __bss_base (OVERLAY) : {
+ *(.bss*)
+ . = ALIGN(4);
+ __bss_limit = .;
+ }
+ .bss_end __bss_limit (OVERLAY) : {
+ KEEP(*(.__bss_end));
+ }
++
++ .dynsym _image_binary_end : { *(.dynsym) }
++ .dynbss : { *(.dynbss) }
++ .dynstr : { *(.dynstr*) }
++ .dynamic : { *(.dynamic*) }
++ .plt : { *(.plt*) }
++ .interp : { *(.interp*) }
++ .gnu.hash : { *(.gnu.hash) }
++ .gnu : { *(.gnu*) }
++ .ARM.exidx : { *(.ARM.exidx*) }
++ .gnu.linkonce.armexidx : { *(.gnu.linkonce.armexidx.*) }
+}
help
Boot an application image from the memory.
+config CMD_BOOTZ
+ bool "bootz"
+ default y
+ help
+ Boot a Linux kernel zImage.
+
+config CMD_BOOTCE
+ bool "bootce"
+ help
+ Boot a WindowsCE image.
+
config CMD_GO
bool "go"
default y
endmenu
+menu "DTB support"
+
+config OF_LIBFDT
+ bool "Enable FDT commands"
+
+config OF_BOARD_SETUP
+ bool "Support DT modifications by board code"
+ depends on OF_LIBFDT
+
+endmenu
+
menu "Environment commands"
config CMD_EXPORTENV
endmenu
+menu "Environment configuration settings"
+
+choice
+ prompt "Select environment non-volatile storage"
+
+config ENV_IS_NOWHERE
+ bool "do not store environment"
+
+config ENV_IS_IN_NAND
+ bool "store environment in NAND"
+ depends on NAND
+
+config ENV_IS_IN_MMC
+ bool "store environment in MMC"
+ depends on MMC
+
+endchoice
+
+endmenu
+
menu "Memory commands"
config CMD_MEMORY
erase - FLASH memory
protect - enable or disable FLASH write protection
+config MTD_DEVICE
+ bool "MTD device support"
+
+config CMD_MTDPARTS
+ bool "MTD partitioning support"
+ default y
+ depends on MTD_DEVICE && (CMD_FLASH || CMD_NAND)
+
config CMD_NAND
bool "nand"
help
NAND support.
+config CMD_NAND_TRIMFFS
+ bool "Enable nand write.trimffs command"
+ help
+ Enable command to leave page sized runs of 0xff patterns in
+ erased state rather than overwriting them. This is required
+ for using NAND flash filesystems on NAND controllers with
+ a non-0xff ECC code for all 0xff data.
+
+config CMD_MMC
+ bool "mmc/sd"
++ select PARTITIONS
+ help
+ MMC/SD support.
+
config CMD_SPI
bool "sspi"
help
menu "Misc commands"
+config CMD_CACHE
+ bool "cache control"
+ help
+ Enable commands to switch data cache on/off.
+
config CMD_TIME
bool "time"
help
# boards
obj-$(CONFIG_SYS_GENERIC_BOARD) += board_f.o
obj-$(CONFIG_SYS_GENERIC_BOARD) += board_r.o
+ obj-$(CONFIG_DISPLAY_BOARDINFO) += board_info.o
+ obj-$(CONFIG_DISPLAY_BOARDINFO_LATE) += board_info.o
# core command
obj-y += cmd_boot.o
obj-$(CONFIG_CMD_BDI) += cmd_bdinfo.o
obj-$(CONFIG_CMD_BEDBUG) += bedbug.o cmd_bedbug.o
obj-$(CONFIG_CMD_BMP) += cmd_bmp.o
+obj-$(CONFIG_CMD_BOOTCE) += cmd_bootce.o
obj-$(CONFIG_CMD_BOOTMENU) += cmd_bootmenu.o
obj-$(CONFIG_CMD_BOOTLDR) += cmd_bootldr.o
obj-$(CONFIG_CMD_BOOTSTAGE) += cmd_bootstage.o
obj-$(CONFIG_I2C_EDID) += edid.o
obj-$(CONFIG_KALLSYMS) += kallsyms.o
obj-y += splash.o
- obj-$(CONFIG_LCD) += lcd.o
+ obj-$(CONFIG_LCD) += lcd.o lcd_console.o
obj-$(CONFIG_LYNXKDI) += lynxkdi.o
obj-$(CONFIG_MENU) += menu.o
obj-$(CONFIG_MODEM_SUPPORT) += modem.o
if (mmc_legacy_init(dev) != 0) {
puts("No MMC card found\n");
- return 1;
+ return CMD_RET_FAILURE;
}
curr_device = dev;
if (argc == 2) {
if (curr_device < 0) {
puts("No MMC device available\n");
- return 1;
+ return CMD_RET_FAILURE;
}
} else if (argc == 3) {
dev = (int)simple_strtoul(argv[2], NULL, 10);
#ifdef CONFIG_SYS_MMC_SET_DEV
if (mmc_set_dev(dev) != 0)
- return 1;
+ return CMD_RET_FAILURE;
#endif
curr_device = dev;
} else {
return CMD_RET_USAGE;
}
- return 0;
+ return CMD_RET_SUCCESS;
}
U_BOOT_CMD(
static void print_mmcinfo(struct mmc *mmc)
{
+ int i;
+
printf("Device: %s\n", mmc->cfg->name);
printf("Manufacturer ID: %x\n", mmc->cid[0] >> 24);
printf("OEM: %x\n", (mmc->cid[0] >> 8) & 0xffff);
printf("Bus Width: %d-bit%s\n", mmc->bus_width,
mmc->ddr_mode ? " DDR" : "");
+
+ puts("Erase Group Size: ");
+ print_size(((u64)mmc->erase_grp_size) << 9, "\n");
+
+ if (!IS_SD(mmc) && mmc->version >= MMC_VERSION_4_41) {
+ bool has_enh = (mmc->part_support & ENHNCD_SUPPORT) != 0;
+ bool usr_enh = has_enh && (mmc->part_attr & EXT_CSD_ENH_USR);
+
+ puts("HC WP Group Size: ");
+ print_size(((u64)mmc->hc_wp_grp_size) << 9, "\n");
+
+ puts("User Capacity: ");
+ print_size(mmc->capacity_user, usr_enh ? " ENH" : "");
+ if (mmc->wr_rel_set & EXT_CSD_WR_DATA_REL_USR)
+ puts(" WRREL\n");
+ else
+ putc('\n');
+ if (usr_enh) {
+ puts("User Enhanced Start: ");
+ print_size(mmc->enh_user_start, "\n");
+ puts("User Enhanced Size: ");
+ print_size(mmc->enh_user_size, "\n");
+ }
+ puts("Boot Capacity: ");
+ print_size(mmc->capacity_boot, has_enh ? " ENH\n" : "\n");
+ puts("RPMB Capacity: ");
+ print_size(mmc->capacity_rpmb, has_enh ? " ENH\n" : "\n");
+
+ for (i = 0; i < ARRAY_SIZE(mmc->capacity_gp); i++) {
+ bool is_enh = has_enh &&
+ (mmc->part_attr & EXT_CSD_ENH_GP(i));
+ if (mmc->capacity_gp[i]) {
+ printf("GP%i Capacity: ", i+1);
+ print_size(mmc->capacity_gp[i],
+ is_enh ? " ENH" : "");
+ if (mmc->wr_rel_set & EXT_CSD_WR_DATA_REL_GP(i))
+ puts(" WRREL\n");
+ else
+ putc('\n');
+ }
+ }
+ }
}
static struct mmc *init_mmc_device(int dev, bool force_init)
{
curr_device = 0;
else {
puts("No MMC device available\n");
- return 1;
+ return CMD_RET_FAILURE;
}
}
print_mmc_devices('\n');
return CMD_RET_SUCCESS;
}
+
+ static int parse_hwpart_user(struct mmc_hwpart_conf *pconf,
+ int argc, char * const argv[])
+ {
+ int i = 0;
+
+ memset(&pconf->user, 0, sizeof(pconf->user));
+
+ while (i < argc) {
+ if (!strcmp(argv[i], "enh")) {
+ if (i + 2 >= argc)
+ return -1;
+ pconf->user.enh_start =
+ simple_strtoul(argv[i+1], NULL, 10);
+ pconf->user.enh_size =
+ simple_strtoul(argv[i+2], NULL, 10);
+ i += 3;
+ } else if (!strcmp(argv[i], "wrrel")) {
+ if (i + 1 >= argc)
+ return -1;
+ pconf->user.wr_rel_change = 1;
+ if (!strcmp(argv[i+1], "on"))
+ pconf->user.wr_rel_set = 1;
+ else if (!strcmp(argv[i+1], "off"))
+ pconf->user.wr_rel_set = 0;
+ else
+ return -1;
+ i += 2;
+ } else {
+ break;
+ }
+ }
+ return i;
+ }
+
+ static int parse_hwpart_gp(struct mmc_hwpart_conf *pconf, int pidx,
+ int argc, char * const argv[])
+ {
+ int i;
+
+ memset(&pconf->gp_part[pidx], 0, sizeof(pconf->gp_part[pidx]));
+
+ if (1 >= argc)
+ return -1;
+ pconf->gp_part[pidx].size = simple_strtoul(argv[0], NULL, 10);
+
+ i = 1;
+ while (i < argc) {
+ if (!strcmp(argv[i], "enh")) {
+ pconf->gp_part[pidx].enhanced = 1;
+ i += 1;
+ } else if (!strcmp(argv[i], "wrrel")) {
+ if (i + 1 >= argc)
+ return -1;
+ pconf->gp_part[pidx].wr_rel_change = 1;
+ if (!strcmp(argv[i+1], "on"))
+ pconf->gp_part[pidx].wr_rel_set = 1;
+ else if (!strcmp(argv[i+1], "off"))
+ pconf->gp_part[pidx].wr_rel_set = 0;
+ else
+ return -1;
+ i += 2;
+ } else {
+ break;
+ }
+ }
+ return i;
+ }
+
+ static int do_mmc_hwpartition(cmd_tbl_t *cmdtp, int flag,
+ int argc, char * const argv[])
+ {
+ struct mmc *mmc;
+ struct mmc_hwpart_conf pconf = { };
+ enum mmc_hwpart_conf_mode mode = MMC_HWPART_CONF_CHECK;
+ int i, r, pidx;
+
+ mmc = init_mmc_device(curr_device, false);
+ if (!mmc)
+ return CMD_RET_FAILURE;
+
+ if (argc < 1)
+ return CMD_RET_USAGE;
+ i = 1;
+ while (i < argc) {
+ if (!strcmp(argv[i], "user")) {
+ i++;
+ r = parse_hwpart_user(&pconf, argc-i, &argv[i]);
+ if (r < 0)
+ return CMD_RET_USAGE;
+ i += r;
+ } else if (!strncmp(argv[i], "gp", 2) &&
+ strlen(argv[i]) == 3 &&
+ argv[i][2] >= '1' && argv[i][2] <= '4') {
+ pidx = argv[i][2] - '1';
+ i++;
+ r = parse_hwpart_gp(&pconf, pidx, argc-i, &argv[i]);
+ if (r < 0)
+ return CMD_RET_USAGE;
+ i += r;
+ } else if (!strcmp(argv[i], "check")) {
+ mode = MMC_HWPART_CONF_CHECK;
+ i++;
+ } else if (!strcmp(argv[i], "set")) {
+ mode = MMC_HWPART_CONF_SET;
+ i++;
+ } else if (!strcmp(argv[i], "complete")) {
+ mode = MMC_HWPART_CONF_COMPLETE;
+ i++;
+ } else {
+ return CMD_RET_USAGE;
+ }
+ }
+
+ puts("Partition configuration:\n");
+ if (pconf.user.enh_size) {
+ puts("\tUser Enhanced Start: ");
+ print_size(((u64)pconf.user.enh_start) << 9, "\n");
+ puts("\tUser Enhanced Size: ");
+ print_size(((u64)pconf.user.enh_size) << 9, "\n");
+ } else {
+ puts("\tNo enhanced user data area\n");
+ }
+ if (pconf.user.wr_rel_change)
+ printf("\tUser partition write reliability: %s\n",
+ pconf.user.wr_rel_set ? "on" : "off");
+ for (pidx = 0; pidx < 4; pidx++) {
+ if (pconf.gp_part[pidx].size) {
+ printf("\tGP%i Capacity: ", pidx+1);
+ print_size(((u64)pconf.gp_part[pidx].size) << 9,
+ pconf.gp_part[pidx].enhanced ?
+ " ENH\n" : "\n");
+ } else {
+ printf("\tNo GP%i partition\n", pidx+1);
+ }
+ if (pconf.gp_part[pidx].wr_rel_change)
+ printf("\tGP%i write reliability: %s\n", pidx+1,
+ pconf.gp_part[pidx].wr_rel_set ? "on" : "off");
+ }
+
+ if (!mmc_hwpart_config(mmc, &pconf, mode)) {
+ if (mode == MMC_HWPART_CONF_COMPLETE)
+ puts("Partitioning successful, "
+ "power-cycle to make effective\n");
+ return CMD_RET_SUCCESS;
+ } else {
+ puts("Failed!\n");
+ return CMD_RET_FAILURE;
+ }
+ }
+
#ifdef CONFIG_SUPPORT_EMMC_BOOT
static int do_mmc_bootbus(cmd_tbl_t *cmdtp, int flag,
int argc, char * const argv[])
U_BOOT_CMD_MKENT(part, 1, 1, do_mmc_part, "", ""),
U_BOOT_CMD_MKENT(dev, 3, 0, do_mmc_dev, "", ""),
U_BOOT_CMD_MKENT(list, 1, 1, do_mmc_list, "", ""),
+ U_BOOT_CMD_MKENT(hwpartition, 28, 0, do_mmc_hwpartition, "", ""),
#ifdef CONFIG_SUPPORT_EMMC_BOOT
U_BOOT_CMD_MKENT(bootbus, 5, 0, do_mmc_bootbus, "", ""),
U_BOOT_CMD_MKENT(bootpart-resize, 4, 0, do_mmc_boot_resize, "", ""),
}
U_BOOT_CMD(
- mmc, 7, 1, do_mmcops,
+ mmc, 29, 1, do_mmcops,
"MMC sub system",
"info - display info of the current MMC device\n"
"mmc read addr blk# cnt\n"
"mmc part - lists available partition on current mmc device\n"
"mmc dev [dev] [part] - show or set current mmc device [partition]\n"
"mmc list - lists available devices\n"
+ "mmc hwpartition [args...] - does hardware partitioning\n"
+ " arguments (sizes in 512-byte blocks):\n"
+ " [user [enh start cnt] [wrrel {on|off}]] - sets user data area attributes\n"
+ " [gp1|gp2|gp3|gp4 cnt [enh] [wrrel {on|off}]] - general purpose partition\n"
+ " [check|set|complete] - mode, complete set partitioning completed\n"
+ " WARNING: Partitioning is a write-once setting once it is set to complete.\n"
+ " Power cycling is required to initialize partitions after set to complete.\n"
#ifdef CONFIG_SUPPORT_EMMC_BOOT
"mmc bootbus dev boot_bus_width reset_boot_bus_width boot_mode\n"
" - Set the BOOT_BUS_WIDTH field of the specified device\n"
#ifdef CONFIG_LCD_LOGO
# include <bmp_logo.h> /* Get logo data, width and height */
# include <bmp_logo_data.h>
-# if (CONSOLE_COLOR_WHITE >= BMP_LOGO_OFFSET) && (LCD_BPP != LCD_COLOR16)
+# if (CONSOLE_COLOR_WHITE >= BMP_LOGO_OFFSET) && (LCD_BPP < LCD_COLOR16)
# error Default Color Map overlaps with Logo Color Map
# endif
#endif
#define CONFIG_LCD_ALIGNMENT PAGE_SIZE
#endif
- /* By default we scroll by a single line */
- #ifndef CONFIG_CONSOLE_SCROLL_LINES
- #define CONFIG_CONSOLE_SCROLL_LINES 1
- #endif
-
- /************************************************************************/
- /* ** CONSOLE DEFINITIONS & FUNCTIONS */
- /************************************************************************/
- #if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO)
- # define CONSOLE_ROWS ((panel_info.vl_row-BMP_LOGO_HEIGHT) \
- / VIDEO_FONT_HEIGHT)
- #else
- # define CONSOLE_ROWS (panel_info.vl_row / VIDEO_FONT_HEIGHT)
- #endif
-
- #define CONSOLE_COLS (panel_info.vl_col / VIDEO_FONT_WIDTH)
- #define CONSOLE_ROW_SIZE (VIDEO_FONT_HEIGHT * lcd_line_length)
- #define CONSOLE_ROW_FIRST lcd_console_address
- #define CONSOLE_ROW_SECOND (lcd_console_address + CONSOLE_ROW_SIZE)
- #define CONSOLE_ROW_LAST (lcd_console_address + CONSOLE_SIZE \
- - CONSOLE_ROW_SIZE)
- #define CONSOLE_SIZE (CONSOLE_ROW_SIZE * CONSOLE_ROWS)
- #define CONSOLE_SCROLL_SIZE (CONSOLE_SIZE - CONSOLE_ROW_SIZE)
-
- #if LCD_BPP == LCD_MONOCHROME
- # define COLOR_MASK(c) ((c) | (c) << 1 | (c) << 2 | (c) << 3 | \
- (c) << 4 | (c) << 5 | (c) << 6 | (c) << 7)
- #elif (LCD_BPP == LCD_COLOR8) || (LCD_BPP == LCD_COLOR16) || \
- (LCD_BPP == LCD_COLOR32)
- # define COLOR_MASK(c) (c)
- #else
+ #if (LCD_BPP != LCD_COLOR8) && (LCD_BPP != LCD_COLOR16) && \
+ (LCD_BPP != LCD_COLOR32)
# error Unsupported LCD BPP.
#endif
DECLARE_GLOBAL_DATA_PTR;
- static void lcd_drawchars(ushort x, ushort y, uchar *str, int count);
- static inline void lcd_putc_xy(ushort x, ushort y, uchar c);
-
static int lcd_init(void *lcdbase);
static void *lcd_logo(void);
char lcd_is_enabled = 0;
- static short console_col;
- static short console_row;
-
- static void *lcd_console_address;
static void *lcd_base; /* Start of framebuffer memory */
static char lcd_flush_dcache; /* 1 to flush dcache after each lcd update */
/*----------------------------------------------------------------------*/
- static void console_scrollup(void)
- {
- const int rows = CONFIG_CONSOLE_SCROLL_LINES;
-
- /* Copy up rows ignoring those that will be overwritten */
- memcpy(CONSOLE_ROW_FIRST,
- lcd_console_address + CONSOLE_ROW_SIZE * rows,
- CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows);
-
- /* Clear the last rows */
- #if (LCD_BPP != LCD_COLOR32)
- memset(lcd_console_address + CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows,
- COLOR_MASK(lcd_color_bg),
- CONSOLE_ROW_SIZE * rows);
- #else
- u32 *ppix = lcd_console_address +
- CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows;
- u32 i;
- for (i = 0;
- i < (CONSOLE_ROW_SIZE * rows) / NBYTES(panel_info.vl_bpix);
- i++) {
- *ppix++ = COLOR_MASK(lcd_color_bg);
- }
- #endif
- lcd_sync();
- console_row -= rows;
- }
-
- /*----------------------------------------------------------------------*/
-
- static inline void console_back(void)
- {
- if (--console_col < 0) {
- console_col = CONSOLE_COLS-1 ;
- if (--console_row < 0)
- console_row = 0;
- }
-
- lcd_putc_xy(console_col * VIDEO_FONT_WIDTH,
- console_row * VIDEO_FONT_HEIGHT, ' ');
- }
-
- /*----------------------------------------------------------------------*/
-
- static inline void console_newline(void)
- {
- console_col = 0;
-
- /* Check if we need to scroll the terminal */
- if (++console_row >= CONSOLE_ROWS)
- console_scrollup();
- else
- lcd_sync();
- }
-
- /*----------------------------------------------------------------------*/
-
static void lcd_stub_putc(struct stdio_dev *dev, const char c)
{
lcd_putc(c);
}
- void lcd_putc(const char c)
- {
- if (!lcd_is_enabled) {
- serial_putc(c);
-
- return;
- }
-
- switch (c) {
- case '\r':
- console_col = 0;
-
- return;
- case '\n':
- console_newline();
-
- return;
- case '\t': /* Tab (8 chars alignment) */
- console_col += 8;
- console_col &= ~7;
-
- if (console_col >= CONSOLE_COLS)
- console_newline();
-
- return;
- case '\b':
- console_back();
-
- return;
- default:
- lcd_putc_xy(console_col * VIDEO_FONT_WIDTH,
- console_row * VIDEO_FONT_HEIGHT, c);
- if (++console_col >= CONSOLE_COLS)
- console_newline();
- }
- }
-
- /*----------------------------------------------------------------------*/
-
static void lcd_stub_puts(struct stdio_dev *dev, const char *s)
{
lcd_puts(s);
}
- void lcd_puts(const char *s)
- {
- if (!lcd_is_enabled) {
- serial_puts(s);
-
- return;
- }
-
- while (*s)
- lcd_putc(*s++);
-
- lcd_sync();
- }
-
- /*----------------------------------------------------------------------*/
-
- void lcd_printf(const char *fmt, ...)
- {
- va_list args;
- char buf[CONFIG_SYS_PBSIZE];
-
- va_start(args, fmt);
- vsprintf(buf, fmt, args);
- va_end(args);
-
- lcd_puts(buf);
- }
-
- /************************************************************************/
- /* ** Low-Level Graphics Routines */
- /************************************************************************/
-
- static void lcd_drawchars(ushort x, ushort y, uchar *str, int count)
- {
- void *dest;
- ushort row;
-
- #if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO)
- y += BMP_LOGO_HEIGHT;
- #endif
-
- #if LCD_BPP == LCD_MONOCHROME
- ushort off = x * NBITS(LCD_BPP) % 8;
- #endif
-
- dest = lcd_base + y * lcd_line_length + x * NBITS(LCD_BPP) / 8;
-
- for (row = 0; row < VIDEO_FONT_HEIGHT; ++row, dest += lcd_line_length) {
- uchar *s = str;
- int i;
- #if LCD_BPP == LCD_COLOR16
- ushort *d = (ushort *)dest;
- #elif LCD_BPP == LCD_COLOR32
- u32 *d = (u32 *)dest;
- #else
- uchar *d = dest;
- #endif
-
- #if LCD_BPP == LCD_MONOCHROME
- uchar rest = *d & -(1 << (8 - off));
- uchar sym;
- #endif
- for (i = 0; i < count; ++i) {
- uchar c, bits;
-
- c = *s++;
- bits = video_fontdata[c * VIDEO_FONT_HEIGHT + row];
-
- #if LCD_BPP == LCD_MONOCHROME
- sym = (COLOR_MASK(lcd_color_fg) & bits) |
- (COLOR_MASK(lcd_color_bg) & ~bits);
-
- *d++ = rest | (sym >> off);
- rest = sym << (8-off);
- #else
- for (c = 0; c < 8; ++c) {
- *d++ = (bits & 0x80) ?
- lcd_color_fg : lcd_color_bg;
- bits <<= 1;
- }
- #endif
- }
- #if LCD_BPP == LCD_MONOCHROME
- *d = rest | (*d & ((1 << (8 - off)) - 1));
- #endif
- }
- }
-
- static inline void lcd_putc_xy(ushort x, ushort y, uchar c)
- {
- lcd_drawchars(x, y, &c, 1);
- }
-
/************************************************************************/
/** Small utility to check that you got the colours right */
/************************************************************************/
CONSOLE_COLOR_BLUE, CONSOLE_COLOR_MAGENTA, CONSOLE_COLOR_CYAN,
};
+#if LCD_BPP == LCD_COLOR8
+typedef uchar pix_t;
+#elif LCD_BPP == LCD_COLOR16
+typedef ushort pix_t;
+#elif LCD_BPP == LCD_COLOR32
+typedef ulong pix_t;
+#else
+#error Unsupported pixelformat
+#endif
+
static void test_pattern(void)
{
ushort v_max = panel_info.vl_row;
ushort v_step = (v_max + N_BLK_VERT - 1) / N_BLK_VERT;
ushort h_step = (h_max + N_BLK_HOR - 1) / N_BLK_HOR;
ushort v, h;
- uchar *pix = (uchar *)lcd_base;
+ pix_t *pix = lcd_base;
printf("[LCD] Test Pattern: %d x %d [%d x %d]\n",
h_max, v_max, h_step, v_step);
/*----------------------------------------------------------------------*/
void lcd_clear(void)
{
- #if LCD_BPP == LCD_MONOCHROME
- /* Setting the palette */
- lcd_initcolregs();
-
- #elif LCD_BPP == LCD_COLOR8
+ short console_rows, console_cols;
+ int bg_color;
+ #if LCD_BPP == LCD_COLOR8
/* Setting the palette */
lcd_setcolreg(CONSOLE_COLOR_BLACK, 0, 0, 0);
lcd_setcolreg(CONSOLE_COLOR_RED, 0xFF, 0, 0);
#ifndef CONFIG_SYS_WHITE_ON_BLACK
lcd_setfgcolor(CONSOLE_COLOR_BLACK);
lcd_setbgcolor(CONSOLE_COLOR_WHITE);
+ bg_color = CONSOLE_COLOR_WHITE;
#else
lcd_setfgcolor(CONSOLE_COLOR_WHITE);
lcd_setbgcolor(CONSOLE_COLOR_BLACK);
+ bg_color = CONSOLE_COLOR_BLACK;
#endif /* CONFIG_SYS_WHITE_ON_BLACK */
#ifdef LCD_TEST_PATTERN
#else
/* set framebuffer to background color */
#if (LCD_BPP != LCD_COLOR32)
- memset((char *)lcd_base,
- COLOR_MASK(lcd_color_bg),
- lcd_line_length * panel_info.vl_row);
+ memset((char *)lcd_base, bg_color, lcd_line_length * panel_info.vl_row);
#else
u32 *ppix = lcd_base;
u32 i;
for (i = 0;
i < (lcd_line_length * panel_info.vl_row)/NBYTES(panel_info.vl_bpix);
i++) {
- *ppix++ = COLOR_MASK(lcd_color_bg);
+ *ppix++ = bg_color;
}
#endif
#endif
/* Paint the logo and retrieve LCD base address */
- debug("[LCD] Drawing the logo...\n");
+ debug("[LCD] Drawing the logo @ %p...\n", lcd_base);
- lcd_console_address = lcd_logo();
-
- console_col = 0;
- console_row = 0;
+ #if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO)
+ console_rows = (panel_info.vl_row - BMP_LOGO_HEIGHT);
+ console_rows /= VIDEO_FONT_HEIGHT;
+ #else
+ console_rows = panel_info.vl_row / VIDEO_FONT_HEIGHT;
+ #endif
+ console_cols = panel_info.vl_col / VIDEO_FONT_WIDTH;
+ lcd_init_console(lcd_base, console_rows, console_cols);
+ lcd_init_console(lcd_logo(), console_rows, console_cols);
lcd_sync();
}
static int lcd_init(void *lcdbase)
{
/* Initialize the lcd controller */
- debug("[LCD] Initializing LCD frambuffer at %p\n", lcdbase);
+ debug("[LCD] Initializing %ux%ux%u LCD framebuffer at %p\n",
+ panel_info.vl_col, panel_info.vl_row, NBITS(panel_info.vl_bpix),
+ lcdbase);
lcd_ctrl_init(lcdbase);
lcd_enable();
/* Initialize the console */
- console_col = 0;
+ lcd_set_col(0);
#ifdef CONFIG_LCD_INFO_BELOW_LOGO
- console_row = 7 + BMP_LOGO_HEIGHT / VIDEO_FONT_HEIGHT;
+ lcd_set_row(7 + BMP_LOGO_HEIGHT / VIDEO_FONT_HEIGHT);
#else
- console_row = 1; /* leave 1 blank line below logo */
+ lcd_set_row(1); /* leave 1 blank line below logo */
#endif
return 0;
lcd_color_fg = color;
}
+ int lcd_getfgcolor(void)
+ {
+ return lcd_color_fg;
+ }
+
/*----------------------------------------------------------------------*/
static void lcd_setbgcolor(int color)
lcd_color_bg = color;
}
+ int lcd_getbgcolor(void)
+ {
+ return lcd_color_bg;
+ }
+
/************************************************************************/
/* ** Chipset depending Bitmap / Logo stuff... */
/************************************************************************/
struct pxafb_info *fbi = &panel_info.pxa;
return (ushort *)fbi->palette;
#elif defined(CONFIG_MPC823)
- immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
+ immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
cpm8xx_t *cp = &(immr->im_cpm);
return (ushort *)&(cp->lcd_cmap[255 * sizeof(ushort)]);
#elif defined(CONFIG_ATMEL_LCD)
uchar *fb;
ushort *fb16;
#if defined(CONFIG_MPC823)
- immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
+ immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
cpm8xx_t *cp = &(immr->im_cpm);
#endif
unsigned bpix = NBITS(panel_info.vl_bpix);
*(cmap + BMP_LOGO_OFFSET) = lut_entry;
cmap++;
#else /* !CONFIG_ATMEL_LCD */
- #ifdef CONFIG_SYS_INVERT_COLORS
- *cmap++ = 0xffff - colreg;
- #else
*cmap++ = colreg;
- #endif
#endif /* CONFIG_ATMEL_LCD */
}
bmap += BMP_LOGO_WIDTH;
fb += panel_info.vl_col;
}
- }
- else { /* true color mode */
+ } else if (NBITS(panel_info.vl_bpix) == 16) {
u16 col16;
fb16 = (ushort *)fb;
for (i = 0; i < BMP_LOGO_HEIGHT; ++i) {
bmap += BMP_LOGO_WIDTH;
fb16 += panel_info.vl_col;
}
+ } else { /* true color mode */
+ u16 col16;
+ u32 *fb32 = lcd_base + y * lcd_line_length + x;
+
+ for (i = 0; i < BMP_LOGO_HEIGHT; i++) {
+ for (j = 0; j < BMP_LOGO_WIDTH; j++) {
+ col16 = bmp_logo_palette[bmap[j] - 16];
+ fb32[j] =
+ ((col16 & 0x000F) << 4) |
+ ((col16 & 0x00F0) << 8) |
+ ((col16 & 0x0F00) << 12);
+ }
+ bmap += BMP_LOGO_WIDTH;
+ fb32 += panel_info.vl_col;
+ }
}
WATCHDOG_RESET();
#endif
#endif /* CONFIG_BMP_16BPP */
+static inline bmp_color_table_entry_t *get_color_table(bmp_image_t *bmp)
+{
+ bmp_header_t *bh = &bmp->header;
+ return (void *)bmp + offsetof(bmp_header_t, size) + bh->size;
+}
+
int lcd_display_bitmap(ulong bmp_image, int x, int y)
{
ushort *cmap = NULL;
bmp_image_t *bmp = (bmp_image_t *)map_sysmem(bmp_image, 0);
uchar *bmap;
ushort padded_width;
- unsigned long width, height, byte_width;
+ unsigned long width, height;
unsigned long pwidth = panel_info.vl_col;
- unsigned colors, bpix, bmp_bpix;
+ unsigned long long colors;
+ unsigned bpix, bmp_bpix;
+ bmp_color_table_entry_t *cte;
if (!bmp || !(bmp->header.signature[0] == 'B' &&
bmp->header.signature[1] == 'M')) {
return 1;
}
- debug("Display-bmp: %d x %d with %d colors\n",
- (int)width, (int)height, (int)colors);
+ debug("Display-bmp: %lu x %lu with %llu colors\n",
+ width, height, colors);
+ cte = get_color_table(bmp);
if (bmp_bpix == 8) {
cmap = configuration_get_cmap();
cmap_base = cmap;
/* Set color map */
for (i = 0; i < colors; ++i) {
- bmp_color_table_entry_t cte = bmp->color_table[i];
#if !defined(CONFIG_ATMEL_LCD)
ushort colreg =
- ( ((cte.red) << 8) & 0xf800) |
- ( ((cte.green) << 3) & 0x07e0) |
- ( ((cte.blue) >> 3) & 0x001f) ;
+ ( ((cte[i].red) << 8) & 0xf800) |
+ ( ((cte[i].green) << 3) & 0x07e0) |
+ ( ((cte[i].blue) >> 3) & 0x001f) ;
- #ifdef CONFIG_SYS_INVERT_COLORS
- *cmap = 0xffff - colreg;
- #else
*cmap = colreg;
- #endif
#if defined(CONFIG_MPC823)
cmap--;
#else
cmap++;
#endif
#else /* CONFIG_ATMEL_LCD */
- lcd_setcolreg(i, cte.red, cte.green, cte.blue);
+ lcd_setcolreg(i, cte[i].red, cte[i].green, cte[i].blue);
#endif
}
}
- padded_width = (width & 0x3 ? (width & ~0x3) + 4 : width);
+ padded_width = ALIGN(width, 4);
#ifdef CONFIG_SPLASH_SCREEN_ALIGN
splash_align_axis(&x, pwidth, width);
splash_align_axis(&y, panel_info.vl_row, height);
#endif /* CONFIG_SPLASH_SCREEN_ALIGN */
+ bmap = (uchar *)bmp + get_unaligned_le32(&bmp->header.data_offset);
if ((x + width) > pwidth)
width = pwidth - x;
- if ((y + height) > panel_info.vl_row)
+ if ((y + height) > panel_info.vl_row) {
height = panel_info.vl_row - y;
+ bmap += (panel_info.vl_row - y) * padded_width;
+ }
- bmap = (uchar *)bmp + get_unaligned_le32(&bmp->header.data_offset);
fb = (uchar *)(lcd_base +
(y + height - 1) * lcd_line_length + x * bpix / 8);
}
#endif
- if (bpix != 16)
- byte_width = width;
- else
- byte_width = width * 2;
-
for (i = 0; i < height; ++i) {
WATCHDOG_RESET();
for (j = 0; j < width; j++) {
- if (bpix != 16) {
- FB_PUT_BYTE(fb, bmap);
- } else {
+ if (bpix == 32) {
+ int i = *bmap++;
+
+ fb[3] = 0; /* T */
+ fb[0] = cte[i].blue;
+ fb[1] = cte[i].green;
+ fb[2] = cte[i].red;
+ fb += sizeof(uint32_t) / sizeof(*fb);
+ } else if (bpix == 16) {
*(uint16_t *)fb = cmap_base[*(bmap++)];
fb += sizeof(uint16_t) / sizeof(*fb);
+ } else {
+ FB_PUT_BYTE(fb, bmap);
}
}
- bmap += (padded_width - width);
- fb -= byte_width + lcd_line_length;
+ if (bpix > 8) {
+ bmap += padded_width - width;
+ fb -= width * bpix / 8 + lcd_line_length;
+ } else {
+ bmap += padded_width;
+ fb -= lcd_line_length;
+ }
}
break;
}
fb -= lcd_line_length + width * (bpix / 8);
}
break;
-#endif /* CONFIG_BMP_24BMP */
+#endif /* CONFIG_BMP_24BPP */
#if defined(CONFIG_BMP_32BPP)
case 32:
for (i = 0; i < height; ++i) {
+ WATCHDOG_RESET();
for (j = 0; j < width; j++) {
- *(fb++) = *(bmap++);
- *(fb++) = *(bmap++);
- *(fb++) = *(bmap++);
- *(fb++) = *(bmap++);
+ fb[3] = *bmap++; /* T */
+ fb[0] = *bmap++; /* B */
+ fb[1] = *bmap++; /* G */
+ fb[2] = *bmap++; /* R */
+ fb += 4;
}
+ bmap += (padded_width - width) * 4;
fb -= lcd_line_length + width * (bpix / 8);
}
break;
#endif /* CONFIG_BMP_32BPP */
- default:
- break;
};
- lcd_sync();
return 0;
}
#endif
if (do_splash && (s = getenv("splashimage")) != NULL) {
int x = 0, y = 0;
+ char *end;
+
do_splash = 0;
if (splash_screen_prepare())
return (void *)lcd_base;
- addr = simple_strtoul (s, NULL, 16);
+ addr = simple_strtoul (s, &end, 16);
+ if (addr == 0 || *end != '\0')
+ return lcd_base;
splash_get_pos(&x, &y);
bitmap_plot(0, 0);
#ifdef CONFIG_LCD_INFO
- console_col = LCD_INFO_X / VIDEO_FONT_WIDTH;
- console_row = LCD_INFO_Y / VIDEO_FONT_HEIGHT;
+ lcd_set_col(LCD_INFO_X / VIDEO_FONT_WIDTH);
+ lcd_set_row(LCD_INFO_Y / VIDEO_FONT_HEIGHT);
lcd_show_board_info();
#endif /* CONFIG_LCD_INFO */
#if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO)
- return (void *)((ulong)lcd_base + BMP_LOGO_HEIGHT * lcd_line_length);
+ return lcd_base + BMP_LOGO_HEIGHT * lcd_line_length;
#else
- return (void *)lcd_base;
-#endif /* CONFIG_LCD_LOGO && !defined(CONFIG_LCD_INFO_BELOW_LOGO) */
+ return lcd_base;
+#endif /* CONFIG_LCD_LOGO && !CONFIG_LCD_INFO_BELOW_LOGO */
}
#ifdef CONFIG_SPLASHIMAGE_GUARD
U_BOOT_ENV_CALLBACK(splashimage, on_splashimage);
#endif
- void lcd_position_cursor(unsigned col, unsigned row)
- {
- console_col = min_t(short, col, CONSOLE_COLS - 1);
- console_row = min_t(short, row, CONSOLE_ROWS - 1);
- }
-
int lcd_get_pixel_width(void)
{
return panel_info.vl_col;
return panel_info.vl_row;
}
- int lcd_get_screen_rows(void)
- {
- return CONSOLE_ROWS;
- }
-
- int lcd_get_screen_columns(void)
- {
- return CONSOLE_COLS;
- }
-
#if defined(CONFIG_LCD_DT_SIMPLEFB)
static int lcd_dt_simplefb_configure_node(void *blob, int off)
{
#endif
#ifdef CONFIG_SPL_NAND_SUPPORT
case BOOT_DEVICE_NAND:
- spl_nand_load_image();
- break;
+ if (spl_nand_load_image() == 0)
+ break;
+ /* fallthru in case of failure to activate ymodem download */
#endif
#ifdef CONFIG_SPL_ONENAND_SUPPORT
case BOOT_DEVICE_ONENAND:
#endif
default:
#if defined(CONFIG_SPL_SERIAL_SUPPORT) && defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
- printf("SPL: Unsupported Boot Device %d\n", boot_device);
+ puts("SPL: Unsupported Boot Device!\n");
#endif
hang();
}
#include <common.h>
#include <dm.h>
#include <errno.h>
+ #include <fdtdec.h>
#include <malloc.h>
#include <asm/gpio.h>
#include <linux/ctype.h>
+ DECLARE_GLOBAL_DATA_PTR;
+
/**
* gpio_to_device() - Convert global GPIO number to device, number
- * gpio: The numeric representation of the GPIO
*
* Convert the GPIO number to an entry in the list of GPIOs
* or GPIO blocks registered with the GPIO controller. Returns
* entry on success, NULL on error.
+ *
+ * @gpio: The numeric representation of the GPIO
+ * @desc: Returns description (desc->flags will always be 0)
+ * @return 0 if found, -ENOENT if not found
*/
- static int gpio_to_device(unsigned int gpio, struct udevice **devp,
- unsigned int *offset)
+ static int gpio_to_device(unsigned int gpio, struct gpio_desc *desc)
{
struct gpio_dev_priv *uc_priv;
struct udevice *dev;
uc_priv = dev->uclass_priv;
if (gpio >= uc_priv->gpio_base &&
gpio < uc_priv->gpio_base + uc_priv->gpio_count) {
- *devp = dev;
- *offset = gpio - uc_priv->gpio_base;
+ desc->dev = dev;
+ desc->offset = gpio - uc_priv->gpio_base;
+ desc->flags = 0;
return 0;
}
}
/* No such GPIO */
- return ret ? ret : -EINVAL;
+ return ret ? ret : -ENOENT;
}
int gpio_lookup_name(const char *name, struct udevice **devp,
return 0;
}
+ static int gpio_find_and_xlate(struct gpio_desc *desc,
+ struct fdtdec_phandle_args *args)
+ {
+ struct dm_gpio_ops *ops = gpio_get_ops(desc->dev);
+
+ /* Use the first argument as the offset by default */
+ if (args->args_count > 0)
+ desc->offset = args->args[0];
+ else
+ desc->offset = -1;
+ desc->flags = 0;
+
+ return ops->xlate ? ops->xlate(desc->dev, desc, args) : 0;
+ }
+
+ static int dm_gpio_request(struct gpio_desc *desc, const char *label)
+ {
+ struct udevice *dev = desc->dev;
+ struct gpio_dev_priv *uc_priv;
+ char *str;
+ int ret;
+
+ uc_priv = dev->uclass_priv;
+ if (uc_priv->name[desc->offset])
+ return -EBUSY;
+ str = strdup(label);
+ if (!str)
+ return -ENOMEM;
+ if (gpio_get_ops(dev)->request) {
+ ret = gpio_get_ops(dev)->request(dev, desc->offset, label);
+ if (ret) {
+ free(str);
+ return ret;
+ }
+ }
+ uc_priv->name[desc->offset] = str;
+
+ return 0;
+ }
+
+ static int dm_gpio_requestf(struct gpio_desc *desc, const char *fmt, ...)
+ {
+ va_list args;
+ char buf[40];
+
+ va_start(args, fmt);
+ vscnprintf(buf, sizeof(buf), fmt, args);
+ va_end(args);
+ return dm_gpio_request(desc, buf);
+ }
+
/**
* gpio_request() - [COMPAT] Request GPIO
* gpio: GPIO number
*/
int gpio_request(unsigned gpio, const char *label)
{
- struct gpio_dev_priv *uc_priv;
- unsigned int offset;
- struct udevice *dev;
- char *str;
+ struct gpio_desc desc;
int ret;
- ret = gpio_to_device(gpio, &dev, &offset);
+ ret = gpio_to_device(gpio, &desc);
if (ret)
return ret;
- uc_priv = dev->uclass_priv;
- if (uc_priv->name[offset])
- return -EBUSY;
- str = strdup(label);
- if (!str)
- return -ENOMEM;
- if (gpio_get_ops(dev)->request) {
- ret = gpio_get_ops(dev)->request(dev, offset, label);
- if (ret) {
- free(str);
- return ret;
- }
- }
- uc_priv->name[offset] = str;
-
- return 0;
+ return dm_gpio_request(&desc, label);
}
/**
return gpio_request(gpio, buf);
}
- /**
- * gpio_free() - [COMPAT] Relinquish GPIO
- * gpio: GPIO number
- *
- * This function implements the API that's compatible with current
- * GPIO API used in U-Boot. The request is forwarded to particular
- * GPIO driver. Returns 0 on success, negative value on error.
- */
- int gpio_free(unsigned gpio)
+int gpio_request_one(unsigned int gpio, enum gpio_flags flags,
+ const char *label)
+{
+ int ret;
+
+ ret = gpio_request(gpio, label);
+ if (ret)
+ return ret;
+
+ if (flags == GPIOFLAG_INPUT)
+ gpio_direction_input(gpio);
+ else if (flags == GPIOFLAG_OUTPUT_INIT_LOW)
+ gpio_direction_output(gpio, 0);
+ else if (flags == GPIOFLAG_OUTPUT_INIT_HIGH)
+ gpio_direction_output(gpio, 1);
+
+ return ret;
+}
+
+int gpio_request_array(const struct gpio *gpios, int count)
+{
+ int ret;
+ int i;
+
+ for (i = 0; i < count; i++) {
+ ret = gpio_request_one(gpios[i].gpio, gpios[i].flags,
+ gpios[i].label);
+ if (ret) {
+ printf("Failed to request GPIO%d (%u of %u): %d\n",
+ gpios[i].gpio, i, count, ret);
+ goto error;
+ }
+ }
+ return 0;
+
+error:
+ while (--i >= 0)
+ gpio_free(gpios[i].gpio);
+
+ return ret;
+}
+
+ int _dm_gpio_free(struct udevice *dev, uint offset)
{
struct gpio_dev_priv *uc_priv;
- unsigned int offset;
- struct udevice *dev;
int ret;
- ret = gpio_to_device(gpio, &dev, &offset);
- if (ret)
- return ret;
-
uc_priv = dev->uclass_priv;
if (!uc_priv->name[offset])
return -ENXIO;
return 0;
}
- static int check_reserved(struct udevice *dev, unsigned offset,
- const char *func)
+int gpio_free_array(const struct gpio *gpios, int count)
+{
+ int ret = 0;
+ int i;
+
+ for (i = 0; i < count; i++)
+ ret |= gpio_free(gpios[i].gpio);
+
+ return ret;
+}
+
+ /**
+ * gpio_free() - [COMPAT] Relinquish GPIO
+ * gpio: GPIO number
+ *
+ * This function implements the API that's compatible with current
+ * GPIO API used in U-Boot. The request is forwarded to particular
+ * GPIO driver. Returns 0 on success, negative value on error.
+ */
+ int gpio_free(unsigned gpio)
+ {
+ struct gpio_desc desc;
+ int ret;
+
+ ret = gpio_to_device(gpio, &desc);
+ if (ret)
+ return ret;
+
+ return _dm_gpio_free(desc.dev, desc.offset);
+ }
+
+ static int check_reserved(struct gpio_desc *desc, const char *func)
{
- struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+ struct gpio_dev_priv *uc_priv = desc->dev->uclass_priv;
- if (!uc_priv->name[offset]) {
+ if (!uc_priv->name[desc->offset]) {
printf("%s: %s: error: gpio %s%d not reserved\n",
- dev->name, func,
- uc_priv->bank_name ? uc_priv->bank_name : "", offset);
+ desc->dev->name, func,
+ uc_priv->bank_name ? uc_priv->bank_name : "",
+ desc->offset);
return -EBUSY;
}
*/
int gpio_direction_input(unsigned gpio)
{
- unsigned int offset;
- struct udevice *dev;
+ struct gpio_desc desc;
int ret;
- ret = gpio_to_device(gpio, &dev, &offset);
+ ret = gpio_to_device(gpio, &desc);
+ if (ret)
+ return ret;
+ ret = check_reserved(&desc, "dir_input");
if (ret)
return ret;
- ret = check_reserved(dev, offset, "dir_input");
- return ret ? ret : gpio_get_ops(dev)->direction_input(dev, offset);
+ return gpio_get_ops(desc.dev)->direction_input(desc.dev, desc.offset);
}
/**
*/
int gpio_direction_output(unsigned gpio, int value)
{
- unsigned int offset;
- struct udevice *dev;
+ struct gpio_desc desc;
+ int ret;
+
+ ret = gpio_to_device(gpio, &desc);
+ if (ret)
+ return ret;
+ ret = check_reserved(&desc, "dir_output");
+ if (ret)
+ return ret;
+
+ return gpio_get_ops(desc.dev)->direction_output(desc.dev,
+ desc.offset, value);
+ }
+
+ int dm_gpio_get_value(struct gpio_desc *desc)
+ {
+ int value;
+ int ret;
+
+ ret = check_reserved(desc, "get_value");
+ if (ret)
+ return ret;
+
+ value = gpio_get_ops(desc->dev)->get_value(desc->dev, desc->offset);
+
+ return desc->flags & GPIOD_ACTIVE_LOW ? !value : value;
+ }
+
+ int dm_gpio_set_value(struct gpio_desc *desc, int value)
+ {
int ret;
- ret = gpio_to_device(gpio, &dev, &offset);
+ ret = check_reserved(desc, "set_value");
if (ret)
return ret;
- ret = check_reserved(dev, offset, "dir_output");
- return ret ? ret :
- gpio_get_ops(dev)->direction_output(dev, offset, value);
+ if (desc->flags & GPIOD_ACTIVE_LOW)
+ value = !value;
+ gpio_get_ops(desc->dev)->set_value(desc->dev, desc->offset, value);
+ return 0;
+ }
+
+ int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags)
+ {
+ struct udevice *dev = desc->dev;
+ struct dm_gpio_ops *ops = gpio_get_ops(dev);
+ int ret;
+
+ ret = check_reserved(desc, "set_dir");
+ if (ret)
+ return ret;
+
+ if (flags & GPIOD_IS_OUT) {
+ int value = flags & GPIOD_IS_OUT_ACTIVE ? 1 : 0;
+
+ if (flags & GPIOD_ACTIVE_LOW)
+ value = !value;
+ ret = ops->direction_output(dev, desc->offset, value);
+ } else if (flags & GPIOD_IS_IN) {
+ ret = ops->direction_input(dev, desc->offset);
+ }
+ if (ret)
+ return ret;
+ /*
+ * Update desc->flags here, so that GPIO_ACTIVE_LOW is honoured in
+ * futures
+ */
+ desc->flags = flags;
+
+ return 0;
+ }
+
+ int dm_gpio_set_dir(struct gpio_desc *desc)
+ {
+ return dm_gpio_set_dir_flags(desc, desc->flags);
}
/**
*/
int gpio_get_value(unsigned gpio)
{
- unsigned int offset;
- struct udevice *dev;
int ret;
- ret = gpio_to_device(gpio, &dev, &offset);
+ struct gpio_desc desc;
+
+ ret = gpio_to_device(gpio, &desc);
if (ret)
return ret;
- ret = check_reserved(dev, offset, "get_value");
-
- return ret ? ret : gpio_get_ops(dev)->get_value(dev, offset);
+ return dm_gpio_get_value(&desc);
}
/**
*/
int gpio_set_value(unsigned gpio, int value)
{
- unsigned int offset;
- struct udevice *dev;
+ struct gpio_desc desc;
int ret;
- ret = gpio_to_device(gpio, &dev, &offset);
+ ret = gpio_to_device(gpio, &desc);
if (ret)
return ret;
- ret = check_reserved(dev, offset, "set_value");
-
- return ret ? ret : gpio_get_ops(dev)->set_value(dev, offset, value);
+ return dm_gpio_set_value(&desc, value);
}
const char *gpio_get_bank_info(struct udevice *dev, int *bit_count)
return vector;
}
+ static int _gpio_request_by_name_nodev(const void *blob, int node,
+ const char *list_name, int index,
+ struct gpio_desc *desc, int flags,
+ bool add_index)
+ {
+ struct fdtdec_phandle_args args;
+ int ret;
+
+ desc->dev = NULL;
+ desc->offset = 0;
+ ret = fdtdec_parse_phandle_with_args(blob, node, list_name,
+ "#gpio-cells", 0, index, &args);
+ if (ret) {
+ debug("%s: fdtdec_parse_phandle_with_args failed\n", __func__);
+ goto err;
+ }
+
+ ret = uclass_get_device_by_of_offset(UCLASS_GPIO, args.node,
+ &desc->dev);
+ if (ret) {
+ debug("%s: uclass_get_device_by_of_offset failed\n", __func__);
+ goto err;
+ }
+ ret = gpio_find_and_xlate(desc, &args);
+ if (ret) {
+ debug("%s: gpio_find_and_xlate failed\n", __func__);
+ goto err;
+ }
+ ret = dm_gpio_requestf(desc, add_index ? "%s.%s%d" : "%s.%s",
+ fdt_get_name(blob, node, NULL),
+ list_name, index);
+ if (ret) {
+ debug("%s: dm_gpio_requestf failed\n", __func__);
+ goto err;
+ }
+ ret = dm_gpio_set_dir_flags(desc, flags | desc->flags);
+ if (ret) {
+ debug("%s: dm_gpio_set_dir failed\n", __func__);
+ goto err;
+ }
+
+ return 0;
+ err:
+ debug("%s: Node '%s', property '%s', failed to request GPIO index %d: %d\n",
+ __func__, fdt_get_name(blob, node, NULL), list_name, index, ret);
+ return ret;
+ }
+
+ int gpio_request_by_name_nodev(const void *blob, int node,
+ const char *list_name, int index,
+ struct gpio_desc *desc, int flags)
+ {
+ return _gpio_request_by_name_nodev(blob, node, list_name, index, desc,
+ flags, index > 0);
+ }
+
+ int gpio_request_by_name(struct udevice *dev, const char *list_name, int index,
+ struct gpio_desc *desc, int flags)
+ {
+ /*
+ * This isn't ideal since we don't use dev->name in the debug()
+ * calls in gpio_request_by_name(), but we can do this until
+ * gpio_request_by_name_nodev() can be dropped.
+ */
+ return gpio_request_by_name_nodev(gd->fdt_blob, dev->of_offset,
+ list_name, index, desc, flags);
+ }
+
+ int gpio_request_list_by_name_nodev(const void *blob, int node,
+ const char *list_name,
+ struct gpio_desc *desc, int max_count,
+ int flags)
+ {
+ int count;
+ int ret;
+
+ for (count = 0; ; count++) {
+ if (count >= max_count) {
+ ret = -ENOSPC;
+ goto err;
+ }
+ ret = _gpio_request_by_name_nodev(blob, node, list_name, count,
+ &desc[count], flags, true);
+ if (ret == -ENOENT)
+ break;
+ else if (ret)
+ goto err;
+ }
+
+ /* We ran out of GPIOs in the list */
+ return count;
+
+ err:
+ gpio_free_list_nodev(desc, count - 1);
+
+ return ret;
+ }
+
+ int gpio_request_list_by_name(struct udevice *dev, const char *list_name,
+ struct gpio_desc *desc, int max_count,
+ int flags)
+ {
+ /*
+ * This isn't ideal since we don't use dev->name in the debug()
+ * calls in gpio_request_by_name(), but we can do this until
+ * gpio_request_list_by_name_nodev() can be dropped.
+ */
+ return gpio_request_list_by_name_nodev(gd->fdt_blob, dev->of_offset,
+ list_name, desc, max_count,
+ flags);
+ }
+
+ int gpio_get_list_count(struct udevice *dev, const char *list_name)
+ {
+ int ret;
+
+ ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev->of_offset,
+ list_name, "#gpio-cells", 0, -1,
+ NULL);
+ if (ret) {
+ debug("%s: Node '%s', property '%s', GPIO count failed: %d\n",
+ __func__, dev->name, list_name, ret);
+ }
+
+ return ret;
+ }
+
+ int dm_gpio_free(struct udevice *dev, struct gpio_desc *desc)
+ {
+ /* For now, we don't do any checking of dev */
+ return _dm_gpio_free(desc->dev, desc->offset);
+ }
+
+ int gpio_free_list(struct udevice *dev, struct gpio_desc *desc, int count)
+ {
+ int i;
+
+ /* For now, we don't do any checking of dev */
+ for (i = 0; i < count; i++)
+ dm_gpio_free(dev, &desc[i]);
+
+ return 0;
+ }
+
+ int gpio_free_list_nodev(struct gpio_desc *desc, int count)
+ {
+ return gpio_free_list(NULL, desc, count);
+ }
+
/* We need to renumber the GPIOs when any driver is probed/removed */
static int gpio_renumber(struct udevice *removed_dev)
{
+ config DM_I2C
+ bool "Enable Driver Model for I2C drivers"
+ depends on DM
+ help
+ If you want to use driver model for I2C drivers, say Y.
+ To use legacy I2C drivers, say N.
+
+ config SYS_I2C_UNIPHIER
+ bool "UniPhier I2C driver"
+ depends on ARCH_UNIPHIER && DM_I2C
+ default y
+ help
+ Support for Panasonic UniPhier I2C controller driver. This I2C
+ controller is used on PH1-LD4, PH1-sLD8 or older UniPhier SoCs.
+
+ config SYS_I2C_UNIPHIER_F
+ bool "UniPhier FIFO-builtin I2C driver"
+ depends on ARCH_UNIPHIER && DM_I2C
+ default y
+ help
+ Support for Panasonic UniPhier FIFO-builtin I2C controller driver.
+ This I2C controller is used on PH1-Pro4 or newer UniPhier SoCs.
+menuconfig SYS_I2C
+ bool "I2C device support"
+
+if SYS_I2C
+
+config HARD_I2C
+ bool
+
+config SYS_I2C_MXC
+ bool "Freescale i.MX I2C controller"
+ select HARD_I2C
+ select I2C_QUIRK_REG if FSL_LSCH3 || LS102XA
+
+endif
- menuconfig MMC
- bool "MMC/SD device support"
- select CMD_MMC
+ menu "MMC Host controller Support"
- if MMC
++config MMC
++ bool
+
+config GENERIC_MMC
+ bool
++ select MMC
++
+ config SH_SDHI
+ bool "SuperH/Renesas ARM SoCs on-chip SDHI host controller support"
+ depends on RMOBILE
+ help
+ Support for the on-chip SDHI host controller on SuperH/Renesas ARM SoCs platform
- endif
+config FSL_ESDHC
+ bool "Freescale ESDHC controller"
+ select GENERIC_MMC
+
+config FSL_USDHC
+ bool "Support USDHC"
+ depends on MX6Q
+ depends on FSL_ESDHC
+
+config SUPPORT_EMMC_BOOT
+ bool "Support boot from eMMC"
+ depends on MMC
+
+ endmenu
udelay(1000);
} while ((!(cmd.response[0] & OCR_BUSY)) && timeout--);
-
- if (timeout <= 0)
+ if (!(cmd.response[0] & OCR_BUSY))
return UNUSABLE_ERR;
if (mmc->version != SD_VERSION_2)
/* Some cards seem to need this */
mmc_go_idle(mmc);
- /* Asking to the card its capabilities */
+ /* Asking to the card its capabilities */
mmc->op_cond_pending = 1;
for (i = 0; i < 2; i++) {
err = mmc_send_op_cond_iter(mmc, &cmd, i != 0);
if (err)
return err;
if (get_timer(start) > timeout)
- return UNUSABLE_ERR;
+ break;
udelay(100);
} while (!(mmc->op_cond_response & OCR_BUSY));
+ if (!(mmc->op_cond_response & OCR_BUSY)) {
+ debug("%s: timeout\n", __func__);
+ return UNUSABLE_ERR;
+ }
if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
char cardtype;
int err;
- mmc->card_caps = MMC_MODE_4BIT | MMC_MODE_8BIT;
+ mmc->card_caps = 0;
if (mmc_host_is_spi(mmc))
return 0;
if (mmc->version < MMC_VERSION_4)
return 0;
+ mmc->card_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
+
err = mmc_send_ext_csd(mmc, ext_csd);
if (err)
return ret;
}
+ int mmc_hwpart_config(struct mmc *mmc,
+ const struct mmc_hwpart_conf *conf,
+ enum mmc_hwpart_conf_mode mode)
+ {
+ u8 part_attrs = 0;
+ u32 enh_size_mult;
+ u32 enh_start_addr;
+ u32 gp_size_mult[4];
+ u32 max_enh_size_mult;
+ u32 tot_enh_size_mult = 0;
+ u8 wr_rel_set;
+ int i, pidx, err;
+ ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
+
+ if (mode < MMC_HWPART_CONF_CHECK || mode > MMC_HWPART_CONF_COMPLETE)
+ return -EINVAL;
+
+ if (IS_SD(mmc) || (mmc->version < MMC_VERSION_4_41)) {
+ printf("eMMC >= 4.4 required for enhanced user data area\n");
+ return -EMEDIUMTYPE;
+ }
+
+ if (!(mmc->part_support & PART_SUPPORT)) {
+ printf("Card does not support partitioning\n");
+ return -EMEDIUMTYPE;
+ }
+
+ if (!mmc->hc_wp_grp_size) {
+ printf("Card does not define HC WP group size\n");
+ return -EMEDIUMTYPE;
+ }
+
+ /* check partition alignment and total enhanced size */
+ if (conf->user.enh_size) {
+ if (conf->user.enh_size % mmc->hc_wp_grp_size ||
+ conf->user.enh_start % mmc->hc_wp_grp_size) {
+ printf("User data enhanced area not HC WP group "
+ "size aligned\n");
+ return -EINVAL;
+ }
+ part_attrs |= EXT_CSD_ENH_USR;
+ enh_size_mult = conf->user.enh_size / mmc->hc_wp_grp_size;
+ if (mmc->high_capacity) {
+ enh_start_addr = conf->user.enh_start;
+ } else {
+ enh_start_addr = (conf->user.enh_start << 9);
+ }
+ } else {
+ enh_size_mult = 0;
+ enh_start_addr = 0;
+ }
+ tot_enh_size_mult += enh_size_mult;
+
+ for (pidx = 0; pidx < 4; pidx++) {
+ if (conf->gp_part[pidx].size % mmc->hc_wp_grp_size) {
+ printf("GP%i partition not HC WP group size "
+ "aligned\n", pidx+1);
+ return -EINVAL;
+ }
+ gp_size_mult[pidx] = conf->gp_part[pidx].size / mmc->hc_wp_grp_size;
+ if (conf->gp_part[pidx].size && conf->gp_part[pidx].enhanced) {
+ part_attrs |= EXT_CSD_ENH_GP(pidx);
+ tot_enh_size_mult += gp_size_mult[pidx];
+ }
+ }
+
+ if (part_attrs && ! (mmc->part_support & ENHNCD_SUPPORT)) {
+ printf("Card does not support enhanced attribute\n");
+ return -EMEDIUMTYPE;
+ }
+
+ err = mmc_send_ext_csd(mmc, ext_csd);
+ if (err)
+ return err;
+
+ max_enh_size_mult =
+ (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT+2] << 16) +
+ (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT+1] << 8) +
+ ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT];
+ if (tot_enh_size_mult > max_enh_size_mult) {
+ printf("Total enhanced size exceeds maximum (%u > %u)\n",
+ tot_enh_size_mult, max_enh_size_mult);
+ return -EMEDIUMTYPE;
+ }
+
+ /* The default value of EXT_CSD_WR_REL_SET is device
+ * dependent, the values can only be changed if the
+ * EXT_CSD_HS_CTRL_REL bit is set. The values can be
+ * changed only once and before partitioning is completed. */
+ wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
+ if (conf->user.wr_rel_change) {
+ if (conf->user.wr_rel_set)
+ wr_rel_set |= EXT_CSD_WR_DATA_REL_USR;
+ else
+ wr_rel_set &= ~EXT_CSD_WR_DATA_REL_USR;
+ }
+ for (pidx = 0; pidx < 4; pidx++) {
+ if (conf->gp_part[pidx].wr_rel_change) {
+ if (conf->gp_part[pidx].wr_rel_set)
+ wr_rel_set |= EXT_CSD_WR_DATA_REL_GP(pidx);
+ else
+ wr_rel_set &= ~EXT_CSD_WR_DATA_REL_GP(pidx);
+ }
+ }
+
+ if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET] &&
+ !(ext_csd[EXT_CSD_WR_REL_PARAM] & EXT_CSD_HS_CTRL_REL)) {
+ puts("Card does not support host controlled partition write "
+ "reliability settings\n");
+ return -EMEDIUMTYPE;
+ }
+
+ if (ext_csd[EXT_CSD_PARTITION_SETTING] &
+ EXT_CSD_PARTITION_SETTING_COMPLETED) {
+ printf("Card already partitioned\n");
+ return -EPERM;
+ }
+
+ if (mode == MMC_HWPART_CONF_CHECK)
+ return 0;
+
+ /* Partitioning requires high-capacity size definitions */
+ if (!(ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01)) {
+ err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
+ EXT_CSD_ERASE_GROUP_DEF, 1);
+
+ if (err)
+ return err;
+
+ ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
+
+ /* update erase group size to be high-capacity */
+ mmc->erase_grp_size =
+ ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
+
+ }
+
+ /* all OK, write the configuration */
+ for (i = 0; i < 4; i++) {
+ err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
+ EXT_CSD_ENH_START_ADDR+i,
+ (enh_start_addr >> (i*8)) & 0xFF);
+ if (err)
+ return err;
+ }
+ for (i = 0; i < 3; i++) {
+ err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
+ EXT_CSD_ENH_SIZE_MULT+i,
+ (enh_size_mult >> (i*8)) & 0xFF);
+ if (err)
+ return err;
+ }
+ for (pidx = 0; pidx < 4; pidx++) {
+ for (i = 0; i < 3; i++) {
+ err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
+ EXT_CSD_GP_SIZE_MULT+pidx*3+i,
+ (gp_size_mult[pidx] >> (i*8)) & 0xFF);
+ if (err)
+ return err;
+ }
+ }
+ err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
+ EXT_CSD_PARTITIONS_ATTRIBUTE, part_attrs);
+ if (err)
+ return err;
+
+ if (mode == MMC_HWPART_CONF_SET)
+ return 0;
+
+ /* The WR_REL_SET is a write-once register but shall be
+ * written before setting PART_SETTING_COMPLETED. As it is
+ * write-once we can only write it when completing the
+ * partitioning. */
+ if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET]) {
+ err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
+ EXT_CSD_WR_REL_SET, wr_rel_set);
+ if (err)
+ return err;
+ }
+
+ /* Setting PART_SETTING_COMPLETED confirms the partition
+ * configuration but it only becomes effective after power
+ * cycle, so we do not adjust the partition related settings
+ * in the mmc struct. */
+
+ err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
+ EXT_CSD_PARTITION_SETTING,
+ EXT_CSD_PARTITION_SETTING_COMPLETED);
+ if (err)
+ return err;
+
+ return 0;
+ }
+
int mmc_getcd(struct mmc *mmc)
{
int cd;
ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
int timeout = 1000;
+ bool has_parts = false;
+ bool part_completed;
#ifdef CONFIG_MMC_SPI_CRC_ON
if (mmc_host_is_spi(mmc)) { /* enable CRC check for spi */
if (!IS_SD(mmc) && (mmc->version >= MMC_VERSION_4)) {
/* check ext_csd version and capacity */
err = mmc_send_ext_csd(mmc, ext_csd);
- if (!err && (ext_csd[EXT_CSD_REV] >= 2)) {
+ if (err)
+ return err;
+ if (ext_csd[EXT_CSD_REV] >= 2) {
/*
* According to the JEDEC Standard, the value of
* ext_csd's capacity is valid if the value is more
break;
}
+ /* The partition data may be non-zero but it is only
+ * effective if PARTITION_SETTING_COMPLETED is set in
+ * EXT_CSD, so ignore any data if this bit is not set,
+ * except for enabling the high-capacity group size
+ * definition (see below). */
+ part_completed = !!(ext_csd[EXT_CSD_PARTITION_SETTING] &
+ EXT_CSD_PARTITION_SETTING_COMPLETED);
+
+ /* store the partition info of emmc */
+ mmc->part_support = ext_csd[EXT_CSD_PARTITIONING_SUPPORT];
+ if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) ||
+ ext_csd[EXT_CSD_BOOT_MULT])
+ mmc->part_config = ext_csd[EXT_CSD_PART_CONF];
+ if (part_completed &&
+ (ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & ENHNCD_SUPPORT))
+ mmc->part_attr = ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE];
+
+ mmc->capacity_boot = ext_csd[EXT_CSD_BOOT_MULT] << 17;
+
+ mmc->capacity_rpmb = ext_csd[EXT_CSD_RPMB_MULT] << 17;
+
+ for (i = 0; i < 4; i++) {
+ int idx = EXT_CSD_GP_SIZE_MULT + i * 3;
+ uint mult = (ext_csd[idx + 2] << 16) +
+ (ext_csd[idx + 1] << 8) + ext_csd[idx];
+ if (mult)
+ has_parts = true;
+ if (!part_completed)
+ continue;
+ mmc->capacity_gp[i] = mult;
+ mmc->capacity_gp[i] *=
+ ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
+ mmc->capacity_gp[i] *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
+ mmc->capacity_gp[i] <<= 19;
+ }
+
+ if (part_completed) {
+ mmc->enh_user_size =
+ (ext_csd[EXT_CSD_ENH_SIZE_MULT+2] << 16) +
+ (ext_csd[EXT_CSD_ENH_SIZE_MULT+1] << 8) +
+ ext_csd[EXT_CSD_ENH_SIZE_MULT];
+ mmc->enh_user_size *= ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
+ mmc->enh_user_size *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
+ mmc->enh_user_size <<= 19;
+ mmc->enh_user_start =
+ (ext_csd[EXT_CSD_ENH_START_ADDR+3] << 24) +
+ (ext_csd[EXT_CSD_ENH_START_ADDR+2] << 16) +
+ (ext_csd[EXT_CSD_ENH_START_ADDR+1] << 8) +
+ ext_csd[EXT_CSD_ENH_START_ADDR];
+ if (mmc->high_capacity)
+ mmc->enh_user_start <<= 9;
+ }
+
/*
* Host needs to enable ERASE_GRP_DEF bit if device is
* partitioned. This bit will be lost every time after a reset
* or power off. This will affect erase size.
*/
+ if (part_completed)
+ has_parts = true;
if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) &&
- (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & PART_ENH_ATTRIB)) {
+ (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & PART_ENH_ATTRIB))
+ has_parts = true;
+ if (has_parts) {
err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
EXT_CSD_ERASE_GROUP_DEF, 1);
return err;
else
ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
+ }
+ if (ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01) {
/* Read out group size from ext_csd */
mmc->erase_grp_size =
- ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] *
- MMC_MAX_BLOCK_LEN * 1024;
+ ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
/*
* if high capacity and partition setting completed
* SEC_COUNT is valid even if it is smaller than 2 GiB
* JEDEC Standard JESD84-B45, 6.2.4
*/
- if (mmc->high_capacity &&
- (ext_csd[EXT_CSD_PARTITION_SETTING] &
- EXT_CSD_PARTITION_SETTING_COMPLETED)) {
+ if (mmc->high_capacity && part_completed) {
capacity = (ext_csd[EXT_CSD_SEC_CNT]) |
(ext_csd[EXT_CSD_SEC_CNT + 1] << 8) |
(ext_csd[EXT_CSD_SEC_CNT + 2] << 16) |
* (erase_gmul + 1);
}
- /* store the partition info of emmc */
- if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) ||
- ext_csd[EXT_CSD_BOOT_MULT])
- mmc->part_config = ext_csd[EXT_CSD_PART_CONF];
-
- mmc->capacity_boot = ext_csd[EXT_CSD_BOOT_MULT] << 17;
-
- mmc->capacity_rpmb = ext_csd[EXT_CSD_RPMB_MULT] << 17;
+ mmc->hc_wp_grp_size = 1024
+ * ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
+ * ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
- for (i = 0; i < 4; i++) {
- int idx = EXT_CSD_GP_SIZE_MULT + i * 3;
- mmc->capacity_gp[i] = (ext_csd[idx + 2] << 16) +
- (ext_csd[idx + 1] << 8) + ext_csd[idx];
- mmc->capacity_gp[i] *=
- ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
- mmc->capacity_gp[i] *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
- }
+ mmc->wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
}
err = mmc_set_capacity(mmc, mmc->part_num);
mmc->tran_speed = 50000000;
else
mmc->tran_speed = 25000000;
- } else {
+ } else if (mmc->version >= MMC_VERSION_4) {
+ /* Only version 4 of MMC supports wider bus widths */
int idx;
/* An array of possible bus widths in order of preference */
unsigned int extw = ext_csd_bits[idx];
unsigned int caps = ext_to_hostcaps[extw];
+ /*
+ * If the bus width is still not changed,
+ * don't try to set the default again.
+ * Otherwise, recover from switch attempts
+ * by switching to 1-bit bus width.
+ */
+ if (extw == EXT_CSD_BUS_WIDTH_1 &&
+ mmc->bus_width == 1) {
+ err = 0;
+ break;
+ }
+
/*
* Check to make sure the card and controller support
* these capabilities
}
#endif
-static unsigned char mmc_board_init(struct mmc *mmc)
+static void mmc_board_init(struct mmc *mmc)
{
#if defined(CONFIG_OMAP34XX)
t2_t *t2_base = (t2_t *)T2_BASE;
pbias_lite = readl(&t2_base->pbias_lite);
pbias_lite &= ~(PBIASLITEPWRDNZ1 | PBIASLITEPWRDNZ0);
+ #ifdef CONFIG_TARGET_OMAP3_CAIRO
+ /* for cairo board, we need to set up 1.8 Volt bias level on MMC1 */
+ pbias_lite &= ~PBIASLITEVMODE0;
+ #endif
writel(pbias_lite, &t2_base->pbias_lite);
writel(pbias_lite | PBIASLITEPWRDNZ1 |
if (mmc->block_dev.dev == 0)
omap5_pbias_config(mmc);
#endif
-
- return 0;
}
void mmc_init_stream(struct hsmmc *mmc_base)
writel(MMC_CMD0, &mmc_base->cmd);
start = get_timer(0);
while (!(readl(&mmc_base->stat) & CC_MASK)) {
- if (get_timer(0) - start > MAX_RETRY_MS) {
- printf("%s: timedout waiting for cc!\n", __func__);
- return;
- }
+ if (get_timer(start) > MAX_RETRY_MS)
+ break;
+ }
+ if (!(readl(&mmc_base->stat) & CC_MASK)) {
+ printf("%s: timeout waiting for cc!\n", __func__);
+ return;
}
- writel(CC_MASK, &mmc_base->stat)
- ;
- writel(MMC_CMD0, &mmc_base->cmd)
- ;
+
+ writel(CC_MASK, &mmc_base->stat);
+ writel(MMC_CMD0, &mmc_base->cmd);
+
start = get_timer(0);
while (!(readl(&mmc_base->stat) & CC_MASK)) {
- if (get_timer(0) - start > MAX_RETRY_MS) {
- printf("%s: timedout waiting for cc2!\n", __func__);
- return;
- }
+ if (get_timer(start) > MAX_RETRY_MS)
+ break;
+ }
+ if (!(readl(&mmc_base->stat) & CC_MASK)) {
+ printf("%s: timeout waiting for cc2!\n", __func__);
+ return;
}
writel(readl(&mmc_base->con) & ~INIT_INITSTREAM, &mmc_base->con);
}
static int omap_hsmmc_init_setup(struct mmc *mmc)
{
- struct hsmmc *mmc_base;
+ struct omap_hsmmc_data *priv_data = mmc->priv;
+ struct hsmmc *mmc_base = priv_data->base_addr;
unsigned int reg_val;
unsigned int dsor;
ulong start;
- mmc_base = ((struct omap_hsmmc_data *)mmc->priv)->base_addr;
mmc_board_init(mmc);
writel(readl(&mmc_base->sysconfig) | MMC_SOFTRESET,
&mmc_base->sysconfig);
start = get_timer(0);
while ((readl(&mmc_base->sysstatus) & RESETDONE) == 0) {
- if (get_timer(0) - start > MAX_RETRY_MS) {
- printf("%s: timedout waiting for cc2!\n", __func__);
- return TIMEOUT;
- }
+ if (get_timer(start) > MAX_RETRY_MS)
+ break;
+ }
+ if ((readl(&mmc_base->sysstatus) & RESETDONE) == 0) {
+ printf("%s: timeout %08x waiting for softreset done!\n", __func__,
+ readl(&mmc_base->sysstatus));
+ return TIMEOUT;
}
writel(readl(&mmc_base->sysctl) | SOFTRESETALL, &mmc_base->sysctl);
start = get_timer(0);
- while ((readl(&mmc_base->sysctl) & SOFTRESETALL) != 0x0) {
- if (get_timer(0) - start > MAX_RETRY_MS) {
- printf("%s: timedout waiting for softresetall!\n",
- __func__);
- return TIMEOUT;
- }
+ while ((readl(&mmc_base->sysctl) & SOFTRESETALL) != 0) {
+ if (get_timer(start) > MAX_RETRY_MS)
+ break;
+ }
+ if ((readl(&mmc_base->sysctl) & SOFTRESETALL) != 0) {
+ printf("%s: timeout waiting for softresetall!\n", __func__);
+ return TIMEOUT;
}
writel(DTW_1_BITMODE | SDBP_PWROFF | SDVS_3V0, &mmc_base->hctl);
writel(readl(&mmc_base->capa) | VS30_3V0SUP | VS18_1V8SUP,
(dsor << CLKD_OFFSET) | ICE_OSCILLATE);
start = get_timer(0);
while ((readl(&mmc_base->sysctl) & ICS_MASK) == ICS_NOTREADY) {
- if (get_timer(0) - start > MAX_RETRY_MS) {
- printf("%s: timedout waiting for ics!\n", __func__);
- return TIMEOUT;
- }
+ if (get_timer(start) > MAX_RETRY_MS)
+ break;
+ }
+ if ((readl(&mmc_base->sysctl) & ICS_MASK) == ICS_NOTREADY) {
+ printf("%s: timeout waiting for ics!\n", __func__);
+ return TIMEOUT;
}
writel(readl(&mmc_base->sysctl) | CEN_ENABLE, &mmc_base->sysctl);
#endif
start = get_timer(0);
while ((readl(&mmc_base->sysctl) & bit) != 0) {
- if (get_timer(0) - start > MAX_RETRY_MS) {
- printf("%s: timedout waiting for sysctl %x to clear\n",
- __func__, bit);
- return;
- }
+ if (get_timer(0) - start > MAX_RETRY_MS)
+ break;
+ }
+ if ((readl(&mmc_base->sysctl) & bit) != 0) {
+ printf("%s: timedout waiting for sysctl %x to clear\n", __func__, bit);
+ return;
}
}
static int omap_hsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
struct mmc_data *data)
{
- struct hsmmc *mmc_base;
+ struct omap_hsmmc_data *priv_data = mmc->priv;
+ struct hsmmc *mmc_base = priv_data->base_addr;
unsigned int flags, mmc_stat;
ulong start;
- mmc_base = ((struct omap_hsmmc_data *)mmc->priv)->base_addr;
start = get_timer(0);
while ((readl(&mmc_base->pstate) & (DATI_MASK | CMDI_MASK)) != 0) {
- if (get_timer(0) - start > MAX_RETRY_MS) {
- printf("%s: timedout waiting on cmd inhibit to clear\n",
- __func__);
- return TIMEOUT;
- }
+ if (get_timer(start) > MAX_RETRY_MS)
+ break;
+ }
+ if ((readl(&mmc_base->pstate) & (DATI_MASK | CMDI_MASK)) != 0) {
+ printf("%s: timeout waiting on cmd inhibit to clear\n", __func__);
+ return TIMEOUT;
}
writel(0xFFFFFFFF, &mmc_base->stat);
start = get_timer(0);
while (readl(&mmc_base->stat)) {
- if (get_timer(0) - start > MAX_RETRY_MS) {
- printf("%s: timedout waiting for STAT (%x) to clear\n",
- __func__, readl(&mmc_base->stat));
- return TIMEOUT;
- }
+ if (get_timer(start) > MAX_RETRY_MS)
+ break;
+ }
+ if (readl(&mmc_base->stat)) {
+ printf("%s: timeout waiting for stat!\n", __func__);
+ return TIMEOUT;
}
/*
* CMDREG
writel((cmd->cmdidx << 24) | flags, &mmc_base->cmd);
start = get_timer(0);
- do {
- mmc_stat = readl(&mmc_base->stat);
- if (get_timer(0) - start > MAX_RETRY_MS) {
- printf("%s : timeout: No status update\n", __func__);
- return TIMEOUT;
- }
- } while (!mmc_stat);
+ while (!(mmc_stat = readl(&mmc_base->stat))) {
+ if (get_timer(start) > MAX_RETRY_MS)
+ break;
+ }
+ if (!mmc_stat) {
+ printf("%s : timeout: No status update\n", __func__);
+ return TIMEOUT;
+ }
if ((mmc_stat & IE_CTO) != 0) {
mmc_reset_controller_fsm(mmc_base, SYSCTL_SRC);
while (size) {
ulong start = get_timer(0);
- do {
- mmc_stat = readl(&mmc_base->stat);
- if (get_timer(0) - start > MAX_RETRY_MS) {
- printf("%s: timedout waiting for status!\n",
- __func__);
- return TIMEOUT;
- }
- } while (mmc_stat == 0);
+
+ while (!(mmc_stat = readl(&mmc_base->stat))) {
+ if (get_timer(start) > MAX_RETRY_MS)
+ break;
+ }
+ if (!mmc_stat) {
+ printf("%s: timeout waiting for status!\n", __func__);
+ return TIMEOUT;
+ }
if ((mmc_stat & (IE_DTO | IE_DCRC | IE_DEB)) != 0)
mmc_reset_controller_fsm(mmc_base, SYSCTL_SRD);
while (size) {
ulong start = get_timer(0);
- do {
- mmc_stat = readl(&mmc_base->stat);
- if (get_timer(0) - start > MAX_RETRY_MS) {
- printf("%s: timedout waiting for status!\n",
- __func__);
- return TIMEOUT;
- }
- } while (mmc_stat == 0);
+
+ while (!(mmc_stat = readl(&mmc_base->stat))) {
+ if (get_timer(start) > MAX_RETRY_MS)
+ break;
+ }
+ if (!mmc_stat) {
+ printf("%s: timeout waiting for status!\n", __func__);
+ return TIMEOUT;
+ }
if ((mmc_stat & (IE_DTO | IE_DCRC | IE_DEB)) != 0)
mmc_reset_controller_fsm(mmc_base, SYSCTL_SRD);
static void omap_hsmmc_set_ios(struct mmc *mmc)
{
- struct hsmmc *mmc_base;
+ struct omap_hsmmc_data *priv_data = mmc->priv;
+ struct hsmmc *mmc_base = priv_data->base_addr;
unsigned int dsor = 0;
ulong start;
- mmc_base = ((struct omap_hsmmc_data *)mmc->priv)->base_addr;
/* configue bus width */
switch (mmc->bus_width) {
case 8:
start = get_timer(0);
while ((readl(&mmc_base->sysctl) & ICS_MASK) == ICS_NOTREADY) {
- if (get_timer(0) - start > MAX_RETRY_MS) {
- printf("%s: timedout waiting for ics!\n", __func__);
- return;
- }
+ if (get_timer(start) > MAX_RETRY_MS)
+ break;
+ }
+ if ((readl(&mmc_base->sysctl) & ICS_MASK) == ICS_NOTREADY) {
+ printf("%s: timeout waiting for ics!\n", __func__);
+ return;
}
writel(readl(&mmc_base->sysctl) | CEN_ENABLE, &mmc_base->sysctl);
}
int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio,
int wp_gpio)
{
+ int ret;
struct mmc *mmc;
struct omap_hsmmc_data *priv_data;
struct mmc_config *cfg;
uint host_caps_val;
- priv_data = malloc(sizeof(*priv_data));
+ priv_data = calloc(sizeof(*priv_data), 1);
if (priv_data == NULL)
- return -1;
+ return -ENOMEM;
host_caps_val = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS |
MMC_MODE_HC;
switch (dev_index) {
case 0:
- priv_data->base_addr = (struct hsmmc *)OMAP_HSMMC1_BASE;
+ base_addr = OMAP_HSMMC1_BASE;
break;
#ifdef OMAP_HSMMC2_BASE
case 1:
break;
#endif
default:
- priv_data->base_addr = (struct hsmmc *)OMAP_HSMMC1_BASE;
- return 1;
+ printf("Invalid MMC device index: %d\n", dev_index);
+ ret = 1;
+ goto out;
}
#ifdef OMAP_HSMMC_USE_GPIO
/* on error gpio values are set to -1, which is what we want */
cfg->b_max = 1;
#endif
mmc = mmc_create(cfg, priv_data);
- if (mmc == NULL)
- return -1;
+ if (mmc == NULL) {
+ ret = -ENOMEM;
+ goto out;
+ }
return 0;
+
+out:
+ free(priv_data);
+ return ret;
}
}
}
#endif
- #ifdef PPCHAMELON_NAND_TIMER_HACK
- time_start = get_timer(0);
- while (get_timer(time_start) < 10)
- ;
- #endif /* PPCHAMELON_NAND_TIMER_HACK */
led_trigger_event(nand_led_trigger, LED_OFF);
status = (int)chip->read_byte(mtd);
return NULL;
}
-#define NOTALIGNED(x) ((x & (chip->subpagesize - 1)) != 0)
+#define NOTALIGNED(x) (((x) & (chip->subpagesize - 1)) != 0)
/**
* nand_do_write_ops - [INTERN] NAND write with ECC
ecc->steps = mtd->writesize / ecc->size;
if (ecc->steps * ecc->size != mtd->writesize) {
pr_warn("Invalid ECC parameters\n");
+ pr_warn("steps=%d size=%d writesize=%d\n",
+ chip->ecc.steps, chip->ecc.size, mtd->writesize);
BUG();
}
ecc->total = ecc->steps * ecc->bytes;
/* We are wasting a bit of memory but al least we are safe */
static struct omap_nand_info omap_nand_info[GPMC_MAX_CS];
+static struct gpmc __iomem *gpmc_cfg = (void __iomem *)GPMC_BASE;
+
+#ifdef CONFIG_SYS_NAND_USE_FLASH_BBT
+static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' };
+static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' };
+
+static struct nand_bbt_descr bbt_main_descr = {
+ .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE |
+ NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
+ .offs = 0, /* may be overwritten depending on ECC layout */
+ .len = 4,
+ .veroffs = 4, /* may be overwritten depending on ECC layout */
+ .maxblocks = 4,
+ .pattern = bbt_pattern,
+};
+
+static struct nand_bbt_descr bbt_mirror_descr = {
+ .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE |
+ NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
+ .offs = 0, /* may be overwritten depending on ECC layout */
+ .len = 4,
+ .veroffs = 4, /* may be overwritten depending on ECC layout */
+ .maxblocks = 4,
+ .pattern = mirror_pattern,
+};
+#endif
+
+#define PREFETCH_FIFOTHRESHOLD_MAX 0x40
+#define PREFETCH_FIFOTHRESHOLD(val) ((val) << 8)
+
+#define PREFETCH_ENABLEOPTIMIZEDACCESS (0x1 << 27)
+
+#define GPMC_PREFETCH_STATUS_FIFO_CNT(val) (((val) >> 24) & 0x7F)
+#define GPMC_PREFETCH_STATUS_COUNT(val) ((val) & 0x00003fff)
+
+#define CS_NUM_SHIFT 24
+#define ENABLE_PREFETCH (0x1 << 7)
+#define DMA_MPU_MODE 2
+
+#define OMAP_NAND_TIMEOUT_MS 5000
+
+#define PRINT_REG(x) debug("+++ %.15s (0x%08x)=0x%08x\n", #x, &gpmc_cfg->x, readl(&gpmc_cfg->x))
+
+#ifdef CONFIG_SYS_GPMC_PREFETCH_ENABLE
+/**
+ * gpmc_prefetch_enable - configures and starts prefetch transfer
+ * @cs: cs (chip select) number
+ * @fifo_th: fifo threshold to be used for read/ write
+ * @count: number of bytes to be transferred
+ * @is_write: prefetch read(0) or write post(1) mode
+ */
+static inline void gpmc_prefetch_enable(int cs, int fifo_th,
+ unsigned int count, int is_write)
+{
+ writel(count, &gpmc_cfg->pref_config2);
+
+ /* Set the prefetch read / post write and enable the engine.
+ * Set which cs is has requested for.
+ */
+ uint32_t val = (cs << CS_NUM_SHIFT) |
+ PREFETCH_ENABLEOPTIMIZEDACCESS |
+ PREFETCH_FIFOTHRESHOLD(fifo_th) |
+ ENABLE_PREFETCH |
+ !!is_write;
+ writel(val, &gpmc_cfg->pref_config1);
+
+ /* Start the prefetch engine */
+ writel(0x1, &gpmc_cfg->pref_control);
+}
+
+/**
+ * gpmc_prefetch_reset - disables and stops the prefetch engine
+ */
+static inline void gpmc_prefetch_reset(void)
+{
+ /* Stop the PFPW engine */
+ writel(0x0, &gpmc_cfg->pref_control);
+
+ /* Reset/disable the PFPW engine */
+ writel(0x0, &gpmc_cfg->pref_config1);
+}
+
+//#define FIFO_IOADDR (nand->IO_ADDR_R)
+#define FIFO_IOADDR PISMO1_NAND_BASE
+
+/**
+ * read_buf_pref - read data from NAND controller into buffer
+ * @mtd: MTD device structure
+ * @buf: buffer to store date
+ * @len: number of bytes to read
+ */
+static void read_buf_pref(struct mtd_info *mtd, u_char *buf, int len)
+{
+ gpmc_prefetch_enable(cs, PREFETCH_FIFOTHRESHOLD_MAX, len, 0);
+ do {
+ // Get number of bytes waiting in the FIFO
+ uint32_t read_bytes = GPMC_PREFETCH_STATUS_FIFO_CNT(readl(&gpmc_cfg->pref_status));
+
+ if (read_bytes == 0)
+ continue;
+ // Alignment of Destination Buffer
+ while (read_bytes && ((unsigned int)buf & 3)) {
+ *buf++ = readb(FIFO_IOADDR);
+ read_bytes--;
+ len--;
+ }
+ // Use maximum word size (32bit) inside this loop, because speed is limited by
+ // GPMC bus arbitration with a maximum transfer rate of 3.000.000/sec.
+ len -= read_bytes & ~3;
+ while (read_bytes >= 4) {
+ *((uint32_t*)buf) = readl(FIFO_IOADDR);
+ buf += 4;
+ read_bytes -= 4;
+ }
+ // Transfer the last (non-aligned) bytes only at the last iteration,
+ // to maintain full speed up to the end of the transfer.
+ if (read_bytes == len) {
+ while (read_bytes) {
+ *buf++ = readb(FIFO_IOADDR);
+ read_bytes--;
+ }
+ len = 0;
+ }
+ } while (len > 0);
+ gpmc_prefetch_reset();
+}
+
+/*
+ * write_buf_pref - write buffer to NAND controller
+ * @mtd: MTD device structure
+ * @buf: data buffer
+ * @len: number of bytes to write
+ */
+static void write_buf_pref(struct mtd_info *mtd, const u_char *buf, int len)
+{
+ /* configure and start prefetch transfer */
+ gpmc_prefetch_enable(cs, PREFETCH_FIFOTHRESHOLD_MAX, len, 1);
+
+ while (len) {
+ // Get number of free bytes in the FIFO
+ uint32_t write_bytes = GPMC_PREFETCH_STATUS_FIFO_CNT(readl(&gpmc_cfg->pref_status));
+
+ // don't write more bytes than requested
+ if (write_bytes > len)
+ write_bytes = len;
+
+ // Alignment of Source Buffer
+ while (write_bytes && ((unsigned int)buf & 3)) {
+ writeb(*buf++, FIFO_IOADDR);
+ write_bytes--;
+ len--;
+ }
+
+ // Use maximum word size (32bit) inside this loop, because speed is limited by
+ // GPMC bus arbitration with a maximum transfer rate of 3.000.000/sec.
+ len -= write_bytes & ~3;
+ while (write_bytes >= 4) {
+ writel(*((uint32_t*)buf), FIFO_IOADDR);
+ buf += 4;
+ write_bytes -= 4;
+ }
+
+ // Transfer the last (non-aligned) bytes only at the last iteration,
+ // to maintain full speed up to the end of the transfer.
+ if (write_bytes == len) {
+ while (write_bytes) {
+ writeb(*buf++, FIFO_IOADDR);
+ write_bytes--;
+ }
+ len = 0;
+ }
+ }
+
+ /* wait for data to be flushed out before resetting the prefetch */
+ while ((len = GPMC_PREFETCH_STATUS_COUNT(readl(&gpmc_cfg->pref_status)))) {
+ debug("%u bytes still in FIFO\n", PREFETCH_FIFOTHRESHOLD_MAX - len);
+ ndelay(1);
+ }
+
+ /* disable and stop the PFPW engine */
+ gpmc_prefetch_reset();
+}
+#endif /* CONFIG_SYS_GPMC_PREFETCH_ENABLE */
+
/*
* omap_nand_hwcontrol - Set the address pointers corretly for the
* following address/data/command operation
/* Check wait pin as dev ready indicator */
static int omap_dev_ready(struct mtd_info *mtd)
{
- return gpmc_cfg->status & (1 << 8);
+ return readl(&gpmc_cfg->status) & (1 << 8);
}
/*
return (err) ? err : error_count;
}
+ #ifdef CONFIG_NAND_OMAP_GPMC_PREFETCH
+
+ #define PREFETCH_CONFIG1_CS_SHIFT 24
+ #define PREFETCH_FIFOTHRESHOLD_MAX 0x40
+ #define PREFETCH_FIFOTHRESHOLD(val) ((val) << 8)
+ #define PREFETCH_STATUS_COUNT(val) (val & 0x00003fff)
+ #define PREFETCH_STATUS_FIFO_CNT(val) ((val >> 24) & 0x7F)
+ #define ENABLE_PREFETCH (1 << 7)
+
+ /**
+ * omap_prefetch_enable - configures and starts prefetch transfer
+ * @fifo_th: fifo threshold to be used for read/ write
+ * @count: number of bytes to be transferred
+ * @is_write: prefetch read(0) or write post(1) mode
+ * @cs: chip select to use
+ */
+ static int omap_prefetch_enable(int fifo_th, unsigned int count, int is_write, int cs)
+ {
+ uint32_t val;
+
+ if (fifo_th > PREFETCH_FIFOTHRESHOLD_MAX)
+ return -EINVAL;
+
+ if (readl(&gpmc_cfg->prefetch_control))
+ return -EBUSY;
+
+ /* Set the amount of bytes to be prefetched */
+ writel(count, &gpmc_cfg->prefetch_config2);
+
+ val = (cs << PREFETCH_CONFIG1_CS_SHIFT) | (is_write & 1) |
+ PREFETCH_FIFOTHRESHOLD(fifo_th) | ENABLE_PREFETCH;
+ writel(val, &gpmc_cfg->prefetch_config1);
+
+ /* Start the prefetch engine */
+ writel(1, &gpmc_cfg->prefetch_control);
+
+ return 0;
+ }
+
+ /**
+ * omap_prefetch_reset - disables and stops the prefetch engine
+ */
+ static void omap_prefetch_reset(void)
+ {
+ writel(0, &gpmc_cfg->prefetch_control);
+ writel(0, &gpmc_cfg->prefetch_config1);
+ }
+
+ static int __read_prefetch_aligned(struct nand_chip *chip, uint32_t *buf, int len)
+ {
+ int ret;
+ uint32_t cnt;
+ struct omap_nand_info *info = chip->priv;
+
+ ret = omap_prefetch_enable(PREFETCH_FIFOTHRESHOLD_MAX, len, 0, info->cs);
+ if (ret < 0)
+ return ret;
+
+ do {
+ int i;
+
+ cnt = readl(&gpmc_cfg->prefetch_status);
+ cnt = PREFETCH_STATUS_FIFO_CNT(cnt);
+
+ for (i = 0; i < cnt / 4; i++) {
+ *buf++ = readl(CONFIG_SYS_NAND_BASE);
+ len -= 4;
+ }
+ } while (len);
+
+ omap_prefetch_reset();
+
+ return 0;
+ }
+
+ static void omap_nand_read_prefetch8(struct mtd_info *mtd, uint8_t *buf, int len)
+ {
+ int ret;
+ uint32_t head, tail;
+ struct nand_chip *chip = mtd->priv;
+
+ /*
+ * If the destination buffer is unaligned, start with reading
+ * the overlap byte-wise.
+ */
+ head = ((uint32_t) buf) % 4;
+ if (head) {
+ nand_read_buf(mtd, buf, head);
+ buf += head;
+ len -= head;
+ }
+
+ /*
+ * Only transfer multiples of 4 bytes in a pre-fetched fashion.
+ * If there's a residue, care for it byte-wise afterwards.
+ */
+ tail = len % 4;
+
+ ret = __read_prefetch_aligned(chip, (uint32_t *) buf, len - tail);
+ if (ret < 0) {
+ /* fallback in case the prefetch engine is busy */
+ nand_read_buf(mtd, buf, len);
+ } else if (tail) {
+ buf += len - tail;
+ nand_read_buf(mtd, buf, tail);
+ }
+ }
+ #endif /* CONFIG_NAND_OMAP_GPMC_PREFETCH */
+
/**
* omap_read_page_bch - hardware ecc based page read function
* @mtd: mtd info structure
uint8_t *ecc_calc = chip->buffers->ecccalc;
uint8_t *ecc_code = chip->buffers->ecccode;
uint32_t *eccpos = chip->ecc.layout->eccpos;
- uint8_t *oob = chip->oob_poi;
+ uint8_t *oob = &chip->oob_poi[eccpos[0]];
uint32_t data_pos;
uint32_t oob_pos;
data_pos = 0;
/* oob area start */
- oob_pos = (eccsize * eccsteps) + chip->ecc.layout->eccpos[0];
- oob += chip->ecc.layout->eccpos[0];
+ oob_pos = (eccsize * eccsteps) + eccpos[0];
for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize,
oob += eccbytes) {
/* read syndrome */
chip->ecc.calculate(mtd, p, &ecc_calc[i]);
+ if (oob_required) {
+ /* reread the OOB area to get the metadata */
+ chip->cmdfunc(mtd, NAND_CMD_RNDOUT, mtd->writesize, page);
+ chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
+ }
+
data_pos += eccsize;
oob_pos += eccbytes;
}
data[errloc[i]/8] ^= 1 << (errloc[i] & 7);
printf("corrected bitflip %u\n", errloc[i]);
#ifdef DEBUG
- puts("read_ecc: ");
+ printf("read_ecc: ");
/*
* BCH8 have 13 bytes of ECC; BCH4 needs adoption
* here!
*/
for (i = 0; i < 13; i++)
printf("%02x ", read_ecc[i]);
- puts("\n");
- puts("calc_ecc: ");
+ printf("\n");
+ printf("calc_ecc: ");
for (i = 0; i < 13; i++)
printf("%02x ", calc_ecc[i]);
- puts("\n");
+ printf("\n");
#endif
}
} else if (count < 0) {
- puts("ecc unrecoverable error\n");
+ printf("ecc unrecoverable error\n");
}
return count;
}
#endif
if (err)
return err;
+#ifdef CONFIG_SYS_NAND_USE_FLASH_BBT
+ if (nand->ecc.layout) {
+ bbt_main_descr.offs = nand->ecc.layout->oobfree[0].offset;
+ bbt_main_descr.veroffs = bbt_main_descr.offs +
+ sizeof(bbt_pattern);
+
+ bbt_mirror_descr.offs = nand->ecc.layout->oobfree[0].offset;
+ bbt_mirror_descr.veroffs = bbt_mirror_descr.offs +
+ sizeof(mirror_pattern);
+ }
+
+ nand->bbt_options |= NAND_BBT_USE_FLASH;
+ nand->bbt_td = &bbt_main_descr;
+ nand->bbt_md = &bbt_mirror_descr;
+#endif
- #ifdef CONFIG_SPL_BUILD
+ #ifdef CONFIG_NAND_OMAP_GPMC_PREFETCH
+ /* TODO: Implement for 16-bit bus width */
if (nand->options & NAND_BUSWIDTH_16)
nand->read_buf = nand_read_buf16;
else
- nand->read_buf = nand_read_buf;
+ nand->read_buf = omap_nand_read_prefetch8;
#endif
nand->dev_ready = omap_dev_ready;
/* Setup standard advertisement */
oldadv = adv = phy_read(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE);
-
if (adv < 0)
return adv;
if (phydev->supported & (SUPPORTED_1000baseT_Half |
SUPPORTED_1000baseT_Full)) {
oldadv = adv = phy_read(phydev, MDIO_DEVAD_NONE, MII_CTRL1000);
-
if (adv < 0)
return adv;
*/
static int genphy_setup_forced(struct phy_device *phydev)
{
- int err;
int ctl = 0;
phydev->pause = phydev->asym_pause = 0;
if (DUPLEX_FULL == phydev->duplex)
ctl |= BMCR_FULLDPLX;
- err = phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, ctl);
-
- return err;
+ return phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, ctl);
}
int ctl;
ctl = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
-
if (ctl < 0)
return ctl;
/* Don't isolate the PHY if we're negotiating */
ctl &= ~(BMCR_ISOLATE);
- ctl = phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, ctl);
-
- return ctl;
+ return phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, ctl);
}
*/
int genphy_update_link(struct phy_device *phydev)
{
- unsigned int mii_reg;
+ int mii_reg;
+ int bmcr;
/*
* Wait if the link is up, and autonegotiation is in progress
* (ie - we're capable and it's not done)
*/
mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
+ if (mii_reg < 0)
+ return mii_reg;
/*
* If we already saw the link up, and it hasn't gone down, then
if (phydev->link && mii_reg & BMSR_LSTATUS)
return 0;
+ bmcr = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
+ if (bmcr < 0)
+ return bmcr;
+
+ if (!(bmcr & BMCR_ANENABLE))
+ return 0;
+
if ((mii_reg & BMSR_ANEGCAPABLE) && !(mii_reg & BMSR_ANEGCOMPLETE)) {
int i = 0;
udelay(1000); /* 1 ms */
mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
+ if (mii_reg < 0)
+ return mii_reg;
}
printf(" done\n");
phydev->link = 1;
} else {
/* Read the link a second time to clear the latched state */
mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
+ if (mii_reg < 0)
+ return mii_reg;
if (mii_reg & BMSR_LSTATUS)
phydev->link = 1;
{
int mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
+ if (mii_reg < 0)
+ return mii_reg;
+
/* We're using autonegotiation */
if (phydev->supported & SUPPORTED_Autoneg) {
+ int ret;
u32 lpa = 0;
- int gblpa = 0;
+ u32 gblpa = 0;
u32 estatus = 0;
/* Check for gigabit capability */
/* We want a list of states supported by
* both PHYs in the link
*/
- gblpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_STAT1000);
- if (gblpa < 0) {
+ ret = phy_read(phydev, MDIO_DEVAD_NONE, MII_STAT1000);
+ if (ret < 0) {
debug("Could not read MII_STAT1000. Ignoring gigabit capability\n");
- gblpa = 0;
+ ret = 0;
}
- gblpa &= phy_read(phydev,
- MDIO_DEVAD_NONE, MII_CTRL1000) << 2;
+ gblpa = ret;
+
+ ret = phy_read(phydev, MDIO_DEVAD_NONE, MII_CTRL1000);
+ if (ret < 0)
+ return ret;
+ gblpa &= ret << 2;
}
/* Set the baseline so we only have to set them
return 0;
}
- lpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE);
- lpa &= phy_read(phydev, MDIO_DEVAD_NONE, MII_LPA);
+ ret = phy_read(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE);
+ if (ret < 0)
+ return ret;
+ lpa = ret;
+
+ ret = phy_read(phydev, MDIO_DEVAD_NONE, MII_LPA);
+ if (ret < 0)
+ return ret;
+ lpa &= ret;
if (lpa & (LPA_100FULL | LPA_100HALF)) {
phydev->speed = SPEED_100;
if ((mii_reg & BMSR_ESTATEN) && !(mii_reg & BMSR_ERCAP))
estatus = phy_read(phydev, MDIO_DEVAD_NONE,
MII_ESTATUS);
+ if (estatus < 0)
+ return estatus;
if (estatus & (ESTATUS_1000_XFULL | ESTATUS_1000_XHALF |
ESTATUS_1000_TFULL | ESTATUS_1000_THALF)) {
}
} else {
- u32 bmcr = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
+ int bmcr = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
+
+ if (bmcr < 0)
+ return bmcr;
phydev->speed = SPEED_10;
phydev->duplex = DUPLEX_HALF;
/* Do we support autonegotiation? */
val = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
-
if (val < 0)
return val;
int phy_init(void)
{
+ #ifdef CONFIG_PHY_AQUANTIA
+ phy_aquantia_init();
+ #endif
#ifdef CONFIG_PHY_ATHEROS
phy_atheros_init();
#endif
return generic_for_interface(interface);
}
+static int aneg_enabled(struct phy_device *phydev)
+{
+ static const char *aneg = "_aneg";
+ char varname[strlen(phydev->bus->name) + strlen(aneg) + 1];
+
+ snprintf(varname, sizeof(varname), "%s%s", phydev->bus->name, aneg);
+ return getenv_yesno(varname);
+}
+
+static int phy_get_speed(struct phy_device *phydev)
+{
+ int ret;
+ static const char *aneg = "_speed";
+ char varname[strlen(phydev->bus->name) + strlen(aneg) + 1];
+ ulong val;
+
+ snprintf(varname, sizeof(varname), "%s%s", phydev->bus->name, aneg);
+
+ val = getenv_ulong(varname, 10, 100);
+ switch (val) {
+ case 1000:
+ ret = SPEED_1000;
+ break;
+ case 100:
+ ret = SPEED_100;
+ break;
+ case 10:
+ ret = SPEED_10;
+ break;
+ default:
+ printf("Improper setting '%s' for %s; assuming 100\n",
+ getenv(varname), varname);
+ ret = SPEED_100;
+ }
+ return ret;
+}
+
+static int phy_get_duplex(struct phy_device *phydev)
+{
+ int ret = DUPLEX_FULL;
+ static const char *aneg = "_duplex";
+ char varname[strlen(phydev->bus->name) + strlen(aneg) + 4];
+ const char *val;
+
+ snprintf(varname, sizeof(varname), "%s%d%s",
+ phydev->bus->name, phydev->addr, aneg);
+
+ val = getenv(varname);
+ if (val != NULL) {
+ if (strcasecmp(val, "full") != 0) {
+ if (strcasecmp(val, "half") == 0) {
+ ret = DUPLEX_HALF;
+ } else {
+ printf("Improper setting '%s' for %s; assuming 'full'\n",
+ val, varname);
+ printf("Expected one of: 'full', 'half'\n");
+ }
+ }
+ }
+
+ return ret;
+}
+
static struct phy_device *phy_device_create(struct mii_dev *bus, int addr,
int phy_id,
phy_interface_t interface)
dev->link = 1;
dev->interface = interface;
- dev->autoneg = AUTONEG_ENABLE;
-
dev->addr = addr;
dev->phy_id = phy_id;
dev->bus = bus;
dev->drv = get_phy_driver(dev, interface);
+ if (aneg_enabled(dev)) {
+ dev->autoneg = AUTONEG_ENABLE;
+ } else {
+ dev->autoneg = AUTONEG_DISABLE;
+ dev->speed = phy_get_speed(dev);
+ dev->duplex = phy_get_duplex(dev);
+
+ switch (dev->speed) {
+ case SPEED_1000:
+ if (dev->duplex == DUPLEX_FULL)
+ dev->supported &= SUPPORTED_1000baseT_Full;
+ else
+ dev->supported &= SUPPORTED_1000baseT_Half;
+ break;
+ case SPEED_100:
+ if (dev->duplex == DUPLEX_FULL)
+ dev->supported &= SUPPORTED_100baseT_Full;
+ else
+ dev->supported &= SUPPORTED_100baseT_Half;
+ break;
+ case SPEED_10:
+ if (dev->duplex == DUPLEX_FULL)
+ dev->supported &= SUPPORTED_10baseT_Full;
+ else
+ dev->supported &= SUPPORTED_10baseT_Half;
+ break;
+ default:
+ printf("Unsupported speed: %d\n", dev->speed);
+ }
+ }
+
phy_probe(dev);
bus->phymap[addr] = dev;
int phy_reset(struct phy_device *phydev)
{
+ int err;
int reg;
int timeout = 500;
int devad = MDIO_DEVAD_NONE;
reg |= BMCR_RESET;
- if (phy_write(phydev, devad, MII_BMCR, reg) < 0) {
+ err = phy_write(phydev, devad, MII_BMCR, reg);
+ if (err < 0) {
debug("PHY reset failed\n");
- return -1;
+ return err;
}
#ifdef CONFIG_PHY_RESET_DELAY
* auto-clearing). This should happen within 0.5 seconds per the
* IEEE spec.
*/
- while ((reg & BMCR_RESET) && timeout--) {
+ while ((reg & BMCR_RESET) && timeout-- >= 0) {
reg = phy_read(phydev, devad, MII_BMCR);
if (reg < 0) {
debug("PHY status read failed\n");
- return -1;
+ return reg;
}
udelay(1000);
}
if (reg & BMCR_RESET) {
puts("PHY reset timed out\n");
- return -1;
+ return -ETIMEDOUT;
}
return 0;
/*
* Generic GPIO API for U-Boot
*
+ * --
+ * NB: This is deprecated. Please use the driver model functions instead:
+ *
+ * - gpio_request_by_name()
+ * - dm_gpio_get_value() etc.
+ *
+ * For now we need a dm_ prefix on some functions to avoid name collision.
+ * --
+ *
* GPIOs are numbered from 0 to GPIO_COUNT-1 which value is defined
* by the SOC/architecture.
*
* an error value of -1.
*/
+enum gpio_flags {
+ GPIOFLAG_INPUT,
+ GPIOFLAG_OUTPUT_INIT_LOW,
+ GPIOFLAG_OUTPUT_INIT_HIGH,
+};
+
+struct gpio {
+ unsigned int gpio;
+ enum gpio_flags flags;
+ const char *label;
+};
+
/**
+ * @deprecated Please use driver model instead
* Request a GPIO. This should be called before any of the other functions
* are used on this GPIO.
*
*/
int gpio_request(unsigned gpio, const char *label);
+/**
++ * @deprecated Please use driver model instead
+ * Request a GPIO and configure it
+ * @param gpios pointer to array of gpio defs
+ * @param count number of GPIOs to set up
+ */
+int gpio_request_one(unsigned gpio, enum gpio_flags flags, const char *label);
+
+/**
+ * Request a set of GPIOs and configure them
+ * @param gpios pointer to array of gpio defs
+ * @param count number of GPIOs to set up
+ */
+int gpio_request_array(const struct gpio *gpios, int count);
+
/**
+ * @deprecated Please use driver model instead
* Stop using the GPIO. This function should not alter pin configuration.
*
* @param gpio GPIO number
*/
int gpio_free(unsigned gpio);
+/**
++ * @deprecated Please use driver model instead
+ * Release a set of GPIOs
+ * @param gpios pointer to array of gpio defs
+ * @param count number of GPIOs to set up
+ */
+int gpio_free_array(const struct gpio *gpios, int count);
+
/**
+ * @deprecated Please use driver model instead
* Make a GPIO an input.
*
* @param gpio GPIO number
int gpio_direction_input(unsigned gpio);
/**
+ * @deprecated Please use driver model instead
* Make a GPIO an output, and set its value.
*
* @param gpio GPIO number
int gpio_direction_output(unsigned gpio, int value);
/**
+ * @deprecated Please use driver model instead
* Get a GPIO's value. This will work whether the GPIO is an input
* or an output.
*
int gpio_get_value(unsigned gpio);
/**
+ * @deprecated Please use driver model instead
* Set an output GPIO's value. The GPIO must already be an output or
* this function may have no effect.
*
struct udevice;
+ struct gpio_desc {
+ struct udevice *dev; /* Device, NULL for invalid GPIO */
+ unsigned long flags;
+ #define GPIOD_REQUESTED (1 << 0) /* Requested/claimed */
+ #define GPIOD_IS_OUT (1 << 1) /* GPIO is an output */
+ #define GPIOD_IS_IN (1 << 2) /* GPIO is an output */
+ #define GPIOD_ACTIVE_LOW (1 << 3) /* value has active low */
+ #define GPIOD_IS_OUT_ACTIVE (1 << 4) /* set output active */
+
+ uint offset; /* GPIO offset within the device */
+ /*
+ * We could consider adding the GPIO label in here. Possibly we could
+ * use this structure for internal GPIO information.
+ */
+ };
+
+ /**
+ * dm_gpio_is_valid() - Check if a GPIO is gpio_is_valie
+ *
+ * @desc: GPIO description containing device, offset and flags,
+ * previously returned by gpio_request_by_name()
+ * @return true if valid, false if not
+ */
+ static inline bool dm_gpio_is_valid(struct gpio_desc *desc)
+ {
+ return desc->dev != NULL;
+ }
+
/**
* gpio_get_status() - get the current GPIO status as a string
*
* which means this is GPIO bank b, offset 4, currently set to input, current
* value 1, [x] means that it is requested and the owner is 'sdmmc_cd'
*
+ * TODO(sjg@chromium.org): This should use struct gpio_desc
+ *
* @dev: Device to check
* @offset: Offset of device GPIO to check
* @buf: Place to put string
*
* Note this returns GPIOF_UNUSED if the GPIO is not requested.
*
+ * TODO(sjg@chromium.org): This should use struct gpio_desc
+ *
* @dev: Device to check
* @offset: Offset of device GPIO to check
* @namep: If non-NULL, this is set to the nane given when the GPIO
* Note this does not return GPIOF_UNUSED - it will always return the GPIO
* driver's view of a pin function, even if it is not correctly set up.
*
+ * TODO(sjg@chromium.org): This should use struct gpio_desc
+ *
* @dev: Device to check
* @offset: Offset of device GPIO to check
* @namep: If non-NULL, this is set to the nane given when the GPIO
int gpio_requestf(unsigned gpio, const char *fmt, ...)
__attribute__ ((format (__printf__, 2, 3)));
+ struct fdtdec_phandle_args;
+
/**
* struct struct dm_gpio_ops - Driver model GPIO operations
*
* @return current function - GPIOF_...
*/
int (*get_function)(struct udevice *dev, unsigned offset);
+
+ /**
+ * xlate() - Translate phandle arguments into a GPIO description
+ *
+ * This function should set up the fields in desc according to the
+ * information in the arguments. The uclass will have set up:
+ *
+ * @desc->dev to @dev
+ * @desc->flags to 0
+ * @desc->offset to the value of the first argument in args, if any,
+ * otherwise -1 (which is invalid)
+ *
+ * This method is optional so if the above defaults suit it can be
+ * omitted. Typical behaviour is to set up the GPIOD_ACTIVE_LOW flag
+ * in desc->flags.
+ *
+ * Note that @dev is passed in as a parameter to follow driver model
+ * uclass conventions, even though it is already available as
+ * desc->dev.
+ *
+ * @dev: GPIO device
+ * @desc: Place to put GPIO description
+ * @args: Arguments provided in descripion
+ * @return 0 if OK, -ve on error
+ */
+ int (*xlate)(struct udevice *dev, struct gpio_desc *desc,
+ struct fdtdec_phandle_args *args);
};
/**
*/
unsigned gpio_get_values_as_int(const int *gpio_list);
+ /**
+ * gpio_request_by_name() - Locate and request a GPIO by name
+ *
+ * This operates by looking up the given list name in the device (device
+ * tree property) and requesting the GPIO for use. The property must exist
+ * in @dev's node.
+ *
+ * Use @flags to specify whether the GPIO should be an input or output. In
+ * principle this can also come from the device tree binding but most
+ * bindings don't provide this information. Specifically, when the GPIO uclass
+ * calls the xlate() method, it can return default flags, which are then
+ * ORed with this @flags.
+ *
+ * If we find that requesting the GPIO is not always needed we could add a
+ * new function or a new GPIOD_NO_REQUEST flag.
+ *
+ * At present driver model has no reference counting so if one device
+ * requests a GPIO which subsequently is unbound, the @desc->dev pointer
+ * will be invalid. However this will only happen if the GPIO device is
+ * unbound, not if it is removed, so this seems like a reasonable limitation
+ * for now. There is no real use case for unbinding drivers in normal
+ * operation.
+ *
+ * The device tree binding is doc/device-tree-bindings/gpio/gpio.txt in
+ * generate terms and each specific device may add additional details in
+ * a binding file in the same directory.
+ *
+ * @dev: Device requesting the GPIO
+ * @list_name: Name of GPIO list (e.g. "board-id-gpios")
+ * @index: Index number of the GPIO in that list use request (0=first)
+ * @desc: Returns GPIO description information. If there is no such
+ * GPIO, dev->dev will be NULL.
+ * @flags: Indicates the GPIO input/output settings (GPIOD_...)
+ * @return 0 if OK, -ENOENT if the GPIO does not exist, -EINVAL if there is
+ * something wrong with the list, or other -ve for another error (e.g.
+ * -EBUSY if a GPIO was already requested)
+ */
+ int gpio_request_by_name(struct udevice *dev, const char *list_name,
+ int index, struct gpio_desc *desc, int flags);
+
+ /**
+ * gpio_request_list_by_name() - Request a list of GPIOs
+ *
+ * Reads all the GPIOs from a list and requetss them. See
+ * gpio_request_by_name() for additional details. Lists should not be
+ * misused to hold unrelated or optional GPIOs. They should only be used
+ * for things like parallel data lines. A zero phandle terminates the list
+ * the list.
+ *
+ * This function will either succeed, and request all GPIOs in the list, or
+ * fail and request none (it will free already-requested GPIOs in case of
+ * an error part-way through).
+ *
+ * @dev: Device requesting the GPIO
+ * @list_name: Name of GPIO list (e.g. "board-id-gpios")
+ * @desc_list: Returns a list of GPIO description information
+ * @max_count: Maximum number of GPIOs to return (@desc_list must be at least
+ * this big)
+ * @flags: Indicates the GPIO input/output settings (GPIOD_...)
+ * @return number of GPIOs requested, or -ve on error
+ */
+ int gpio_request_list_by_name(struct udevice *dev, const char *list_name,
+ struct gpio_desc *desc_list, int max_count,
+ int flags);
+
+ /**
+ * gpio_get_list_count() - Returns the number of GPIOs in a list
+ *
+ * Counts the GPIOs in a list. See gpio_request_by_name() for additional
+ * details.
+ *
+ * @dev: Device requesting the GPIO
+ * @list_name: Name of GPIO list (e.g. "board-id-gpios")
+ * @return number of GPIOs (0 for an empty property) or -ENOENT if the list
+ * does not exist
+ */
+ int gpio_get_list_count(struct udevice *dev, const char *list_name);
+
+ /**
+ * gpio_request_by_name_nodev() - request GPIOs without a device
+ *
+ * This is a version of gpio_request_list_by_name() that does not use a
+ * device. Avoid it unless the caller is not yet using driver model
+ */
+ int gpio_request_by_name_nodev(const void *blob, int node,
+ const char *list_name,
+ int index, struct gpio_desc *desc, int flags);
+
+ /**
+ * gpio_request_list_by_name_nodev() - request GPIOs without a device
+ *
+ * This is a version of gpio_request_list_by_name() that does not use a
+ * device. Avoid it unless the caller is not yet using driver model
+ */
+ int gpio_request_list_by_name_nodev(const void *blob, int node,
+ const char *list_name,
+ struct gpio_desc *desc_list, int max_count,
+ int flags);
+
+ /**
+ * dm_gpio_free() - Free a single GPIO
+ *
+ * This frees a single GPIOs previously returned from gpio_request_by_name().
+ *
+ * @dev: Device which requested the GPIO
+ * @desc: GPIO to free
+ * @return 0 if OK, -ve on error
+ */
+ int dm_gpio_free(struct udevice *dev, struct gpio_desc *desc);
+
+ /**
+ * gpio_free_list() - Free a list of GPIOs
+ *
+ * This frees a list of GPIOs previously returned from
+ * gpio_request_list_by_name().
+ *
+ * @dev: Device which requested the GPIOs
+ * @desc: List of GPIOs to free
+ * @count: Number of GPIOs in the list
+ * @return 0 if OK, -ve on error
+ */
+ int gpio_free_list(struct udevice *dev, struct gpio_desc *desc, int count);
+
+ /**
+ * gpio_free_list_nodev() - free GPIOs without a device
+ *
+ * This is a version of gpio_free_list() that does not use a
+ * device. Avoid it unless the caller is not yet using driver model
+ */
+ int gpio_free_list_nodev(struct gpio_desc *desc, int count);
+
+ /**
+ * dm_gpio_get_value() - Get the value of a GPIO
+ *
+ * This is the driver model version of the existing gpio_get_value() function
+ * and should be used instead of that.
+ *
+ * For now, these functions have a dm_ prefix since they conflict with
+ * existing names.
+ *
+ * @desc: GPIO description containing device, offset and flags,
+ * previously returned by gpio_request_by_name()
+ * @return GPIO value (0 for inactive, 1 for active) or -ve on error
+ */
+ int dm_gpio_get_value(struct gpio_desc *desc);
+
+ int dm_gpio_set_value(struct gpio_desc *desc, int value);
+
+ /**
+ * dm_gpio_set_dir() - Set the direction for a GPIO
+ *
+ * This sets up the direction according tot the provided flags. It will do
+ * nothing unless the direction is actually specified.
+ *
+ * @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_dir(struct gpio_desc *desc);
+
+ /**
+ * dm_gpio_set_dir_flags() - Set direction using specific flags
+ *
+ * This is like dm_gpio_set_dir() except that the flags value is provided
+ * instead of being used from desc->flags. This is needed because in many
+ * cases the GPIO description does not include direction information.
+ * Note that desc->flags is updated by this function.
+ *
+ * @desc: GPIO description containing device, offset and flags,
+ * previously returned by gpio_request_by_name()
+ * @flags: New flags to use
+ * @return 0 if OK, -ve on error, in which case desc->flags is not updated
+ */
+ int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags);
+
+ /**
+ * gpio_get_number() - Get the global GPIO number of a GPIO
+ *
+ * This should only be used for debugging or interest. It returns the nummber
+ * that should be used for gpio_get_value() etc. to access this GPIO.
+ *
+ * @desc: GPIO description containing device, offset and flags,
+ * previously returned by gpio_request_by_name()
+ * @return GPIO number, or -ve if not found
+ */
+ int gpio_get_number(struct gpio_desc *desc);
+
#endif /* _ASM_GENERIC_GPIO_H_ */
--- /dev/null
- #ifdef CONFIG_CMD_MMC
- #ifndef CONFIG_ENV_IS_IN_NAND
- #endif
+/*
+ * Copyright (C) 2012-2014 <LW@KARO-electronics.de>
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ *
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#include <linux/sizes.h>
+#include <asm/arch/imx-regs.h>
+
+/*
+ * Ka-Ro TX53 board - SoC configuration
+ */
+#define CONFIG_SYS_MX5_IOMUX_V3
+#define CONFIG_MXC_GPIO /* GPIO control */
+#define CONFIG_SYS_MX5_HCLK 24000000
+#define CONFIG_SYS_DDR_CLKSEL 0
+#define CONFIG_SYS_HZ 1000 /* Ticks per second */
+#define CONFIG_SHOW_ACTIVITY
+#define CONFIG_DISPLAY_BOARDINFO
+#define CONFIG_BOARD_LATE_INIT
+#define CONFIG_BOARD_EARLY_INIT_F
+
+/* LCD Logo and Splash screen support */
+#define CONFIG_LCD
+#ifdef CONFIG_LCD
+#define CONFIG_SPLASH_SCREEN
+#define CONFIG_SPLASH_SCREEN_ALIGN
+#define CONFIG_VIDEO_IPUV3
+#define CONFIG_IPUV3_CLK 200000000
+#define CONFIG_LCD_LOGO
+#define LCD_BPP LCD_COLOR32
+#define CONFIG_CMD_BMP
+#define CONFIG_VIDEO_BMP_RLE8
+#endif /* CONFIG_LCD */
+
+/*
+ * Memory configuration options
+ */
+#ifndef CONFIG_SYS_SDRAM_SIZE
+#define CONFIG_SYS_SDRAM_SIZE (SZ_512M * CONFIG_NR_DRAM_BANKS)
+#endif
+
+#define PHYS_SDRAM_1 0x70000000 /* Base address of bank 1 */
+#define PHYS_SDRAM_1_SIZE (CONFIG_SYS_SDRAM_SIZE / CONFIG_NR_DRAM_BANKS)
+#if CONFIG_NR_DRAM_BANKS > 1
+#define PHYS_SDRAM_2 0xb0000000 /* Base address of bank 2 */
+#define PHYS_SDRAM_2_SIZE PHYS_SDRAM_1_SIZE
+#endif
+#define CONFIG_STACKSIZE SZ_128K
+#define CONFIG_SYS_MALLOC_LEN SZ_8M
+#define CONFIG_SYS_MEMTEST_START PHYS_SDRAM_1 /* Memtest start address */
+#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_MEMTEST_START + SZ_4M)
+#define CONFIG_SYS_SDRAM_CLK 400
+
+/*
+ * U-Boot general configurations
+ */
+#define CONFIG_SYS_LONGHELP
+#define CONFIG_SYS_PROMPT "TX53 U-Boot > "
+#define CONFIG_SYS_CBSIZE 2048 /* Console I/O buffer size */
+#define CONFIG_SYS_PBSIZE \
+ (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
+ /* Print buffer size */
+#define CONFIG_SYS_MAXARGS 256 /* Max number of command args */
+#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE
+ /* Boot argument buffer size */
+#define CONFIG_VERSION_VARIABLE /* U-BOOT version */
+#define CONFIG_AUTO_COMPLETE /* Command auto complete */
+#define CONFIG_CMDLINE_EDITING /* Command history etc */
+
+#define CONFIG_SYS_64BIT_VSPRINTF
+
+/*
+ * Flattened Device Tree (FDT) support
+*/
+
+/*
+ * Boot Linux
+ */
+#define xstr(s) str(s)
+#define str(s) #s
+#define __pfx(x, s) (x##s)
+#define _pfx(x, s) __pfx(x, s)
+
+#define CONFIG_CMDLINE_TAG
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_BOOTDELAY 3
+#define CONFIG_ZERO_BOOTDELAY_CHECK
+#define CONFIG_SYS_AUTOLOAD "no"
+#define CONFIG_BOOTFILE "uImage"
+#define CONFIG_BOOTARGS "init=/linuxrc console=ttymxc0,115200 ro debug panic=1"
+#define CONFIG_BOOTCOMMAND "run bootcmd_${boot_mode} bootm_cmd"
+#define CONFIG_LOADADDR 78000000
+#define CONFIG_FDTADDR 71000000
+#define CONFIG_SYS_LOAD_ADDR _pfx(0x, CONFIG_LOADADDR)
+#define CONFIG_SYS_FDT_ADDR _pfx(0x, CONFIG_FDTADDR)
+#define CONFIG_U_BOOT_IMG_SIZE SZ_1M
+#ifndef CONFIG_SYS_LVDS_IF
+#define DEFAULT_VIDEO_MODE "VGA"
+#else
+#define DEFAULT_VIDEO_MODE "HSD100PXN1"
+#endif
+
+/*
+ * Extra Environment Settings
+ */
+#define CONFIG_EXTRA_ENV_SETTINGS \
+ "autostart=no\0" \
+ "baseboard=stk5-v3\0" \
+ "bootargs_jffs2=run default_bootargs;set bootargs ${bootargs}" \
+ " root=/dev/mtdblock3 rootfstype=jffs2\0" \
+ "bootargs_mmc=run default_bootargs;set bootargs ${bootargs}" \
+ " root=/dev/mmcblk0p2 rootwait\0" \
+ "bootargs_nfs=run default_bootargs;set bootargs ${bootargs}" \
+ " root=/dev/nfs nfsroot=${nfs_server}:${nfsroot},nolock" \
+ " ip=dhcp\0" \
+ "bootargs_ubifs=run default_bootargs;set bootargs ${bootargs}" \
+ " ubi.mtd=rootfs root=ubi0:rootfs rootfstype=ubifs\0" \
+ "bootcmd_jffs2=set autostart no;run bootargs_jffs2" \
+ ";nboot linux\0" \
+ "bootcmd_mmc=set autostart no;run bootargs_mmc" \
+ ";fatload mmc 0 ${loadaddr} uImage\0" \
+ "bootcmd_nand=set autostart no;run bootargs_ubifs" \
+ ";nboot linux\0" \
+ "bootcmd_net=set autoload y;set autostart n;run bootargs_nfs" \
+ ";dhcp\0" \
+ "bootm_cmd=bootm ${loadaddr} - ${fdtaddr}\0" \
+ "boot_mode=nand\0" \
+ "cpu_clk=800\0" \
+ "default_bootargs=set bootargs " CONFIG_BOOTARGS \
+ " ${append_bootargs}\0" \
+ "fdtaddr=" xstr(CONFIG_FDTADDR) "\0" \
+ "fdtsave=fdt resize;nand erase.part dtb" \
+ ";nand write ${fdtaddr} dtb ${fdtsize}\0" \
+ "mtdids=" MTDIDS_DEFAULT "\0" \
+ "mtdparts=" MTDPARTS_DEFAULT "\0" \
+ "nfsroot=/tftpboot/rootfs\0" \
+ "otg_mode=device\0" \
+ "touchpanel=tsc2007\0" \
+ "video_mode=" DEFAULT_VIDEO_MODE "\0"
+
+#define MTD_NAME "mxc_nand"
+#define MTDIDS_DEFAULT "nand0=" MTD_NAME
+
+/*
+ * U-Boot Commands
+ */
+#include <config_cmd_default.h>
+
+/*
+ * Serial Driver
+ */
+#define CONFIG_MXC_UART
+#define CONFIG_MXC_UART_BASE UART1_BASE
+#define CONFIG_BAUDRATE 115200 /* Default baud rate */
+#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, }
+#define CONFIG_SYS_CONSOLE_INFO_QUIET
+
+/*
+ * GPIO driver
+ */
+#define CONFIG_MXC_GPIO
+
+/*
+ * Ethernet Driver
+ */
+#ifdef CONFIG_FEC_MXC
+#define IMX_FEC_BASE FEC_BASE_ADDR
+#define CONFIG_FEC_XCV_TYPE MII100
+#define CONFIG_CMD_MII
+/* Add for working with "strict" DHCP server */
+#define CONFIG_BOOTP_SUBNETMASK
+#define CONFIG_BOOTP_GATEWAY
+#define CONFIG_BOOTP_DNS
+#endif
+
+/*
+ * I2C Configs
+ */
+#ifdef CONFIG_CMD_I2C
+#define CONFIG_I2C_MXC
+#define CONFIG_SYS_I2C_BASE I2C1_BASE_ADDR
+#define CONFIG_SYS_I2C_MX6_PORT1
+#define CONFIG_SYS_I2C_SPEED 400000
+#define CONFIG_SYS_I2C_SLAVE 0x34
+#endif
+
+/*
+ * NAND flash driver
+ */
+#ifdef CONFIG_CMD_NAND
+#define CONFIG_MXC_NAND_REGS_BASE NFC_BASE_ADDR_AXI
+#define CONFIG_MXC_NAND_IP_REGS_BASE NFC_BASE_ADDR
+#define CONFIG_MXC_NAND_HWECC
+#define CONFIG_SYS_NAND_MAX_CHIPS 0x1
+#define CONFIG_SYS_MAX_NAND_DEVICE 0x1
+#define CONFIG_SYS_NAND_5_ADDR_CYCLE
+#ifdef CONFIG_ENV_IS_IN_NAND
+#define CONFIG_ENV_OVERWRITE
+#define CONFIG_ENV_OFFSET CONFIG_U_BOOT_IMG_SIZE
+#define CONFIG_ENV_SIZE 0x20000 /* 128 KiB */
+#define CONFIG_ENV_RANGE 0x60000
+#endif
+#define CONFIG_SYS_NAND_BASE 0x00000000
+#endif /* CONFIG_CMD_NAND */
+
+/*
+ * MMC Driver
+ */
- #define CONFIG_DOS_PARTITION
++#ifdef CONFIG_FSL_ESDHC
+#define CONFIG_SYS_FSL_ESDHC_ADDR 0
+
+#define CONFIG_CMD_FAT
+#define CONFIG_FAT_WRITE
+#define CONFIG_CMD_EXT2
+
+/*
+ * Environments on MMC
+ */
+#ifdef CONFIG_ENV_IS_IN_MMC
+#define CONFIG_SYS_MMC_ENV_DEV 0
+#define CONFIG_ENV_OVERWRITE
+/* Associated with the MMC layout defined in mmcops.c */
+#define CONFIG_ENV_OFFSET SZ_1K
+#define CONFIG_ENV_SIZE (SZ_128K - CONFIG_ENV_OFFSET)
+#define CONFIG_DYNAMIC_MMC_DEVNO
+#endif /* CONFIG_ENV_IS_IN_MMC */
+#endif /* CONFIG_CMD_MMC */
+
+#ifdef CONFIG_ENV_OFFSET_REDUND
+#define MTDPARTS_DEFAULT "mtdparts=" MTD_NAME ":" \
+ "1m(u-boot)," \
+ xstr(CONFIG_ENV_RANGE) \
+ "(env)," \
+ xstr(CONFIG_ENV_RANGE) \
+ "(env2),6m(linux),32m(rootfs),89344k(userfs),512k@0x7f00000(dtb),512k@0x7f80000(bbt)ro"
+#else
+#define MTDPARTS_DEFAULT "mtdparts=" MTD_NAME ":" \
+ "1m(u-boot)," \
+ xstr(CONFIG_ENV_RANGE) \
+ "(env),6m(linux),32m(rootfs),89728k(userfs),512k@0x7f00000(dtb),512k@0x7f80000(bbt)ro"
+#endif
+
+#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1
+#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + 0x1000 - /* Fix this */ \
+ GENERATED_GBL_DATA_SIZE)
+
+#ifdef CONFIG_CMD_IIM
+#define CONFIG_FSL_IIM
+#endif
+
+#endif /* __CONFIG_H */
/*
+ * Copyright (C) 2004-2010 Freescale Semiconductor, Inc.
+ *
* MPC823 and PXA LCD Controller
*
* Modeled after video interface by Paolo Scaffardi
#ifndef _LCD_H_
#define _LCD_H_
+ #include <lcd_console.h>
extern char lcd_is_enabled;
/* Video functions */
+void lcd_disable(void);
+void lcd_panel_disable(void);
+
void lcd_putc(const char c);
void lcd_puts(const char *s);
void lcd_printf(const char *fmt, ...);
*/
int lcd_get_screen_columns(void);
+ /**
+ * Get the background color of the LCD
+ *
+ * @return background color value
+ */
+ int lcd_getbgcolor(void);
+
+ /**
+ * Get the foreground color of the LCD
+ *
+ * @return foreground color value
+ */
+ int lcd_getfgcolor(void);
+
/**
* Set the position of the text cursor
*
/************************************************************************/
/* ** CONSOLE CONSTANTS */
/************************************************************************/
- #if LCD_BPP == LCD_MONOCHROME
-
- /*
- * Simple black/white definitions
- */
- # define CONSOLE_COLOR_BLACK 0
- # define CONSOLE_COLOR_WHITE 1 /* Must remain last / highest */
-
- #elif LCD_BPP == LCD_COLOR8
+ #if LCD_BPP == LCD_COLOR8
/*
* 8bpp color definitions
# define CONSOLE_COLOR_WHITE 0x00ffffff /* Must remain last / highest*/
# define NBYTES(bit_code) (NBITS(bit_code) >> 3)
-#else
+#elif LCD_BPP == LCD_COLOR16
/*
* 16bpp color definitions
*/
# define CONSOLE_COLOR_BLACK 0x0000
+# define CONSOLE_COLOR_RED 0xf800
+# define CONSOLE_COLOR_GREEN 0x07e0
+# define CONSOLE_COLOR_YELLOW 0xffe0
+# define CONSOLE_COLOR_BLUE 0x001f
+# define CONSOLE_COLOR_MAGENTA 0xf81f
+# define CONSOLE_COLOR_CYAN 0x07ff
+# define CONSOLE_COLOR_GREY 0xcccc
# define CONSOLE_COLOR_WHITE 0xffff /* Must remain last / highest */
+#else
+#error Invalid LCD_BPP setting
#endif /* color definitions */
/************************************************************************/
struct eth_device {
char name[16];
unsigned char enetaddr[6];
- int iobase;
+ phys_addr_t iobase;
int state;
int (*init) (struct eth_device *, bd_t *);
enum proto_t {
BOOTP, RARP, ARP, TFTPGET, DHCP, PING, DNS, NFS, CDP, NETCONS, SNTP,
- TFTPSRV, TFTPPUT, LINKLOCAL
+ TFTPSRV, TFTPPUT, LINKLOCAL, BOOTME
};
/* from net/net.c */
extern void net_set_udp_header(uchar *pkt, IPaddr_t dest, int dport,
int sport, int len);
+ /**
+ * compute_ip_checksum() - Compute IP checksum
+ *
+ * @addr: Address to check (must be 16-bit aligned)
+ * @nbytes: Number of bytes to check (normally a multiple of 2)
+ * @return 16-bit IP checksum
+ */
+ unsigned compute_ip_checksum(const void *addr, unsigned nbytes);
+
+ /**
+ * add_ip_checksums() - add two IP checksums
+ *
+ * @offset: Offset of first sum (if odd we do a byte-swap)
+ * @sum: First checksum
+ * @new_sum: New checksum to add
+ * @return updated 16-bit IP checksum
+ */
+ unsigned add_ip_checksums(unsigned offset, unsigned sum, unsigned new_sum);
+
+ /**
+ * ip_checksum_ok() - check if a checksum is correct
+ *
+ * This works by making sure the checksum sums to 0
+ *
+ * @addr: Address to check (must be 16-bit aligned)
+ * @nbytes: Number of bytes to check (normally a multiple of 2)
+ * @return true if the checksum matches, false if not
+ */
+ int ip_checksum_ok(const void *addr, unsigned nbytes);
+
/* Checksum */
extern int NetCksumOk(uchar *, int); /* Return true if cksum OK */
extern uint NetCksum(uchar *, int); /* Calculate the checksum */
net_loop_last_protocol = protocol;
#endif
}
+#ifdef CONFIG_CMD_BOOTCE
+void BootmeStart(void);
+#endif
/*
* Check if autoload is enabled. If so, use either NFS or TFTP to download
int xilinx_ll_temac_eth_init(bd_t *bis, unsigned long base_addr, int flags,
unsigned long ctrl_addr);
int zynq_gem_of_init(const void *blob);
- int zynq_gem_initialize(bd_t *bis, int base_addr, int phy_addr, u32 emio);
+ int zynq_gem_initialize(bd_t *bis, phys_addr_t base_addr,
+ int phy_addr, u32 emio);
/*
* As long as the Xilinx xps_ll_temac ethernet driver has not its own interface
* exported by a public hader file, we need a global definition at this point.
int fecmxc_register_mii_postcall(struct eth_device *dev, int (*cb)(int));
#endif
+#ifdef CONFIG_DRIVER_TI_CPSW
+enum {
+ CPSW_CTRL_VERSION_1 = 0, /* version1 devices */
+ CPSW_CTRL_VERSION_2 /* version2 devices */
+};
+
+struct cpsw_slave_data {
+ u32 slave_reg_ofs;
+ u32 sliver_reg_ofs;
+ int phy_id;
+ int phy_if;
+};
+
+struct cpsw_platform_data {
+ u32 mdio_base;
+ u32 cpsw_base;
+ int mdio_div;
+ int channels; /* number of cpdma channels (symmetric) */
+ u32 cpdma_reg_ofs; /* cpdma register offset */
+ int slaves; /* number of slave cpgmac ports */
+ u32 ale_reg_ofs; /* address lookup engine reg offset */
+ int ale_entries; /* ale table size */
+ u32 host_port_reg_ofs; /* cpdma host port registers */
+ u32 hw_stats_reg_ofs; /* cpsw hw stats counters */
+ u32 mac_control;
+ struct cpsw_slave_data *slave_data;
+ void (*control)(int enabled);
+ void (*phy_init)(char *name, int addr);
+ u32 gigabit_en; /* gigabit capable AND enabled */
+ u32 host_port_num;
+ u8 version;
+};
+
+int cpsw_register(struct cpsw_platform_data *data);
+#endif /* CONFIG_DRIVER_TI_CPSW */
+
#endif /* _NETDEV_H_ */
#ccflags-y += -DDEBUG
+ obj-y += checksum.o
obj-$(CONFIG_CMD_NET) += arp.o
+obj-$(CONFIG_CMD_BOOTCE) += bootme.o
obj-$(CONFIG_CMD_NET) += bootp.o
obj-$(CONFIG_CMD_CDP) += cdp.o
obj-$(CONFIG_CMD_DNS) += dns.o
hostprogs-y += mkenvimage
mkenvimage-objs := mkenvimage.o os_support.o lib/crc32.o
-hostprogs-y += dumpimage mkimage
+#hostprogs-y += dumpimage mkimage
hostprogs-$(CONFIG_FIT_SIGNATURE) += fit_info fit_check_sign
FIT_SIG_OBJS-$(CONFIG_FIT_SIGNATURE) := common/image-sig.o
LIBFDT_OBJS := $(addprefix lib/libfdt/, \
fdt.o fdt_ro.o fdt_rw.o fdt_strerror.o fdt_wip.o)
RSA_OBJS-$(CONFIG_FIT_SIGNATURE) := $(addprefix lib/rsa/, \
- rsa-sign.o rsa-verify.o rsa-checksum.o)
+ rsa-sign.o rsa-verify.o rsa-checksum.o \
+ rsa-mod-exp.o)
# common objs for dumpimage and mkimage
dumpimage-mkimage-objs := aisimage.o \
socfpgaimage.o \
lib/sha1.o \
lib/sha256.o \
+ common/hash.o \
ublimage.o \
$(LIBFDT_OBJS) \
$(RSA_OBJS-y)
HOSTLOADLIBES_fit_info := $(HOSTLOADLIBES_mkimage)
HOSTLOADLIBES_fit_check_sign := $(HOSTLOADLIBES_mkimage)
+ HOSTLDFLAGS += -T $(srctree)/tools/imagetool.lds
+
hostprogs-$(CONFIG_EXYNOS5250) += mkexynosspl
hostprogs-$(CONFIG_EXYNOS5420) += mkexynosspl
HOSTCFLAGS_mkexynosspl.o := -pedantic
$(patsubst -I%,-idirafter%, $(filter -I%, $(UBOOTINCLUDE))) \
-I$(srctree)/lib/libfdt \
-I$(srctree)/tools \
+ -include $(srctree)/include/linux/kconfig.h \
+ -Wno-variadic-macros \
-DCONFIG_SYS_TEXT_BASE=$(CONFIG_SYS_TEXT_BASE) \
-DUSE_HOSTCC \
-D__KERNEL_STRICT_NAMES \