summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/cpu/armv7/mx6/clock.c33
-rw-r--r--arch/arm/cpu/armv7/mx6/hab.c173
-rw-r--r--arch/arm/include/asm/arch-mx6/clock.h1
-rw-r--r--arch/arm/include/asm/arch-mx6/crm_regs.h5
-rw-r--r--arch/arm/include/asm/arch-mx6/hab.h85
-rw-r--r--arch/arm/include/asm/arch-vf610/crm_regs.h3
-rw-r--r--arch/arm/include/asm/arch-vf610/imx-regs.h3
-rw-r--r--arch/arm/include/asm/arch-vf610/iomux-vf610.h11
-rw-r--r--arch/arm/include/asm/imx-common/iomux-v3.h2
-rw-r--r--board/compulab/cm_fx6/spl.c2
-rw-r--r--drivers/i2c/mxc_i2c.c3
-rw-r--r--drivers/net/fec_mxc.c20
-rw-r--r--drivers/thermal/imx_thermal.c18
-rw-r--r--include/configs/aristainetos-common.h3
-rw-r--r--include/configs/embestmx6boards.h5
-rw-r--r--include/configs/gw_ventana.h5
-rw-r--r--include/configs/mx53loco.h7
-rw-r--r--include/configs/mx6_common.h4
-rw-r--r--include/configs/mx6cuboxi.h2
-rw-r--r--include/configs/mx6sabre_common.h5
-rw-r--r--include/configs/mx6slevk.h5
-rw-r--r--include/configs/mx6sxsabresd.h5
-rw-r--r--include/configs/nitrogen6x.h5
-rw-r--r--include/configs/novena.h6
-rw-r--r--include/configs/ot1200.h4
-rw-r--r--include/configs/platinum.h4
-rw-r--r--include/configs/tbs2910.h6
-rw-r--r--include/configs/tqma6.h4
-rw-r--r--include/configs/wandboard.h5
-rw-r--r--include/configs/warp.h4
-rw-r--r--tools/imximage.h1
31 files changed, 296 insertions, 143 deletions
diff --git a/arch/arm/cpu/armv7/mx6/clock.c b/arch/arm/cpu/armv7/mx6/clock.c
index ae99945..b461898 100644
--- a/arch/arm/cpu/armv7/mx6/clock.c
+++ b/arch/arm/cpu/armv7/mx6/clock.c
@@ -102,25 +102,6 @@ void enable_uart_clk(unsigned char enable)
}
#endif
-#ifdef CONFIG_SPI
-/* spi_num can be from 0 - 4 */
-int enable_cspi_clock(unsigned char enable, unsigned spi_num)
-{
- u32 mask;
-
- if (spi_num > 4)
- return -EINVAL;
-
- mask = MXC_CCM_CCGR_CG_MASK << (spi_num * 2);
- if (enable)
- setbits_le32(&imx_ccm->CCGR1, mask);
- else
- clrbits_le32(&imx_ccm->CCGR1, mask);
-
- return 0;
-}
-#endif
-
#ifdef CONFIG_MMC
int enable_usdhc_clk(unsigned char enable, unsigned bus_num)
{
@@ -145,6 +126,7 @@ int enable_i2c_clk(unsigned char enable, unsigned i2c_num)
{
u32 reg;
u32 mask;
+ u32 *addr;
if (i2c_num > 3)
return -EINVAL;
@@ -159,14 +141,19 @@ int enable_i2c_clk(unsigned char enable, unsigned i2c_num)
reg &= ~mask;
__raw_writel(reg, &imx_ccm->CCGR2);
} else {
- mask = MXC_CCM_CCGR_CG_MASK
- << (MXC_CCM_CCGR1_I2C4_SERIAL_OFFSET);
- reg = __raw_readl(&imx_ccm->CCGR1);
+ if (is_cpu_type(MXC_CPU_MX6SX)) {
+ mask = MXC_CCM_CCGR6_I2C4_MASK;
+ addr = &imx_ccm->CCGR6;
+ } else {
+ mask = MXC_CCM_CCGR1_I2C4_SERIAL_MASK;
+ addr = &imx_ccm->CCGR1;
+ }
+ reg = __raw_readl(addr);
if (enable)
reg |= mask;
else
reg &= ~mask;
- __raw_writel(reg, &imx_ccm->CCGR1);
+ __raw_writel(reg, addr);
}
return 0;
}
diff --git a/arch/arm/cpu/armv7/mx6/hab.c b/arch/arm/cpu/armv7/mx6/hab.c
index 8dee595..87f422d 100644
--- a/arch/arm/cpu/armv7/mx6/hab.c
+++ b/arch/arm/cpu/armv7/mx6/hab.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2014 Freescale Semiconductor, Inc.
+ * Copyright (C) 2010-2015 Freescale Semiconductor, Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
@@ -111,6 +111,153 @@
* +------------+ + CSF_PAD_SIZE
*/
+#define MAX_RECORD_BYTES (8*1024) /* 4 kbytes */
+
+struct record {
+ uint8_t tag; /* Tag */
+ uint8_t len[2]; /* Length */
+ uint8_t par; /* Version */
+ uint8_t contents[MAX_RECORD_BYTES];/* Record Data */
+ bool any_rec_flag;
+};
+
+char *rsn_str[] = {"RSN = HAB_RSN_ANY (0x00)\n",
+ "RSN = HAB_ENG_FAIL (0x30)\n",
+ "RSN = HAB_INV_ADDRESS (0x22)\n",
+ "RSN = HAB_INV_ASSERTION (0x0C)\n",
+ "RSN = HAB_INV_CALL (0x28)\n",
+ "RSN = HAB_INV_CERTIFICATE (0x21)\n",
+ "RSN = HAB_INV_COMMAND (0x06)\n",
+ "RSN = HAB_INV_CSF (0x11)\n",
+ "RSN = HAB_INV_DCD (0x27)\n",
+ "RSN = HAB_INV_INDEX (0x0F)\n",
+ "RSN = HAB_INV_IVT (0x05)\n",
+ "RSN = HAB_INV_KEY (0x1D)\n",
+ "RSN = HAB_INV_RETURN (0x1E)\n",
+ "RSN = HAB_INV_SIGNATURE (0x18)\n",
+ "RSN = HAB_INV_SIZE (0x17)\n",
+ "RSN = HAB_MEM_FAIL (0x2E)\n",
+ "RSN = HAB_OVR_COUNT (0x2B)\n",
+ "RSN = HAB_OVR_STORAGE (0x2D)\n",
+ "RSN = HAB_UNS_ALGORITHM (0x12)\n",
+ "RSN = HAB_UNS_COMMAND (0x03)\n",
+ "RSN = HAB_UNS_ENGINE (0x0A)\n",
+ "RSN = HAB_UNS_ITEM (0x24)\n",
+ "RSN = HAB_UNS_KEY (0x1B)\n",
+ "RSN = HAB_UNS_PROTOCOL (0x14)\n",
+ "RSN = HAB_UNS_STATE (0x09)\n",
+ "RSN = INVALID\n",
+ NULL};
+
+char *sts_str[] = {"STS = HAB_SUCCESS (0xF0)\n",
+ "STS = HAB_FAILURE (0x33)\n",
+ "STS = HAB_WARNING (0x69)\n",
+ "STS = INVALID\n",
+ NULL};
+
+char *eng_str[] = {"ENG = HAB_ENG_ANY (0x00)\n",
+ "ENG = HAB_ENG_SCC (0x03)\n",
+ "ENG = HAB_ENG_RTIC (0x05)\n",
+ "ENG = HAB_ENG_SAHARA (0x06)\n",
+ "ENG = HAB_ENG_CSU (0x0A)\n",
+ "ENG = HAB_ENG_SRTC (0x0C)\n",
+ "ENG = HAB_ENG_DCP (0x1B)\n",
+ "ENG = HAB_ENG_CAAM (0x1D)\n",
+ "ENG = HAB_ENG_SNVS (0x1E)\n",
+ "ENG = HAB_ENG_OCOTP (0x21)\n",
+ "ENG = HAB_ENG_DTCP (0x22)\n",
+ "ENG = HAB_ENG_ROM (0x36)\n",
+ "ENG = HAB_ENG_HDCP (0x24)\n",
+ "ENG = HAB_ENG_RTL (0x77)\n",
+ "ENG = HAB_ENG_SW (0xFF)\n",
+ "ENG = INVALID\n",
+ NULL};
+
+char *ctx_str[] = {"CTX = HAB_CTX_ANY(0x00)\n",
+ "CTX = HAB_CTX_FAB (0xFF)\n",
+ "CTX = HAB_CTX_ENTRY (0xE1)\n",
+ "CTX = HAB_CTX_TARGET (0x33)\n",
+ "CTX = HAB_CTX_AUTHENTICATE (0x0A)\n",
+ "CTX = HAB_CTX_DCD (0xDD)\n",
+ "CTX = HAB_CTX_CSF (0xCF)\n",
+ "CTX = HAB_CTX_COMMAND (0xC0)\n",
+ "CTX = HAB_CTX_AUT_DAT (0xDB)\n",
+ "CTX = HAB_CTX_ASSERT (0xA0)\n",
+ "CTX = HAB_CTX_EXIT (0xEE)\n",
+ "CTX = INVALID\n",
+ NULL};
+
+uint8_t hab_statuses[5] = {
+ HAB_STS_ANY,
+ HAB_FAILURE,
+ HAB_WARNING,
+ HAB_SUCCESS,
+ -1
+};
+
+uint8_t hab_reasons[26] = {
+ HAB_RSN_ANY,
+ HAB_ENG_FAIL,
+ HAB_INV_ADDRESS,
+ HAB_INV_ASSERTION,
+ HAB_INV_CALL,
+ HAB_INV_CERTIFICATE,
+ HAB_INV_COMMAND,
+ HAB_INV_CSF,
+ HAB_INV_DCD,
+ HAB_INV_INDEX,
+ HAB_INV_IVT,
+ HAB_INV_KEY,
+ HAB_INV_RETURN,
+ HAB_INV_SIGNATURE,
+ HAB_INV_SIZE,
+ HAB_MEM_FAIL,
+ HAB_OVR_COUNT,
+ HAB_OVR_STORAGE,
+ HAB_UNS_ALGORITHM,
+ HAB_UNS_COMMAND,
+ HAB_UNS_ENGINE,
+ HAB_UNS_ITEM,
+ HAB_UNS_KEY,
+ HAB_UNS_PROTOCOL,
+ HAB_UNS_STATE,
+ -1
+};
+
+uint8_t hab_contexts[12] = {
+ HAB_CTX_ANY,
+ HAB_CTX_FAB,
+ HAB_CTX_ENTRY,
+ HAB_CTX_TARGET,
+ HAB_CTX_AUTHENTICATE,
+ HAB_CTX_DCD,
+ HAB_CTX_CSF,
+ HAB_CTX_COMMAND,
+ HAB_CTX_AUT_DAT,
+ HAB_CTX_ASSERT,
+ HAB_CTX_EXIT,
+ -1
+};
+
+uint8_t hab_engines[16] = {
+ HAB_ENG_ANY,
+ HAB_ENG_SCC,
+ HAB_ENG_RTIC,
+ HAB_ENG_SAHARA,
+ HAB_ENG_CSU,
+ HAB_ENG_SRTC,
+ HAB_ENG_DCP,
+ HAB_ENG_CAAM,
+ HAB_ENG_SNVS,
+ HAB_ENG_OCOTP,
+ HAB_ENG_DTCP,
+ HAB_ENG_ROM,
+ HAB_ENG_HDCP,
+ HAB_ENG_RTL,
+ HAB_ENG_SW,
+ -1
+};
+
bool is_hab_enabled(void)
{
struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
@@ -122,6 +269,28 @@ bool is_hab_enabled(void)
return (reg & 0x2) == 0x2;
}
+static inline uint8_t get_idx(uint8_t *list, uint8_t tgt)
+{
+ uint8_t idx = 0;
+ uint8_t element = list[idx];
+ while (element != -1) {
+ if (element == tgt)
+ return idx;
+ element = list[++idx];
+ }
+ return -1;
+}
+
+void process_event_record(uint8_t *event_data, size_t bytes)
+{
+ struct record *rec = (struct record *)event_data;
+
+ printf("\n\n%s", sts_str[get_idx(hab_statuses, rec->contents[0])]);
+ printf("%s", rsn_str[get_idx(hab_reasons, rec->contents[1])]);
+ printf("%s", ctx_str[get_idx(hab_contexts, rec->contents[2])]);
+ printf("%s", eng_str[get_idx(hab_engines, rec->contents[3])]);
+}
+
void display_event(uint8_t *event_data, size_t bytes)
{
uint32_t i;
@@ -137,6 +306,8 @@ void display_event(uint8_t *event_data, size_t bytes)
else
printf(" 0x%02x", event_data[i]);
}
+
+ process_event_record(event_data, bytes);
}
int get_hab_status(void)
diff --git a/arch/arm/include/asm/arch-mx6/clock.h b/arch/arm/include/asm/arch-mx6/clock.h
index a6de5ee..7b3bbb8 100644
--- a/arch/arm/include/asm/arch-mx6/clock.h
+++ b/arch/arm/include/asm/arch-mx6/clock.h
@@ -57,7 +57,6 @@ void hab_caam_clock_enable(unsigned char enable);
void enable_ocotp_clk(unsigned char enable);
void enable_usboh3_clk(unsigned char enable);
void enable_uart_clk(unsigned char enable);
-int enable_cspi_clock(unsigned char enable, unsigned spi_num);
int enable_usdhc_clk(unsigned char enable, unsigned bus_num);
int enable_sata_clock(void);
void disable_sata_clock(void);
diff --git a/arch/arm/include/asm/arch-mx6/crm_regs.h b/arch/arm/include/asm/arch-mx6/crm_regs.h
index 887d048..98415ac 100644
--- a/arch/arm/include/asm/arch-mx6/crm_regs.h
+++ b/arch/arm/include/asm/arch-mx6/crm_regs.h
@@ -740,7 +740,7 @@ struct mxc_ccm_reg {
#define MXC_CCM_CCGR6_USDHC4_MASK (3 << MXC_CCM_CCGR6_USDHC4_OFFSET)
#define MXC_CCM_CCGR6_EMI_SLOW_OFFSET 10
#define MXC_CCM_CCGR6_EMI_SLOW_MASK (3 << MXC_CCM_CCGR6_EMI_SLOW_OFFSET)
-#ifdef CONFIG_MX6SX
+/* The following *CCGR6* exist only i.MX6SX */
#define MXC_CCM_CCGR6_PWM8_OFFSET 16
#define MXC_CCM_CCGR6_PWM8_MASK (3 << MXC_CCM_CCGR6_PWM8_OFFSET)
#define MXC_CCM_CCGR6_VADC_OFFSET 20
@@ -755,10 +755,9 @@ struct mxc_ccm_reg {
#define MXC_CCM_CCGR6_PWM6_MASK (3 << MXC_CCM_CCGR6_PWM6_OFFSET)
#define MXC_CCM_CCGR6_PWM7_OFFSET 30
#define MXC_CCM_CCGR6_PWM7_MASK (3 << MXC_CCM_CCGR6_PWM7_OFFSET)
-#else
+/* The two does not exist on i.MX6SX */
#define MXC_CCM_CCGR6_VDOAXICLK_OFFSET 12
#define MXC_CCM_CCGR6_VDOAXICLK_MASK (3 << MXC_CCM_CCGR6_VDOAXICLK_OFFSET)
-#endif
#define BM_ANADIG_PLL_SYS_LOCK 0x80000000
#define BP_ANADIG_PLL_SYS_RSVD0 20
diff --git a/arch/arm/include/asm/arch-mx6/hab.h b/arch/arm/include/asm/arch-mx6/hab.h
index c9e5318..d0eaa67 100644
--- a/arch/arm/include/asm/arch-mx6/hab.h
+++ b/arch/arm/include/asm/arch-mx6/hab.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2012-2015 Freescale Semiconductor, Inc. All Rights Reserved.
*
* SPDX-License-Identifier: GPL-2.0+
*
@@ -23,24 +23,68 @@ enum hab_status {
/* Security Configuration definitions */
enum hab_config {
- HAB_CFG_RETURN = 0x33, /**< Field Return IC */
- HAB_CFG_OPEN = 0xf0, /**< Non-secure IC */
- HAB_CFG_CLOSED = 0xcc /**< Secure IC */
+ HAB_CFG_RETURN = 0x33, /* < Field Return IC */
+ HAB_CFG_OPEN = 0xf0, /* < Non-secure IC */
+ HAB_CFG_CLOSED = 0xcc /* < Secure IC */
};
/* State definitions */
enum hab_state {
- HAB_STATE_INITIAL = 0x33, /**< Initialising state (transitory) */
- HAB_STATE_CHECK = 0x55, /**< Check state (non-secure) */
- HAB_STATE_NONSECURE = 0x66, /**< Non-secure state */
- HAB_STATE_TRUSTED = 0x99, /**< Trusted state */
- HAB_STATE_SECURE = 0xaa, /**< Secure state */
- HAB_STATE_FAIL_SOFT = 0xcc, /**< Soft fail state */
- HAB_STATE_FAIL_HARD = 0xff, /**< Hard fail state (terminal) */
- HAB_STATE_NONE = 0xf0, /**< No security state machine */
+ HAB_STATE_INITIAL = 0x33, /* Initialising state (transitory) */
+ HAB_STATE_CHECK = 0x55, /* Check state (non-secure) */
+ HAB_STATE_NONSECURE = 0x66, /* Non-secure state */
+ HAB_STATE_TRUSTED = 0x99, /* Trusted state */
+ HAB_STATE_SECURE = 0xaa, /* Secure state */
+ HAB_STATE_FAIL_SOFT = 0xcc, /* Soft fail state */
+ HAB_STATE_FAIL_HARD = 0xff, /* Hard fail state (terminal) */
+ HAB_STATE_NONE = 0xf0, /* No security state machine */
HAB_STATE_MAX
};
+enum hab_reason {
+ HAB_RSN_ANY = 0x00, /* Match any reason */
+ HAB_ENG_FAIL = 0x30, /* Engine failure */
+ HAB_INV_ADDRESS = 0x22, /* Invalid address: access denied */
+ HAB_INV_ASSERTION = 0x0c, /* Invalid assertion */
+ HAB_INV_CALL = 0x28, /* Function called out of sequence */
+ HAB_INV_CERTIFICATE = 0x21, /* Invalid certificate */
+ HAB_INV_COMMAND = 0x06, /* Invalid command: command malformed */
+ HAB_INV_CSF = 0x11, /* Invalid csf */
+ HAB_INV_DCD = 0x27, /* Invalid dcd */
+ HAB_INV_INDEX = 0x0f, /* Invalid index: access denied */
+ HAB_INV_IVT = 0x05, /* Invalid ivt */
+ HAB_INV_KEY = 0x1d, /* Invalid key */
+ HAB_INV_RETURN = 0x1e, /* Failed callback function */
+ HAB_INV_SIGNATURE = 0x18, /* Invalid signature */
+ HAB_INV_SIZE = 0x17, /* Invalid data size */
+ HAB_MEM_FAIL = 0x2e, /* Memory failure */
+ HAB_OVR_COUNT = 0x2b, /* Expired poll count */
+ HAB_OVR_STORAGE = 0x2d, /* Exhausted storage region */
+ HAB_UNS_ALGORITHM = 0x12, /* Unsupported algorithm */
+ HAB_UNS_COMMAND = 0x03, /* Unsupported command */
+ HAB_UNS_ENGINE = 0x0a, /* Unsupported engine */
+ HAB_UNS_ITEM = 0x24, /* Unsupported configuration item */
+ HAB_UNS_KEY = 0x1b, /* Unsupported key type/parameters */
+ HAB_UNS_PROTOCOL = 0x14, /* Unsupported protocol */
+ HAB_UNS_STATE = 0x09, /* Unsuitable state */
+ HAB_RSN_MAX
+};
+
+enum hab_context {
+ HAB_CTX_ANY = 0x00, /* Match any context */
+ HAB_CTX_FAB = 0xff, /* Event logged in hab_fab_test() */
+ HAB_CTX_ENTRY = 0xe1, /* Event logged in hab_rvt.entry() */
+ HAB_CTX_TARGET = 0x33, /* Event logged in hab_rvt.check_target() */
+ HAB_CTX_AUTHENTICATE = 0x0a,/* Logged in hab_rvt.authenticate_image() */
+ HAB_CTX_DCD = 0xdd, /* Event logged in hab_rvt.run_dcd() */
+ HAB_CTX_CSF = 0xcf, /* Event logged in hab_rvt.run_csf() */
+ HAB_CTX_COMMAND = 0xc0, /* Event logged executing csf/dcd command */
+ HAB_CTX_AUT_DAT = 0xdb, /* Authenticated data block */
+ HAB_CTX_ASSERT = 0xa0, /* Event logged in hab_rvt.assert() */
+ HAB_CTX_EXIT = 0xee, /* Event logged in hab_rvt.exit() */
+ HAB_CTX_MAX
+};
+
/*Function prototype description*/
typedef enum hab_status hab_rvt_report_event_t(enum hab_status, uint32_t,
uint8_t* , size_t*);
@@ -53,6 +97,22 @@ typedef void *hab_rvt_authenticate_image_t(uint8_t, ptrdiff_t,
void **, size_t *, hab_loader_callback_f_t);
typedef void hapi_clock_init_t(void);
+#define HAB_ENG_ANY 0x00 /* Select first compatible engine */
+#define HAB_ENG_SCC 0x03 /* Security controller */
+#define HAB_ENG_RTIC 0x05 /* Run-time integrity checker */
+#define HAB_ENG_SAHARA 0x06 /* Crypto accelerator */
+#define HAB_ENG_CSU 0x0a /* Central Security Unit */
+#define HAB_ENG_SRTC 0x0c /* Secure clock */
+#define HAB_ENG_DCP 0x1b /* Data Co-Processor */
+#define HAB_ENG_CAAM 0x1d /* CAAM */
+#define HAB_ENG_SNVS 0x1e /* Secure Non-Volatile Storage */
+#define HAB_ENG_OCOTP 0x21 /* Fuse controller */
+#define HAB_ENG_DTCP 0x22 /* DTCP co-processor */
+#define HAB_ENG_ROM 0x36 /* Protected ROM area */
+#define HAB_ENG_HDCP 0x24 /* HDCP co-processor */
+#define HAB_ENG_RTL 0x77 /* RTL simulation engine */
+#define HAB_ENG_SW 0xff /* Software engine */
+
#ifdef CONFIG_MX6SX
#define HAB_RVT_BASE 0x00000100
#else
@@ -73,6 +133,7 @@ typedef void hapi_clock_init_t(void);
#define HAB_CID_ROM 0 /**< ROM Caller ID */
#define HAB_CID_UBOOT 1 /**< UBOOT Caller ID*/
+
/* ----------- end of HAB API updates ------------*/
#endif
diff --git a/arch/arm/include/asm/arch-vf610/crm_regs.h b/arch/arm/include/asm/arch-vf610/crm_regs.h
index fdb45e9..a46e396 100644
--- a/arch/arm/include/asm/arch-vf610/crm_regs.h
+++ b/arch/arm/include/asm/arch-vf610/crm_regs.h
@@ -207,6 +207,7 @@ struct anadig_reg {
#define CCM_CCGR4_CCM_CTRL_MASK (0x3 << 22)
#define CCM_CCGR4_GPC_CTRL_MASK (0x3 << 24)
#define CCM_CCGR4_I2C0_CTRL_MASK (0x3 << 12)
+#define CCM_CCGR4_I2C1_CTRL_MASK (0x3 << 14)
#define CCM_CCGR6_OCOTP_CTRL_MASK (0x3 << 10)
#define CCM_CCGR6_DSPI2_CTRL_MASK (0x3 << 24)
#define CCM_CCGR6_DSPI3_CTRL_MASK (0x3 << 26)
@@ -216,6 +217,8 @@ struct anadig_reg {
#define CCM_CCGR9_FEC0_CTRL_MASK 0x3
#define CCM_CCGR9_FEC1_CTRL_MASK (0x3 << 2)
#define CCM_CCGR10_NFC_CTRL_MASK 0x3
+#define CCM_CCGR10_I2C2_CTRL_MASK (0x3 << 12)
+#define CCM_CCGR10_I2C3_CTRL_MASK (0x3 << 14)
#define ANADIG_PLL7_CTRL_BYPASS (1 << 16)
#define ANADIG_PLL7_CTRL_ENABLE (1 << 13)
diff --git a/arch/arm/include/asm/arch-vf610/imx-regs.h b/arch/arm/include/asm/arch-vf610/imx-regs.h
index 7df3b1e..4366985 100644
--- a/arch/arm/include/asm/arch-vf610/imx-regs.h
+++ b/arch/arm/include/asm/arch-vf610/imx-regs.h
@@ -75,6 +75,9 @@
#define ESAI_FIFO_BASE_ADDR (AIPS0_BASE_ADDR + 0x00063000)
#define WDOG_BASE_ADDR (AIPS0_BASE_ADDR + 0x00065000)
#define I2C1_BASE_ADDR (AIPS0_BASE_ADDR + 0x00066000)
+#define I2C2_BASE_ADDR (AIPS0_BASE_ADDR + 0x00067000)
+#define I2C3_BASE_ADDR (AIPS0_BASE_ADDR + 0x000E6000)
+#define I2C4_BASE_ADDR (AIPS0_BASE_ADDR + 0x000E7000)
#define WKUP_BASE_ADDR (AIPS0_BASE_ADDR + 0x0006A000)
#define CCM_BASE_ADDR (AIPS0_BASE_ADDR + 0x0006B000)
#define GPC_BASE_ADDR (AIPS0_BASE_ADDR + 0x0006C000)
diff --git a/arch/arm/include/asm/arch-vf610/iomux-vf610.h b/arch/arm/include/asm/arch-vf610/iomux-vf610.h
index 019307b..0e2bd53 100644
--- a/arch/arm/include/asm/arch-vf610/iomux-vf610.h
+++ b/arch/arm/include/asm/arch-vf610/iomux-vf610.h
@@ -20,7 +20,8 @@
#define VF610_DDR_PAD_CTRL_1 (PAD_CTL_DSE_25ohm | \
PAD_CTL_INPUT_DIFFERENTIAL)
#define VF610_I2C_PAD_CTRL (PAD_CTL_PUS_47K_UP | PAD_CTL_DSE_50ohm | \
- PAD_CTL_SPEED_HIGH | PAD_CTL_OBE_IBE_ENABLE)
+ PAD_CTL_SPEED_HIGH | PAD_CTL_ODE | \
+ PAD_CTL_OBE_IBE_ENABLE)
#define VF610_NFC_IO_PAD_CTRL (PAD_CTL_SPEED_MED | PAD_CTL_SRE | \
PAD_CTL_DSE_50ohm | PAD_CTL_PUS_47K_UP | \
PAD_CTL_OBE_IBE_ENABLE)
@@ -110,6 +111,8 @@ enum {
VF610_PAD_PTA29__ESDHC1_DAT3 = IOMUX_PAD(0x004c, 0x004c, 5, __NA_, 0, VF610_SDHC_PAD_CTRL),
VF610_PAD_PTB14__I2C0_SCL = IOMUX_PAD(0x0090, 0x0090, 2, 0x033c, 1, VF610_I2C_PAD_CTRL),
VF610_PAD_PTB15__I2C0_SDA = IOMUX_PAD(0x0094, 0x0094, 2, 0x0340, 1, VF610_I2C_PAD_CTRL),
+ VF610_PAD_PTA22__I2C2_SCL = IOMUX_PAD(0x0030, 0x0030, 6, 0x034c, 0, VF610_I2C_PAD_CTRL),
+ VF610_PAD_PTA23__I2C2_SDA = IOMUX_PAD(0x0034, 0x0034, 6, 0x0350, 0, VF610_I2C_PAD_CTRL),
VF610_PAD_PTD31__NF_IO15 = IOMUX_PAD(0x00fc, 0x00fc, 2, __NA_, 0, VF610_NFC_IO_PAD_CTRL),
VF610_PAD_PTD31__GPIO_63 = IOMUX_PAD(0x00fc, 0x00fc, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
VF610_PAD_PTD30__NF_IO14 = IOMUX_PAD(0x0100, 0x0100, 2, __NA_, 0, VF610_NFC_IO_PAD_CTRL),
@@ -146,10 +149,10 @@ enum {
VF610_PAD_PTD12__GPIO_91 = IOMUX_PAD(0x016c, 0x016c, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
VF610_PAD_PTD13__GPIO_92 = IOMUX_PAD(0x0170, 0x0170, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
VF610_PAD_PTD22__NF_IO6 = IOMUX_PAD(0x0120, 0x0120, 2, __NA_, 0, VF610_NFC_IO_PAD_CTRL),
- VF610_PAD_PTD21__NF_IO5 = IOMUX_PAD(0x0124, 0x0124, 2, __NA_, 0, VF610_NFC_IO_PAD_CTRL),
- VF610_PAD_PTD20__NF_IO4 = IOMUX_PAD(0x0128, 0x0128, 2, __NA_, 0, VF610_NFC_IO_PAD_CTRL),
+ VF610_PAD_PTD21__NF_IO5 = IOMUX_PAD(0x0124, 0x0124, 2, __NA_, 0, VF610_NFC_IO_PAD_CTRL),
+ VF610_PAD_PTD20__NF_IO4 = IOMUX_PAD(0x0128, 0x0128, 2, __NA_, 0, VF610_NFC_IO_PAD_CTRL),
VF610_PAD_PTD19__NF_IO3 = IOMUX_PAD(0x012c, 0x012c, 2, __NA_, 0, VF610_NFC_IO_PAD_CTRL),
- VF610_PAD_PTD18__NF_IO2 = IOMUX_PAD(0x0130, 0x0130, 2, __NA_, 0, VF610_NFC_IO_PAD_CTRL),
+ VF610_PAD_PTD18__NF_IO2 = IOMUX_PAD(0x0130, 0x0130, 2, __NA_, 0, VF610_NFC_IO_PAD_CTRL),
VF610_PAD_PTD17__NF_IO1 = IOMUX_PAD(0x0134, 0x0134, 2, __NA_, 0, VF610_NFC_IO_PAD_CTRL),
VF610_PAD_PTD16__NF_IO0 = IOMUX_PAD(0x0138, 0x0138, 2, __NA_, 0, VF610_NFC_IO_PAD_CTRL),
VF610_PAD_PTB24__NF_WE_B = IOMUX_PAD(0x0178, 0x0178, 5, __NA_, 0, VF610_NFC_CN_PAD_CTRL),
diff --git a/arch/arm/include/asm/imx-common/iomux-v3.h b/arch/arm/include/asm/imx-common/iomux-v3.h
index 2581019..5cde90f 100644
--- a/arch/arm/include/asm/imx-common/iomux-v3.h
+++ b/arch/arm/include/asm/imx-common/iomux-v3.h
@@ -127,6 +127,8 @@ typedef u64 iomux_v3_cfg_t;
#define PAD_CTL_SRE (1 << 11)
+#define PAD_CTL_ODE (1 << 10)
+
#define PAD_CTL_DSE_150ohm (1 << 6)
#define PAD_CTL_DSE_50ohm (3 << 6)
#define PAD_CTL_DSE_25ohm (6 << 6)
diff --git a/board/compulab/cm_fx6/spl.c b/board/compulab/cm_fx6/spl.c
index 5b4b76f..d94ced9 100644
--- a/board/compulab/cm_fx6/spl.c
+++ b/board/compulab/cm_fx6/spl.c
@@ -303,7 +303,7 @@ static void cm_fx6_setup_uart(void)
static void cm_fx6_setup_ecspi(void)
{
cm_fx6_set_ecspi_iomux();
- enable_cspi_clock(1, 0);
+ enable_spi_clk(1, 0);
}
#else
static void cm_fx6_setup_ecspi(void) { }
diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
index b3c50aa..f1056e2 100644
--- a/drivers/i2c/mxc_i2c.c
+++ b/drivers/i2c/mxc_i2c.c
@@ -523,7 +523,8 @@ static int bus_i2c_write(struct mxc_i2c_bus *i2c_bus, u8 chip, u32 addr,
#endif
static struct mxc_i2c_bus mxc_i2c_buses[] = {
-#if defined(CONFIG_LS102XA) || defined(CONFIG_FSL_LSCH3)
+#if defined(CONFIG_LS102XA) || defined(CONFIG_FSL_LSCH3) || \
+ defined(CONFIG_VF610)
{ 0, I2C1_BASE_ADDR, I2C_QUIRK_FLAG },
{ 1, I2C2_BASE_ADDR, I2C_QUIRK_FLAG },
{ 2, I2C3_BASE_ADDR, I2C_QUIRK_FLAG },
diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c
index 9225d37..c5dcbbb 100644
--- a/drivers/net/fec_mxc.c
+++ b/drivers/net/fec_mxc.c
@@ -67,13 +67,6 @@ DECLARE_GLOBAL_DATA_PTR;
#undef DEBUG
-struct nbuf {
- uint8_t data[1500]; /**< actual data */
- int length; /**< actual length */
- int used; /**< buffer in use or not */
- uint8_t head[16]; /**< MAC header(6 + 6 + 2) + 2(aligned) */
-};
-
#ifdef CONFIG_FEC_MXC_SWAP_PACKET
static void swap_packet(uint32_t *packet, int length)
{
@@ -775,7 +768,6 @@ static int fec_recv(struct eth_device *dev)
struct fec_bd *rbd = &fec->rbd_base[fec->rbd_index];
unsigned long ievent;
int frame_length, len = 0;
- struct nbuf *frame;
uint16_t bd_status;
uint32_t addr, size, end;
int i;
@@ -835,12 +827,11 @@ static int fec_recv(struct eth_device *dev)
/*
* Get buffer address and size
*/
- frame = (struct nbuf *)readl(&rbd->data_pointer);
+ addr = readl(&rbd->data_pointer);
frame_length = readw(&rbd->data_length) - 4;
/*
* Invalidate data cache over the buffer
*/
- addr = (uint32_t)frame;
end = roundup(addr + frame_length, ARCH_DMA_MINALIGN);
addr &= ~(ARCH_DMA_MINALIGN - 1);
invalidate_dcache_range(addr, end);
@@ -849,16 +840,15 @@ static int fec_recv(struct eth_device *dev)
* Fill the buffer and pass it to upper layers
*/
#ifdef CONFIG_FEC_MXC_SWAP_PACKET
- swap_packet((uint32_t *)frame->data, frame_length);
+ swap_packet((uint32_t *)addr, frame_length);
#endif
- memcpy(buff, frame->data, frame_length);
+ memcpy(buff, (char *)addr, frame_length);
net_process_received_packet(buff, frame_length);
len = frame_length;
} else {
if (bd_status & FEC_RBD_ERR)
- printf("error frame: 0x%08lx 0x%08x\n",
- (ulong)rbd->data_pointer,
- bd_status);
+ printf("error frame: 0x%08x 0x%08x\n",
+ addr, bd_status);
}
/*
diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c
index 0d893c9..3c6c967 100644
--- a/drivers/thermal/imx_thermal.c
+++ b/drivers/thermal/imx_thermal.c
@@ -115,7 +115,7 @@ static int read_cpu_temperature(struct udevice *dev)
writel(TEMPSENSE0_FINISHED, &anatop->tempsense0_clr);
/* milli_Tmeas = c2 - Nmeas * c1 */
- temperature = (c2 - n_meas * c1)/1000;
+ temperature = (long)(c2 - n_meas * c1)/1000;
/* power down anatop thermal sensor */
writel(TEMPSENSE0_POWER_DOWN, &anatop->tempsense0_set);
@@ -130,16 +130,12 @@ int imx_thermal_get_temp(struct udevice *dev, int *temp)
int cpu_tmp = 0;
cpu_tmp = read_cpu_temperature(dev);
- while (cpu_tmp > priv->minc && cpu_tmp < priv->maxc) {
- if (cpu_tmp >= priv->critical) {
- printf("CPU Temperature (%dC) too close to max (%dC)",
- cpu_tmp, priv->maxc);
- puts(" waiting...\n");
- udelay(5000000);
- cpu_tmp = read_cpu_temperature(dev);
- } else {
- break;
- }
+ while (cpu_tmp >= priv->critical) {
+ printf("CPU Temperature (%dC) too close to max (%dC)",
+ cpu_tmp, priv->maxc);
+ puts(" waiting...\n");
+ udelay(5000000);
+ cpu_tmp = read_cpu_temperature(dev);
}
*temp = cpu_tmp;
diff --git a/include/configs/aristainetos-common.h b/include/configs/aristainetos-common.h
index dd012f1..4a5d4fb 100644
--- a/include/configs/aristainetos-common.h
+++ b/include/configs/aristainetos-common.h
@@ -26,9 +26,6 @@
#define CONFIG_MXC_UART
-#define CONFIG_CMD_FUSE
-#define CONFIG_MXC_OCOTP
-
/* MMC Configs */
#define CONFIG_SYS_FSL_ESDHC_ADDR 0
diff --git a/include/configs/embestmx6boards.h b/include/configs/embestmx6boards.h
index cba58aa..12744a6 100644
--- a/include/configs/embestmx6boards.h
+++ b/include/configs/embestmx6boards.h
@@ -29,11 +29,6 @@
#define CONFIG_MXC_UART
-#define CONFIG_CMD_FUSE
-#ifdef CONFIG_CMD_FUSE
-#define CONFIG_MXC_OCOTP
-#endif
-
/* I2C Configs */
#define CONFIG_CMD_I2C
#define CONFIG_SYS_I2C
diff --git a/include/configs/gw_ventana.h b/include/configs/gw_ventana.h
index 902ec2c..df1ff43 100644
--- a/include/configs/gw_ventana.h
+++ b/include/configs/gw_ventana.h
@@ -165,11 +165,6 @@
#define CONFIG_CMD_EECONFIG /* Gateworks EEPROM config cmd */
#define CONFIG_CMD_UBI
#define CONFIG_RBTREE
-#define CONFIG_CMD_FUSE /* eFUSE read/write support */
-#ifdef CONFIG_CMD_FUSE
-#define CONFIG_MXC_OCOTP
-#endif
-
/* Ethernet support */
#define CONFIG_FEC_MXC
diff --git a/include/configs/mx53loco.h b/include/configs/mx53loco.h
index 53f725d..ad2629d 100644
--- a/include/configs/mx53loco.h
+++ b/include/configs/mx53loco.h
@@ -43,6 +43,7 @@
#define CONFIG_MMC
#define CONFIG_CMD_MMC
#define CONFIG_GENERIC_MMC
+#define CONFIG_CMD_FS_GENERIC
#define CONFIG_CMD_FAT
#define CONFIG_CMD_EXT2
#define CONFIG_DOS_PARTITION
@@ -113,11 +114,11 @@
"mmcroot=/dev/mmcblk0p2 rw rootwait\0" \
"mmcargs=setenv bootargs console=ttymxc0,${baudrate} root=${mmcroot}\0" \
"loadbootscript=" \
- "fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};\0" \
+ "load mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};\0" \
"bootscript=echo Running bootscript from mmc ...; " \
"source\0" \
- "loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}\0" \
- "loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}\0" \
+ "loadimage=load mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}\0" \
+ "loadfdt=load mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}\0" \
"mmcboot=echo Booting from mmc ...; " \
"run mmcargs; " \
"if test ${boot_fdt} = yes || test ${boot_fdt} = try; then " \
diff --git a/include/configs/mx6_common.h b/include/configs/mx6_common.h
index 86d7b16..54ab890 100644
--- a/include/configs/mx6_common.h
+++ b/include/configs/mx6_common.h
@@ -111,4 +111,8 @@
#define CONFIG_FSL_ESDHC
#define CONFIG_FSL_USDHC
+/* Fuses */
+#define CONFIG_CMD_FUSE
+#define CONFIG_MXC_OCOTP
+
#endif
diff --git a/include/configs/mx6cuboxi.h b/include/configs/mx6cuboxi.h
index 3d5bba7..634a09f 100644
--- a/include/configs/mx6cuboxi.h
+++ b/include/configs/mx6cuboxi.h
@@ -20,8 +20,6 @@
#define CONFIG_BOARD_EARLY_INIT_F
#define CONFIG_BOARD_LATE_INIT
#define CONFIG_MXC_UART
-#define CONFIG_CMD_FUSE
-#define CONFIG_MXC_OCOTP
/* MMC Configs */
#define CONFIG_SYS_FSL_ESDHC_ADDR USDHC2_BASE_ADDR
diff --git a/include/configs/mx6sabre_common.h b/include/configs/mx6sabre_common.h
index 6c3c52e..e42dfc9 100644
--- a/include/configs/mx6sabre_common.h
+++ b/include/configs/mx6sabre_common.h
@@ -21,11 +21,6 @@
#define CONFIG_MXC_UART
-#define CONFIG_CMD_FUSE
-#if defined(CONFIG_CMD_FUSE) || defined(CONFIG_IMX6_THERMAL)
-#define CONFIG_MXC_OCOTP
-#endif
-
/* MMC Configs */
#define CONFIG_SYS_FSL_ESDHC_ADDR 0
diff --git a/include/configs/mx6slevk.h b/include/configs/mx6slevk.h
index a7da111..3cecd94 100644
--- a/include/configs/mx6slevk.h
+++ b/include/configs/mx6slevk.h
@@ -192,9 +192,4 @@
#define CONFIG_IMX6_THERMAL
-#define CONFIG_CMD_FUSE
-#if defined(CONFIG_CMD_FUSE) || defined(CONFIG_IMX6_THERMAL)
-#define CONFIG_MXC_OCOTP
-#endif
-
#endif /* __CONFIG_H */
diff --git a/include/configs/mx6sxsabresd.h b/include/configs/mx6sxsabresd.h
index 2b278a8..848bdcd 100644
--- a/include/configs/mx6sxsabresd.h
+++ b/include/configs/mx6sxsabresd.h
@@ -178,11 +178,6 @@
#define CONFIG_IMX6_THERMAL
-#define CONFIG_CMD_FUSE
-#if defined(CONFIG_CMD_FUSE) || defined(CONFIG_IMX6_THERMAL)
-#define CONFIG_MXC_OCOTP
-#endif
-
#define CONFIG_CMD_TIME
#define CONFIG_FSL_QSPI
diff --git a/include/configs/nitrogen6x.h b/include/configs/nitrogen6x.h
index 67a3c97..2e81ad4 100644
--- a/include/configs/nitrogen6x.h
+++ b/include/configs/nitrogen6x.h
@@ -26,11 +26,6 @@
#define CONFIG_USB_ETH_CDC
#define CONFIG_NETCONSOLE
-#define CONFIG_CMD_FUSE
-#ifdef CONFIG_CMD_FUSE
-#define CONFIG_MXC_OCOTP
-#endif
-
#define CONFIG_MXC_UART
#define CONFIG_MXC_UART_BASE UART2_BASE
diff --git a/include/configs/novena.h b/include/configs/novena.h
index d9b7250..0970fd7 100644
--- a/include/configs/novena.h
+++ b/include/configs/novena.h
@@ -25,7 +25,6 @@
#define CONFIG_CMD_EEPROM
#define CONFIG_CMD_I2C
#define CONFIG_FAT_WRITE
-#define CONFIG_CMD_FUSE
#define CONFIG_CMD_MII
#define CONFIG_CMD_PCI
#define CONFIG_CMD_PING
@@ -118,11 +117,6 @@
#define CONFIG_SYS_FSL_ESDHC_ADDR 0
#define CONFIG_SYS_FSL_USDHC_NUM 2
-/* OCOTP Configs */
-#ifdef CONFIG_CMD_FUSE
-#define CONFIG_MXC_OCOTP
-#endif
-
/* PCI express */
#ifdef CONFIG_CMD_PCI
#define CONFIG_PCI
diff --git a/include/configs/ot1200.h b/include/configs/ot1200.h
index fb58acf..0d06fce 100644
--- a/include/configs/ot1200.h
+++ b/include/configs/ot1200.h
@@ -16,10 +16,6 @@
#define CONFIG_BOARD_EARLY_INIT_F
#define CONFIG_MISC_INIT_R
-/* FUSE Configs */
-#define CONFIG_CMD_FUSE
-#define CONFIG_MXC_OCOTP
-
/* UART Configs */
#define CONFIG_MXC_UART
#define CONFIG_MXC_UART_BASE UART1_BASE
diff --git a/include/configs/platinum.h b/include/configs/platinum.h
index fd19461..d651432 100644
--- a/include/configs/platinum.h
+++ b/include/configs/platinum.h
@@ -23,7 +23,6 @@
#define CONFIG_CMD_BMODE
#define CONFIG_CMD_DHCP
-#define CONFIG_CMD_FUSE
#define CONFIG_CMD_I2C
#define CONFIG_CMD_MII
#define CONFIG_CMD_MTDPARTS
@@ -103,9 +102,6 @@
#define CONFIG_APBH_DMA_BURST
#define CONFIG_APBH_DMA_BURST8
-/* Fuse support */
-#define CONFIG_MXC_OCOTP
-
/* Environment in NAND */
#define CONFIG_ENV_IS_IN_NAND
#define CONFIG_ENV_OFFSET (16 << 20)
diff --git a/include/configs/tbs2910.h b/include/configs/tbs2910.h
index 42e5821..5bc1209 100644
--- a/include/configs/tbs2910.h
+++ b/include/configs/tbs2910.h
@@ -173,12 +173,6 @@
#define CONFIG_I2C_EDID
#endif
-/* Fuses */
-#define CONFIG_CMD_FUSE
-#ifdef CONFIG_CMD_FUSE
-#define CONFIG_MXC_OCOTP
-#endif
-
/* Environment organization */
#define CONFIG_ENV_IS_IN_MMC
#define CONFIG_SYS_MMC_ENV_DEV 2
diff --git a/include/configs/tqma6.h b/include/configs/tqma6.h
index e0c4ada..bd93ec7 100644
--- a/include/configs/tqma6.h
+++ b/include/configs/tqma6.h
@@ -100,10 +100,6 @@
#define CONFIG_USB_MAX_CONTROLLER_COUNT 2
#define CONFIG_EHCI_HCD_INIT_AFTER_RESET /* For OTG port */
-/* Fuses */
-#define CONFIG_MXC_OCOTP
-#define CONFIG_CMD_FUSE
-
#define CONFIG_CMD_PING
#define CONFIG_CMD_DHCP
#define CONFIG_CMD_MII
diff --git a/include/configs/wandboard.h b/include/configs/wandboard.h
index f05b55a..f4e9cf2 100644
--- a/include/configs/wandboard.h
+++ b/include/configs/wandboard.h
@@ -84,11 +84,6 @@
#define CONFIG_IMX_HDMI
#define CONFIG_IMX_VIDEO_SKIP
-#define CONFIG_CMD_FUSE
-#ifdef CONFIG_CMD_FUSE
-#define CONFIG_MXC_OCOTP
-#endif
-
#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
#define CONFIG_EXTRA_ENV_SETTINGS \
"script=boot.scr\0" \
diff --git a/include/configs/warp.h b/include/configs/warp.h
index 48e2058..2331767 100644
--- a/include/configs/warp.h
+++ b/include/configs/warp.h
@@ -94,10 +94,6 @@
#define CONFIG_SYS_DFU_DATA_BUF_SIZE SZ_16M
#define DFU_DEFAULT_POLL_TIMEOUT 300
-/* Fuses */
-#define CONFIG_CMD_FUSE
-#define CONFIG_MXC_OCOTP
-
#define CONFIG_EXTRA_ENV_SETTINGS \
"script=boot.scr\0" \
"image=zImage\0" \
diff --git a/tools/imximage.h b/tools/imximage.h
index 36fe095..a913329 100644
--- a/tools/imximage.h
+++ b/tools/imximage.h
@@ -129,6 +129,7 @@ typedef struct {
ivt_header_t header;
write_dcd_command_t write_dcd_command;
dcd_addr_data_t addr_data[MAX_HW_CFG_SIZE_V2];
+ uint32_t padding[1]; /* end up on an 8-byte boundary */
} dcd_v2_t;
typedef struct {