summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorStefano Babic <sbabic@denx.de>2015-03-02 09:42:53 +0100
committerStefano Babic <sbabic@denx.de>2015-03-02 09:42:53 +0100
commitb9cb64825b5e6efeb715abd8b48d9b12f98973e9 (patch)
treed70d73a986308dee88474572006f5c60b10749be /drivers
parent4579dc37c3cce36d9521c26c6e82881393ec769e (diff)
parent1606b34aa50804227806971dbb6b82ea0bf81f55 (diff)
downloadtalos-obmc-uboot-b9cb64825b5e6efeb715abd8b48d9b12f98973e9.tar.gz
talos-obmc-uboot-b9cb64825b5e6efeb715abd8b48d9b12f98973e9.zip
Merge branch 'master' of git://git.denx.de/u-boot
Diffstat (limited to 'drivers')
-rw-r--r--drivers/Kconfig4
-rw-r--r--drivers/core/Kconfig48
-rw-r--r--drivers/core/device.c12
-rw-r--r--drivers/core/root.c64
-rw-r--r--drivers/crypto/fsl/fsl_blob.c4
-rw-r--r--drivers/crypto/fsl/fsl_hash.c138
-rw-r--r--drivers/crypto/fsl/fsl_hash.h34
-rw-r--r--drivers/ddr/fsl/arm_ddr_gen3.c2
-rw-r--r--drivers/ddr/fsl/ctrl_regs.c216
-rw-r--r--drivers/ddr/fsl/ddr1_dimm_params.c18
-rw-r--r--drivers/ddr/fsl/ddr2_dimm_params.c12
-rw-r--r--drivers/ddr/fsl/ddr3_dimm_params.c8
-rw-r--r--drivers/ddr/fsl/ddr4_dimm_params.c8
-rw-r--r--drivers/ddr/fsl/fsl_ddr_gen4.c36
-rw-r--r--drivers/ddr/fsl/lc_common_dimm_params.c27
-rw-r--r--drivers/ddr/fsl/main.c29
-rw-r--r--drivers/ddr/fsl/mpc85xx_ddr_gen3.c4
-rw-r--r--drivers/ddr/fsl/options.c6
-rw-r--r--drivers/ddr/fsl/util.c67
-rw-r--r--drivers/demo/Kconfig26
-rw-r--r--drivers/gpio/Kconfig7
-rw-r--r--drivers/gpio/at91_gpio.c10
-rw-r--r--drivers/gpio/mxc_gpio.c84
-rw-r--r--drivers/gpio/omap_gpio.c2
-rw-r--r--drivers/i2c/Kconfig21
-rw-r--r--drivers/i2c/adi_i2c.c6
-rw-r--r--drivers/i2c/i2c-uclass.c11
-rw-r--r--drivers/i2c/kona_i2c.c16
-rw-r--r--drivers/i2c/mv_i2c.c10
-rw-r--r--drivers/i2c/s3c24x0_i2c.c4
-rw-r--r--drivers/input/Kconfig6
-rw-r--r--drivers/misc/Kconfig55
-rw-r--r--drivers/mmc/dw_mmc.c2
-rw-r--r--drivers/mmc/exynos_dw_mmc.c71
-rw-r--r--drivers/mmc/fsl_esdhc.c8
-rw-r--r--drivers/mmc/mmc.c8
-rw-r--r--drivers/mmc/sdhci.c3
-rw-r--r--drivers/mmc/sunxi_mmc.c6
-rw-r--r--drivers/mtd/Kconfig2
-rw-r--r--drivers/mtd/nand/Kconfig6
-rw-r--r--drivers/mtd/nand/omap_gpmc.c5
-rw-r--r--drivers/mtd/spi/Kconfig14
-rw-r--r--drivers/net/Makefile3
-rw-r--r--drivers/net/fsl-mc/Makefile (renamed from drivers/net/fsl_mc/Makefile)4
-rw-r--r--drivers/net/fsl-mc/dpmng.c91
-rw-r--r--drivers/net/fsl-mc/fsl_dpmng_cmd.h49
-rw-r--r--drivers/net/fsl-mc/mc.c (renamed from drivers/net/fsl_mc/mc.c)132
-rw-r--r--drivers/net/fsl-mc/mc_sys.c63
-rw-r--r--drivers/net/keystone_net.c4
-rw-r--r--drivers/net/ks8695eth.c229
-rw-r--r--drivers/pci/pci_auto.c36
-rw-r--r--drivers/pci/pcie_layerscape.c471
-rw-r--r--drivers/serial/Kconfig65
-rw-r--r--drivers/serial/Makefile2
-rw-r--r--drivers/serial/ns16550.c98
-rw-r--r--drivers/serial/serial-uclass.c16
-rw-r--r--drivers/serial/serial.c2
-rw-r--r--drivers/serial/serial_ks8695.c121
-rw-r--r--drivers/serial/serial_ppc.c40
-rw-r--r--drivers/serial/serial_sh.c321
-rw-r--r--drivers/serial/serial_sh.h30
-rw-r--r--drivers/spi/Kconfig10
-rw-r--r--drivers/thermal/Kconfig7
-rw-r--r--drivers/usb/musb-new/sunxi.c42
-rw-r--r--drivers/video/Makefile1
-rw-r--r--drivers/video/mb86r0xgdc.c168
-rw-r--r--drivers/video/sunxi_display.c54
-rw-r--r--drivers/watchdog/Makefile1
-rw-r--r--drivers/watchdog/tnetv107x_wdt.c165
69 files changed, 2207 insertions, 1138 deletions
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 128736dae3..dcce532e2d 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -2,6 +2,8 @@ menu "Device Drivers"
source "drivers/core/Kconfig"
+source "drivers/demo/Kconfig"
+
source "drivers/pci/Kconfig"
source "drivers/pcmcia/Kconfig"
@@ -48,4 +50,6 @@ source "drivers/dma/Kconfig"
source "drivers/crypto/Kconfig"
+source "drivers/thermal/Kconfig"
+
endmenu
diff --git a/drivers/core/Kconfig b/drivers/core/Kconfig
index d2799dc861..75d182d27f 100644
--- a/drivers/core/Kconfig
+++ b/drivers/core/Kconfig
@@ -1,6 +1,48 @@
config DM
bool "Enable Driver Model"
- depends on !SPL_BUILD
help
- This config option enables Driver Model.
- To use legacy drivers, say N.
+ This config option enables Driver Model. This brings in the core
+ support, including scanning of platform data on start-up. If
+ CONFIG_OF_CONTROL is enabled, the device tree will be scanned also
+ when available.
+
+config SPL_DM
+ bool "Enable Driver Model for SPL"
+ depends on DM && SPL
+ help
+ Enable driver model in SPL. You will need to provide a
+ suitable malloc() implementation. If you are not using the
+ full malloc() enabled by CONFIG_SYS_SPL_MALLOC_START,
+ consider using CONFIG_SYS_MALLOC_SIMPLE. In that case you
+ must provide CONFIG_SYS_MALLOC_F_LEN to set the size.
+ In most cases driver model will only allocate a few uclasses
+ and devices in SPL, so 1KB should be enable. See
+ CONFIG_SYS_MALLOC_F_LEN for more details on how to enable it.
+
+config DM_WARN
+ bool "Enable warnings in driver model"
+ depends on DM
+ default y
+ help
+ The dm_warn() function can use up quite a bit of space for its
+ strings. By default this is disabled for SPL builds to save space.
+ This will cause dm_warn() to be compiled out - it will do nothing
+ when called.
+
+config DM_DEVICE_REMOVE
+ bool "Support device removal"
+ depends on DM
+ default y
+ help
+ We can save some code space by dropping support for removing a
+ device. This is not normally required in SPL, so by default this
+ option is disabled for SPL.
+
+config DM_STDIO
+ bool "Support stdio registration"
+ depends on DM
+ default y
+ help
+ Normally serial drivers register with stdio so that they can be used
+ as normal output devices. In SPL we don't normally use stdio, so
+ we can omit this feature.
diff --git a/drivers/core/device.c b/drivers/core/device.c
index b73d3b8961..73c3e07c28 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -449,3 +449,15 @@ enum uclass_id device_get_uclass_id(struct udevice *dev)
{
return dev->uclass->uc_drv->id;
}
+
+#ifdef CONFIG_OF_CONTROL
+fdt_addr_t dev_get_addr(struct udevice *dev)
+{
+ return fdtdec_get_addr(gd->fdt_blob, dev->of_offset, "reg");
+}
+#else
+fdt_addr_t dev_get_addr(struct udevice *dev)
+{
+ return FDT_ADDR_T_NONE;
+}
+#endif
diff --git a/drivers/core/root.c b/drivers/core/root.c
index 73e3c7228e..9b5c6bb10c 100644
--- a/drivers/core/root.c
+++ b/drivers/core/root.c
@@ -37,6 +37,65 @@ struct udevice *dm_root(void)
return gd->dm_root;
}
+#if defined(CONFIG_NEEDS_MANUAL_RELOC)
+void fix_drivers(void)
+{
+ struct driver *drv =
+ ll_entry_start(struct driver, driver);
+ const int n_ents = ll_entry_count(struct driver, driver);
+ struct driver *entry;
+
+ for (entry = drv; entry != drv + n_ents; entry++) {
+ if (entry->of_match)
+ entry->of_match = (const struct udevice_id *)
+ ((u32)entry->of_match + gd->reloc_off);
+ if (entry->bind)
+ entry->bind += gd->reloc_off;
+ if (entry->probe)
+ entry->probe += gd->reloc_off;
+ if (entry->remove)
+ entry->remove += gd->reloc_off;
+ if (entry->unbind)
+ entry->unbind += gd->reloc_off;
+ if (entry->ofdata_to_platdata)
+ entry->ofdata_to_platdata += gd->reloc_off;
+ if (entry->child_pre_probe)
+ entry->child_pre_probe += gd->reloc_off;
+ if (entry->child_post_remove)
+ entry->child_post_remove += gd->reloc_off;
+ /* OPS are fixed in every uclass post_probe function */
+ if (entry->ops)
+ entry->ops += gd->reloc_off;
+ }
+}
+
+void fix_uclass(void)
+{
+ struct uclass_driver *uclass =
+ ll_entry_start(struct uclass_driver, uclass);
+ const int n_ents = ll_entry_count(struct uclass_driver, uclass);
+ struct uclass_driver *entry;
+
+ for (entry = uclass; entry != uclass + n_ents; entry++) {
+ if (entry->post_bind)
+ entry->post_bind += gd->reloc_off;
+ if (entry->pre_unbind)
+ entry->pre_unbind += gd->reloc_off;
+ if (entry->post_probe)
+ entry->post_probe += gd->reloc_off;
+ if (entry->pre_remove)
+ entry->pre_remove += gd->reloc_off;
+ if (entry->init)
+ entry->init += gd->reloc_off;
+ if (entry->destroy)
+ entry->destroy += gd->reloc_off;
+ /* FIXME maybe also need to fix these ops */
+ if (entry->ops)
+ entry->ops += gd->reloc_off;
+ }
+}
+#endif
+
int dm_init(void)
{
int ret;
@@ -47,6 +106,11 @@ int dm_init(void)
}
INIT_LIST_HEAD(&DM_UCLASS_ROOT_NON_CONST);
+#if defined(CONFIG_NEEDS_MANUAL_RELOC)
+ fix_drivers();
+ fix_uclass();
+#endif
+
ret = device_bind_by_name(NULL, false, &root_info, &DM_ROOT_NON_CONST);
if (ret)
return ret;
diff --git a/drivers/crypto/fsl/fsl_blob.c b/drivers/crypto/fsl/fsl_blob.c
index bc0107521c..9923bcbfe9 100644
--- a/drivers/crypto/fsl/fsl_blob.c
+++ b/drivers/crypto/fsl/fsl_blob.c
@@ -11,7 +11,7 @@
#include "desc.h"
#include "jr.h"
-int blob_decrypt(u8 *key_mod, u8 *src, u8 *dst, u8 len)
+int blob_decap(u8 *key_mod, u8 *src, u8 *dst, u32 len)
{
int ret, i = 0;
u32 *desc;
@@ -36,7 +36,7 @@ int blob_decrypt(u8 *key_mod, u8 *src, u8 *dst, u8 len)
return ret;
}
-int blob_encrypt(u8 *key_mod, u8 *src, u8 *dst, u8 len)
+int blob_encap(u8 *key_mod, u8 *src, u8 *dst, u32 len)
{
int ret, i = 0;
u32 *desc;
diff --git a/drivers/crypto/fsl/fsl_hash.c b/drivers/crypto/fsl/fsl_hash.c
index d77f2573d0..c298404f25 100644
--- a/drivers/crypto/fsl/fsl_hash.c
+++ b/drivers/crypto/fsl/fsl_hash.c
@@ -10,6 +10,9 @@
#include "jobdesc.h"
#include "desc.h"
#include "jr.h"
+#include "fsl_hash.h"
+#include <hw_sha.h>
+#include <asm-generic/errno.h>
#define CRYPTO_MAX_ALG_NAME 80
#define SHA1_DIGEST_SIZE 20
@@ -39,6 +42,122 @@ static struct caam_hash_template driver_hash[] = {
},
};
+static enum caam_hash_algos get_hash_type(struct hash_algo *algo)
+{
+ if (!strcmp(algo->name, driver_hash[SHA1].name))
+ return SHA1;
+ else
+ return SHA256;
+}
+
+/* Create the context for progressive hashing using h/w acceleration.
+ *
+ * @ctxp: Pointer to the pointer of the context for hashing
+ * @caam_algo: Enum for SHA1 or SHA256
+ * @return 0 if ok, -ENOMEM on error
+ */
+static int caam_hash_init(void **ctxp, enum caam_hash_algos caam_algo)
+{
+ *ctxp = calloc(1, sizeof(struct sha_ctx));
+ if (*ctxp == NULL) {
+ debug("Cannot allocate memory for context\n");
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+/*
+ * Update sg table for progressive hashing using h/w acceleration
+ *
+ * The context is freed by this function if an error occurs.
+ * We support at most 32 Scatter/Gather Entries.
+ *
+ * @hash_ctx: Pointer to the context for hashing
+ * @buf: Pointer to the buffer being hashed
+ * @size: Size of the buffer being hashed
+ * @is_last: 1 if this is the last update; 0 otherwise
+ * @caam_algo: Enum for SHA1 or SHA256
+ * @return 0 if ok, -EINVAL on error
+ */
+static int caam_hash_update(void *hash_ctx, const void *buf,
+ unsigned int size, int is_last,
+ enum caam_hash_algos caam_algo)
+{
+ uint32_t final = 0;
+ dma_addr_t addr = virt_to_phys((void *)buf);
+ struct sha_ctx *ctx = hash_ctx;
+
+ if (ctx->sg_num >= MAX_SG_32) {
+ free(ctx);
+ return -EINVAL;
+ }
+
+#ifdef CONFIG_PHYS_64BIT
+ ctx->sg_tbl[ctx->sg_num].addr_hi = addr >> 32;
+#else
+ ctx->sg_tbl[ctx->sg_num].addr_hi = 0x0;
+#endif
+ ctx->sg_tbl[ctx->sg_num].addr_lo = addr;
+
+ sec_out32(&ctx->sg_tbl[ctx->sg_num].len_flag,
+ (size & SG_ENTRY_LENGTH_MASK));
+
+ ctx->sg_num++;
+
+ if (is_last) {
+ final = sec_in32(&ctx->sg_tbl[ctx->sg_num - 1].len_flag) |
+ SG_ENTRY_FINAL_BIT;
+ sec_out32(&ctx->sg_tbl[ctx->sg_num - 1].len_flag, final);
+ }
+
+ return 0;
+}
+
+/*
+ * Perform progressive hashing on the given buffer and copy hash at
+ * destination buffer
+ *
+ * The context is freed after completion of hash operation.
+ *
+ * @hash_ctx: Pointer to the context for hashing
+ * @dest_buf: Pointer to the destination buffer where hash is to be copied
+ * @size: Size of the buffer being hashed
+ * @caam_algo: Enum for SHA1 or SHA256
+ * @return 0 if ok, -EINVAL on error
+ */
+static int caam_hash_finish(void *hash_ctx, void *dest_buf,
+ int size, enum caam_hash_algos caam_algo)
+{
+ uint32_t len = 0;
+ struct sha_ctx *ctx = hash_ctx;
+ int i = 0, ret = 0;
+
+ if (size < driver_hash[caam_algo].digestsize) {
+ free(ctx);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < ctx->sg_num; i++)
+ len += (sec_in32(&ctx->sg_tbl[i].len_flag) &
+ SG_ENTRY_LENGTH_MASK);
+
+ inline_cnstr_jobdesc_hash(ctx->sha_desc, (uint8_t *)ctx->sg_tbl, len,
+ ctx->hash,
+ driver_hash[caam_algo].alg_type,
+ driver_hash[caam_algo].digestsize,
+ 1);
+
+ ret = run_descriptor_jr(ctx->sha_desc);
+
+ if (ret)
+ debug("Error %x\n", ret);
+ else
+ memcpy(dest_buf, ctx->hash, sizeof(ctx->hash));
+
+ free(ctx);
+ return ret;
+}
+
int caam_hash(const unsigned char *pbuf, unsigned int buf_len,
unsigned char *pout, enum caam_hash_algos algo)
{
@@ -48,7 +167,7 @@ int caam_hash(const unsigned char *pbuf, unsigned int buf_len,
desc = malloc(sizeof(int) * MAX_CAAM_DESCSIZE);
if (!desc) {
debug("Not enough memory for descriptor allocation\n");
- return -1;
+ return -ENOMEM;
}
inline_cnstr_jobdesc_hash(desc, pbuf, buf_len, pout,
@@ -75,3 +194,20 @@ void hw_sha1(const unsigned char *pbuf, unsigned int buf_len,
if (caam_hash(pbuf, buf_len, pout, SHA1))
printf("CAAM was not setup properly or it is faulty\n");
}
+
+int hw_sha_init(struct hash_algo *algo, void **ctxp)
+{
+ return caam_hash_init(ctxp, get_hash_type(algo));
+}
+
+int hw_sha_update(struct hash_algo *algo, void *ctx, const void *buf,
+ unsigned int size, int is_last)
+{
+ return caam_hash_update(ctx, buf, size, is_last, get_hash_type(algo));
+}
+
+int hw_sha_finish(struct hash_algo *algo, void *ctx, void *dest_buf,
+ int size)
+{
+ return caam_hash_finish(ctx, dest_buf, size, get_hash_type(algo));
+}
diff --git a/drivers/crypto/fsl/fsl_hash.h b/drivers/crypto/fsl/fsl_hash.h
new file mode 100644
index 0000000000..f5be651d7a
--- /dev/null
+++ b/drivers/crypto/fsl/fsl_hash.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2014 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ */
+
+#ifndef _SHA_H
+#define _SHA_H
+
+#include <fsl_sec.h>
+#include <hash.h>
+#include "jr.h"
+
+/* We support at most 32 Scatter/Gather Entries.*/
+#define MAX_SG_32 32
+
+/*
+ * Hash context contains the following fields
+ * @sha_desc: Sha Descriptor
+ * @sg_num: number of entries in sg table
+ * @len: total length of buffer
+ * @sg_tbl: sg entry table
+ * @hash: index to the hash calculated
+ */
+struct sha_ctx {
+ uint32_t sha_desc[64];
+ uint32_t sg_num;
+ uint32_t len;
+ struct sg_entry sg_tbl[MAX_SG_32];
+ u8 hash[HASH_MAX_DIGEST_SIZE];
+};
+
+#endif
diff --git a/drivers/ddr/fsl/arm_ddr_gen3.c b/drivers/ddr/fsl/arm_ddr_gen3.c
index c139da6da9..7160da4ec8 100644
--- a/drivers/ddr/fsl/arm_ddr_gen3.c
+++ b/drivers/ddr/fsl/arm_ddr_gen3.c
@@ -222,7 +222,7 @@ step2:
bus_width = 3 - ((ddr_in32(&ddr->sdram_cfg) & SDRAM_CFG_DBW_MASK)
>> SDRAM_CFG_DBW_SHIFT);
timeout = ((total_gb_size_per_controller << (6 - bus_width)) * 100 /
- (get_ddr_freq(0) >> 20)) << 1;
+ (get_ddr_freq(ctrl_num) >> 20)) << 1;
total_gb_size_per_controller >>= 4; /* shift down to gb size */
debug("total %d GB\n", total_gb_size_per_controller);
debug("Need to wait up to %d * 10ms\n", timeout);
diff --git a/drivers/ddr/fsl/ctrl_regs.c b/drivers/ddr/fsl/ctrl_regs.c
index 03d7ff17dd..690e73dacf 100644
--- a/drivers/ddr/fsl/ctrl_regs.c
+++ b/drivers/ddr/fsl/ctrl_regs.c
@@ -17,8 +17,6 @@
#include <fsl_immap.h>
#include <asm/io.h>
-unsigned int picos_to_mclk(unsigned int picos);
-
/*
* Determine Rtt value.
*
@@ -78,10 +76,11 @@ static inline int fsl_ddr_get_rtt(void)
* 16 for <= 2933MT/s
* 18 for higher
*/
-static inline unsigned int compute_cas_write_latency(void)
+static inline unsigned int compute_cas_write_latency(
+ const unsigned int ctrl_num)
{
unsigned int cwl;
- const unsigned int mclk_ps = get_memory_clk_period_ps();
+ const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num);
if (mclk_ps >= 1250)
cwl = 9;
else if (mclk_ps >= 1070)
@@ -111,10 +110,11 @@ static inline unsigned int compute_cas_write_latency(void)
* 11 if 0.935ns > tCK >= 0.833ns
* 12 if 0.833ns > tCK >= 0.75ns
*/
-static inline unsigned int compute_cas_write_latency(void)
+static inline unsigned int compute_cas_write_latency(
+ const unsigned int ctrl_num)
{
unsigned int cwl;
- const unsigned int mclk_ps = get_memory_clk_period_ps();
+ const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num);
if (mclk_ps >= 2500)
cwl = 5;
@@ -287,7 +287,8 @@ static inline int avoid_odt_overlap(const dimm_params_t *dimm_params)
* Avoid writing for DDR I. The new PQ38 DDR controller
* dreams up non-zero default values to be backwards compatible.
*/
-static void set_timing_cfg_0(fsl_ddr_cfg_regs_t *ddr,
+static void set_timing_cfg_0(const unsigned int ctrl_num,
+ fsl_ddr_cfg_regs_t *ddr,
const memctl_options_t *popts,
const dimm_params_t *dimm_params)
{
@@ -306,7 +307,7 @@ static void set_timing_cfg_0(fsl_ddr_cfg_regs_t *ddr,
/* Mode register set cycle time (tMRD). */
unsigned char tmrd_mclk;
#if defined(CONFIG_SYS_FSL_DDR4) || defined(CONFIG_SYS_FSL_DDR3)
- const unsigned int mclk_ps = get_memory_clk_period_ps();
+ const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num);
#endif
#ifdef CONFIG_SYS_FSL_DDR4
@@ -314,15 +315,15 @@ static void set_timing_cfg_0(fsl_ddr_cfg_regs_t *ddr,
int txp = max((int)mclk_ps * 4, 6000); /* unit=ps */
trwt_mclk = 2;
twrt_mclk = 1;
- act_pd_exit_mclk = picos_to_mclk(txp);
+ act_pd_exit_mclk = picos_to_mclk(ctrl_num, txp);
pre_pd_exit_mclk = act_pd_exit_mclk;
/*
* MRS_CYC = max(tMRD, tMOD)
* tMRD = 8nCK, tMOD = max(24nCK, 15ns)
*/
- tmrd_mclk = max(24U, picos_to_mclk(15000));
+ tmrd_mclk = max(24U, picos_to_mclk(ctrl_num, 15000));
#elif defined(CONFIG_SYS_FSL_DDR3)
- unsigned int data_rate = get_ddr_freq(0);
+ unsigned int data_rate = get_ddr_freq(ctrl_num);
int txp;
unsigned int ip_rev;
int odt_overlap;
@@ -344,7 +345,8 @@ static void set_timing_cfg_0(fsl_ddr_cfg_regs_t *ddr,
* tMRD = 4nCK (8nCK for RDIMM)
* tMOD = max(12nCK, 15ns)
*/
- tmrd_mclk = max((unsigned int)12, picos_to_mclk(15000));
+ tmrd_mclk = max((unsigned int)12,
+ picos_to_mclk(ctrl_num, 15000));
} else {
/*
* MRS_CYC = tMRD
@@ -388,7 +390,7 @@ static void set_timing_cfg_0(fsl_ddr_cfg_regs_t *ddr,
taxpd_mclk = 1;
} else {
/* act_pd_exit_mclk = tXARD, see above */
- act_pd_exit_mclk = picos_to_mclk(txp);
+ act_pd_exit_mclk = picos_to_mclk(ctrl_num, txp);
/* Mode register MR0[A12] is '1' - fast exit */
pre_pd_exit_mclk = act_pd_exit_mclk;
taxpd_mclk = 1;
@@ -424,11 +426,12 @@ static void set_timing_cfg_0(fsl_ddr_cfg_regs_t *ddr,
#endif /* !defined(CONFIG_SYS_FSL_DDR1) */
/* DDR SDRAM Timing Configuration 3 (TIMING_CFG_3) */
-static void set_timing_cfg_3(fsl_ddr_cfg_regs_t *ddr,
- const memctl_options_t *popts,
- const common_timing_params_t *common_dimm,
- unsigned int cas_latency,
- unsigned int additive_latency)
+static void set_timing_cfg_3(const unsigned int ctrl_num,
+ fsl_ddr_cfg_regs_t *ddr,
+ const memctl_options_t *popts,
+ const common_timing_params_t *common_dimm,
+ unsigned int cas_latency,
+ unsigned int additive_latency)
{
/* Extended precharge to activate interval (tRP) */
unsigned int ext_pretoact = 0;
@@ -447,18 +450,18 @@ static void set_timing_cfg_3(fsl_ddr_cfg_regs_t *ddr,
/* Control Adjust */
unsigned int cntl_adj = 0;
- ext_pretoact = picos_to_mclk(common_dimm->trp_ps) >> 4;
- ext_acttopre = picos_to_mclk(common_dimm->tras_ps) >> 4;
- ext_acttorw = picos_to_mclk(common_dimm->trcd_ps) >> 4;
+ ext_pretoact = picos_to_mclk(ctrl_num, common_dimm->trp_ps) >> 4;
+ ext_acttopre = picos_to_mclk(ctrl_num, common_dimm->tras_ps) >> 4;
+ ext_acttorw = picos_to_mclk(ctrl_num, common_dimm->trcd_ps) >> 4;
ext_caslat = (2 * cas_latency - 1) >> 4;
ext_add_lat = additive_latency >> 4;
#ifdef CONFIG_SYS_FSL_DDR4
- ext_refrec = (picos_to_mclk(common_dimm->trfc1_ps) - 8) >> 4;
+ ext_refrec = (picos_to_mclk(ctrl_num, common_dimm->trfc1_ps) - 8) >> 4;
#else
- ext_refrec = (picos_to_mclk(common_dimm->trfc_ps) - 8) >> 4;
+ ext_refrec = (picos_to_mclk(ctrl_num, common_dimm->trfc_ps) - 8) >> 4;
/* ext_wrrec only deals with 16 clock and above, or 14 with OTF */
#endif
- ext_wrrec = (picos_to_mclk(common_dimm->twr_ps) +
+ ext_wrrec = (picos_to_mclk(ctrl_num, common_dimm->twr_ps) +
(popts->otf_burst_chop_en ? 2 : 0)) >> 4;
ddr->timing_cfg_3 = (0
@@ -475,10 +478,11 @@ static void set_timing_cfg_3(fsl_ddr_cfg_regs_t *ddr,
}
/* DDR SDRAM Timing Configuration 1 (TIMING_CFG_1) */
-static void set_timing_cfg_1(fsl_ddr_cfg_regs_t *ddr,
- const memctl_options_t *popts,
- const common_timing_params_t *common_dimm,
- unsigned int cas_latency)
+static void set_timing_cfg_1(const unsigned int ctrl_num,
+ fsl_ddr_cfg_regs_t *ddr,
+ const memctl_options_t *popts,
+ const common_timing_params_t *common_dimm,
+ unsigned int cas_latency)
{
/* Precharge-to-activate interval (tRP) */
unsigned char pretoact_mclk;
@@ -510,9 +514,9 @@ static void set_timing_cfg_1(fsl_ddr_cfg_regs_t *ddr,
1, 2, 3, 4, 5, 6, 7, 8, 10, 10, 12, 12, 14, 14, 0, 0};
#endif
- pretoact_mclk = picos_to_mclk(common_dimm->trp_ps);
- acttopre_mclk = picos_to_mclk(common_dimm->tras_ps);
- acttorw_mclk = picos_to_mclk(common_dimm->trcd_ps);
+ pretoact_mclk = picos_to_mclk(ctrl_num, common_dimm->trp_ps);
+ acttopre_mclk = picos_to_mclk(ctrl_num, common_dimm->tras_ps);
+ acttorw_mclk = picos_to_mclk(ctrl_num, common_dimm->trcd_ps);
/*
* Translate CAS Latency to a DDR controller field value:
@@ -547,19 +551,19 @@ static void set_timing_cfg_1(fsl_ddr_cfg_regs_t *ddr,
#endif
#ifdef CONFIG_SYS_FSL_DDR4
- refrec_ctrl = picos_to_mclk(common_dimm->trfc1_ps) - 8;
- wrrec_mclk = picos_to_mclk(common_dimm->twr_ps);
- acttoact_mclk = max(picos_to_mclk(common_dimm->trrds_ps), 4U);
- wrtord_mclk = max(2U, picos_to_mclk(2500));
+ refrec_ctrl = picos_to_mclk(ctrl_num, common_dimm->trfc1_ps) - 8;
+ wrrec_mclk = picos_to_mclk(ctrl_num, common_dimm->twr_ps);
+ acttoact_mclk = max(picos_to_mclk(ctrl_num, common_dimm->trrds_ps), 4U);
+ wrtord_mclk = max(2U, picos_to_mclk(ctrl_num, 2500));
if ((wrrec_mclk < 1) || (wrrec_mclk > 24))
printf("Error: WRREC doesn't support %d clocks\n", wrrec_mclk);
else
wrrec_mclk = wrrec_table[wrrec_mclk - 1];
#else
- refrec_ctrl = picos_to_mclk(common_dimm->trfc_ps) - 8;
- wrrec_mclk = picos_to_mclk(common_dimm->twr_ps);
- acttoact_mclk = picos_to_mclk(common_dimm->trrd_ps);
- wrtord_mclk = picos_to_mclk(common_dimm->twtr_ps);
+ refrec_ctrl = picos_to_mclk(ctrl_num, common_dimm->trfc_ps) - 8;
+ wrrec_mclk = picos_to_mclk(ctrl_num, common_dimm->twr_ps);
+ acttoact_mclk = picos_to_mclk(ctrl_num, common_dimm->trrd_ps);
+ wrtord_mclk = picos_to_mclk(ctrl_num, common_dimm->twtr_ps);
if ((wrrec_mclk < 1) || (wrrec_mclk > 16))
printf("Error: WRREC doesn't support %d clocks\n", wrrec_mclk);
else
@@ -602,11 +606,12 @@ static void set_timing_cfg_1(fsl_ddr_cfg_regs_t *ddr,
}
/* DDR SDRAM Timing Configuration 2 (TIMING_CFG_2) */
-static void set_timing_cfg_2(fsl_ddr_cfg_regs_t *ddr,
- const memctl_options_t *popts,
- const common_timing_params_t *common_dimm,
- unsigned int cas_latency,
- unsigned int additive_latency)
+static void set_timing_cfg_2(const unsigned int ctrl_num,
+ fsl_ddr_cfg_regs_t *ddr,
+ const memctl_options_t *popts,
+ const common_timing_params_t *common_dimm,
+ unsigned int cas_latency,
+ unsigned int additive_latency)
{
/* Additive latency */
unsigned char add_lat_mclk;
@@ -623,7 +628,7 @@ static void set_timing_cfg_2(fsl_ddr_cfg_regs_t *ddr,
/* Window for four activates (tFAW) */
unsigned short four_act;
#ifdef CONFIG_SYS_FSL_DDR3
- const unsigned int mclk_ps = get_memory_clk_period_ps();
+ const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num);
#endif
/* FIXME add check that this must be less than acttorw_mclk */
@@ -641,13 +646,13 @@ static void set_timing_cfg_2(fsl_ddr_cfg_regs_t *ddr,
#elif defined(CONFIG_SYS_FSL_DDR2)
wr_lat = cas_latency - 1;
#else
- wr_lat = compute_cas_write_latency();
+ wr_lat = compute_cas_write_latency(ctrl_num);
#endif
#ifdef CONFIG_SYS_FSL_DDR4
- rd_to_pre = picos_to_mclk(7500);
+ rd_to_pre = picos_to_mclk(ctrl_num, 7500);
#else
- rd_to_pre = picos_to_mclk(common_dimm->trtp_ps);
+ rd_to_pre = picos_to_mclk(ctrl_num, common_dimm->trtp_ps);
#endif
/*
* JEDEC has some min requirements for tRTP
@@ -665,19 +670,20 @@ static void set_timing_cfg_2(fsl_ddr_cfg_regs_t *ddr,
wr_data_delay = popts->write_data_delay;
#ifdef CONFIG_SYS_FSL_DDR4
cpo = 0;
- cke_pls = max(3U, picos_to_mclk(5000));
+ cke_pls = max(3U, picos_to_mclk(ctrl_num, 5000));
#elif defined(CONFIG_SYS_FSL_DDR3)
/*
* cke pulse = max(3nCK, 7.5ns) for DDR3-800
* max(3nCK, 5.625ns) for DDR3-1066, 1333
* max(3nCK, 5ns) for DDR3-1600, 1866, 2133
*/
- cke_pls = max(3U, picos_to_mclk(mclk_ps > 1870 ? 7500 :
- (mclk_ps > 1245 ? 5625 : 5000)));
+ cke_pls = max(3U, picos_to_mclk(ctrl_num, mclk_ps > 1870 ? 7500 :
+ (mclk_ps > 1245 ? 5625 : 5000)));
#else
cke_pls = FSL_DDR_MIN_TCKE_PULSE_WIDTH_DDR;
#endif
- four_act = picos_to_mclk(popts->tfaw_window_four_activates_ps);
+ four_act = picos_to_mclk(ctrl_num,
+ popts->tfaw_window_four_activates_ps);
ddr->timing_cfg_2 = (0
| ((add_lat_mclk & 0xf) << 28)
@@ -818,7 +824,8 @@ static void set_ddr_sdram_cfg(fsl_ddr_cfg_regs_t *ddr,
}
/* DDR SDRAM control configuration 2 (DDR_SDRAM_CFG_2) */
-static void set_ddr_sdram_cfg_2(fsl_ddr_cfg_regs_t *ddr,
+static void set_ddr_sdram_cfg_2(const unsigned int ctrl_num,
+ fsl_ddr_cfg_regs_t *ddr,
const memctl_options_t *popts,
const unsigned int unq_mrs_en)
{
@@ -865,7 +872,7 @@ static void set_ddr_sdram_cfg_2(fsl_ddr_cfg_regs_t *ddr,
#endif
#if (CONFIG_SYS_FSL_DDR_VER >= FSL_DDR_VER_4_7)
- slow = get_ddr_freq(0) < 1249000000;
+ slow = get_ddr_freq(ctrl_num) < 1249000000;
#endif
if (popts->registered_dimm_en) {
@@ -915,7 +922,8 @@ static void set_ddr_sdram_cfg_2(fsl_ddr_cfg_regs_t *ddr,
#ifdef CONFIG_SYS_FSL_DDR4
/* DDR SDRAM Mode configuration 2 (DDR_SDRAM_MODE_2) */
-static void set_ddr_sdram_mode_2(fsl_ddr_cfg_regs_t *ddr,
+static void set_ddr_sdram_mode_2(const unsigned int ctrl_num,
+ fsl_ddr_cfg_regs_t *ddr,
const memctl_options_t *popts,
const common_timing_params_t *common_dimm,
const unsigned int unq_mrs_en)
@@ -926,10 +934,10 @@ static void set_ddr_sdram_mode_2(fsl_ddr_cfg_regs_t *ddr,
unsigned int wr_crc = 0; /* Disable */
unsigned int rtt_wr = 0; /* Rtt_WR - dynamic ODT off */
unsigned int srt = 0; /* self-refresh temerature, normal range */
- unsigned int cwl = compute_cas_write_latency() - 9;
+ unsigned int cwl = compute_cas_write_latency(ctrl_num) - 9;
unsigned int mpr = 0; /* serial */
unsigned int wc_lat;
- const unsigned int mclk_ps = get_memory_clk_period_ps();
+ const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num);
if (popts->rtt_override)
rtt_wr = popts->rtt_wr_override_value;
@@ -1002,7 +1010,8 @@ static void set_ddr_sdram_mode_2(fsl_ddr_cfg_regs_t *ddr,
}
#elif defined(CONFIG_SYS_FSL_DDR3)
/* DDR SDRAM Mode configuration 2 (DDR_SDRAM_MODE_2) */
-static void set_ddr_sdram_mode_2(fsl_ddr_cfg_regs_t *ddr,
+static void set_ddr_sdram_mode_2(const unsigned int ctrl_num,
+ fsl_ddr_cfg_regs_t *ddr,
const memctl_options_t *popts,
const common_timing_params_t *common_dimm,
const unsigned int unq_mrs_en)
@@ -1013,7 +1022,7 @@ static void set_ddr_sdram_mode_2(fsl_ddr_cfg_regs_t *ddr,
unsigned int rtt_wr = 0; /* Rtt_WR - dynamic ODT off */
unsigned int srt = 0; /* self-refresh temerature, normal range */
unsigned int asr = 0; /* auto self-refresh disable */
- unsigned int cwl = compute_cas_write_latency() - 5;
+ unsigned int cwl = compute_cas_write_latency(ctrl_num) - 5;
unsigned int pasr = 0; /* partial array self refresh disable */
if (popts->rtt_override)
@@ -1077,7 +1086,8 @@ static void set_ddr_sdram_mode_2(fsl_ddr_cfg_regs_t *ddr,
#else /* for DDR2 and DDR1 */
/* DDR SDRAM Mode configuration 2 (DDR_SDRAM_MODE_2) */
-static void set_ddr_sdram_mode_2(fsl_ddr_cfg_regs_t *ddr,
+static void set_ddr_sdram_mode_2(const unsigned int ctrl_num,
+ fsl_ddr_cfg_regs_t *ddr,
const memctl_options_t *popts,
const common_timing_params_t *common_dimm,
const unsigned int unq_mrs_en)
@@ -1144,7 +1154,8 @@ static void set_ddr_sdram_mode_9(fsl_ddr_cfg_regs_t *ddr,
}
/* DDR SDRAM Mode configuration 10 (DDR_SDRAM_MODE_10) */
-static void set_ddr_sdram_mode_10(fsl_ddr_cfg_regs_t *ddr,
+static void set_ddr_sdram_mode_10(const unsigned int ctrl_num,
+ fsl_ddr_cfg_regs_t *ddr,
const memctl_options_t *popts,
const common_timing_params_t *common_dimm,
const unsigned int unq_mrs_en)
@@ -1152,7 +1163,7 @@ static void set_ddr_sdram_mode_10(fsl_ddr_cfg_regs_t *ddr,
int i;
unsigned short esdmode6 = 0; /* Extended SDRAM mode 6 */
unsigned short esdmode7 = 0; /* Extended SDRAM mode 7 */
- unsigned int tccdl_min = picos_to_mclk(common_dimm->tccdl_ps);
+ unsigned int tccdl_min = picos_to_mclk(ctrl_num, common_dimm->tccdl_ps);
esdmode6 = ((tccdl_min - 4) & 0x7) << 10;
@@ -1196,14 +1207,15 @@ static void set_ddr_sdram_mode_10(fsl_ddr_cfg_regs_t *ddr,
#endif
/* DDR SDRAM Interval Configuration (DDR_SDRAM_INTERVAL) */
-static void set_ddr_sdram_interval(fsl_ddr_cfg_regs_t *ddr,
- const memctl_options_t *popts,
- const common_timing_params_t *common_dimm)
+static void set_ddr_sdram_interval(const unsigned int ctrl_num,
+ fsl_ddr_cfg_regs_t *ddr,
+ const memctl_options_t *popts,
+ const common_timing_params_t *common_dimm)
{
unsigned int refint; /* Refresh interval */
unsigned int bstopre; /* Precharge interval */
- refint = picos_to_mclk(common_dimm->refresh_rate_ps);
+ refint = picos_to_mclk(ctrl_num, common_dimm->refresh_rate_ps);
bstopre = popts->bstopre;
@@ -1217,7 +1229,8 @@ static void set_ddr_sdram_interval(fsl_ddr_cfg_regs_t *ddr,
#ifdef CONFIG_SYS_FSL_DDR4
/* DDR SDRAM Mode configuration set (DDR_SDRAM_MODE) */
-static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr,
+static void set_ddr_sdram_mode(const unsigned int ctrl_num,
+ fsl_ddr_cfg_regs_t *ddr,
const memctl_options_t *popts,
const common_timing_params_t *common_dimm,
unsigned int cas_latency,
@@ -1292,7 +1305,7 @@ static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr,
* 1=fast exit DLL on (tXP)
*/
- wr_mclk = picos_to_mclk(common_dimm->twr_ps);
+ wr_mclk = picos_to_mclk(ctrl_num, common_dimm->twr_ps);
if (wr_mclk <= 24) {
wr = wr_table[wr_mclk - 10];
} else {
@@ -1387,7 +1400,8 @@ static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr,
#elif defined(CONFIG_SYS_FSL_DDR3)
/* DDR SDRAM Mode configuration set (DDR_SDRAM_MODE) */
-static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr,
+static void set_ddr_sdram_mode(const unsigned int ctrl_num,
+ fsl_ddr_cfg_regs_t *ddr,
const memctl_options_t *popts,
const common_timing_params_t *common_dimm,
unsigned int cas_latency,
@@ -1466,7 +1480,7 @@ static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr,
*/
dll_on = 1;
- wr_mclk = picos_to_mclk(common_dimm->twr_ps);
+ wr_mclk = picos_to_mclk(ctrl_num, common_dimm->twr_ps);
if (wr_mclk <= 16) {
wr = wr_table[wr_mclk - 5];
} else {
@@ -1582,7 +1596,8 @@ static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr,
#else /* !CONFIG_SYS_FSL_DDR3 */
/* DDR SDRAM Mode configuration set (DDR_SDRAM_MODE) */
-static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr,
+static void set_ddr_sdram_mode(const unsigned int ctrl_num,
+ fsl_ddr_cfg_regs_t *ddr,
const memctl_options_t *popts,
const common_timing_params_t *common_dimm,
unsigned int cas_latency,
@@ -1654,7 +1669,7 @@ static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr,
#if defined(CONFIG_SYS_FSL_DDR1)
wr = 0; /* Historical */
#elif defined(CONFIG_SYS_FSL_DDR2)
- wr = picos_to_mclk(common_dimm->twr_ps);
+ wr = picos_to_mclk(ctrl_num, common_dimm->twr_ps);
#endif
dll_res = 0;
mode = 0;
@@ -1842,15 +1857,16 @@ static void set_timing_cfg_6(fsl_ddr_cfg_regs_t *ddr)
debug("FSLDDR: timing_cfg_6 = 0x%08x\n", ddr->timing_cfg_6);
}
-static void set_timing_cfg_7(fsl_ddr_cfg_regs_t *ddr,
- const common_timing_params_t *common_dimm)
+static void set_timing_cfg_7(const unsigned int ctrl_num,
+ fsl_ddr_cfg_regs_t *ddr,
+ const common_timing_params_t *common_dimm)
{
unsigned int txpr, tcksre, tcksrx;
unsigned int cke_rst, cksre, cksrx, par_lat, cs_to_cmd;
- txpr = max(5U, picos_to_mclk(common_dimm->trfc1_ps + 10000));
- tcksre = max(5U, picos_to_mclk(10000));
- tcksrx = max(5U, picos_to_mclk(10000));
+ txpr = max(5U, picos_to_mclk(ctrl_num, common_dimm->trfc1_ps + 10000));
+ tcksre = max(5U, picos_to_mclk(ctrl_num, 10000));
+ tcksrx = max(5U, picos_to_mclk(ctrl_num, 10000));
par_lat = 0;
cs_to_cmd = 0;
@@ -1883,14 +1899,15 @@ static void set_timing_cfg_7(fsl_ddr_cfg_regs_t *ddr,
debug("FSLDDR: timing_cfg_7 = 0x%08x\n", ddr->timing_cfg_7);
}
-static void set_timing_cfg_8(fsl_ddr_cfg_regs_t *ddr,
+static void set_timing_cfg_8(const unsigned int ctrl_num,
+ fsl_ddr_cfg_regs_t *ddr,
const memctl_options_t *popts,
const common_timing_params_t *common_dimm,
unsigned int cas_latency)
{
unsigned int rwt_bg, wrt_bg, rrt_bg, wwt_bg;
unsigned int acttoact_bg, wrtord_bg, pre_all_rec;
- unsigned int tccdl = picos_to_mclk(common_dimm->tccdl_ps);
+ unsigned int tccdl = picos_to_mclk(ctrl_num, common_dimm->tccdl_ps);
unsigned int wr_lat = ((ddr->timing_cfg_2 & 0x00780000) >> 19) +
((ddr->timing_cfg_2 & 0x00040000) >> 14);
@@ -1911,11 +1928,11 @@ static void set_timing_cfg_8(fsl_ddr_cfg_regs_t *ddr,
wwt_bg = tccdl - 4;
} else {
rrt_bg = tccdl - 2;
- wwt_bg = tccdl - 4;
+ wwt_bg = tccdl - 2;
}
- acttoact_bg = picos_to_mclk(common_dimm->trrdl_ps);
- wrtord_bg = max(4U, picos_to_mclk(7500));
+ acttoact_bg = picos_to_mclk(ctrl_num, common_dimm->trrdl_ps);
+ wrtord_bg = max(4U, picos_to_mclk(ctrl_num, 7500));
if (popts->otf_burst_chop_en)
wrtord_bg += 2;
@@ -2147,7 +2164,8 @@ check_fsl_memctl_config_regs(const fsl_ddr_cfg_regs_t *ddr)
}
unsigned int
-compute_fsl_memctl_config_regs(const memctl_options_t *popts,
+compute_fsl_memctl_config_regs(const unsigned int ctrl_num,
+ const memctl_options_t *popts,
fsl_ddr_cfg_regs_t *ddr,
const common_timing_params_t *common_dimm,
const dimm_params_t *dimm_params,
@@ -2319,14 +2337,14 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,
set_ddr_eor(ddr, popts);
#if !defined(CONFIG_SYS_FSL_DDR1)
- set_timing_cfg_0(ddr, popts, dimm_params);
+ set_timing_cfg_0(ctrl_num, ddr, popts, dimm_params);
#endif
- set_timing_cfg_3(ddr, popts, common_dimm, cas_latency,
+ set_timing_cfg_3(ctrl_num, ddr, popts, common_dimm, cas_latency,
additive_latency);
- set_timing_cfg_1(ddr, popts, common_dimm, cas_latency);
- set_timing_cfg_2(ddr, popts, common_dimm,
- cas_latency, additive_latency);
+ set_timing_cfg_1(ctrl_num, ddr, popts, common_dimm, cas_latency);
+ set_timing_cfg_2(ctrl_num, ddr, popts, common_dimm,
+ cas_latency, additive_latency);
set_ddr_cdr1(ddr, popts);
set_ddr_cdr2(ddr, popts);
@@ -2338,15 +2356,15 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,
if ((ip_rev > 0x40700) && (popts->cswl_override != 0))
ddr->debug[18] = popts->cswl_override;
- set_ddr_sdram_cfg_2(ddr, popts, unq_mrs_en);
- set_ddr_sdram_mode(ddr, popts, common_dimm,
- cas_latency, additive_latency, unq_mrs_en);
- set_ddr_sdram_mode_2(ddr, popts, common_dimm, unq_mrs_en);
+ set_ddr_sdram_cfg_2(ctrl_num, ddr, popts, unq_mrs_en);
+ set_ddr_sdram_mode(ctrl_num, ddr, popts, common_dimm,
+ cas_latency, additive_latency, unq_mrs_en);
+ set_ddr_sdram_mode_2(ctrl_num, ddr, popts, common_dimm, unq_mrs_en);
#ifdef CONFIG_SYS_FSL_DDR4
set_ddr_sdram_mode_9(ddr, popts, common_dimm, unq_mrs_en);
- set_ddr_sdram_mode_10(ddr, popts, common_dimm, unq_mrs_en);
+ set_ddr_sdram_mode_10(ctrl_num, ddr, popts, common_dimm, unq_mrs_en);
#endif
- set_ddr_sdram_interval(ddr, popts, common_dimm);
+ set_ddr_sdram_interval(ctrl_num, ddr, popts, common_dimm);
set_ddr_data_init(ddr);
set_ddr_sdram_clk_cntl(ddr, popts);
set_ddr_init_addr(ddr);
@@ -2356,8 +2374,8 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,
#ifdef CONFIG_SYS_FSL_DDR4
set_ddr_sdram_cfg_3(ddr, popts);
set_timing_cfg_6(ddr);
- set_timing_cfg_7(ddr, common_dimm);
- set_timing_cfg_8(ddr, popts, common_dimm, cas_latency);
+ set_timing_cfg_7(ctrl_num, ddr, common_dimm);
+ set_timing_cfg_8(ctrl_num, ddr, popts, common_dimm, cas_latency);
set_timing_cfg_9(ddr);
set_ddr_dq_mapping(ddr, dimm_params);
#endif
@@ -2372,7 +2390,11 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,
#ifdef CONFIG_SYS_FSL_DDR_EMU
/* disble DDR training for emulator */
ddr->debug[2] = 0x00000400;
- ddr->debug[4] = 0xff800000;
+ ddr->debug[4] = 0xff800800;
+ ddr->debug[5] = 0x08000800;
+ ddr->debug[6] = 0x08000800;
+ ddr->debug[7] = 0x08000800;
+ ddr->debug[8] = 0x08000800;
#endif
#ifdef CONFIG_SYS_FSL_ERRATUM_A004508
if ((ip_rev >= 0x40000) && (ip_rev < 0x40400))
diff --git a/drivers/ddr/fsl/ddr1_dimm_params.c b/drivers/ddr/fsl/ddr1_dimm_params.c
index 7df27b90b7..7f1c3afcc4 100644
--- a/drivers/ddr/fsl/ddr1_dimm_params.c
+++ b/drivers/ddr/fsl/ddr1_dimm_params.c
@@ -228,10 +228,10 @@ compute_derated_DDR1_CAS_latency(unsigned int mclk_ps)
*
* FIXME: use #define for the retvals
*/
-unsigned int
-ddr_compute_dimm_parameters(const ddr1_spd_eeprom_t *spd,
- dimm_params_t *pdimm,
- unsigned int dimm_number)
+unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num,
+ const ddr1_spd_eeprom_t *spd,
+ dimm_params_t *pdimm,
+ unsigned int dimm_number)
{
unsigned int retval;
@@ -311,16 +311,16 @@ ddr_compute_dimm_parameters(const ddr1_spd_eeprom_t *spd,
& ~(1 << pdimm->caslat_x_minus_1));
/* Compute CAS latencies below that defined by SPD */
- pdimm->caslat_lowest_derated
- = compute_derated_DDR1_CAS_latency(get_memory_clk_period_ps());
+ pdimm->caslat_lowest_derated = compute_derated_DDR1_CAS_latency(
+ get_memory_clk_period_ps(ctrl_num));
/* Compute timing parameters */
pdimm->trcd_ps = spd->trcd * 250;
pdimm->trp_ps = spd->trp * 250;
pdimm->tras_ps = spd->tras * 1000;
- pdimm->twr_ps = mclk_to_picos(3);
- pdimm->twtr_ps = mclk_to_picos(1);
+ pdimm->twr_ps = mclk_to_picos(ctrl_num, 3);
+ pdimm->twtr_ps = mclk_to_picos(ctrl_num, 1);
pdimm->trfc_ps = compute_trfc_ps_from_spd(0, spd->trfc);
pdimm->trrd_ps = spd->trrd * 250;
@@ -335,7 +335,7 @@ ddr_compute_dimm_parameters(const ddr1_spd_eeprom_t *spd,
pdimm->tdh_ps
= convert_bcd_hundredths_to_cycle_time_ps(spd->data_hold);
- pdimm->trtp_ps = mclk_to_picos(2); /* By the book. */
+ pdimm->trtp_ps = mclk_to_picos(ctrl_num, 2); /* By the book. */
pdimm->tdqsq_max_ps = spd->tdqsq * 10;
pdimm->tqhs_ps = spd->tqhs * 10;
diff --git a/drivers/ddr/fsl/ddr2_dimm_params.c b/drivers/ddr/fsl/ddr2_dimm_params.c
index d865df78a8..49cc1a07ff 100644
--- a/drivers/ddr/fsl/ddr2_dimm_params.c
+++ b/drivers/ddr/fsl/ddr2_dimm_params.c
@@ -211,10 +211,10 @@ compute_derated_DDR2_CAS_latency(unsigned int mclk_ps)
*
* FIXME: use #define for the retvals
*/
-unsigned int
-ddr_compute_dimm_parameters(const ddr2_spd_eeprom_t *spd,
- dimm_params_t *pdimm,
- unsigned int dimm_number)
+unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num,
+ const ddr2_spd_eeprom_t *spd,
+ dimm_params_t *pdimm,
+ unsigned int dimm_number)
{
unsigned int retval;
@@ -310,8 +310,8 @@ ddr_compute_dimm_parameters(const ddr2_spd_eeprom_t *spd,
& ~(1 << pdimm->caslat_x_minus_1));
/* Compute CAS latencies below that defined by SPD */
- pdimm->caslat_lowest_derated
- = compute_derated_DDR2_CAS_latency(get_memory_clk_period_ps());
+ pdimm->caslat_lowest_derated = compute_derated_DDR2_CAS_latency(
+ get_memory_clk_period_ps(ctrl_num));
/* Compute timing parameters */
pdimm->trcd_ps = spd->trcd * 250;
diff --git a/drivers/ddr/fsl/ddr3_dimm_params.c b/drivers/ddr/fsl/ddr3_dimm_params.c
index a4b8c101f5..69177150ec 100644
--- a/drivers/ddr/fsl/ddr3_dimm_params.c
+++ b/drivers/ddr/fsl/ddr3_dimm_params.c
@@ -83,10 +83,10 @@ compute_ranksize(const ddr3_spd_eeprom_t *spd)
* Writes the results to the dimm_params_t structure pointed by pdimm.
*
*/
-unsigned int
-ddr_compute_dimm_parameters(const ddr3_spd_eeprom_t *spd,
- dimm_params_t *pdimm,
- unsigned int dimm_number)
+unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num,
+ const ddr3_spd_eeprom_t *spd,
+ dimm_params_t *pdimm,
+ unsigned int dimm_number)
{
unsigned int retval;
unsigned int mtb_ps;
diff --git a/drivers/ddr/fsl/ddr4_dimm_params.c b/drivers/ddr/fsl/ddr4_dimm_params.c
index aaddc8fa08..bbfb4ee417 100644
--- a/drivers/ddr/fsl/ddr4_dimm_params.c
+++ b/drivers/ddr/fsl/ddr4_dimm_params.c
@@ -119,10 +119,10 @@ compute_ranksize(const struct ddr4_spd_eeprom_s *spd)
* Writes the results to the dimm_params_t structure pointed by pdimm.
*
*/
-unsigned int
-ddr_compute_dimm_parameters(const generic_spd_eeprom_t *spd,
- dimm_params_t *pdimm,
- unsigned int dimm_number)
+unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num,
+ const generic_spd_eeprom_t *spd,
+ dimm_params_t *pdimm,
+ unsigned int dimm_number)
{
unsigned int retval;
int i;
diff --git a/drivers/ddr/fsl/fsl_ddr_gen4.c b/drivers/ddr/fsl/fsl_ddr_gen4.c
index 4eef047343..d9fce7d2f3 100644
--- a/drivers/ddr/fsl/fsl_ddr_gen4.c
+++ b/drivers/ddr/fsl/fsl_ddr_gen4.c
@@ -32,24 +32,44 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
u32 temp_sdram_cfg;
u32 total_gb_size_per_controller;
int timeout;
+#if defined(CONFIG_SYS_FSL_ERRATUM_A008336) || \
+ defined(CONFIG_SYS_FSL_ERRATUM_A008514)
+ u32 *eddrtqcr1;
+#endif
switch (ctrl_num) {
case 0:
ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
+#if defined(CONFIG_SYS_FSL_ERRATUM_A008336) || \
+ defined(CONFIG_SYS_FSL_ERRATUM_A008514)
+ eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR_ADDR + 0x800;
+#endif
break;
#if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1)
case 1:
ddr = (void *)CONFIG_SYS_FSL_DDR2_ADDR;
+#if defined(CONFIG_SYS_FSL_ERRATUM_A008336) || \
+ defined(CONFIG_SYS_FSL_ERRATUM_A008514)
+ eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR2_ADDR + 0x800;
+#endif
break;
#endif
#if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2)
case 2:
ddr = (void *)CONFIG_SYS_FSL_DDR3_ADDR;
+#if defined(CONFIG_SYS_FSL_ERRATUM_A008336) || \
+ defined(CONFIG_SYS_FSL_ERRATUM_A008514)
+ eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR3_ADDR + 0x800;
+#endif
break;
#endif
#if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3)
case 3:
ddr = (void *)CONFIG_SYS_FSL_DDR4_ADDR;
+#if defined(CONFIG_SYS_FSL_ERRATUM_A008336) || \
+ defined(CONFIG_SYS_FSL_ERRATUM_A008514)
+ eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR4_ADDR + 0x800;
+#endif
break;
#endif
default:
@@ -60,6 +80,20 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
if (step == 2)
goto step2;
+#ifdef CONFIG_SYS_FSL_ERRATUM_A008336
+#ifdef CONFIG_LS2085A
+ /* A008336 only applies to general DDR controllers */
+ if ((ctrl_num == 0) || (ctrl_num == 1))
+#endif
+ ddr_out32(eddrtqcr1, 0x63b30002);
+#endif
+#ifdef CONFIG_SYS_FSL_ERRATUM_A008514
+#ifdef CONFIG_LS2085A
+ /* A008514 only applies to DP-DDR controler */
+ if (ctrl_num == 2)
+#endif
+ ddr_out32(eddrtqcr1, 0x63b20002);
+#endif
if (regs->ddr_eor)
ddr_out32(&ddr->eor, regs->ddr_eor);
@@ -253,7 +287,7 @@ step2:
bus_width = 3 - ((ddr_in32(&ddr->sdram_cfg) & SDRAM_CFG_DBW_MASK)
>> SDRAM_CFG_DBW_SHIFT);
timeout = ((total_gb_size_per_controller << (6 - bus_width)) * 100 /
- (get_ddr_freq(0) >> 20)) << 2;
+ (get_ddr_freq(ctrl_num) >> 20)) << 2;
total_gb_size_per_controller >>= 4; /* shift down to gb size */
debug("total %d GB\n", total_gb_size_per_controller);
debug("Need to wait up to %d * 10ms\n", timeout);
diff --git a/drivers/ddr/fsl/lc_common_dimm_params.c b/drivers/ddr/fsl/lc_common_dimm_params.c
index 73db444615..b295344c4d 100644
--- a/drivers/ddr/fsl/lc_common_dimm_params.c
+++ b/drivers/ddr/fsl/lc_common_dimm_params.c
@@ -13,7 +13,8 @@
#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
static unsigned int
-compute_cas_latency(const dimm_params_t *dimm_params,
+compute_cas_latency(const unsigned int ctrl_num,
+ const dimm_params_t *dimm_params,
common_timing_params_t *outpdimm,
unsigned int number_of_dimms)
{
@@ -22,7 +23,7 @@ compute_cas_latency(const dimm_params_t *dimm_params,
unsigned int caslat_actual;
unsigned int retry = 16;
unsigned int tmp;
- const unsigned int mclk_ps = get_memory_clk_period_ps();
+ const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num);
#ifdef CONFIG_SYS_FSL_DDR3
const unsigned int taamax = 20000;
#else
@@ -72,12 +73,13 @@ compute_cas_latency(const dimm_params_t *dimm_params,
}
#else /* for DDR1 and DDR2 */
static unsigned int
-compute_cas_latency(const dimm_params_t *dimm_params,
+compute_cas_latency(const unsigned int ctrl_num,
+ const dimm_params_t *dimm_params,
common_timing_params_t *outpdimm,
unsigned int number_of_dimms)
{
int i;
- const unsigned int mclk_ps = get_memory_clk_period_ps();
+ const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num);
unsigned int lowest_good_caslat;
unsigned int not_ok;
unsigned int temp1, temp2;
@@ -212,7 +214,8 @@ compute_cas_latency(const dimm_params_t *dimm_params,
* by dimm_params.
*/
unsigned int
-compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,
+compute_lowest_common_dimm_parameters(const unsigned int ctrl_num,
+ const dimm_params_t *dimm_params,
common_timing_params_t *outpdimm,
const unsigned int number_of_dimms)
{
@@ -442,7 +445,8 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,
printf("ERROR: Mix different RDIMM detected!\n");
/* calculate cas latency for all DDR types */
- if (compute_cas_latency(dimm_params, outpdimm, number_of_dimms))
+ if (compute_cas_latency(ctrl_num, dimm_params,
+ outpdimm, number_of_dimms))
return 1;
/* Determine if all DIMMs ECC capable. */
@@ -518,11 +522,12 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,
#if defined(CONFIG_SYS_FSL_DDR2)
if ((outpdimm->lowest_common_spd_caslat < 4) &&
- (picos_to_mclk(trcd_ps) > outpdimm->lowest_common_spd_caslat)) {
- additive_latency = picos_to_mclk(trcd_ps) -
+ (picos_to_mclk(ctrl_num, trcd_ps) >
+ outpdimm->lowest_common_spd_caslat)) {
+ additive_latency = picos_to_mclk(ctrl_num, trcd_ps) -
outpdimm->lowest_common_spd_caslat;
- if (mclk_to_picos(additive_latency) > trcd_ps) {
- additive_latency = picos_to_mclk(trcd_ps);
+ if (mclk_to_picos(ctrl_num, additive_latency) > trcd_ps) {
+ additive_latency = picos_to_mclk(ctrl_num, trcd_ps);
debug("setting additive_latency to %u because it was "
" greater than tRCD_ps\n", additive_latency);
}
@@ -534,7 +539,7 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,
*
* AL <= tRCD(min)
*/
- if (mclk_to_picos(additive_latency) > trcd_ps) {
+ if (mclk_to_picos(ctrl_num, additive_latency) > trcd_ps) {
printf("Error: invalid additive latency exceeds tRCD(min).\n");
return 1;
}
diff --git a/drivers/ddr/fsl/main.c b/drivers/ddr/fsl/main.c
index 6f291ebc03..b72b24290e 100644
--- a/drivers/ddr/fsl/main.c
+++ b/drivers/ddr/fsl/main.c
@@ -450,7 +450,8 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step,
&(pinfo->spd_installed_dimms[i][j]);
dimm_params_t *pdimm =
&(pinfo->dimm_params[i][j]);
- retval = compute_dimm_parameters(spd, pdimm, i);
+ retval = compute_dimm_parameters(
+ i, spd, pdimm, j);
#ifdef CONFIG_SYS_DDR_RAW_TIMING
if (!i && !j && retval) {
printf("SPD error on controller %d! "
@@ -507,10 +508,11 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step,
for (i = first_ctrl; i <= last_ctrl; i++) {
debug("Computing lowest common DIMM"
" parameters for memctl=%u\n", i);
- compute_lowest_common_dimm_parameters(
- pinfo->dimm_params[i],
- &timing_params[i],
- CONFIG_DIMM_SLOTS_PER_CTLR);
+ compute_lowest_common_dimm_parameters
+ (i,
+ pinfo->dimm_params[i],
+ &timing_params[i],
+ CONFIG_DIMM_SLOTS_PER_CTLR);
}
case STEP_GATHER_OPTS:
@@ -562,12 +564,13 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step,
continue;
}
- compute_fsl_memctl_config_regs(
- &pinfo->memctl_opts[i],
- &ddr_reg[i], &timing_params[i],
- pinfo->dimm_params[i],
- dbw_capacity_adjust[i],
- size_only);
+ compute_fsl_memctl_config_regs
+ (i,
+ &pinfo->memctl_opts[i],
+ &ddr_reg[i], &timing_params[i],
+ pinfo->dimm_params[i],
+ dbw_capacity_adjust[i],
+ size_only);
}
default:
@@ -689,6 +692,10 @@ phys_size_t __fsl_ddr_sdram(fsl_ddr_info_t *pinfo)
}
}
+#ifdef CONFIG_FSL_DDR_SYNC_REFRESH
+ fsl_ddr_sync_memctl_refresh(first_ctrl, last_ctrl);
+#endif
+
#ifdef CONFIG_PPC
/* program LAWs */
for (i = first_ctrl; i <= last_ctrl; i++) {
diff --git a/drivers/ddr/fsl/mpc85xx_ddr_gen3.c b/drivers/ddr/fsl/mpc85xx_ddr_gen3.c
index 8f4d01ad85..6752d4d29e 100644
--- a/drivers/ddr/fsl/mpc85xx_ddr_gen3.c
+++ b/drivers/ddr/fsl/mpc85xx_ddr_gen3.c
@@ -426,7 +426,7 @@ step2:
bus_width = 3 - ((ddr->sdram_cfg & SDRAM_CFG_DBW_MASK)
>> SDRAM_CFG_DBW_SHIFT);
timeout = ((total_gb_size_per_controller << (6 - bus_width)) * 100 /
- (get_ddr_freq(0) >> 20)) << 1;
+ (get_ddr_freq(ctrl_num) >> 20)) << 1;
#ifdef CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134
timeout_save = timeout;
#endif
@@ -538,12 +538,14 @@ step2:
case 1:
out_be32(&ddr->cs1_bnds, regs->cs[csn].bnds);
break;
+#if CONFIG_CHIP_SELECTS_PER_CTRL > 2
case 2:
out_be32(&ddr->cs2_bnds, regs->cs[csn].bnds);
break;
case 3:
out_be32(&ddr->cs3_bnds, regs->cs[csn].bnds);
break;
+#endif
}
clrbits_be32(&ddr->sdram_cfg, 0x2);
}
diff --git a/drivers/ddr/fsl/options.c b/drivers/ddr/fsl/options.c
index 6d098d1fa2..5beb11b02b 100644
--- a/drivers/ddr/fsl/options.c
+++ b/drivers/ddr/fsl/options.c
@@ -732,7 +732,7 @@ unsigned int populate_memctl_options(int all_dimms_registered,
#endif
/* Global Timing Parameters. */
- debug("mclk_ps = %u ps\n", get_memory_clk_period_ps());
+ debug("mclk_ps = %u ps\n", get_memory_clk_period_ps(ctrl_num));
/* Pick a caslat override. */
popts->cas_latency_override = 0;
@@ -785,7 +785,7 @@ unsigned int populate_memctl_options(int all_dimms_registered,
* FIXME: width, was considering looking at pdimm->primary_sdram_width
*/
#if defined(CONFIG_SYS_FSL_DDR1)
- popts->tfaw_window_four_activates_ps = mclk_to_picos(1);
+ popts->tfaw_window_four_activates_ps = mclk_to_picos(ctrl_num, 1);
#elif defined(CONFIG_SYS_FSL_DDR2)
/*
@@ -1036,7 +1036,7 @@ done:
if (pdimm[0].n_ranks == 4)
popts->quad_rank_present = 1;
- ddr_freq = get_ddr_freq(0) / 1000000;
+ ddr_freq = get_ddr_freq(ctrl_num) / 1000000;
if (popts->registered_dimm_en) {
popts->rcw_override = 1;
popts->rcw_1 = 0x000a5a00;
diff --git a/drivers/ddr/fsl/util.c b/drivers/ddr/fsl/util.c
index 58b519b403..664081b1b8 100644
--- a/drivers/ddr/fsl/util.c
+++ b/drivers/ddr/fsl/util.c
@@ -43,9 +43,9 @@ u32 fsl_ddr_get_version(void)
* propagation, compute a suitably rounded mclk_ps to compute
* a working memory controller configuration.
*/
-unsigned int get_memory_clk_period_ps(void)
+unsigned int get_memory_clk_period_ps(const unsigned int ctrl_num)
{
- unsigned int data_rate = get_ddr_freq(0);
+ unsigned int data_rate = get_ddr_freq(ctrl_num);
unsigned int result;
/* Round to nearest 10ps, being careful about 64-bit multiply/divide */
@@ -59,10 +59,10 @@ unsigned int get_memory_clk_period_ps(void)
}
/* Convert picoseconds into DRAM clock cycles (rounding up if needed). */
-unsigned int picos_to_mclk(unsigned int picos)
+unsigned int picos_to_mclk(const unsigned int ctrl_num, unsigned int picos)
{
unsigned long long clks, clks_rem;
- unsigned long data_rate = get_ddr_freq(0);
+ unsigned long data_rate = get_ddr_freq(ctrl_num);
/* Short circuit for zero picos */
if (!picos)
@@ -88,9 +88,9 @@ unsigned int picos_to_mclk(unsigned int picos)
return (unsigned int) clks;
}
-unsigned int mclk_to_picos(unsigned int mclk)
+unsigned int mclk_to_picos(const unsigned int ctrl_num, unsigned int mclk)
{
- return get_memory_clk_period_ps() * mclk;
+ return get_memory_clk_period_ps(ctrl_num) * mclk;
}
#ifdef CONFIG_PPC
@@ -308,3 +308,58 @@ void board_add_ram_info(int use_default)
{
detail_board_ddr_info();
}
+
+#ifdef CONFIG_FSL_DDR_SYNC_REFRESH
+#define DDRC_DEBUG20_INIT_DONE 0x80000000
+#define DDRC_DEBUG2_RF 0x00000040
+void fsl_ddr_sync_memctl_refresh(unsigned int first_ctrl,
+ unsigned int last_ctrl)
+{
+ unsigned int i;
+ u32 ddrc_debug20;
+ u32 ddrc_debug2[CONFIG_NUM_DDR_CONTROLLERS] = {};
+ u32 *ddrc_debug2_p[CONFIG_NUM_DDR_CONTROLLERS] = {};
+ struct ccsr_ddr __iomem *ddr;
+
+ for (i = first_ctrl; i <= last_ctrl; i++) {
+ switch (i) {
+ case 0:
+ ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
+ break;
+#if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1)
+ case 1:
+ ddr = (void *)CONFIG_SYS_FSL_DDR2_ADDR;
+ break;
+#endif
+#if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2)
+ case 2:
+ ddr = (void *)CONFIG_SYS_FSL_DDR3_ADDR;
+ break;
+#endif
+#if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3)
+ case 3:
+ ddr = (void *)CONFIG_SYS_FSL_DDR4_ADDR;
+ break;
+#endif
+ default:
+ printf("%s unexpected ctrl = %u\n", __func__, i);
+ return;
+ }
+ ddrc_debug20 = ddr_in32(&ddr->debug[19]);
+ ddrc_debug2_p[i] = &ddr->debug[1];
+ while (!(ddrc_debug20 & DDRC_DEBUG20_INIT_DONE)) {
+ /* keep polling until DDRC init is done */
+ udelay(100);
+ ddrc_debug20 = ddr_in32(&ddr->debug[19]);
+ }
+ ddrc_debug2[i] = ddr_in32(&ddr->debug[1]) | DDRC_DEBUG2_RF;
+ }
+ /*
+ * Sync refresh
+ * This is put together to make sure the refresh reqeusts are sent
+ * closely to each other.
+ */
+ for (i = first_ctrl; i <= last_ctrl; i++)
+ ddr_out32(ddrc_debug2_p[i], ddrc_debug2[i]);
+}
+#endif /* CONFIG_FSL_DDR_SYNC_REFRESH */
diff --git a/drivers/demo/Kconfig b/drivers/demo/Kconfig
new file mode 100644
index 0000000000..7a8ce18555
--- /dev/null
+++ b/drivers/demo/Kconfig
@@ -0,0 +1,26 @@
+config DM_DEMO
+ bool "Enable demo uclass support"
+ depends on DM
+ help
+ This uclass allows you to play around with driver model. It provides
+ an interface to a couple of demo devices. You can access it using
+ the 'demo' command or by calling the uclass functions from your
+ own code.
+
+config DM_DEMO_SIMPLE
+ bool "Enable simple demo device for driver model"
+ depends on DM_DEMO
+ help
+ This device allows you to play around with driver model. It prints
+ a message when the 'demo hello' command is executed which targets
+ this device. It can be used to help understand how driver model
+ works.
+
+config DM_DEMO_SHAPE
+ bool "Enable shape demo device for driver model"
+ depends on DM_DEMO
+ help
+ This device allows you to play around with driver model. It prints
+ a shape when the 'demo hello' command is executed which targets
+ this device. It can be used to help understand how driver model
+ works.
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index d21302f8da..b609e73bba 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -2,5 +2,8 @@ config DM_GPIO
bool "Enable Driver Model for GPIO drivers"
depends on DM
help
- If you want to use driver model for GPIO drivers, say Y.
- To use legacy GPIO drivers, say N.
+ Enable driver model for GPIO access. The standard GPIO
+ interface (gpio_get_value(), etc.) is then implemented by
+ the GPIO uclass. Drivers provide methods to query the
+ particular GPIOs that they provide. The uclass interface
+ is defined in include/asm-generic/gpio.h.
diff --git a/drivers/gpio/at91_gpio.c b/drivers/gpio/at91_gpio.c
index 6129c020ea..22fbd63098 100644
--- a/drivers/gpio/at91_gpio.c
+++ b/drivers/gpio/at91_gpio.c
@@ -451,7 +451,7 @@ struct at91_port_priv {
/* set GPIO pin 'gpio' as an input */
static int at91_gpio_direction_input(struct udevice *dev, unsigned offset)
{
- struct at91_port_priv *port = dev_get_platdata(dev);
+ struct at91_port_priv *port = dev_get_priv(dev);
at91_set_port_input(port->regs, offset, 0);
@@ -462,7 +462,7 @@ static int at91_gpio_direction_input(struct udevice *dev, unsigned offset)
static int at91_gpio_direction_output(struct udevice *dev, unsigned offset,
int value)
{
- struct at91_port_priv *port = dev_get_platdata(dev);
+ struct at91_port_priv *port = dev_get_priv(dev);
at91_set_port_output(port->regs, offset, value);
@@ -472,7 +472,7 @@ static int at91_gpio_direction_output(struct udevice *dev, unsigned offset,
/* read GPIO IN value of pin 'gpio' */
static int at91_gpio_get_value(struct udevice *dev, unsigned offset)
{
- struct at91_port_priv *port = dev_get_platdata(dev);
+ struct at91_port_priv *port = dev_get_priv(dev);
return at91_get_port_value(port->regs, offset);
}
@@ -481,7 +481,7 @@ static int at91_gpio_get_value(struct udevice *dev, unsigned offset)
static int at91_gpio_set_value(struct udevice *dev, unsigned offset,
int value)
{
- struct at91_port_priv *port = dev_get_platdata(dev);
+ struct at91_port_priv *port = dev_get_priv(dev);
at91_set_port_value(port->regs, offset, value);
@@ -490,7 +490,7 @@ static int at91_gpio_set_value(struct udevice *dev, unsigned offset,
static int at91_gpio_get_function(struct udevice *dev, unsigned offset)
{
- struct at91_port_priv *port = dev_get_platdata(dev);
+ struct at91_port_priv *port = dev_get_priv(dev);
/* GPIOF_FUNC is not implemented yet */
if (at91_get_port_output(port->regs, offset))
diff --git a/drivers/gpio/mxc_gpio.c b/drivers/gpio/mxc_gpio.c
index 8bb9e39b72..815407bb03 100644
--- a/drivers/gpio/mxc_gpio.c
+++ b/drivers/gpio/mxc_gpio.c
@@ -23,6 +23,7 @@ enum mxc_gpio_direction {
#define GPIO_PER_BANK 32
struct mxc_gpio_plat {
+ int bank_index;
struct gpio_regs *regs;
};
@@ -150,6 +151,9 @@ int gpio_direction_output(unsigned gpio, int value)
#endif
#ifdef CONFIG_DM_GPIO
+#include <fdtdec.h>
+DECLARE_GLOBAL_DATA_PTR;
+
static int mxc_gpio_is_output(struct gpio_regs *regs, int offset)
{
u32 val;
@@ -258,23 +262,6 @@ static const struct dm_gpio_ops gpio_mxc_ops = {
.get_function = mxc_gpio_get_function,
};
-static const struct mxc_gpio_plat mxc_plat[] = {
- { (struct gpio_regs *)GPIO1_BASE_ADDR },
- { (struct gpio_regs *)GPIO2_BASE_ADDR },
- { (struct gpio_regs *)GPIO3_BASE_ADDR },
-#if defined(CONFIG_MX25) || defined(CONFIG_MX27) || defined(CONFIG_MX51) || \
- defined(CONFIG_MX53) || defined(CONFIG_MX6)
- { (struct gpio_regs *)GPIO4_BASE_ADDR },
-#endif
-#if defined(CONFIG_MX27) || defined(CONFIG_MX53) || defined(CONFIG_MX6)
- { (struct gpio_regs *)GPIO5_BASE_ADDR },
- { (struct gpio_regs *)GPIO6_BASE_ADDR },
-#endif
-#if defined(CONFIG_MX53) || defined(CONFIG_MX6)
- { (struct gpio_regs *)GPIO7_BASE_ADDR },
-#endif
-};
-
static int mxc_gpio_probe(struct udevice *dev)
{
struct mxc_bank_info *bank = dev_get_priv(dev);
@@ -283,7 +270,7 @@ static int mxc_gpio_probe(struct udevice *dev)
int banknum;
char name[18], *str;
- banknum = plat - mxc_plat;
+ banknum = plat->bank_index;
sprintf(name, "GPIO%d_", banknum + 1);
str = strdup(name);
if (!str)
@@ -295,12 +282,72 @@ static int mxc_gpio_probe(struct udevice *dev)
return 0;
}
+static int mxc_gpio_bind(struct udevice *dev)
+{
+ struct mxc_gpio_plat *plat = dev->platdata;
+ fdt_addr_t addr;
+
+ /*
+ * If platdata already exsits, directly return.
+ * Actually only when DT is not supported, platdata
+ * is statically initialized in U_BOOT_DEVICES.Here
+ * will return.
+ */
+ if (plat)
+ return 0;
+
+ addr = dev_get_addr(dev);
+ if (addr == FDT_ADDR_T_NONE)
+ return -ENODEV;
+
+ /*
+ * TODO:
+ * When every board is converted to driver model and DT is supported,
+ * this can be done by auto-alloc feature, but not using calloc
+ * to alloc memory for platdata.
+ */
+ plat = calloc(1, sizeof(*plat));
+ if (!plat)
+ return -ENOMEM;
+
+ plat->regs = (struct gpio_regs *)addr;
+ plat->bank_index = dev->req_seq;
+ dev->platdata = plat;
+
+ return 0;
+}
+
+static const struct udevice_id mxc_gpio_ids[] = {
+ { .compatible = "fsl,imx35-gpio" },
+ { }
+};
+
U_BOOT_DRIVER(gpio_mxc) = {
.name = "gpio_mxc",
.id = UCLASS_GPIO,
.ops = &gpio_mxc_ops,
.probe = mxc_gpio_probe,
.priv_auto_alloc_size = sizeof(struct mxc_bank_info),
+ .of_match = mxc_gpio_ids,
+ .bind = mxc_gpio_bind,
+};
+
+#ifndef CONFIG_OF_CONTROL
+static const struct mxc_gpio_plat mxc_plat[] = {
+ { 0, (struct gpio_regs *)GPIO1_BASE_ADDR },
+ { 1, (struct gpio_regs *)GPIO2_BASE_ADDR },
+ { 2, (struct gpio_regs *)GPIO3_BASE_ADDR },
+#if defined(CONFIG_MX25) || defined(CONFIG_MX27) || defined(CONFIG_MX51) || \
+ defined(CONFIG_MX53) || defined(CONFIG_MX6)
+ { 3, (struct gpio_regs *)GPIO4_BASE_ADDR },
+#endif
+#if defined(CONFIG_MX27) || defined(CONFIG_MX53) || defined(CONFIG_MX6)
+ { 4, (struct gpio_regs *)GPIO5_BASE_ADDR },
+ { 5, (struct gpio_regs *)GPIO6_BASE_ADDR },
+#endif
+#if defined(CONFIG_MX53) || defined(CONFIG_MX6)
+ { 6, (struct gpio_regs *)GPIO7_BASE_ADDR },
+#endif
};
U_BOOT_DEVICES(mxc_gpios) = {
@@ -320,3 +367,4 @@ U_BOOT_DEVICES(mxc_gpios) = {
#endif
};
#endif
+#endif
diff --git a/drivers/gpio/omap_gpio.c b/drivers/gpio/omap_gpio.c
index f3a7ccb51e..19fc451079 100644
--- a/drivers/gpio/omap_gpio.c
+++ b/drivers/gpio/omap_gpio.c
@@ -291,7 +291,7 @@ static int omap_gpio_get_function(struct udevice *dev, unsigned offset)
struct gpio_bank *bank = dev_get_priv(dev);
/* GPIOF_FUNC is not implemented yet */
- if (_get_gpio_direction(bank->base, offset) == OMAP_GPIO_DIR_OUT)
+ if (_get_gpio_direction(bank, offset) == OMAP_GPIO_DIR_OUT)
return GPIOF_OUTPUT;
else
return GPIOF_INPUT;
diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
index 202ea5d679..692810d057 100644
--- a/drivers/i2c/Kconfig
+++ b/drivers/i2c/Kconfig
@@ -2,8 +2,25 @@ 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.
+ Enable driver model for I2C. This SPI flash interface
+ (spi_flash_probe(), spi_flash_write(), etc.) is then
+ implemented by the SPI flash uclass. There is one standard
+ SPI flash driver which knows how to probe most chips
+ supported by U-Boot. The uclass interface is defined in
+ include/spi_flash.h, but is currently fully compatible
+ with the old interface to avoid confusion and duplication
+ during the transition parent. SPI and SPI flash must be
+ enabled together (it is not possible to use driver model
+ for one and not the other).
+
+config DM_I2C_COMPAT
+ bool "Enable I2C compatibility layer"
+ depends on DM
+ help
+ Enable old-style I2C functions for compatibility with existing code.
+ This option can be enabled as a temporary measure to avoid needing
+ to convert all code for a board in a single commit. It should not
+ be enabled for any board in an official release.
config SYS_I2C_UNIPHIER
bool "UniPhier I2C driver"
diff --git a/drivers/i2c/adi_i2c.c b/drivers/i2c/adi_i2c.c
index 20495b1d7f..c58f14a36e 100644
--- a/drivers/i2c/adi_i2c.c
+++ b/drivers/i2c/adi_i2c.c
@@ -63,7 +63,7 @@ struct twi_regs {
#endif
/* All transfers are described by this data structure */
-struct i2c_msg {
+struct adi_i2c_msg {
u8 flags;
#define I2C_M_COMBO 0x4
#define I2C_M_STOP 0x2
@@ -81,7 +81,7 @@ struct i2c_msg {
* wait_for_completion - manage the actual i2c transfer
* @msg: the i2c msg
*/
-static int wait_for_completion(struct twi_regs *twi, struct i2c_msg *msg)
+static int wait_for_completion(struct twi_regs *twi, struct adi_i2c_msg *msg)
{
u16 int_stat, ctl;
ulong timebase = get_timer(0);
@@ -151,7 +151,7 @@ static int i2c_transfer(struct i2c_adapter *adap, uint8_t chip, uint addr,
(addr >> 8),
(addr >> 16),
};
- struct i2c_msg msg = {
+ struct adi_i2c_msg msg = {
.flags = flags | (len >= 0xff ? I2C_M_STOP : 0),
.buf = buffer,
.len = len,
diff --git a/drivers/i2c/i2c-uclass.c b/drivers/i2c/i2c-uclass.c
index eafa457845..a6991bf875 100644
--- a/drivers/i2c/i2c-uclass.c
+++ b/drivers/i2c/i2c-uclass.c
@@ -325,7 +325,7 @@ int dm_i2c_probe(struct udevice *bus, uint chip_addr, uint chip_flags,
return ret;
}
-int i2c_set_bus_speed(struct udevice *bus, unsigned int speed)
+int dm_i2c_set_bus_speed(struct udevice *bus, unsigned int speed)
{
struct dm_i2c_ops *ops = i2c_get_ops(bus);
struct dm_i2c_bus *i2c = bus->uclass_priv;
@@ -346,12 +346,7 @@ int i2c_set_bus_speed(struct udevice *bus, unsigned int speed)
return 0;
}
-/*
- * i2c_get_bus_speed:
- *
- * Returns speed of selected I2C bus in Hz
- */
-int i2c_get_bus_speed(struct udevice *bus)
+int dm_i2c_get_bus_speed(struct udevice *bus)
{
struct dm_i2c_ops *ops = i2c_get_ops(bus);
struct dm_i2c_bus *i2c = bus->uclass_priv;
@@ -440,7 +435,7 @@ static int i2c_post_probe(struct udevice *dev)
i2c->speed_hz = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
"clock-frequency", 100000);
- return i2c_set_bus_speed(dev, i2c->speed_hz);
+ return dm_i2c_set_bus_speed(dev, i2c->speed_hz);
}
static int i2c_post_bind(struct udevice *dev)
diff --git a/drivers/i2c/kona_i2c.c b/drivers/i2c/kona_i2c.c
index 5eab338cfc..9af496bbb1 100644
--- a/drivers/i2c/kona_i2c.c
+++ b/drivers/i2c/kona_i2c.c
@@ -156,7 +156,7 @@ static struct bcm_kona_i2c_dev g_i2c_devs[CONFIG_SYS_MAX_I2C_BUS] = {
#define I2C_M_RD 0x0001 /* read data */
#define I2C_M_NOSTART 0x4000 /* no restart between msgs */
-struct i2c_msg {
+struct kona_i2c_msg {
uint16_t addr;
uint16_t flags;
uint16_t len;
@@ -297,7 +297,7 @@ static int bcm_kona_i2c_read_fifo_single(struct bcm_kona_i2c_dev *dev,
/* Read any amount of data using the RX FIFO from the i2c bus */
static int bcm_kona_i2c_read_fifo(struct bcm_kona_i2c_dev *dev,
- struct i2c_msg *msg)
+ struct kona_i2c_msg *msg)
{
unsigned int bytes_to_read = MAX_RX_FIFO_SIZE;
unsigned int last_byte_nak = 0;
@@ -392,7 +392,7 @@ static int bcm_kona_i2c_write_fifo_single(struct bcm_kona_i2c_dev *dev,
/* Write any amount of data using TX FIFO to the i2c bus */
static int bcm_kona_i2c_write_fifo(struct bcm_kona_i2c_dev *dev,
- struct i2c_msg *msg)
+ struct kona_i2c_msg *msg)
{
unsigned int bytes_to_write = MAX_TX_FIFO_SIZE;
unsigned int bytes_written = 0;
@@ -418,7 +418,7 @@ static int bcm_kona_i2c_write_fifo(struct bcm_kona_i2c_dev *dev,
/* Send i2c address */
static int bcm_kona_i2c_do_addr(struct bcm_kona_i2c_dev *dev,
- struct i2c_msg *msg)
+ struct kona_i2c_msg *msg)
{
unsigned char addr;
@@ -480,9 +480,9 @@ static void bcm_kona_i2c_config_timing(struct bcm_kona_i2c_dev *dev)
/* Master transfer function */
static int bcm_kona_i2c_xfer(struct bcm_kona_i2c_dev *dev,
- struct i2c_msg msgs[], int num)
+ struct kona_i2c_msg msgs[], int num)
{
- struct i2c_msg *pmsg;
+ struct kona_i2c_msg *pmsg;
int rc = 0;
int i;
@@ -635,7 +635,7 @@ static int kona_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
int alen, uchar *buffer, int len)
{
/* msg[0] writes the addr, msg[1] reads the data */
- struct i2c_msg msg[2];
+ struct kona_i2c_msg msg[2];
unsigned char msgbuf0[64];
struct bcm_kona_i2c_dev *dev = kona_get_dev(adap);
@@ -663,7 +663,7 @@ static int kona_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
static int kona_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
int alen, uchar *buffer, int len)
{
- struct i2c_msg msg[1];
+ struct kona_i2c_msg msg[1];
unsigned char msgbuf0[64];
unsigned int i;
struct bcm_kona_i2c_dev *dev = kona_get_dev(adap);
diff --git a/drivers/i2c/mv_i2c.c b/drivers/i2c/mv_i2c.c
index dac346334d..e65cce0d8e 100644
--- a/drivers/i2c/mv_i2c.c
+++ b/drivers/i2c/mv_i2c.c
@@ -31,7 +31,7 @@
#endif
/* All transfers are described by this data structure */
-struct i2c_msg {
+struct mv_i2c_msg {
u8 condition;
u8 acknack;
u8 direction;
@@ -157,7 +157,7 @@ static int i2c_isr_set_cleared(unsigned long set_mask,
* -5: illegal parameters
* -6: bus is busy and couldn't be aquired
*/
-int i2c_transfer(struct i2c_msg *msg)
+int i2c_transfer(struct mv_i2c_msg *msg)
{
int ret;
@@ -286,7 +286,7 @@ void i2c_init(int speed, int slaveaddr)
*/
int i2c_probe(uchar chip)
{
- struct i2c_msg msg;
+ struct mv_i2c_msg msg;
i2c_reset();
@@ -322,7 +322,7 @@ int i2c_probe(uchar chip)
*/
int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
{
- struct i2c_msg msg;
+ struct mv_i2c_msg msg;
u8 addr_bytes[3]; /* lowest...highest byte of data address */
PRINTD(("i2c_read(chip=0x%02x, addr=0x%02x, alen=0x%02x, "
@@ -410,7 +410,7 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
*/
int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
{
- struct i2c_msg msg;
+ struct mv_i2c_msg msg;
u8 addr_bytes[3]; /* lowest...highest byte of data address */
PRINTD(("i2c_write(chip=0x%02x, addr=0x%02x, alen=0x%02x, "
diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c
index 0dd1abcf80..b4ee33f7da 100644
--- a/drivers/i2c/s3c24x0_i2c.c
+++ b/drivers/i2c/s3c24x0_i2c.c
@@ -112,9 +112,9 @@
#define I2C_START_STOP 0x20 /* START / STOP */
#define I2C_TXRX_ENA 0x10 /* I2C Tx/Rx enable */
-#define I2C_TIMEOUT_MS 1000 /* 1 second */
+#define I2C_TIMEOUT_MS 10 /* 10 ms */
-#define HSI2C_TIMEOUT_US 100000 /* 100 ms, finer granularity */
+#define HSI2C_TIMEOUT_US 10000 /* 10 ms, finer granularity */
/* To support VCMA9 boards and other who dont define max_i2c_num */
diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig
index e69de29bb2..bb00de7c57 100644
--- a/drivers/input/Kconfig
+++ b/drivers/input/Kconfig
@@ -0,0 +1,6 @@
+config CROS_EC_KEYB
+ bool "Enable Chrome OS EC keyboard support"
+ help
+ Most ARM Chromebooks use an EC to provide access to the keyboard.
+ Messages are used to request key scans from the EC and these are
+ then decoded into keys by this driver.
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index e69de29bb2..0df25c331f 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -0,0 +1,55 @@
+config CMD_CROS_EC
+ bool "Enable crosec command"
+ depends on CROS_EC
+ help
+ Enable command-line access to the Chrome OS EC (Embedded
+ Controller). This provides the 'crosec' command which has
+ a number of sub-commands for performing EC tasks such as
+ updating its flash, accessing a small saved context area
+ and talking to the I2C bus behind the EC (if there is one).
+
+config CROS_EC
+ bool "Enable Chrome OS EC"
+ help
+ Enable access to the Chrome OS EC. This is a separate
+ microcontroller typically available on a SPI bus on Chromebooks. It
+ provides access to the keyboard, some internal storage and may
+ control access to the battery and main PMIC depending on the
+ device. You can use the 'crosec' command to access it.
+
+config CROS_EC_I2C
+ bool "Enable Chrome OS EC I2C driver"
+ depends on CROS_EC
+ help
+ Enable I2C access to the Chrome OS EC. This is used on older
+ ARM Chromebooks such as snow and spring before the standard bus
+ changed to SPI. The EC will accept commands across the I2C using
+ a special message protocol, and provide responses.
+
+config CROS_EC_LPC
+ bool "Enable Chrome OS EC LPC driver"
+ depends on CROS_EC
+ help
+ Enable I2C access to the Chrome OS EC. This is used on x86
+ Chromebooks such as link and falco. The keyboard is provided
+ through a legacy port interface, so on x86 machines the main
+ function of the EC is power and thermal management.
+
+config CROS_EC_SPI
+ bool "Enable Chrome OS EC SPI driver"
+ depends on CROS_EC
+ help
+ Enable SPI access to the Chrome OS EC. This is used on newer
+ ARM Chromebooks such as pit, pi and nyan-big. The SPI interface
+ provides a faster and more robust interface than I2C but the bugs
+ are less interesting.
+
+config DM_CROS_EC
+ bool "Enable Driver Model for Chrome OS EC"
+ depends on DM
+ help
+ Enable driver model for the Chrome OS EC interface. This
+ allows the cros_ec SPI driver to operate with CONFIG_DM_SPI
+ but otherwise makes few changes. Since cros_ec also supports
+ LPC (which doesn't support driver model yet), a full
+ conversion is not yet possible.
diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
index b18c75dee2..76fa0b0534 100644
--- a/drivers/mmc/dw_mmc.c
+++ b/drivers/mmc/dw_mmc.c
@@ -321,7 +321,7 @@ static void dwmci_set_ios(struct mmc *mmc)
if (mmc->ddr_mode)
regs |= DWMCI_DDR_MODE;
else
- regs &= DWMCI_DDR_MODE;
+ regs &= ~DWMCI_DDR_MODE;
dwmci_writel(host, DWMCI_UHS_REG, regs);
diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c
index dfa209bded..e083745235 100644
--- a/drivers/mmc/exynos_dw_mmc.c
+++ b/drivers/mmc/exynos_dw_mmc.c
@@ -13,14 +13,20 @@
#include <asm/arch/dwmmc.h>
#include <asm/arch/clk.h>
#include <asm/arch/pinmux.h>
+#include <asm/arch/power.h>
#include <asm/gpio.h>
#include <asm-generic/errno.h>
#define DWMMC_MAX_CH_NUM 4
#define DWMMC_MAX_FREQ 52000000
#define DWMMC_MIN_FREQ 400000
-#define DWMMC_MMC0_CLKSEL_VAL 0x03030001
-#define DWMMC_MMC2_CLKSEL_VAL 0x03020001
+#define DWMMC_MMC0_SDR_TIMING_VAL 0x03030001
+#define DWMMC_MMC2_SDR_TIMING_VAL 0x03020001
+
+/* Exynos implmentation specific drver private data */
+struct dwmci_exynos_priv_data {
+ u32 sdr_timing;
+};
/*
* Function used as callback function to initialise the
@@ -28,7 +34,9 @@
*/
static void exynos_dwmci_clksel(struct dwmci_host *host)
{
- dwmci_writel(host, DWMCI_CLKSEL, host->clksel_val);
+ struct dwmci_exynos_priv_data *priv = host->priv;
+
+ dwmci_writel(host, DWMCI_CLKSEL, priv->sdr_timing);
}
unsigned int exynos_dwmci_get_clk(struct dwmci_host *host)
@@ -55,6 +63,8 @@ unsigned int exynos_dwmci_get_clk(struct dwmci_host *host)
static void exynos_dwmci_board_init(struct dwmci_host *host)
{
+ struct dwmci_exynos_priv_data *priv = host->priv;
+
if (host->quirks & DWMCI_QUIRK_DISABLE_SMU) {
dwmci_writel(host, EMMCP_MPSBEGIN0, 0);
dwmci_writel(host, EMMCP_SEND0, 0);
@@ -64,12 +74,17 @@ static void exynos_dwmci_board_init(struct dwmci_host *host)
MPSCTRL_NON_SECURE_READ_BIT |
MPSCTRL_NON_SECURE_WRITE_BIT | MPSCTRL_VALID);
}
+
+ /* Set to timing value at initial time */
+ if (priv->sdr_timing)
+ exynos_dwmci_clksel(host);
}
static int exynos_dwmci_core_init(struct dwmci_host *host, int index)
{
unsigned int div;
unsigned long freq, sclk;
+ struct dwmci_exynos_priv_data *priv = host->priv;
if (host->bus_hz)
freq = host->bus_hz;
@@ -88,11 +103,11 @@ static int exynos_dwmci_core_init(struct dwmci_host *host, int index)
#endif
host->board_init = exynos_dwmci_board_init;
- if (!host->clksel_val) {
+ if (!priv->sdr_timing) {
if (index == 0)
- host->clksel_val = DWMMC_MMC0_CLKSEL_VAL;
+ priv->sdr_timing = DWMMC_MMC0_SDR_TIMING_VAL;
else if (index == 2)
- host->clksel_val = DWMMC_MMC2_CLKSEL_VAL;
+ priv->sdr_timing = DWMMC_MMC2_SDR_TIMING_VAL;
}
host->caps = MMC_MODE_DDR_52MHz;
@@ -118,6 +133,7 @@ static int exynos_dwmci_core_init(struct dwmci_host *host, int index)
int exynos_dwmci_add_port(int index, u32 regbase, int bus_width, u32 clksel)
{
struct dwmci_host *host = NULL;
+ struct dwmci_exynos_priv_data *priv;
host = malloc(sizeof(struct dwmci_host));
if (!host) {
@@ -125,11 +141,19 @@ int exynos_dwmci_add_port(int index, u32 regbase, int bus_width, u32 clksel)
return -ENOMEM;
}
+ priv = malloc(sizeof(struct dwmci_exynos_priv_data));
+ if (!priv) {
+ error("dwmci_exynos_priv_data malloc fail!\n");
+ return -ENOMEM;
+ }
+
host->ioaddr = (void *)regbase;
host->buswidth = bus_width;
if (clksel)
- host->clksel_val = clksel;
+ priv->sdr_timing = clksel;
+
+ host->priv = priv;
return exynos_dwmci_core_init(host, index);
}
@@ -157,7 +181,14 @@ static int exynos_dwmci_get_config(const void *blob, int node,
struct dwmci_host *host)
{
int err = 0;
- u32 base, clksel_val, timing[3];
+ u32 base, timing[3];
+ struct dwmci_exynos_priv_data *priv;
+
+ priv = malloc(sizeof(struct dwmci_exynos_priv_data));
+ if (!priv) {
+ error("dwmci_exynos_priv_data malloc fail!\n");
+ return -ENOMEM;
+ }
/* Extract device id for each mmc channel */
host->dev_id = pinmux_decode_periph_id(blob, node);
@@ -166,7 +197,6 @@ static int exynos_dwmci_get_config(const void *blob, int node,
if (host->dev_index == host->dev_id)
host->dev_index = host->dev_id - PERIPH_ID_SDMMC0;
-
/* Get the bus width from the device node */
host->buswidth = fdtdec_get_int(blob, node, "samsung,bus-width", 0);
if (host->buswidth <= 0) {
@@ -190,16 +220,24 @@ static int exynos_dwmci_get_config(const void *blob, int node,
return -EINVAL;
}
- clksel_val = (DWMCI_SET_SAMPLE_CLK(timing[0]) |
+ priv->sdr_timing = (DWMCI_SET_SAMPLE_CLK(timing[0]) |
DWMCI_SET_DRV_CLK(timing[1]) |
DWMCI_SET_DIV_RATIO(timing[2]));
- if (clksel_val)
- host->clksel_val = clksel_val;
+
+ /* sdr_timing didn't assigned anything, use the default value */
+ if (!priv->sdr_timing) {
+ if (host->dev_index == 0)
+ priv->sdr_timing = DWMMC_MMC0_SDR_TIMING_VAL;
+ else if (host->dev_index == 2)
+ priv->sdr_timing = DWMMC_MMC2_SDR_TIMING_VAL;
+ }
host->fifoth_val = fdtdec_get_int(blob, node, "fifoth_val", 0);
host->bus_hz = fdtdec_get_int(blob, node, "bus_hz", 0);
host->div = fdtdec_get_int(blob, node, "div", 0);
+ host->priv = priv;
+
return 0;
}
@@ -229,12 +267,21 @@ int exynos_dwmmc_init(const void *blob)
{
int compat_id;
int node_list[DWMMC_MAX_CH_NUM];
+ int boot_dev_node;
int err = 0, count;
compat_id = COMPAT_SAMSUNG_EXYNOS_DWMMC;
count = fdtdec_find_aliases_for_id(blob, "mmc",
compat_id, node_list, DWMMC_MAX_CH_NUM);
+
+ /* For DWMMC always set boot device as mmc 0 */
+ if (count >= 3 && get_boot_mode() == BOOT_MODE_SD) {
+ boot_dev_node = node_list[2];
+ node_list[2] = node_list[0];
+ node_list[0] = boot_dev_node;
+ }
+
err = exynos_dwmci_process_node(blob, node_list, count);
return err;
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index 67ee179f86..c5e270dd57 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -321,7 +321,8 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
esdhc_write32(&regs->cmdarg, cmd->cmdarg);
#if defined(CONFIG_FSL_USDHC)
esdhc_write32(&regs->mixctrl,
- (esdhc_read32(&regs->mixctrl) & 0xFFFFFF80) | (xfertyp & 0x7F));
+ (esdhc_read32(&regs->mixctrl) & 0xFFFFFF80) | (xfertyp & 0x7F)
+ | (mmc->ddr_mode ? XFERTYP_DDREN : 0));
esdhc_write32(&regs->xfertyp, xfertyp & 0xFFFF0000);
#else
esdhc_write32(&regs->xfertyp, xfertyp);
@@ -457,7 +458,7 @@ static void set_sysctl(struct mmc *mmc, uint clock)
if ((sdhc_clk / (div * pre_div)) <= clock)
break;
- pre_div >>= 1;
+ pre_div >>= mmc->ddr_mode ? 2 : 1;
div -= 1;
clk = (pre_div << 8) | (div << 4);
@@ -620,6 +621,9 @@ int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg)
}
cfg->cfg.host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT | MMC_MODE_HC;
+#ifdef CONFIG_SYS_FSL_ESDHC_HAS_DDR_MODE
+ cfg->cfg.host_caps |= MMC_MODE_DDR_52MHz;
+#endif
if (cfg->max_bus_width > 0) {
if (cfg->max_bus_width < 8)
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index b8039cd092..a13769ea25 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -1693,11 +1693,19 @@ void print_mmc_devices(char separator)
{
struct mmc *m;
struct list_head *entry;
+ char *mmc_type;
list_for_each(entry, &mmc_devices) {
m = list_entry(entry, struct mmc, link);
+ if (m->has_init)
+ mmc_type = IS_SD(m) ? "SD" : "eMMC";
+ else
+ mmc_type = NULL;
+
printf("%s: %d", m->cfg->name, m->block_dev.dev);
+ if (mmc_type)
+ printf(" (%s)", mmc_type);
if (entry->next != &mmc_devices) {
printf("%c", separator);
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index de88e19609..82d7984a51 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -374,7 +374,8 @@ static void sdhci_set_ios(struct mmc *mmc)
(host->quirks & SDHCI_QUIRK_USE_WIDE8))
ctrl |= SDHCI_CTRL_8BITBUS;
} else {
- if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300)
+ if ((SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) ||
+ (host->quirks & SDHCI_QUIRK_USE_WIDE8))
ctrl &= ~SDHCI_CTRL_8BITBUS;
if (mmc->bus_width == 4)
ctrl |= SDHCI_CTRL_4BITBUS;
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
index ebfec7cf07..22335452c5 100644
--- a/drivers/mmc/sunxi_mmc.c
+++ b/drivers/mmc/sunxi_mmc.c
@@ -449,11 +449,7 @@ struct mmc *sunxi_mmc_init(int sdc_no)
cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
cfg->host_caps = MMC_MODE_4BIT;
- cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
-#if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN7I) || \
- defined(CONFIG_MACH_SUN8I) || defined(CONFIG_MACH_SUN9I)
- cfg->host_caps |= MMC_MODE_HC;
-#endif
+ cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS | MMC_MODE_HC;
cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
cfg->f_min = 400000;
diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
index 415ab4eba9..59278d1eef 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -1 +1,3 @@
source "drivers/mtd/nand/Kconfig"
+
+source "drivers/mtd/spi/Kconfig"
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index c24221499b..72825c3e2e 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -6,8 +6,6 @@ config SYS_NAND_SELF_INIT
This option, if enabled, provides more flexible and linux-like
NAND initialization process.
-if !SPL_BUILD
-
config NAND_DENALI
bool "Support Denali NAND controller"
select SYS_NAND_SELF_INIT
@@ -34,9 +32,7 @@ config NAND_DENALI_SPARE_AREA_SKIP_BYTES
of OOB area before last ECC sector data starts. This is potentially
used to preserve the bad block marker in the OOB area.
-endif
-
-if SPL_BUILD
+if SPL
config SPL_NAND_DENALI
bool "Support Denali NAND controller for SPL"
diff --git a/drivers/mtd/nand/omap_gpmc.c b/drivers/mtd/nand/omap_gpmc.c
index fc64f48144..24123fcfe5 100644
--- a/drivers/mtd/nand/omap_gpmc.c
+++ b/drivers/mtd/nand/omap_gpmc.c
@@ -989,12 +989,15 @@ int board_nand_init(struct nand_chip *nand)
if (err)
return err;
-#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;
+#ifdef CONFIG_NAND_OMAP_GPMC_PREFETCH
else
nand->read_buf = omap_nand_read_prefetch8;
+#else
+ else
+ nand->read_buf = nand_read_buf;
#endif
nand->dev_ready = omap_dev_ready;
diff --git a/drivers/mtd/spi/Kconfig b/drivers/mtd/spi/Kconfig
new file mode 100644
index 0000000000..2dc46b4b34
--- /dev/null
+++ b/drivers/mtd/spi/Kconfig
@@ -0,0 +1,14 @@
+config DM_SPI_FLASH
+ bool "Enable Driver Model for SPI flash"
+ depends on DM && SPI
+ help
+ Enable driver model for SPI flash. This SPI flash interface
+ (spi_flash_probe(), spi_flash_write(), etc.) is then
+ implemented by the SPI flash uclass. There is one standard
+ SPI flash driver which knows how to probe most chips
+ supported by U-Boot. The uclass interface is defined in
+ include/spi_flash.h, but is currently fully compatible
+ with the old interface to avoid confusion and duplication
+ during the transition parent. SPI and SPI flash must be
+ enabled together (it is not possible to use driver model
+ for one and not the other).
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 46c4ac697d..b8b08034eb 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -33,7 +33,6 @@ obj-$(CONFIG_FTMAC110) += ftmac110.o
obj-$(CONFIG_FTMAC100) += ftmac100.o
obj-$(CONFIG_GRETH) += greth.o
obj-$(CONFIG_DRIVER_TI_KEYSTONE_NET) += keystone_net.o
-obj-$(CONFIG_DRIVER_KS8695ETH) += ks8695eth.o
obj-$(CONFIG_KS8851_MLL) += ks8851_mll.o
obj-$(CONFIG_LAN91C96) += lan91c96.o
obj-$(CONFIG_MACB) += macb.o
@@ -65,5 +64,5 @@ obj-$(CONFIG_XILINX_EMACLITE) += xilinx_emaclite.o
obj-$(CONFIG_XILINX_LL_TEMAC) += xilinx_ll_temac.o xilinx_ll_temac_mdio.o \
xilinx_ll_temac_fifo.o xilinx_ll_temac_sdma.o
obj-$(CONFIG_ZYNQ_GEM) += zynq_gem.o
-obj-$(CONFIG_FSL_MC_ENET) += fsl_mc/
+obj-$(CONFIG_FSL_MC_ENET) += fsl-mc/
obj-$(CONFIG_VSC9953) += vsc9953.o
diff --git a/drivers/net/fsl_mc/Makefile b/drivers/net/fsl-mc/Makefile
index 483408623c..206ac6be07 100644
--- a/drivers/net/fsl_mc/Makefile
+++ b/drivers/net/fsl-mc/Makefile
@@ -5,4 +5,6 @@
#
# Layerscape MC driver
-obj-y += mc.o
+obj-y += mc.o \
+ mc_sys.o \
+ dpmng.o
diff --git a/drivers/net/fsl-mc/dpmng.c b/drivers/net/fsl-mc/dpmng.c
new file mode 100644
index 0000000000..cc14c7b755
--- /dev/null
+++ b/drivers/net/fsl-mc/dpmng.c
@@ -0,0 +1,91 @@
+/* Copyright 2014 Freescale Semiconductor Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#include <fsl-mc/fsl_mc_sys.h>
+#include <fsl-mc/fsl_mc_cmd.h>
+#include <fsl-mc/fsl_dpmng.h>
+#include "fsl_dpmng_cmd.h"
+
+int mc_get_version(struct fsl_mc_io *mc_io, struct mc_version *mc_ver_info)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPMNG_CMDID_GET_VERSION,
+ MC_CMD_PRI_LOW, 0);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPMNG_RSP_GET_VERSION(cmd, mc_ver_info);
+
+ return 0;
+}
+
+int dpmng_reset_aiop(struct fsl_mc_io *mc_io, int container_id,
+ int aiop_tile_id)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPMNG_CMDID_RESET_AIOP,
+ MC_CMD_PRI_LOW, 0);
+ DPMNG_CMD_RESET_AIOP(cmd, container_id, aiop_tile_id);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpmng_load_aiop(struct fsl_mc_io *mc_io,
+ int container_id,
+ int aiop_tile_id,
+ uint64_t img_iova,
+ uint32_t img_size)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPMNG_CMDID_LOAD_AIOP,
+ MC_CMD_PRI_LOW,
+ 0);
+ DPMNG_CMD_LOAD_AIOP(cmd, container_id, aiop_tile_id, img_size,
+ img_iova);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpmng_run_aiop(struct fsl_mc_io *mc_io,
+ int container_id,
+ int aiop_tile_id,
+ const struct dpmng_aiop_run_cfg *cfg)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPMNG_CMDID_RUN_AIOP,
+ MC_CMD_PRI_LOW,
+ 0);
+ DPMNG_CMD_RUN_AIOP(cmd, container_id, aiop_tile_id, cfg);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpmng_reset_mc_portal(struct fsl_mc_io *mc_io)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPMNG_CMDID_RESET_MC_PORTAL,
+ MC_CMD_PRI_LOW,
+ 0);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
diff --git a/drivers/net/fsl-mc/fsl_dpmng_cmd.h b/drivers/net/fsl-mc/fsl_dpmng_cmd.h
new file mode 100644
index 0000000000..c9fe021f45
--- /dev/null
+++ b/drivers/net/fsl-mc/fsl_dpmng_cmd.h
@@ -0,0 +1,49 @@
+/* Copyright 2014 Freescale Semiconductor Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#ifndef __FSL_DPMNG_CMD_H
+#define __FSL_DPMNG_CMD_H
+
+/* Command IDs */
+#define DPMNG_CMDID_GET_VERSION 0x831
+#define DPMNG_CMDID_RESET_AIOP 0x832
+#define DPMNG_CMDID_LOAD_AIOP 0x833
+#define DPMNG_CMDID_RUN_AIOP 0x834
+#define DPMNG_CMDID_RESET_MC_PORTAL 0x835
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPMNG_RSP_GET_VERSION(cmd, mc_ver_info) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 32, uint32_t, mc_ver_info->revision); \
+ MC_RSP_OP(cmd, 0, 32, 32, uint32_t, mc_ver_info->major); \
+ MC_RSP_OP(cmd, 1, 0, 32, uint32_t, mc_ver_info->minor); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPMNG_CMD_RESET_AIOP(cmd, container_id, aiop_tile_id) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 32, int, aiop_tile_id); \
+ MC_CMD_OP(cmd, 0, 32, 32, int, container_id); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPMNG_CMD_LOAD_AIOP(cmd, container_id, aiop_tile_id, img_size, \
+ img_iova) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 32, int, aiop_tile_id); \
+ MC_CMD_OP(cmd, 0, 32, 32, int, container_id); \
+ MC_CMD_OP(cmd, 1, 0, 32, uint32_t, img_size); \
+ MC_CMD_OP(cmd, 2, 0, 64, uint64_t, img_iova); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPMNG_CMD_RUN_AIOP(cmd, container_id, aiop_tile_id, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 32, int, aiop_tile_id); \
+ MC_CMD_OP(cmd, 0, 32, 32, int, container_id); \
+ MC_CMD_OP(cmd, 1, 0, 32, uint32_t, cfg->cores_mask); \
+ MC_CMD_OP(cmd, 2, 0, 64, uint64_t, cfg->options); \
+} while (0)
+
+#endif /* __FSL_DPMNG_CMD_H */
diff --git a/drivers/net/fsl_mc/mc.c b/drivers/net/fsl-mc/mc.c
index df84568a94..74b0085301 100644
--- a/drivers/net/fsl_mc/mc.c
+++ b/drivers/net/fsl-mc/mc.c
@@ -3,9 +3,12 @@
*
* SPDX-License-Identifier: GPL-2.0+
*/
+
#include <errno.h>
#include <asm/io.h>
-#include <fsl_mc.h>
+#include <fsl-mc/fsl_mc.h>
+#include <fsl-mc/fsl_mc_sys.h>
+#include <fsl-mc/fsl_dpmng.h>
DECLARE_GLOBAL_DATA_PTR;
static int mc_boot_status;
@@ -14,7 +17,7 @@ static int mc_boot_status;
* Copying MC firmware or DPL image to DDR
*/
static int mc_copy_image(const char *title,
- u64 image_addr, u32 image_size, u64 mc_ram_addr)
+ u64 image_addr, u32 image_size, u64 mc_ram_addr)
{
debug("%s copied to address %p\n", title, (void *)mc_ram_addr);
memcpy((void *)mc_ram_addr, (void *)image_addr, image_size);
@@ -25,10 +28,9 @@ static int mc_copy_image(const char *title,
* MC firmware FIT image parser checks if the image is in FIT
* format, verifies integrity of the image and calculates
* raw image address and size values.
- * Returns 0 if success and 1 if any of the above mentioned
+ * Returns 0 on success and a negative errno on error.
* task fail.
**/
-
int parse_mc_firmware_fit_image(const void **raw_image_addr,
size_t *raw_image_size)
{
@@ -39,7 +41,7 @@ int parse_mc_firmware_fit_image(const void **raw_image_addr,
size_t size;
const char *uname = "firmware";
- /* Check if the image is in NOR flash*/
+ /* Check if the image is in NOR flash */
#ifdef CONFIG_SYS_LS_MC_FW_IN_NOR
fit_hdr = (void *)CONFIG_SYS_LS_MC_FW_ADDR;
#else
@@ -50,26 +52,26 @@ int parse_mc_firmware_fit_image(const void **raw_image_addr,
format = genimg_get_format(fit_hdr);
if (format != IMAGE_FORMAT_FIT) {
- debug("Not a FIT image\n");
- return 1;
+ printf("fsl-mc: ERROR: Bad firmware image (not a FIT image)\n");
+ return -EINVAL;
}
if (!fit_check_format(fit_hdr)) {
- debug("Bad FIT image format\n");
- return 1;
+ printf("fsl-mc: ERROR: Bad firmware image (bad FIT header)\n");
+ return -EINVAL;
}
node_offset = fit_image_get_node(fit_hdr, uname);
if (node_offset < 0) {
- debug("Can not find %s subimage\n", uname);
- return 1;
+ printf("fsl-mc: ERROR: Bad firmware image (missing subimage)\n");
+ return -ENOENT;
}
/* Verify MC firmware image */
if (!(fit_image_verify(fit_hdr, node_offset))) {
- debug("Bad MC firmware hash");
- return 1;
+ printf("fsl-mc: ERROR: Bad firmware image (bad CRC)\n");
+ return -EINVAL;
}
/* Get address and size of raw image */
@@ -90,12 +92,13 @@ int mc_init(bd_t *bis)
u64 mc_dpl_offset;
u32 reg_gsr;
u32 mc_fw_boot_status;
- void *fdt_hdr;
+ void *dpl_fdt_hdr;
int dpl_size;
const void *raw_image_addr;
size_t raw_image_size = 0;
-
- BUILD_BUG_ON(CONFIG_SYS_LS_MC_FW_LENGTH % 4 != 0);
+ struct fsl_mc_io mc_io;
+ int portal_id;
+ struct mc_version mc_ver_info;
/*
* The MC private DRAM block was already carved at the end of DRAM
@@ -130,25 +133,44 @@ int mc_init(bd_t *bis)
/*
* Load the MC FW at the beginning of the MC private DRAM block:
*/
- mc_copy_image(
- "MC Firmware",
- (u64)raw_image_addr,
- raw_image_size,
- mc_ram_addr);
+ mc_copy_image("MC Firmware",
+ (u64)raw_image_addr, raw_image_size, mc_ram_addr);
+
+ /*
+ * Get address and size of the DPL blob stored in flash:
+ */
+#ifdef CONFIG_SYS_LS_MC_DPL_IN_NOR
+ dpl_fdt_hdr = (void *)CONFIG_SYS_LS_MC_DPL_ADDR;
+#else
+#error "No CONFIG_SYS_LS_MC_DPL_IN_xxx defined"
+#endif
+
+ error = fdt_check_header(dpl_fdt_hdr);
+ if (error != 0) {
+ printf("fsl-mc: ERROR: Bad DPL image (bad header)\n");
+ goto out;
+ }
+
+ dpl_size = fdt_totalsize(dpl_fdt_hdr);
+ if (dpl_size > CONFIG_SYS_LS_MC_DPL_MAX_LENGTH) {
+ printf("fsl-mc: ERROR: Bad DPL image (too large: %d)\n",
+ dpl_size);
+ error = -EINVAL;
+ goto out;
+ }
/*
* Calculate offset in the MC private DRAM block at which the MC DPL
* blob is to be placed:
*/
#ifdef CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET
- BUILD_BUG_ON(
- (CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET & 0x3) != 0 ||
- CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET > 0xffffffff);
+ BUILD_BUG_ON((CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET & 0x3) != 0 ||
+ CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET > 0xffffffff);
mc_dpl_offset = CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET;
#else
mc_dpl_offset = mc_get_dram_block_size() -
- roundup(CONFIG_SYS_LS_MC_DPL_LENGTH, 4096);
+ roundup(CONFIG_SYS_LS_MC_DPL_MAX_LENGTH, 4096);
if ((mc_dpl_offset & 0x3) != 0 || mc_dpl_offset > 0xffffffff) {
printf("%s: Invalid MC DPL offset: %llu\n",
@@ -158,23 +180,14 @@ int mc_init(bd_t *bis)
}
#endif
- /* Check if DPL image is in NOR flash */
-#ifdef CONFIG_SYS_LS_MC_DPL_IN_NOR
- fdt_hdr = (void *)CONFIG_SYS_LS_MC_DPL_ADDR;
-#else
-#error "No CONFIG_SYS_LS_MC_DPL_IN_xxx defined"
-#endif
-
- dpl_size = fdt_totalsize(fdt_hdr);
-
/*
* Load the MC DPL blob at the far end of the MC private DRAM block:
+ *
+ * TODO: Should we place the DPL at a different location to match
+ * assumptions of MC firmware about its memory layout?
*/
- mc_copy_image(
- "MC DPL blob",
- (u64)fdt_hdr,
- dpl_size,
- mc_ram_addr + mc_dpl_offset);
+ mc_copy_image("MC DPL blob",
+ (u64)dpl_fdt_hdr, dpl_size, mc_ram_addr + mc_dpl_offset);
debug("mc_ccsr_regs %p\n", mc_ccsr_regs);
@@ -200,6 +213,8 @@ int mc_init(bd_t *bis)
*/
out_le32(&mc_ccsr_regs->reg_gsr, (u32)(mc_dpl_offset >> 2));
+ printf("\nfsl-mc: Booting Management Complex ...\n");
+
/*
* Deassert reset and release MC core 0 to run
*/
@@ -219,17 +234,13 @@ int mc_init(bd_t *bis)
}
if (timeout <= 0) {
- printf("%s: timeout booting management complex firmware\n",
- __func__);
+ printf("fsl-mc: timeout booting management complex firmware\n");
/* TODO: Get an error status from an MC CCSR register */
error = -ETIMEDOUT;
goto out;
}
- printf("Management complex booted (boot status: %#x)\n",
- mc_fw_boot_status);
-
if (mc_fw_boot_status != 0x1) {
/*
* TODO: Identify critical errors from the GSR register's FS
@@ -237,8 +248,41 @@ int mc_init(bd_t *bis)
* appropriate errno, so that the status property is set to
* failure in the fsl,dprc device tree node.
*/
+ printf("fsl-mc: WARNING: Firmware booted with error (GSR: %#x)\n",
+ reg_gsr);
}
+ /*
+ * TODO: need to obtain the portal_id for the root container from the
+ * DPL
+ */
+ portal_id = 0;
+
+ /*
+ * Check that the MC firmware is responding portal commands:
+ */
+ mc_io.mmio_regs = SOC_MC_PORTAL_ADDR(portal_id);
+ debug("Checking access to MC portal of root DPRC container (portal_id %d, portal physical addr %p)\n",
+ portal_id, mc_io.mmio_regs);
+
+ error = mc_get_version(&mc_io, &mc_ver_info);
+ if (error != 0) {
+ printf("fsl-mc: ERROR: Firmware version check failed (error: %d)\n",
+ error);
+ goto out;
+ }
+
+ if (MC_VER_MAJOR != mc_ver_info.major)
+ printf("fsl-mc: ERROR: Firmware major version mismatch (found: %d, expected: %d)\n",
+ mc_ver_info.major, MC_VER_MAJOR);
+
+ if (MC_VER_MINOR != mc_ver_info.minor)
+ printf("fsl-mc: WARNING: Firmware minor version mismatch (found: %d, expected: %d)\n",
+ mc_ver_info.minor, MC_VER_MINOR);
+
+ printf("fsl-mc: Management Complex booted (version: %d.%d.%d, boot status: %#x)\n",
+ mc_ver_info.major, mc_ver_info.minor, mc_ver_info.revision,
+ mc_fw_boot_status);
out:
if (error != 0)
mc_boot_status = -error;
diff --git a/drivers/net/fsl-mc/mc_sys.c b/drivers/net/fsl-mc/mc_sys.c
new file mode 100644
index 0000000000..7c8e003ad0
--- /dev/null
+++ b/drivers/net/fsl-mc/mc_sys.c
@@ -0,0 +1,63 @@
+/*
+ * Freescale Layerscape MC I/O wrapper
+ *
+ * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ * Author: German Rivera <German.Rivera@freescale.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <fsl-mc/fsl_mc_sys.h>
+#include <fsl-mc/fsl_mc_cmd.h>
+#include <common.h>
+#include <errno.h>
+#include <asm/io.h>
+
+#define MC_CMD_HDR_READ_CMDID(_hdr) \
+ ((uint16_t)u64_dec((_hdr), MC_CMD_HDR_CMDID_O, MC_CMD_HDR_CMDID_S))
+
+/**
+ * mc_send_command - Send MC command and wait for response
+ *
+ * @mc_io: Pointer to MC I/O object to be used
+ * @cmd: MC command buffer. On input, it contains the command to send to the MC.
+ * On output, it contains the response from the MC if any.
+ *
+ * Depending on the sharing option specified when creating the MC portal
+ * wrapper, this function will use a spinlock or mutex to ensure exclusive
+ * access to the MC portal from the point when the command is sent until a
+ * response is received from the MC.
+ */
+int mc_send_command(struct fsl_mc_io *mc_io,
+ struct mc_command *cmd)
+{
+ enum mc_cmd_status status;
+ int timeout = 2000;
+
+ mc_write_command(mc_io->mmio_regs, cmd);
+
+ for ( ; ; ) {
+ status = mc_read_response(mc_io->mmio_regs, cmd);
+ if (status != MC_CMD_STATUS_READY)
+ break;
+
+ if (--timeout == 0) {
+ printf("Error: Timeout waiting for MC response\n");
+ return -ETIMEDOUT;
+ }
+
+ udelay(500);
+ }
+
+ if (status != MC_CMD_STATUS_OK) {
+ printf("Error: MC command failed (portal: %p, obj handle: %#x, command: %#x, status: %#x)\n",
+ mc_io->mmio_regs,
+ (unsigned int)MC_CMD_HDR_READ_AUTHID(cmd->header),
+ (unsigned int)MC_CMD_HDR_READ_CMDID(cmd->header),
+ (unsigned int)status);
+
+ return -EIO;
+ }
+
+ return 0;
+}
diff --git a/drivers/net/keystone_net.c b/drivers/net/keystone_net.c
index bedab1d606..35f1a57331 100644
--- a/drivers/net/keystone_net.c
+++ b/drivers/net/keystone_net.c
@@ -398,8 +398,6 @@ static int keystone2_eth_open(struct eth_device *dev, bd_t *bis)
sys_has_mdio =
(eth_priv->sgmii_link_type == SGMII_LINK_MAC_PHY) ? 1 : 0;
- keystone2_net_serdes_setup();
-
if (sys_has_mdio)
keystone2_mdio_reset(mdio_bus);
@@ -556,6 +554,8 @@ int keystone2_emac_initialize(struct eth_priv_t *eth_priv)
return res;
}
+ keystone2_net_serdes_setup();
+
/* Create phy device and bind it with driver */
#ifdef CONFIG_KSNET_MDIO_PHY_CONFIG_ENABLE
phy_dev = phy_connect(mdio_bus, eth_priv->phy_addr,
diff --git a/drivers/net/ks8695eth.c b/drivers/net/ks8695eth.c
deleted file mode 100644
index b4822e9504..0000000000
--- a/drivers/net/ks8695eth.c
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * ks8695eth.c -- KS8695 ethernet driver
- *
- * (C) Copyright 2004-2005, Greg Ungerer <greg.ungerer@opengear.com>
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-/****************************************************************************/
-
-#include <common.h>
-#include <malloc.h>
-#include <net.h>
-#include <asm/io.h>
-#include <asm/arch/platform.h>
-
-/****************************************************************************/
-
-/*
- * Hardware register access to the KS8695 LAN ethernet port
- * (well, it is the 4 port switch really).
- */
-#define ks8695_read(a) *((volatile unsigned long *) (KS8695_IO_BASE + (a)))
-#define ks8695_write(a,v) *((volatile unsigned long *) (KS8695_IO_BASE + (a))) = (v)
-
-/****************************************************************************/
-
-/*
- * Define the descriptor in-memory data structures.
- */
-struct ks8695_txdesc {
- uint32_t owner;
- uint32_t ctrl;
- uint32_t addr;
- uint32_t next;
-};
-
-struct ks8695_rxdesc {
- uint32_t status;
- uint32_t ctrl;
- uint32_t addr;
- uint32_t next;
-};
-
-/****************************************************************************/
-
-/*
- * Allocate local data structures to use for receiving and sending
- * packets. Just to keep it all nice and simple.
- */
-
-#define TXDESCS 4
-#define RXDESCS 4
-#define BUFSIZE 2048
-
-volatile struct ks8695_txdesc ks8695_tx[TXDESCS] __attribute__((aligned(256)));
-volatile struct ks8695_rxdesc ks8695_rx[RXDESCS] __attribute__((aligned(256)));
-volatile uint8_t ks8695_bufs[BUFSIZE*(TXDESCS+RXDESCS)] __attribute__((aligned(2048)));;
-
-/****************************************************************************/
-
-/*
- * Ideally we want to use the MAC address stored in flash.
- * But we do some sanity checks in case they are not present
- * first.
- */
-unsigned char eth_mac[] = {
- 0x00, 0x13, 0xc6, 0x00, 0x00, 0x00
-};
-
-void ks8695_getmac(void)
-{
- unsigned char *fp;
- int i;
-
- /* Check if flash MAC is valid */
- fp = (unsigned char *) 0x0201c000;
- for (i = 0; (i < 6); i++) {
- if ((fp[i] != 0) && (fp[i] != 0xff))
- break;
- }
-
- /* If we found a valid looking MAC address then use it */
- if (i < 6)
- memcpy(&eth_mac[0], fp, 6);
-}
-
-/****************************************************************************/
-
-static int ks8695_eth_init(struct eth_device *dev, bd_t *bd)
-{
- int i;
-
- debug ("%s(%d): eth_reset()\n", __FILE__, __LINE__);
-
- /* Reset the ethernet engines first */
- ks8695_write(KS8695_LAN_DMA_TX, 0x80000000);
- ks8695_write(KS8695_LAN_DMA_RX, 0x80000000);
-
- ks8695_getmac();
-
- /* Set MAC address */
- ks8695_write(KS8695_LAN_MAC_LOW, (eth_mac[5] | (eth_mac[4] << 8) |
- (eth_mac[3] << 16) | (eth_mac[2] << 24)));
- ks8695_write(KS8695_LAN_MAC_HIGH, (eth_mac[1] | (eth_mac[0] << 8)));
-
- /* Turn the 4 port switch on */
- i = ks8695_read(KS8695_SWITCH_CTRL0);
- ks8695_write(KS8695_SWITCH_CTRL0, (i | 0x1));
- /* ks8695_write(KS8695_WAN_CONTROL, 0x3f000066); */
-
- /* Initialize descriptor rings */
- for (i = 0; (i < TXDESCS); i++) {
- ks8695_tx[i].owner = 0;
- ks8695_tx[i].ctrl = 0;
- ks8695_tx[i].addr = (uint32_t) &ks8695_bufs[i*BUFSIZE];
- ks8695_tx[i].next = (uint32_t) &ks8695_tx[i+1];
- }
- ks8695_tx[TXDESCS-1].ctrl = 0x02000000;
- ks8695_tx[TXDESCS-1].next = (uint32_t) &ks8695_tx[0];
-
- for (i = 0; (i < RXDESCS); i++) {
- ks8695_rx[i].status = 0x80000000;
- ks8695_rx[i].ctrl = BUFSIZE - 4;
- ks8695_rx[i].addr = (uint32_t) &ks8695_bufs[(i+TXDESCS)*BUFSIZE];
- ks8695_rx[i].next = (uint32_t) &ks8695_rx[i+1];
- }
- ks8695_rx[RXDESCS-1].ctrl |= 0x00080000;
- ks8695_rx[RXDESCS-1].next = (uint32_t) &ks8695_rx[0];
-
- /* The KS8695 is pretty slow reseting the ethernets... */
- udelay(2000000);
-
- /* Enable the ethernet engine */
- ks8695_write(KS8695_LAN_TX_LIST, (uint32_t) &ks8695_tx[0]);
- ks8695_write(KS8695_LAN_RX_LIST, (uint32_t) &ks8695_rx[0]);
- ks8695_write(KS8695_LAN_DMA_TX, 0x3);
- ks8695_write(KS8695_LAN_DMA_RX, 0x71);
- ks8695_write(KS8695_LAN_DMA_RX_START, 0x1);
-
- printf("KS8695 ETHERNET: %pM\n", eth_mac);
- return 0;
-}
-
-/****************************************************************************/
-
-static void ks8695_eth_halt(struct eth_device *dev)
-{
- debug ("%s(%d): eth_halt()\n", __FILE__, __LINE__);
-
- /* Reset the ethernet engines */
- ks8695_write(KS8695_LAN_DMA_TX, 0x80000000);
- ks8695_write(KS8695_LAN_DMA_RX, 0x80000000);
-}
-
-/****************************************************************************/
-
-static int ks8695_eth_recv(struct eth_device *dev)
-{
- volatile struct ks8695_rxdesc *dp;
- int i, len = 0;
-
- debug ("%s(%d): eth_rx()\n", __FILE__, __LINE__);
-
- for (i = 0; (i < RXDESCS); i++) {
- dp= &ks8695_rx[i];
- if ((dp->status & 0x80000000) == 0) {
- len = (dp->status & 0x7ff) - 4;
- NetReceive((void *) dp->addr, len);
- dp->status = 0x80000000;
- ks8695_write(KS8695_LAN_DMA_RX_START, 0x1);
- break;
- }
- }
-
- return len;
-}
-
-/****************************************************************************/
-
-static int ks8695_eth_send(struct eth_device *dev, void *packet, int len)
-{
- volatile struct ks8695_txdesc *dp;
- static int next = 0;
-
- debug ("%s(%d): eth_send(packet=%p,len=%d)\n", __FILE__, __LINE__,
- packet, len);
-
- dp = &ks8695_tx[next];
- memcpy((void *) dp->addr, (void *) packet, len);
-
- if (len < 64) {
- memset((void *) (dp->addr + len), 0, 64-len);
- len = 64;
- }
-
- dp->ctrl = len | 0xe0000000;
- dp->owner = 0x80000000;
-
- ks8695_write(KS8695_LAN_DMA_TX, 0x3);
- ks8695_write(KS8695_LAN_DMA_TX_START, 0x1);
-
- if (++next >= TXDESCS)
- next = 0;
-
- return 0;
-}
-
-/****************************************************************************/
-
-int ks8695_eth_initialize(void)
-{
- struct eth_device *dev;
-
- dev = malloc(sizeof(*dev));
- if (dev == NULL)
- return -1;
- memset(dev, 0, sizeof(*dev));
-
- dev->iobase = KS8695_IO_BASE + KS8695_LAN_DMA_TX;
- dev->init = ks8695_eth_init;
- dev->halt = ks8695_eth_halt;
- dev->send = ks8695_eth_send;
- dev->recv = ks8695_eth_recv;
- strcpy(dev->name, "ks8695eth");
-
- eth_register(dev);
- return 0;
-}
diff --git a/drivers/pci/pci_auto.c b/drivers/pci/pci_auto.c
index ed92857406..378efbfd9f 100644
--- a/drivers/pci/pci_auto.c
+++ b/drivers/pci/pci_auto.c
@@ -223,9 +223,12 @@ void pciauto_prescan_setup_bridge(struct pci_controller *hose,
struct pci_region *pci_mem = hose->pci_mem;
struct pci_region *pci_prefetch = hose->pci_prefetch;
struct pci_region *pci_io = hose->pci_io;
- u16 cmdstat;
+ u16 cmdstat, prefechable_64;
pci_hose_read_config_word(hose, dev, PCI_COMMAND, &cmdstat);
+ pci_hose_read_config_word(hose, dev, PCI_PREF_MEMORY_BASE,
+ &prefechable_64);
+ prefechable_64 &= PCI_PREF_RANGE_TYPE_MASK;
/* Configure bus number registers */
pci_hose_write_config_byte(hose, dev, PCI_PRIMARY_BUS,
@@ -252,12 +255,26 @@ void pciauto_prescan_setup_bridge(struct pci_controller *hose,
/* Set up memory and I/O filter limits, assume 32-bit I/O space */
pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_BASE,
(pci_prefetch->bus_lower & 0xfff00000) >> 16);
+ if (prefechable_64 == PCI_PREF_RANGE_TYPE_64)
+#ifdef CONFIG_SYS_PCI_64BIT
+ pci_hose_write_config_dword(hose, dev,
+ PCI_PREF_BASE_UPPER32,
+ pci_prefetch->bus_lower >> 32);
+#else
+ pci_hose_write_config_dword(hose, dev,
+ PCI_PREF_BASE_UPPER32,
+ 0x0);
+#endif
cmdstat |= PCI_COMMAND_MEMORY;
} else {
/* We don't support prefetchable memory for now, so disable */
pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_BASE, 0x1000);
pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_LIMIT, 0x0);
+ if (prefechable_64 == PCI_PREF_RANGE_TYPE_64) {
+ pci_hose_write_config_word(hose, dev, PCI_PREF_BASE_UPPER32, 0x0);
+ pci_hose_write_config_word(hose, dev, PCI_PREF_LIMIT_UPPER32, 0x0);
+ }
}
if (pci_io) {
@@ -297,11 +314,28 @@ void pciauto_postscan_setup_bridge(struct pci_controller *hose,
}
if (pci_prefetch) {
+ u16 prefechable_64;
+
+ pci_hose_read_config_word(hose, dev,
+ PCI_PREF_MEMORY_LIMIT,
+ &prefechable_64);
+ prefechable_64 &= PCI_PREF_RANGE_TYPE_MASK;
+
/* Round memory allocator to 1MB boundary */
pciauto_region_align(pci_prefetch, 0x100000);
pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_LIMIT,
(pci_prefetch->bus_lower - 1) >> 16);
+ if (prefechable_64 == PCI_PREF_RANGE_TYPE_64)
+#ifdef CONFIG_SYS_PCI_64BIT
+ pci_hose_write_config_dword(hose, dev,
+ PCI_PREF_LIMIT_UPPER32,
+ (pci_prefetch->bus_lower - 1) >> 32);
+#else
+ pci_hose_write_config_dword(hose, dev,
+ PCI_PREF_LIMIT_UPPER32,
+ 0x0);
+#endif
}
if (pci_io) {
diff --git a/drivers/pci/pcie_layerscape.c b/drivers/pci/pcie_layerscape.c
index 291c249c86..bcad8f2aec 100644
--- a/drivers/pci/pcie_layerscape.c
+++ b/drivers/pci/pcie_layerscape.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2014 Freescale Semiconductor, Inc.
+ * Copyright 2014-2015 Freescale Semiconductor, Inc.
* Layerscape PCIe driver
*
* SPDX-License-Identifier: GPL-2.0+
@@ -9,8 +9,465 @@
#include <asm/arch/fsl_serdes.h>
#include <pci.h>
#include <asm/io.h>
+#include <errno.h>
+#include <malloc.h>
#include <asm/pcie_layerscape.h>
+#ifndef CONFIG_SYS_PCI_MEMORY_BUS
+#define CONFIG_SYS_PCI_MEMORY_BUS CONFIG_SYS_SDRAM_BASE
+#endif
+
+#ifndef CONFIG_SYS_PCI_MEMORY_PHYS
+#define CONFIG_SYS_PCI_MEMORY_PHYS CONFIG_SYS_SDRAM_BASE
+#endif
+
+#ifndef CONFIG_SYS_PCI_MEMORY_SIZE
+#define CONFIG_SYS_PCI_MEMORY_SIZE (2 * 1024 * 1024 * 1024UL) /* 2G */
+#endif
+
+/* iATU registers */
+#define PCIE_ATU_VIEWPORT 0x900
+#define PCIE_ATU_REGION_INBOUND (0x1 << 31)
+#define PCIE_ATU_REGION_OUTBOUND (0x0 << 31)
+#define PCIE_ATU_REGION_INDEX0 (0x0 << 0)
+#define PCIE_ATU_REGION_INDEX1 (0x1 << 0)
+#define PCIE_ATU_REGION_INDEX2 (0x2 << 0)
+#define PCIE_ATU_REGION_INDEX3 (0x3 << 0)
+#define PCIE_ATU_CR1 0x904
+#define PCIE_ATU_TYPE_MEM (0x0 << 0)
+#define PCIE_ATU_TYPE_IO (0x2 << 0)
+#define PCIE_ATU_TYPE_CFG0 (0x4 << 0)
+#define PCIE_ATU_TYPE_CFG1 (0x5 << 0)
+#define PCIE_ATU_CR2 0x908
+#define PCIE_ATU_ENABLE (0x1 << 31)
+#define PCIE_ATU_BAR_MODE_ENABLE (0x1 << 30)
+#define PCIE_ATU_LOWER_BASE 0x90C
+#define PCIE_ATU_UPPER_BASE 0x910
+#define PCIE_ATU_LIMIT 0x914
+#define PCIE_ATU_LOWER_TARGET 0x918
+#define PCIE_ATU_BUS(x) (((x) & 0xff) << 24)
+#define PCIE_ATU_DEV(x) (((x) & 0x1f) << 19)
+#define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16)
+#define PCIE_ATU_UPPER_TARGET 0x91C
+
+#define PCIE_LINK_CAP 0x7c
+#define PCIE_LINK_SPEED_MASK 0xf
+#define PCIE_LINK_STA 0x82
+
+#define PCIE_DBI_SIZE (4 * 1024) /* 4K */
+
+struct ls_pcie {
+ int idx;
+ void __iomem *dbi;
+ void __iomem *va_cfg0;
+ void __iomem *va_cfg1;
+ struct pci_controller hose;
+};
+
+struct ls_pcie_info {
+ unsigned long regs;
+ int pci_num;
+ u64 cfg0_phys;
+ u64 cfg0_size;
+ u64 cfg1_phys;
+ u64 cfg1_size;
+ u64 mem_bus;
+ u64 mem_phys;
+ u64 mem_size;
+ u64 io_bus;
+ u64 io_phys;
+ u64 io_size;
+};
+
+#define SET_LS_PCIE_INFO(x, num) \
+{ \
+ x.regs = CONFIG_SYS_PCIE##num##_ADDR; \
+ x.cfg0_phys = CONFIG_SYS_PCIE_CFG0_PHYS_OFF + \
+ CONFIG_SYS_PCIE##num##_PHYS_ADDR; \
+ x.cfg0_size = CONFIG_SYS_PCIE_CFG0_SIZE; \
+ x.cfg1_phys = CONFIG_SYS_PCIE_CFG1_PHYS_OFF + \
+ CONFIG_SYS_PCIE##num##_PHYS_ADDR; \
+ x.cfg1_size = CONFIG_SYS_PCIE_CFG1_SIZE; \
+ x.mem_bus = CONFIG_SYS_PCIE_MEM_BUS; \
+ x.mem_phys = CONFIG_SYS_PCIE_MEM_PHYS_OFF + \
+ CONFIG_SYS_PCIE##num##_PHYS_ADDR; \
+ x.mem_size = CONFIG_SYS_PCIE_MEM_SIZE; \
+ x.io_bus = CONFIG_SYS_PCIE_IO_BUS; \
+ x.io_phys = CONFIG_SYS_PCIE_IO_PHYS_OFF + \
+ CONFIG_SYS_PCIE##num##_PHYS_ADDR; \
+ x.io_size = CONFIG_SYS_PCIE_IO_SIZE; \
+ x.pci_num = num; \
+}
+
+#ifdef CONFIG_LS102XA
+#include <asm/arch/immap_ls102xa.h>
+
+/* PEX1/2 Misc Ports Status Register */
+#define LTSSM_STATE_SHIFT 20
+#define LTSSM_STATE_MASK 0x3f
+#define LTSSM_PCIE_L0 0x11 /* L0 state */
+
+static int ls_pcie_link_state(struct ls_pcie *pcie)
+{
+ u32 state;
+ struct ccsr_scfg *scfg = (struct ccsr_scfg *)CONFIG_SYS_FSL_SCFG_ADDR;
+
+ state = in_be32(&scfg->pexmscportsr[pcie->idx]);
+ state = (state >> LTSSM_STATE_SHIFT) & LTSSM_STATE_MASK;
+ if (state < LTSSM_PCIE_L0) {
+ debug("....PCIe link error. LTSSM=0x%02x.\n", state);
+ return 0;
+ }
+
+ return 1;
+}
+#else
+#define PCIE_LDBG 0x7FC
+
+static int ls_pcie_link_state(struct ls_pcie *pcie)
+{
+ u32 state;
+
+ state = readl(pcie->dbi + PCIE_LDBG);
+ if (state)
+ return 1;
+
+ debug("....PCIe link error.\n");
+ return 0;
+}
+#endif
+
+static int ls_pcie_link_up(struct ls_pcie *pcie)
+{
+ int state;
+ u32 cap;
+
+ state = ls_pcie_link_state(pcie);
+ if (state)
+ return state;
+
+ /* Try to download speed to gen1 */
+ cap = readl(pcie->dbi + PCIE_LINK_CAP);
+ writel((cap & (~PCIE_LINK_SPEED_MASK)) | 1, pcie->dbi + PCIE_LINK_CAP);
+ udelay(2000);
+ state = ls_pcie_link_state(pcie);
+ if (state)
+ return state;
+
+ writel(cap, pcie->dbi + PCIE_LINK_CAP);
+
+ return 0;
+}
+
+static void ls_pcie_cfg0_set_busdev(struct ls_pcie *pcie, u32 busdev)
+{
+ writel(PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX0,
+ pcie->dbi + PCIE_ATU_VIEWPORT);
+ writel(busdev, pcie->dbi + PCIE_ATU_LOWER_TARGET);
+}
+
+static void ls_pcie_cfg1_set_busdev(struct ls_pcie *pcie, u32 busdev)
+{
+ writel(PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX1,
+ pcie->dbi + PCIE_ATU_VIEWPORT);
+ writel(busdev, pcie->dbi + PCIE_ATU_LOWER_TARGET);
+}
+
+static void ls_pcie_iatu_outbound_set(struct ls_pcie *pcie, int idx, int type,
+ u64 phys, u64 bus_addr, pci_size_t size)
+{
+ writel(PCIE_ATU_REGION_OUTBOUND | idx, pcie->dbi + PCIE_ATU_VIEWPORT);
+ writel((u32)phys, pcie->dbi + PCIE_ATU_LOWER_BASE);
+ writel(phys >> 32, pcie->dbi + PCIE_ATU_UPPER_BASE);
+ writel(phys + size - 1, pcie->dbi + PCIE_ATU_LIMIT);
+ writel((u32)bus_addr, pcie->dbi + PCIE_ATU_LOWER_TARGET);
+ writel(bus_addr >> 32, pcie->dbi + PCIE_ATU_UPPER_TARGET);
+ writel(type, pcie->dbi + PCIE_ATU_CR1);
+ writel(PCIE_ATU_ENABLE, pcie->dbi + PCIE_ATU_CR2);
+}
+
+static void ls_pcie_setup_atu(struct ls_pcie *pcie, struct ls_pcie_info *info)
+{
+#ifdef DEBUG
+ int i;
+#endif
+
+ /* ATU 0 : OUTBOUND : CFG0 */
+ ls_pcie_iatu_outbound_set(pcie, PCIE_ATU_REGION_INDEX0,
+ PCIE_ATU_TYPE_CFG0,
+ info->cfg0_phys,
+ 0,
+ info->cfg0_size);
+ /* ATU 1 : OUTBOUND : CFG1 */
+ ls_pcie_iatu_outbound_set(pcie, PCIE_ATU_REGION_INDEX1,
+ PCIE_ATU_TYPE_CFG1,
+ info->cfg1_phys,
+ 0,
+ info->cfg1_size);
+ /* ATU 2 : OUTBOUND : MEM */
+ ls_pcie_iatu_outbound_set(pcie, PCIE_ATU_REGION_INDEX2,
+ PCIE_ATU_TYPE_MEM,
+ info->mem_phys,
+ info->mem_bus,
+ info->mem_size);
+ /* ATU 3 : OUTBOUND : IO */
+ ls_pcie_iatu_outbound_set(pcie, PCIE_ATU_REGION_INDEX3,
+ PCIE_ATU_TYPE_IO,
+ info->io_phys,
+ info->io_bus,
+ info->io_size);
+
+#ifdef DEBUG
+ for (i = 0; i <= PCIE_ATU_REGION_INDEX3; i++) {
+ writel(PCIE_ATU_REGION_OUTBOUND | i,
+ pcie->dbi + PCIE_ATU_VIEWPORT);
+ debug("iATU%d:\n", i);
+ debug("\tLOWER PHYS 0x%08x\n",
+ readl(pcie->dbi + PCIE_ATU_LOWER_BASE));
+ debug("\tUPPER PHYS 0x%08x\n",
+ readl(pcie->dbi + PCIE_ATU_UPPER_BASE));
+ debug("\tLOWER BUS 0x%08x\n",
+ readl(pcie->dbi + PCIE_ATU_LOWER_TARGET));
+ debug("\tUPPER BUS 0x%08x\n",
+ readl(pcie->dbi + PCIE_ATU_UPPER_TARGET));
+ debug("\tLIMIT 0x%08x\n",
+ readl(pcie->dbi + PCIE_ATU_LIMIT));
+ debug("\tCR1 0x%08x\n",
+ readl(pcie->dbi + PCIE_ATU_CR1));
+ debug("\tCR2 0x%08x\n",
+ readl(pcie->dbi + PCIE_ATU_CR2));
+ }
+#endif
+}
+
+int pci_skip_dev(struct pci_controller *hose, pci_dev_t dev)
+{
+ /* Do not skip controller */
+ return 0;
+}
+
+static int ls_pcie_addr_valid(struct pci_controller *hose, pci_dev_t d)
+{
+ if (PCI_DEV(d) > 0)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int ls_pcie_read_config(struct pci_controller *hose, pci_dev_t d,
+ int where, u32 *val)
+{
+ struct ls_pcie *pcie = hose->priv_data;
+ u32 busdev, *addr;
+
+ if (ls_pcie_addr_valid(hose, d)) {
+ *val = 0xffffffff;
+ return -EINVAL;
+ }
+
+ if (PCI_BUS(d) == hose->first_busno) {
+ addr = pcie->dbi + (where & ~0x3);
+ } else {
+ busdev = PCIE_ATU_BUS(PCI_BUS(d)) |
+ PCIE_ATU_DEV(PCI_DEV(d)) |
+ PCIE_ATU_FUNC(PCI_FUNC(d));
+
+ if (PCI_BUS(d) == hose->first_busno + 1) {
+ ls_pcie_cfg0_set_busdev(pcie, busdev);
+ addr = pcie->va_cfg0 + (where & ~0x3);
+ } else {
+ ls_pcie_cfg1_set_busdev(pcie, busdev);
+ addr = pcie->va_cfg1 + (where & ~0x3);
+ }
+ }
+
+ *val = readl(addr);
+
+ return 0;
+}
+
+static int ls_pcie_write_config(struct pci_controller *hose, pci_dev_t d,
+ int where, u32 val)
+{
+ struct ls_pcie *pcie = hose->priv_data;
+ u32 busdev, *addr;
+
+ if (ls_pcie_addr_valid(hose, d))
+ return -EINVAL;
+
+ if (PCI_BUS(d) == hose->first_busno) {
+ addr = pcie->dbi + (where & ~0x3);
+ } else {
+ busdev = PCIE_ATU_BUS(PCI_BUS(d)) |
+ PCIE_ATU_DEV(PCI_DEV(d)) |
+ PCIE_ATU_FUNC(PCI_FUNC(d));
+
+ if (PCI_BUS(d) == hose->first_busno + 1) {
+ ls_pcie_cfg0_set_busdev(pcie, busdev);
+ addr = pcie->va_cfg0 + (where & ~0x3);
+ } else {
+ ls_pcie_cfg1_set_busdev(pcie, busdev);
+ addr = pcie->va_cfg1 + (where & ~0x3);
+ }
+ }
+
+ writel(val, addr);
+
+ return 0;
+}
+
+static void ls_pcie_setup_ctrl(struct ls_pcie *pcie,
+ struct ls_pcie_info *info)
+{
+ struct pci_controller *hose = &pcie->hose;
+ pci_dev_t dev = PCI_BDF(hose->first_busno, 0, 0);
+
+ ls_pcie_setup_atu(pcie, info);
+
+ pci_hose_write_config_dword(hose, dev, PCI_BASE_ADDRESS_0, 0);
+
+ /* program correct class for RC */
+ pci_hose_write_config_word(hose, dev, PCI_CLASS_DEVICE,
+ PCI_CLASS_BRIDGE_PCI);
+}
+
+int ls_pcie_init_ctrl(int busno, enum srds_prtcl dev, struct ls_pcie_info *info)
+{
+ struct ls_pcie *pcie;
+ struct pci_controller *hose;
+ int num = dev - PCIE1;
+ pci_dev_t pdev = PCI_BDF(busno, 0, 0);
+ int i, linkup, ep_mode;
+ u8 header_type;
+ u16 temp16;
+
+ if (!is_serdes_configured(dev)) {
+ printf("PCIe%d: disabled\n", num + 1);
+ return busno;
+ }
+
+ pcie = malloc(sizeof(*pcie));
+ if (!pcie)
+ return busno;
+ memset(pcie, 0, sizeof(*pcie));
+
+ hose = &pcie->hose;
+ hose->priv_data = pcie;
+ hose->first_busno = busno;
+ pcie->idx = num;
+ pcie->dbi = map_physmem(info->regs, PCIE_DBI_SIZE, MAP_NOCACHE);
+ pcie->va_cfg0 = map_physmem(info->cfg0_phys,
+ info->cfg0_size,
+ MAP_NOCACHE);
+ pcie->va_cfg1 = map_physmem(info->cfg1_phys,
+ info->cfg1_size,
+ MAP_NOCACHE);
+
+ /* outbound memory */
+ pci_set_region(&hose->regions[0],
+ (pci_size_t)info->mem_bus,
+ (phys_size_t)info->mem_phys,
+ (pci_size_t)info->mem_size,
+ PCI_REGION_MEM);
+
+ /* outbound io */
+ pci_set_region(&hose->regions[1],
+ (pci_size_t)info->io_bus,
+ (phys_size_t)info->io_phys,
+ (pci_size_t)info->io_size,
+ PCI_REGION_IO);
+
+ /* System memory space */
+ pci_set_region(&hose->regions[2],
+ CONFIG_SYS_PCI_MEMORY_BUS,
+ CONFIG_SYS_PCI_MEMORY_PHYS,
+ CONFIG_SYS_PCI_MEMORY_SIZE,
+ PCI_REGION_SYS_MEMORY);
+
+ hose->region_count = 3;
+
+ for (i = 0; i < hose->region_count; i++)
+ debug("PCI reg:%d %016llx:%016llx %016llx %08lx\n",
+ i,
+ (u64)hose->regions[i].phys_start,
+ (u64)hose->regions[i].bus_start,
+ (u64)hose->regions[i].size,
+ hose->regions[i].flags);
+
+ pci_set_ops(hose,
+ pci_hose_read_config_byte_via_dword,
+ pci_hose_read_config_word_via_dword,
+ ls_pcie_read_config,
+ pci_hose_write_config_byte_via_dword,
+ pci_hose_write_config_word_via_dword,
+ ls_pcie_write_config);
+
+ pci_hose_read_config_byte(hose, pdev, PCI_HEADER_TYPE, &header_type);
+ ep_mode = (header_type & 0x7f) == PCI_HEADER_TYPE_NORMAL;
+ printf("PCIe%u: %s ", info->pci_num,
+ ep_mode ? "Endpoint" : "Root Complex");
+
+ linkup = ls_pcie_link_up(pcie);
+
+ if (!linkup) {
+ /* Let the user know there's no PCIe link */
+ printf("no link, regs @ 0x%lx\n", info->regs);
+ hose->last_busno = hose->first_busno;
+ return busno;
+ }
+
+ /* Print the negotiated PCIe link width */
+ pci_hose_read_config_word(hose, dev, PCIE_LINK_STA, &temp16);
+ printf("x%d gen%d, regs @ 0x%lx\n", (temp16 & 0x3f0) >> 4,
+ (temp16 & 0xf), info->regs);
+
+ if (ep_mode)
+ return busno;
+
+ ls_pcie_setup_ctrl(pcie, info);
+
+ pci_register_hose(hose);
+
+ hose->last_busno = pci_hose_scan(hose);
+
+ printf("PCIe%x: Bus %02x - %02x\n",
+ info->pci_num, hose->first_busno, hose->last_busno);
+
+ return hose->last_busno + 1;
+}
+
+int ls_pcie_init_board(int busno)
+{
+ struct ls_pcie_info info;
+
+#ifdef CONFIG_PCIE1
+ SET_LS_PCIE_INFO(info, 1);
+ busno = ls_pcie_init_ctrl(busno, PCIE1, &info);
+#endif
+
+#ifdef CONFIG_PCIE2
+ SET_LS_PCIE_INFO(info, 2);
+ busno = ls_pcie_init_ctrl(busno, PCIE2, &info);
+#endif
+
+#ifdef CONFIG_PCIE3
+ SET_LS_PCIE_INFO(info, 3);
+ busno = ls_pcie_init_ctrl(busno, PCIE3, &info);
+#endif
+
+#ifdef CONFIG_PCIE4
+ SET_LS_PCIE_INFO(info, 4);
+ busno = ls_pcie_init_ctrl(busno, PCIE4, &info);
+#endif
+
+ return busno;
+}
+
+void pci_init_board(void)
+{
+ ls_pcie_init_board(0);
+}
+
#ifdef CONFIG_OF_BOARD_SETUP
#include <libfdt.h>
#include <fdt_support.h>
@@ -38,6 +495,14 @@ void ft_pcie_setup(void *blob, bd_t *bd)
#ifdef CONFIG_PCIE2
ft_pcie_ls_setup(blob, FSL_PCIE_COMPAT, CONFIG_SYS_PCIE2_ADDR, PCIE2);
#endif
+
+ #ifdef CONFIG_PCIE3
+ ft_pcie_ls_setup(blob, FSL_PCIE_COMPAT, CONFIG_SYS_PCIE3_ADDR, PCIE3);
+ #endif
+
+ #ifdef CONFIG_PCIE4
+ ft_pcie_ls_setup(blob, FSL_PCIE_COMPAT, CONFIG_SYS_PCIE4_ADDR, PCIE4);
+ #endif
}
#else
@@ -45,7 +510,3 @@ void ft_pcie_setup(void *blob, bd_t *bd)
{
}
#endif
-
-void pci_init_board(void)
-{
-}
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index a0b6e02b54..1686a1f951 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -2,8 +2,69 @@ config DM_SERIAL
bool "Enable Driver Model for serial drivers"
depends on DM
help
- If you want to use driver model for serial drivers, say Y.
- To use legacy serial drivers, say N.
+ Enable driver model for serial. This replaces
+ drivers/serial/serial.c with the serial uclass, which
+ implements serial_putc() etc. The uclass interface is
+ defined in include/serial.h.
+
+config DEBUG_UART
+ bool "Enable an early debug UART for debugging"
+ help
+ The debug UART is intended for use very early in U-Boot to debug
+ problems when an ICE or other debug mechanism is not available.
+
+ To use it you should:
+ - Make sure your UART supports this interface
+ - Enable CONFIG_DEBUG_UART
+ - Enable the CONFIG for your UART to tell it to provide this interface
+ (e.g. CONFIG_DEBUG_UART_NS16550)
+ - Define the required settings as needed (see below)
+ - Call debug_uart_init() before use
+ - Call debug_uart_putc() to output a character
+
+ Depending on your platform it may be possible to use this UART before
+ a stack is available.
+
+ If your UART does not support this interface you can probably add
+ support quite easily. Remember that you cannot use driver model and
+ it is preferred to use no stack.
+
+ You must not use this UART once driver model is working and the
+ serial drivers are up and running (done in serial_init()). Otherwise
+ the drivers may conflict and you will get strange output.
+
+choice
+ prompt "Select which UART will provide the debug UART"
+ depends on DEBUG_UART
+
+config DEBUG_UART_NS16550
+ bool "ns16550"
+ help
+ Select this to enable a debug UART using the ns16550 driver. You
+ will need to provide parameters to make this work. The driver will
+ be available until the real driver model serial is running.
+
+endchoice
+
+config DEBUG_UART_BASE
+ hex "Base address of UART"
+ depends on DEBUG_UART
+ help
+ This is the base address of your UART for memory-mapped UARTs.
+
+ A default should be provided by your board, but if not you will need
+ to use the correct value here.
+
+config DEBUG_UART_CLOCK
+ int "UART input clock"
+ depends on DEBUG_UART
+ help
+ The UART input clock determines the speed of the internal UART
+ circuitry. The baud rate is derived from this by dividing the input
+ clock down.
+
+ A default should be provided by your board, but if not you will need
+ to use the correct value here.
config UNIPHIER_SERIAL
bool "UniPhier on-chip UART support"
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 4cc00cd2f8..b385852eee 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -8,6 +8,7 @@
ifdef CONFIG_DM_SERIAL
obj-y += serial-uclass.o
obj-$(CONFIG_PL01X_SERIAL) += serial_pl01x.o
+obj-$(CONFIG_PPC) += serial_ppc.o
else
obj-y += serial.o
obj-$(CONFIG_PL010_SERIAL) += serial_pl01x.o
@@ -26,7 +27,6 @@ obj-$(CONFIG_OPENCORES_YANU) += opencores_yanu.o
obj-$(CONFIG_SYS_NS16550) += ns16550.o
obj-$(CONFIG_S5P) += serial_s5p.o
obj-$(CONFIG_IMX_SERIAL) += serial_imx.o
-obj-$(CONFIG_KS8695_SERIAL) += serial_ks8695.o
obj-$(CONFIG_MAX3100_SERIAL) += serial_max3100.o
obj-$(CONFIG_MXC_UART) += serial_mxc.o
obj-$(CONFIG_PXA_SERIAL) += serial_pxa.o
diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
index 70c946249f..eb00f1ca8a 100644
--- a/drivers/serial/ns16550.c
+++ b/drivers/serial/ns16550.c
@@ -55,17 +55,9 @@ DECLARE_GLOBAL_DATA_PTR;
#endif /* CONFIG_SYS_NS16550_IER */
#ifdef CONFIG_DM_SERIAL
-static void ns16550_writeb(NS16550_t port, int offset, int value)
-{
- struct ns16550_platdata *plat = port->plat;
- unsigned char *addr;
- offset *= 1 << plat->reg_shift;
- addr = map_sysmem(plat->base, 0) + offset;
- /*
- * As far as we know it doesn't make sense to support selection of
- * these options at run-time, so use the existing CONFIG options.
- */
+static inline void serial_out_shift(unsigned char *addr, int shift, int value)
+{
#ifdef CONFIG_SYS_NS16550_PORT_MAPPED
outb(value, (ulong)addr);
#elif defined(CONFIG_SYS_NS16550_MEM32) && !defined(CONFIG_SYS_BIG_ENDIAN)
@@ -73,19 +65,14 @@ static void ns16550_writeb(NS16550_t port, int offset, int value)
#elif defined(CONFIG_SYS_NS16550_MEM32) && defined(CONFIG_SYS_BIG_ENDIAN)
out_be32(addr, value);
#elif defined(CONFIG_SYS_BIG_ENDIAN)
- writeb(value, addr + (1 << plat->reg_shift) - 1);
+ writeb(value, addr + (1 << shift) - 1);
#else
writeb(value, addr);
#endif
}
-static int ns16550_readb(NS16550_t port, int offset)
+static inline int serial_in_shift(unsigned char *addr, int shift)
{
- struct ns16550_platdata *plat = port->plat;
- unsigned char *addr;
-
- offset *= 1 << plat->reg_shift;
- addr = map_sysmem(plat->base, 0) + offset;
#ifdef CONFIG_SYS_NS16550_PORT_MAPPED
return inb((ulong)addr);
#elif defined(CONFIG_SYS_NS16550_MEM32) && !defined(CONFIG_SYS_BIG_ENDIAN)
@@ -93,12 +80,37 @@ static int ns16550_readb(NS16550_t port, int offset)
#elif defined(CONFIG_SYS_NS16550_MEM32) && defined(CONFIG_SYS_BIG_ENDIAN)
return in_be32(addr);
#elif defined(CONFIG_SYS_BIG_ENDIAN)
- return readb(addr + (1 << plat->reg_shift) - 1);
+ return readb(addr + (1 << reg_shift) - 1);
#else
return readb(addr);
#endif
}
+static void ns16550_writeb(NS16550_t port, int offset, int value)
+{
+ struct ns16550_platdata *plat = port->plat;
+ unsigned char *addr;
+
+ offset *= 1 << plat->reg_shift;
+ addr = map_sysmem(plat->base, 0) + offset;
+ /*
+ * As far as we know it doesn't make sense to support selection of
+ * these options at run-time, so use the existing CONFIG options.
+ */
+ serial_out_shift(addr, plat->reg_shift, value);
+}
+
+static int ns16550_readb(NS16550_t port, int offset)
+{
+ struct ns16550_platdata *plat = port->plat;
+ unsigned char *addr;
+
+ offset *= 1 << plat->reg_shift;
+ addr = map_sysmem(plat->base, 0) + offset;
+
+ return serial_in_shift(addr, plat->reg_shift);
+}
+
/* We can clean these up once everything is moved to driver model */
#define serial_out(value, addr) \
ns16550_writeb(com_port, addr - (unsigned char *)com_port, value)
@@ -106,10 +118,15 @@ static int ns16550_readb(NS16550_t port, int offset)
ns16550_readb(com_port, addr - (unsigned char *)com_port)
#endif
-int ns16550_calc_divisor(NS16550_t port, int clock, int baudrate)
+static inline int calc_divisor(NS16550_t port, int clock, int baudrate)
{
const unsigned int mode_x_div = 16;
+ return DIV_ROUND_CLOSEST(clock, mode_x_div * baudrate);
+}
+
+int ns16550_calc_divisor(NS16550_t port, int clock, int baudrate)
+{
#ifdef CONFIG_OMAP1510
/* If can't cleanly clock 115200 set div to 1 */
if ((clock == 12000000) && (baudrate == 115200)) {
@@ -119,7 +136,7 @@ int ns16550_calc_divisor(NS16550_t port, int clock, int baudrate)
port->osc_12m_sel = 0; /* clear if previsouly set */
#endif
- return DIV_ROUND_CLOSEST(clock, mode_x_div * baudrate);
+ return calc_divisor(port, clock, baudrate);
}
static void NS16550_setbrg(NS16550_t com_port, int baud_divisor)
@@ -219,6 +236,47 @@ int NS16550_tstc(NS16550_t com_port)
#endif /* CONFIG_NS16550_MIN_FUNCTIONS */
+#ifdef CONFIG_DEBUG_UART_NS16550
+
+#include <debug_uart.h>
+
+void debug_uart_init(void)
+{
+ struct NS16550 *com_port = (struct NS16550 *)CONFIG_DEBUG_UART_BASE;
+ int baud_divisor;
+
+ /*
+ * We copy the code from above because it is already horribly messy.
+ * Trying to refactor to nicely remove the duplication doesn't seem
+ * feasible. The better fix is to move all users of this driver to
+ * driver model.
+ */
+ baud_divisor = calc_divisor(com_port, CONFIG_DEBUG_UART_CLOCK,
+ CONFIG_BAUDRATE);
+
+ serial_out_shift(&com_port->ier, 0, CONFIG_SYS_NS16550_IER);
+ serial_out_shift(&com_port->mcr, 0, UART_MCRVAL);
+ serial_out_shift(&com_port->fcr, 0, UART_FCRVAL);
+
+ serial_out_shift(&com_port->lcr, 0, UART_LCR_BKSE | UART_LCRVAL);
+ serial_out_shift(&com_port->dll, 0, baud_divisor & 0xff);
+ serial_out_shift(&com_port->dlm, 0, (baud_divisor >> 8) & 0xff);
+ serial_out_shift(&com_port->lcr, 0, UART_LCRVAL);
+}
+
+static inline void _debug_uart_putc(int ch)
+{
+ struct NS16550 *com_port = (struct NS16550 *)CONFIG_DEBUG_UART_BASE;
+
+ while (!(serial_in_shift(&com_port->lsr, 0) & UART_LSR_THRE))
+ ;
+ serial_out_shift(&com_port->thr, 0, ch);
+}
+
+DEBUG_UART_FUNCS
+
+#endif
+
#ifdef CONFIG_DM_SERIAL
static int ns16550_serial_putc(struct udevice *dev, const char ch)
{
diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c
index 9131a8f93d..3fc7104359 100644
--- a/drivers/serial/serial-uclass.c
+++ b/drivers/serial/serial-uclass.c
@@ -258,6 +258,22 @@ static int serial_post_probe(struct udevice *dev)
#endif
int ret;
+#if defined(CONFIG_NEEDS_MANUAL_RELOC)
+ if (ops->setbrg)
+ ops->setbrg += gd->reloc_off;
+ if (ops->getc)
+ ops->getc += gd->reloc_off;
+ if (ops->putc)
+ ops->putc += gd->reloc_off;
+ if (ops->pending)
+ ops->pending += gd->reloc_off;
+ if (ops->clear)
+ ops->clear += gd->reloc_off;
+#if CONFIG_POST & CONFIG_SYS_POST_UART
+ if (ops->loop)
+ ops->loop += gd->reloc_off
+#endif
+#endif
/* Set the baud rate */
if (ops->setbrg) {
ret = ops->setbrg(dev, gd->baudrate);
diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c
index 95c992a5a3..9f78492298 100644
--- a/drivers/serial/serial.c
+++ b/drivers/serial/serial.c
@@ -127,7 +127,6 @@ serial_initfunc(evb64260_serial_initialize);
serial_initfunc(imx_serial_initialize);
serial_initfunc(iop480_serial_initialize);
serial_initfunc(jz_serial_initialize);
-serial_initfunc(ks8695_serial_initialize);
serial_initfunc(leon2_serial_initialize);
serial_initfunc(leon3_serial_initialize);
serial_initfunc(lh7a40x_serial_initialize);
@@ -220,7 +219,6 @@ void serial_initialize(void)
imx_serial_initialize();
iop480_serial_initialize();
jz_serial_initialize();
- ks8695_serial_initialize();
leon2_serial_initialize();
leon3_serial_initialize();
lh7a40x_serial_initialize();
diff --git a/drivers/serial/serial_ks8695.c b/drivers/serial/serial_ks8695.c
deleted file mode 100644
index 13adabd112..0000000000
--- a/drivers/serial/serial_ks8695.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * serial.c -- KS8695 serial driver
- *
- * (C) Copyright 2004, Greg Ungerer <greg.ungerer@opengear.com>
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#include <common.h>
-#include <asm/arch/platform.h>
-#include <serial.h>
-#include <linux/compiler.h>
-
-#ifndef CONFIG_SERIAL1
-#error "Bad: you didn't configure serial ..."
-#endif
-
-DECLARE_GLOBAL_DATA_PTR;
-
-/*
- * Define the UART hardware register access structure.
- */
-struct ks8695uart {
- unsigned int RX; /* 0x00 - Receive data (r) */
- unsigned int TX; /* 0x04 - Transmit data (w) */
- unsigned int FCR; /* 0x08 - Fifo Control (r/w) */
- unsigned int LCR; /* 0x0c - Line Control (r/w) */
- unsigned int MCR; /* 0x10 - Modem Control (r/w) */
- unsigned int LSR; /* 0x14 - Line Status (r/w) */
- unsigned int MSR; /* 0x18 - Modem Status (r/w) */
- unsigned int BD; /* 0x1c - Baud Rate (r/w) */
- unsigned int SR; /* 0x20 - Status (r/w) */
-};
-
-#define KS8695_UART_ADDR ((void *) (KS8695_IO_BASE + KS8695_UART_RX_BUFFER))
-#define KS8695_UART_CLK 25000000
-
-
-/*
- * Under some circumstances we want to be "quiet" and not issue any
- * serial output - though we want u-boot to otherwise work and behave
- * the same. By default be noisy.
- */
-int serial_console = 1;
-
-
-static void ks8695_serial_setbrg(void)
-{
- volatile struct ks8695uart *uartp = KS8695_UART_ADDR;
-
- /* Set to global baud rate and 8 data bits, no parity, 1 stop bit*/
- uartp->BD = KS8695_UART_CLK / gd->baudrate;
- uartp->LCR = KS8695_UART_LINEC_WLEN8;
-}
-
-static int ks8695_serial_init(void)
-{
- serial_console = 1;
- serial_setbrg();
- return 0;
-}
-
-static void ks8695_serial_raw_putc(const char c)
-{
- volatile struct ks8695uart *uartp = KS8695_UART_ADDR;
- int i;
-
- for (i = 0; (i < 0x100000); i++) {
- if (uartp->LSR & KS8695_UART_LINES_TXFE)
- break;
- }
-
- uartp->TX = c;
-}
-
-static void ks8695_serial_putc(const char c)
-{
- if (serial_console) {
- ks8695_serial_raw_putc(c);
- if (c == '\n')
- ks8695_serial_raw_putc('\r');
- }
-}
-
-static int ks8695_serial_tstc(void)
-{
- volatile struct ks8695uart *uartp = KS8695_UART_ADDR;
- if (serial_console)
- return ((uartp->LSR & KS8695_UART_LINES_RXFE) ? 1 : 0);
- return 0;
-}
-
-static int ks8695_serial_getc(void)
-{
- volatile struct ks8695uart *uartp = KS8695_UART_ADDR;
-
- while ((uartp->LSR & KS8695_UART_LINES_RXFE) == 0)
- ;
- return (uartp->RX);
-}
-
-static struct serial_device ks8695_serial_drv = {
- .name = "ks8695_serial",
- .start = ks8695_serial_init,
- .stop = NULL,
- .setbrg = ks8695_serial_setbrg,
- .putc = ks8695_serial_putc,
- .puts = default_serial_puts,
- .getc = ks8695_serial_getc,
- .tstc = ks8695_serial_tstc,
-};
-
-void ks8695_serial_initialize(void)
-{
- serial_register(&ks8695_serial_drv);
-}
-
-__weak struct serial_device *default_serial_console(void)
-{
- return &ks8695_serial_drv;
-}
diff --git a/drivers/serial/serial_ppc.c b/drivers/serial/serial_ppc.c
new file mode 100644
index 0000000000..47141c64eb
--- /dev/null
+++ b/drivers/serial/serial_ppc.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2014 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <ns16550.h>
+#include <serial.h>
+
+static const struct udevice_id ppc_serial_ids[] = {
+ { .compatible = "ns16550" },
+ { }
+};
+
+static int ppc_serial_ofdata_to_platdata(struct udevice *dev)
+{
+ struct ns16550_platdata *plat = dev_get_platdata(dev);
+ int ret;
+
+ ret = ns16550_serial_ofdata_to_platdata(dev);
+ if (ret)
+ return ret;
+ plat->clock = get_serial_clock();
+
+ return 0;
+}
+
+U_BOOT_DRIVER(serial_ns16550) = {
+ .name = "serial_ppc",
+ .id = UCLASS_SERIAL,
+ .of_match = ppc_serial_ids,
+ .ofdata_to_platdata = ppc_serial_ofdata_to_platdata,
+ .platdata_auto_alloc_size = sizeof(struct ns16550_platdata),
+ .priv_auto_alloc_size = sizeof(struct NS16550),
+ .probe = ns16550_serial_probe,
+ .ops = &ns16550_serial_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/serial/serial_sh.c b/drivers/serial/serial_sh.c
index 7c1f271376..3641c9f834 100644
--- a/drivers/serial/serial_sh.c
+++ b/drivers/serial/serial_sh.c
@@ -1,78 +1,21 @@
/*
* SuperH SCIF device driver.
* Copyright (C) 2013 Renesas Electronics Corporation
- * Copyright (C) 2007,2008,2010 Nobuhiro Iwamatsu
+ * Copyright (C) 2007,2008,2010, 2014 Nobuhiro Iwamatsu
* Copyright (C) 2002 - 2008 Paul Mundt
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
+#include <errno.h>
+#include <dm.h>
#include <asm/io.h>
#include <asm/processor.h>
-#include "serial_sh.h"
#include <serial.h>
#include <linux/compiler.h>
-
-#if defined(CONFIG_CONS_SCIF0)
-# define SCIF_BASE SCIF0_BASE
-#elif defined(CONFIG_CONS_SCIF1)
-# define SCIF_BASE SCIF1_BASE
-#elif defined(CONFIG_CONS_SCIF2)
-# define SCIF_BASE SCIF2_BASE
-#elif defined(CONFIG_CONS_SCIF3)
-# define SCIF_BASE SCIF3_BASE
-#elif defined(CONFIG_CONS_SCIF4)
-# define SCIF_BASE SCIF4_BASE
-#elif defined(CONFIG_CONS_SCIF5)
-# define SCIF_BASE SCIF5_BASE
-#elif defined(CONFIG_CONS_SCIF6)
-# define SCIF_BASE SCIF6_BASE
-#elif defined(CONFIG_CONS_SCIF7)
-# define SCIF_BASE SCIF7_BASE
-#else
-# error "Default SCIF doesn't set....."
-#endif
-
-#if defined(CONFIG_SCIF_A)
- #define SCIF_BASE_PORT PORT_SCIFA
-#else
- #define SCIF_BASE_PORT PORT_SCIF
-#endif
-
-static struct uart_port sh_sci = {
- .membase = (unsigned char*)SCIF_BASE,
- .mapbase = SCIF_BASE,
- .type = SCIF_BASE_PORT,
-};
-
-static void sh_serial_setbrg(void)
-{
- DECLARE_GLOBAL_DATA_PTR;
-#ifdef CONFIG_SCIF_USE_EXT_CLK
- unsigned short dl = DL_VALUE(gd->baudrate, CONFIG_SH_SCIF_CLK_FREQ);
- sci_out(&sh_sci, DL, dl);
- /* Need wait: Clock * 1/dl $B!_(B 1/16 */
- udelay((1000000 * dl * 16 / CONFIG_SYS_CLK_FREQ) * 1000 + 1);
-#else
- sci_out(&sh_sci, SCBRR,
- SCBRR_VALUE(gd->baudrate, CONFIG_SH_SCIF_CLK_FREQ));
-#endif
-}
-
-static int sh_serial_init(void)
-{
- sci_out(&sh_sci, SCSCR , SCSCR_INIT(&sh_sci));
- sci_out(&sh_sci, SCSCR , SCSCR_INIT(&sh_sci));
- sci_out(&sh_sci, SCSMR, 0);
- sci_out(&sh_sci, SCSMR, 0);
- sci_out(&sh_sci, SCFCR, SCFCR_RFRST|SCFCR_TFRST);
- sci_in(&sh_sci, SCFCR);
- sci_out(&sh_sci, SCFCR, 0);
-
- serial_setbrg();
- return 0;
-}
+#include <dm/platform_data/serial_sh.h>
+#include "serial_sh.h"
#if defined(CONFIG_CPU_SH7760) || \
defined(CONFIG_CPU_SH7780) || \
@@ -86,7 +29,7 @@ static int scif_rxfill(struct uart_port *port)
static int scif_rxfill(struct uart_port *port)
{
if ((port->mapbase == 0xffe00000) ||
- (port->mapbase == 0xffe08000)) {
+ (port->mapbase == 0xffe08000)) {
/* SCIF0/1*/
return sci_in(port, SCRFDR) & 0xff;
} else {
@@ -109,80 +52,253 @@ static int scif_rxfill(struct uart_port *port)
}
#endif
-static int serial_rx_fifo_level(void)
+static void sh_serial_init_generic(struct uart_port *port)
{
- return scif_rxfill(&sh_sci);
+ sci_out(port, SCSCR , SCSCR_INIT(port));
+ sci_out(port, SCSCR , SCSCR_INIT(port));
+ sci_out(port, SCSMR, 0);
+ sci_out(port, SCSMR, 0);
+ sci_out(port, SCFCR, SCFCR_RFRST|SCFCR_TFRST);
+ sci_in(port, SCFCR);
+ sci_out(port, SCFCR, 0);
}
-static void handle_error(void)
+static void
+sh_serial_setbrg_generic(struct uart_port *port, int clk, int baudrate)
{
- sci_in(&sh_sci, SCxSR);
- sci_out(&sh_sci, SCxSR, SCxSR_ERROR_CLEAR(&sh_sci));
- sci_in(&sh_sci, SCLSR);
- sci_out(&sh_sci, SCLSR, 0x00);
+ if (port->clk_mode == EXT_CLK) {
+ unsigned short dl = DL_VALUE(baudrate, clk);
+ sci_out(port, DL, dl);
+ /* Need wait: Clock * 1/dl $B!_(B 1/16 */
+ udelay((1000000 * dl * 16 / clk) * 1000 + 1);
+ } else {
+ sci_out(port, SCBRR, SCBRR_VALUE(baudrate, clk));
+ }
}
-static void serial_raw_putc(const char c)
+static void handle_error(struct uart_port *port)
{
- while (1) {
- /* Tx fifo is empty */
- if (sci_in(&sh_sci, SCxSR) & SCxSR_TEND(&sh_sci))
- break;
- }
+ sci_in(port, SCxSR);
+ sci_out(port, SCxSR, SCxSR_ERROR_CLEAR(port));
+ sci_in(port, SCLSR);
+ sci_out(port, SCLSR, 0x00);
+}
+
+static int serial_raw_putc(struct uart_port *port, const char c)
+{
+ /* Tx fifo is empty */
+ if (!(sci_in(port, SCxSR) & SCxSR_TEND(port)))
+ return -EAGAIN;
- sci_out(&sh_sci, SCxTDR, c);
- sci_out(&sh_sci, SCxSR, sci_in(&sh_sci, SCxSR) & ~SCxSR_TEND(&sh_sci));
+ sci_out(port, SCxTDR, c);
+ sci_out(port, SCxSR, sci_in(port, SCxSR) & ~SCxSR_TEND(port));
+
+ return 0;
}
-static void sh_serial_putc(const char c)
+static int serial_rx_fifo_level(struct uart_port *port)
{
- if (c == '\n')
- serial_raw_putc('\r');
- serial_raw_putc(c);
+ return scif_rxfill(port);
}
-static int sh_serial_tstc(void)
+static int sh_serial_tstc_generic(struct uart_port *port)
{
- if (sci_in(&sh_sci, SCxSR) & SCIF_ERRORS) {
- handle_error();
+ if (sci_in(port, SCxSR) & SCIF_ERRORS) {
+ handle_error(port);
return 0;
}
- return serial_rx_fifo_level() ? 1 : 0;
+ return serial_rx_fifo_level(port) ? 1 : 0;
}
-
-static int serial_getc_check(void)
+static int serial_getc_check(struct uart_port *port)
{
unsigned short status;
- status = sci_in(&sh_sci, SCxSR);
+ status = sci_in(port, SCxSR);
if (status & SCIF_ERRORS)
- handle_error();
- if (sci_in(&sh_sci, SCLSR) & SCxSR_ORER(&sh_sci))
- handle_error();
- return status & (SCIF_DR | SCxSR_RDxF(&sh_sci));
+ handle_error(port);
+ if (sci_in(port, SCLSR) & SCxSR_ORER(port))
+ handle_error(port);
+ return status & (SCIF_DR | SCxSR_RDxF(port));
}
-static int sh_serial_getc(void)
+static int sh_serial_getc_generic(struct uart_port *port)
{
unsigned short status;
char ch;
- while (!serial_getc_check())
- ;
+ if (!serial_getc_check(port))
+ return -EAGAIN;
- ch = sci_in(&sh_sci, SCxRDR);
- status = sci_in(&sh_sci, SCxSR);
+ ch = sci_in(port, SCxRDR);
+ status = sci_in(port, SCxSR);
- sci_out(&sh_sci, SCxSR, SCxSR_RDxF_CLEAR(&sh_sci));
+ sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
if (status & SCIF_ERRORS)
- handle_error();
+ handle_error(port);
+
+ if (sci_in(port, SCLSR) & SCxSR_ORER(port))
+ handle_error(port);
+
+ return ch;
+}
+
+#ifdef CONFIG_DM_SERIAL
+
+static int sh_serial_pending(struct udevice *dev, bool input)
+{
+ struct uart_port *priv = dev_get_priv(dev);
+
+ return sh_serial_tstc_generic(priv);
+}
+
+static int sh_serial_putc(struct udevice *dev, const char ch)
+{
+ struct uart_port *priv = dev_get_priv(dev);
+
+ return serial_raw_putc(priv, ch);
+}
+
+static int sh_serial_getc(struct udevice *dev)
+{
+ struct uart_port *priv = dev_get_priv(dev);
+
+ return sh_serial_getc_generic(priv);
+}
+
+static int sh_serial_setbrg(struct udevice *dev, int baudrate)
+{
+ struct sh_serial_platdata *plat = dev_get_platdata(dev);
+ struct uart_port *priv = dev_get_priv(dev);
+
+ sh_serial_setbrg_generic(priv, plat->clk, baudrate);
+
+ return 0;
+}
+
+static int sh_serial_probe(struct udevice *dev)
+{
+ struct sh_serial_platdata *plat = dev_get_platdata(dev);
+ struct uart_port *priv = dev_get_priv(dev);
+
+ priv->membase = (unsigned char *)plat->base;
+ priv->mapbase = plat->base;
+ priv->type = plat->type;
+ priv->clk_mode = plat->clk_mode;
+
+ sh_serial_init_generic(priv);
+
+ return 0;
+}
+
+static const struct dm_serial_ops sh_serial_ops = {
+ .putc = sh_serial_putc,
+ .pending = sh_serial_pending,
+ .getc = sh_serial_getc,
+ .setbrg = sh_serial_setbrg,
+};
+
+U_BOOT_DRIVER(serial_sh) = {
+ .name = "serial_sh",
+ .id = UCLASS_SERIAL,
+ .probe = sh_serial_probe,
+ .ops = &sh_serial_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+ .priv_auto_alloc_size = sizeof(struct uart_port),
+};
+
+#else /* CONFIG_DM_SERIAL */
+
+#if defined(CONFIG_CONS_SCIF0)
+# define SCIF_BASE SCIF0_BASE
+#elif defined(CONFIG_CONS_SCIF1)
+# define SCIF_BASE SCIF1_BASE
+#elif defined(CONFIG_CONS_SCIF2)
+# define SCIF_BASE SCIF2_BASE
+#elif defined(CONFIG_CONS_SCIF3)
+# define SCIF_BASE SCIF3_BASE
+#elif defined(CONFIG_CONS_SCIF4)
+# define SCIF_BASE SCIF4_BASE
+#elif defined(CONFIG_CONS_SCIF5)
+# define SCIF_BASE SCIF5_BASE
+#elif defined(CONFIG_CONS_SCIF6)
+# define SCIF_BASE SCIF6_BASE
+#elif defined(CONFIG_CONS_SCIF7)
+# define SCIF_BASE SCIF7_BASE
+#else
+# error "Default SCIF doesn't set....."
+#endif
+
+#if defined(CONFIG_SCIF_A)
+ #define SCIF_BASE_PORT PORT_SCIFA
+#else
+ #define SCIF_BASE_PORT PORT_SCIF
+#endif
+
+static struct uart_port sh_sci = {
+ .membase = (unsigned char *)SCIF_BASE,
+ .mapbase = SCIF_BASE,
+ .type = SCIF_BASE_PORT,
+#ifdef CONFIG_SCIF_USE_EXT_CLK
+ .clk_mode = EXT_CLK,
+#endif
+};
+
+static void sh_serial_setbrg(void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+ struct uart_port *port = &sh_sci;
+
+ sh_serial_setbrg_generic(port, CONFIG_SH_SCIF_CLK_FREQ, gd->baudrate);
+}
+
+static int sh_serial_init(void)
+{
+ struct uart_port *port = &sh_sci;
+
+ sh_serial_init_generic(port);
+ serial_setbrg();
+
+ return 0;
+}
+
+static void sh_serial_putc(const char c)
+{
+ struct uart_port *port = &sh_sci;
+
+ if (c == '\n') {
+ while (1) {
+ if (serial_raw_putc(port, '\r') != -EAGAIN)
+ break;
+ }
+ }
+ while (1) {
+ if (serial_raw_putc(port, c) != -EAGAIN)
+ break;
+ }
+}
+
+static int sh_serial_tstc(void)
+{
+ struct uart_port *port = &sh_sci;
+
+ return sh_serial_tstc_generic(port);
+}
+
+static int sh_serial_getc(void)
+{
+ struct uart_port *port = &sh_sci;
+ int ch;
+
+ while (1) {
+ ch = sh_serial_getc_generic(port);
+ if (ch != -EAGAIN)
+ break;
+ }
- if (sci_in(&sh_sci, SCLSR) & SCxSR_ORER(&sh_sci))
- handle_error();
return ch;
}
@@ -206,3 +322,4 @@ __weak struct serial_device *default_serial_console(void)
{
return &sh_serial_drv;
}
+#endif /* CONFIG_DM_SERIAL */
diff --git a/drivers/serial/serial_sh.h b/drivers/serial/serial_sh.h
index ef88c8f273..528aa7351d 100644
--- a/drivers/serial/serial_sh.h
+++ b/drivers/serial/serial_sh.h
@@ -2,18 +2,16 @@
* Copy and modify from linux/drivers/serial/sh-sci.h
*/
+#include <dm/platform_data/serial_sh.h>
+
struct uart_port {
unsigned long iobase; /* in/out[bwl] */
unsigned char *membase; /* read/write[bwl] */
unsigned long mapbase; /* for ioremap */
- unsigned int type; /* port type */
+ enum sh_serial_type type; /* port type */
+ enum sh_clk_mode clk_mode; /* clock mode */
};
-#define PORT_SCI 52
-#define PORT_SCIF 53
-#define PORT_SCIFA 83
-#define PORT_SCIFB 93
-
#if defined(CONFIG_H83007) || defined(CONFIG_H83068)
#include <asm/regs306x.h>
#endif
@@ -526,6 +524,7 @@ SCIF_FNS(SCFDR, 0x1c, 16)
SCIF_FNS(SCxTDR, 0x20, 8)
SCIF_FNS(SCxRDR, 0x24, 8)
SCIF_FNS(SCLSR, 0x00, 0)
+SCIF_FNS(DL, 0x00, 0) /* dummy */
#elif defined(CONFIG_ARCH_SH7372) || \
defined(CONFIG_R8A7740)
SCIF_FNS(SCSMR, 0x00, 16)
@@ -541,6 +540,7 @@ SCIF_FNS(SCRFDR, 0x3c, 16)
SCIx_FNS(SCxTDR, 0x20, 8, 0x40, 8)
SCIx_FNS(SCxRDR, 0x24, 8, 0x60, 8)
SCIF_FNS(SCLSR, 0x00, 0)
+SCIF_FNS(DL, 0x00, 0) /* dummy */
#elif defined(CONFIG_CPU_SH7723) ||\
defined(CONFIG_CPU_SH7724)
SCIx_FNS(SCSMR, 0x00, 16, 0x00, 16)
@@ -555,6 +555,7 @@ SCIF_FNS(SCFER, 0x10, 16)
SCIF_FNS(SCFCR, 0x18, 16)
SCIF_FNS(SCFDR, 0x1c, 16)
SCIF_FNS(SCLSR, 0x24, 16)
+SCIF_FNS(DL, 0x00, 0) /* dummy */
#else
/* reg SCI/SH3 SCI/SH4 SCIF/SH3 SCIF/SH4 SCI/H8*/
/* name off sz off sz off sz off sz off sz*/
@@ -583,18 +584,21 @@ SCIF_FNS(SCRFDR, 0x0e, 16, 0x20, 16)
SCIF_FNS(SCSPTR, 0, 0, 0x24, 16)
SCIF_FNS(SCLSR, 0, 0, 0x28, 16)
#else
+
SCIF_FNS(SCFDR, 0x0e, 16, 0x1C, 16)
#if defined(CONFIG_CPU_SH7722)
SCIF_FNS(SCSPTR, 0, 0, 0, 0)
#else
SCIF_FNS(SCSPTR, 0, 0, 0x20, 16)
#endif
+SCIF_FNS(SCLSR, 0, 0, 0x24, 16)
+#endif
#if defined(CONFIG_R8A7790) || defined(CONFIG_R8A7791) || \
defined(CONFIG_R8A7793) || defined(CONFIG_R8A7794)
SCIF_FNS(DL, 0, 0, 0x30, 16)
SCIF_FNS(CKS, 0, 0, 0x34, 16)
-#endif
-SCIF_FNS(SCLSR, 0, 0, 0x24, 16)
+#else
+SCIF_FNS(DL, 0, 0, 0x0, 0) /* dummy */
#endif
#endif
#define sci_in(port, reg) sci_##reg##_in(port)
@@ -725,14 +729,14 @@ static inline int sci_rxd_in(struct uart_port *port)
#define SCBRR_VALUE(bps, clk) (((clk*2)+16*bps)/(32*bps)-1)
#elif defined(CONFIG_CPU_SH7723) ||\
defined(CONFIG_CPU_SH7724)
-static inline int scbrr_calc(struct uart_port port, int bps, int clk)
+static inline int scbrr_calc(struct uart_port *port, int bps, int clk)
{
- if (port.type == PORT_SCIF)
+ if (port->type == PORT_SCIF)
return (clk+16*bps)/(32*bps)-1;
else
return ((clk*2)+16*bps)/(16*bps)-1;
}
-#define SCBRR_VALUE(bps, clk) scbrr_calc(sh_sci, bps, clk)
+#define SCBRR_VALUE(bps, clk) scbrr_calc(port, bps, clk)
#elif defined(__H8300H__) || defined(__H8300S__)
#define SCBRR_VALUE(bps, clk) (((clk*1000/32)/bps)-1)
#elif defined(CONFIG_R8A7790) || defined(CONFIG_R8A7791) || \
@@ -742,3 +746,7 @@ static inline int scbrr_calc(struct uart_port port, int bps, int clk)
#else /* Generic SH */
#define SCBRR_VALUE(bps, clk) ((clk+16*bps)/(32*bps)-1)
#endif
+
+#ifndef DL_VALUE
+#define DL_VALUE(bps, clk) 0
+#endif
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index e1678e63e6..7ae2727cf7 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -2,5 +2,11 @@ config DM_SPI
bool "Enable Driver Model for SPI drivers"
depends on DM
help
- If you want to use driver model for SPI drivers, say Y.
- To use legacy SPI drivers, say N.
+ Enable driver model for SPI. The SPI slave interface
+ (spi_setup_slave(), spi_xfer(), etc.) is then implemented by
+ the SPI uclass. Drivers provide methods to access the SPI
+ buses that they control. The uclass interface is defined in
+ include/spi.h. The existing spi_slave structure is attached
+ as 'parent data' to every slave on each bus. Slaves
+ typically use driver-private data instead of extending the
+ spi_slave structure.
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
new file mode 100644
index 0000000000..3c6b36d1cf
--- /dev/null
+++ b/drivers/thermal/Kconfig
@@ -0,0 +1,7 @@
+config DM_THERMAL
+ bool "Driver support for thermal devices"
+ help
+ Enable support for temporary-sensing devices. Some SoCs have on-chip
+ temperature sensors to permit warnings, speed throttling or even
+ automatic power-off when the temperature gets too high or low. Other
+ devices may be discrete but connected on a suitable bus.
diff --git a/drivers/usb/musb-new/sunxi.c b/drivers/usb/musb-new/sunxi.c
index 778916df00..fe45db1e06 100644
--- a/drivers/usb/musb-new/sunxi.c
+++ b/drivers/usb/musb-new/sunxi.c
@@ -22,7 +22,9 @@
*/
#include <common.h>
#include <asm/arch/cpu.h>
+#include <asm/arch/gpio.h>
#include <asm/arch/usbc.h>
+#include <asm-generic/gpio.h>
#include "linux-compat.h"
#include "musb_core.h"
@@ -145,16 +147,6 @@ static void USBC_ForceIdToHigh(__iomem void *base)
musb_writel(base, USBC_REG_o_ISCR, reg_val);
}
-static void USBC_ForceVbusValidDisable(__iomem void *base)
-{
- u32 reg_val;
-
- reg_val = musb_readl(base, USBC_REG_o_ISCR);
- reg_val &= ~(0x03 << USBC_BP_ISCR_FORCE_VBUS_VALID);
- reg_val = USBC_WakeUp_ClearChangeDetect(reg_val);
- musb_writel(base, USBC_REG_o_ISCR, reg_val);
-}
-
static void USBC_ForceVbusValidToHigh(__iomem void *base)
{
u32 reg_val;
@@ -234,6 +226,33 @@ static int sunxi_musb_init(struct musb *musb)
pr_debug("%s():\n", __func__);
+ if (is_host_enabled(musb)) {
+ int vbus_det = sunxi_name_to_gpio(CONFIG_USB0_VBUS_DET);
+ if (vbus_det == -1) {
+ eprintf("Error invalid Vusb-det pin\n");
+ return -EINVAL;
+ }
+
+ err = gpio_request(vbus_det, "vbus0_det");
+ if (err)
+ return err;
+
+ err = gpio_direction_input(vbus_det);
+ if (err) {
+ gpio_free(vbus_det);
+ return err;
+ }
+
+ err = gpio_get_value(vbus_det);
+ if (err) {
+ eprintf("Error: A charger is plugged into the OTG\n");
+ gpio_free(vbus_det);
+ return -EIO;
+ }
+
+ gpio_free(vbus_det);
+ }
+
err = sunxi_usbc_request_resources(0);
if (err)
return err;
@@ -248,12 +267,11 @@ static int sunxi_musb_init(struct musb *musb)
if (is_host_enabled(musb)) {
/* Host mode */
USBC_ForceIdToLow(musb->mregs);
- USBC_ForceVbusValidToHigh(musb->mregs);
} else {
/* Peripheral mode */
USBC_ForceIdToHigh(musb->mregs);
- USBC_ForceVbusValidDisable(musb->mregs);
}
+ USBC_ForceVbusValidToHigh(musb->mregs);
return 0;
}
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index af2d47bd75..22a316b536 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -32,7 +32,6 @@ obj-$(CONFIG_VIDEO_IMX25LCDC) += imx25lcdc.o videomodes.o
obj-$(CONFIG_VIDEO_LCD_HITACHI_TX18D42VM) += hitachi_tx18d42vm_lcd.o
obj-$(CONFIG_VIDEO_LCD_SSD2828) += ssd2828.o
obj-$(CONFIG_VIDEO_MB862xx) += mb862xx.o videomodes.o
-obj-$(CONFIG_VIDEO_MB86R0xGDC) += mb86r0xgdc.o videomodes.o
obj-$(CONFIG_VIDEO_MX3) += mx3fb.o videomodes.o
obj-$(CONFIG_VIDEO_IPUV3) += mxc_ipuv3_fb.o ipu_common.o ipu_disp.o
obj-$(CONFIG_VIDEO_MXS) += mxsfb.o videomodes.o
diff --git a/drivers/video/mb86r0xgdc.c b/drivers/video/mb86r0xgdc.c
deleted file mode 100644
index bb7a7497cc..0000000000
--- a/drivers/video/mb86r0xgdc.c
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * (C) Copyright 2010
- * Matthias Weisser <weisserm@arcor.de>
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-/*
- * mb86r0xgdc.c - Graphic interface for Fujitsu MB86R0x integrated graphic
- * controller.
- */
-
-#include <common.h>
-
-#include <malloc.h>
-#include <asm/io.h>
-#include <asm/arch/hardware.h>
-#include <video_fb.h>
-#include "videomodes.h"
-
-/*
- * 4MB (at the end of system RAM)
- */
-#define VIDEO_MEM_SIZE 0x400000
-
-#define FB_SYNC_CLK_INV (1<<16) /* pixel clock inverted */
-
-/*
- * Graphic Device
- */
-static GraphicDevice mb86r0x;
-
-static void dsp_init(struct mb86r0x_gdc_dsp *dsp, char *modestr,
- u32 *videomem)
-{
- struct ctfb_res_modes var_mode;
- u32 dcm1, dcm2, dcm3;
- u16 htp, hdp, hdb, hsp, vtr, vsp, vdp;
- u8 hsw, vsw;
- u32 l2m, l2em, l2oa0, l2da0, l2oa1, l2da1;
- u16 l2dx, l2dy, l2wx, l2wy, l2ww, l2wh;
- unsigned long div;
- int bpp;
-
- bpp = video_get_params(&var_mode, modestr);
-
- if (bpp == 0) {
- var_mode.xres = 640;
- var_mode.yres = 480;
- var_mode.pixclock = 39721; /* 25MHz */
- var_mode.left_margin = 48;
- var_mode.right_margin = 16;
- var_mode.upper_margin = 33;
- var_mode.lower_margin = 10;
- var_mode.hsync_len = 96;
- var_mode.vsync_len = 2;
- var_mode.sync = 0;
- var_mode.vmode = 0;
- bpp = 15;
- }
-
- /* Fill memory with white */
- memset(videomem, 0xFF, var_mode.xres * var_mode.yres * 2);
-
- mb86r0x.winSizeX = var_mode.xres;
- mb86r0x.winSizeY = var_mode.yres;
-
- /* LCD base clock is ~ 660MHZ. We do calculations in kHz */
- div = 660000 / (1000000000L / var_mode.pixclock);
- if (div > 64)
- div = 64;
- if (0 == div)
- div = 1;
-
- dcm1 = (div - 1) << 8;
- dcm2 = 0x00000000;
- if (var_mode.sync & FB_SYNC_CLK_INV)
- dcm3 = 0x00000100;
- else
- dcm3 = 0x00000000;
-
- htp = var_mode.left_margin + var_mode.xres +
- var_mode.hsync_len + var_mode.right_margin;
- hdp = var_mode.xres;
- hdb = var_mode.xres;
- hsp = var_mode.xres + var_mode.right_margin;
- hsw = var_mode.hsync_len;
-
- vsw = var_mode.vsync_len;
- vtr = var_mode.upper_margin + var_mode.yres +
- var_mode.vsync_len + var_mode.lower_margin;
- vsp = var_mode.yres + var_mode.lower_margin;
- vdp = var_mode.yres;
-
- l2m = ((var_mode.yres - 1) << (0)) |
- (((var_mode.xres * 2) / 64) << (16)) |
- ((1) << (31));
-
- l2em = (1 << 0) | (1 << 1);
-
- l2oa0 = mb86r0x.frameAdrs;
- l2da0 = mb86r0x.frameAdrs;
- l2oa1 = mb86r0x.frameAdrs;
- l2da1 = mb86r0x.frameAdrs;
- l2dx = 0;
- l2dy = 0;
- l2wx = 0;
- l2wy = 0;
- l2ww = var_mode.xres;
- l2wh = var_mode.yres - 1;
-
- writel(dcm1, &dsp->dcm1);
- writel(dcm2, &dsp->dcm2);
- writel(dcm3, &dsp->dcm3);
-
- writew(htp, &dsp->htp);
- writew(hdp, &dsp->hdp);
- writew(hdb, &dsp->hdb);
- writew(hsp, &dsp->hsp);
- writeb(hsw, &dsp->hsw);
-
- writeb(vsw, &dsp->vsw);
- writew(vtr, &dsp->vtr);
- writew(vsp, &dsp->vsp);
- writew(vdp, &dsp->vdp);
-
- writel(l2m, &dsp->l2m);
- writel(l2em, &dsp->l2em);
- writel(l2oa0, &dsp->l2oa0);
- writel(l2da0, &dsp->l2da0);
- writel(l2oa1, &dsp->l2oa1);
- writel(l2da1, &dsp->l2da1);
- writew(l2dx, &dsp->l2dx);
- writew(l2dy, &dsp->l2dy);
- writew(l2wx, &dsp->l2wx);
- writew(l2wy, &dsp->l2wy);
- writew(l2ww, &dsp->l2ww);
- writew(l2wh, &dsp->l2wh);
-
- writel(dcm1 | (1 << 18) | (1 << 31), &dsp->dcm1);
-}
-
-void *video_hw_init(void)
-{
- struct mb86r0x_gdc *gdc = (struct mb86r0x_gdc *) MB86R0x_GDC_BASE;
- GraphicDevice *pGD = &mb86r0x;
- char *s;
- u32 *vid;
-
- memset(pGD, 0, sizeof(GraphicDevice));
-
- pGD->gdfIndex = GDF_15BIT_555RGB;
- pGD->gdfBytesPP = 2;
- pGD->memSize = VIDEO_MEM_SIZE;
- pGD->frameAdrs = PHYS_SDRAM + PHYS_SDRAM_SIZE - VIDEO_MEM_SIZE;
-
- vid = (u32 *)pGD->frameAdrs;
-
- s = getenv("videomode");
- if (s != NULL)
- dsp_init(&gdc->dsp0, s, vid);
-
- s = getenv("videomode1");
- if (s != NULL)
- dsp_init(&gdc->dsp1, s, vid);
-
- return pGD;
-}
diff --git a/drivers/video/sunxi_display.c b/drivers/video/sunxi_display.c
index f5f24fc020..4e12150027 100644
--- a/drivers/video/sunxi_display.c
+++ b/drivers/video/sunxi_display.c
@@ -18,6 +18,7 @@
#include <errno.h>
#include <fdtdec.h>
#include <fdt_support.h>
+#include <i2c.h>
#include <video_fb.h>
#include "videomodes.h"
#include "hitachi_tx18d42vm_lcd.h"
@@ -46,6 +47,7 @@ struct sunxi_display {
GraphicDevice graphic_device;
enum sunxi_monitor monitor;
unsigned int depth;
+ unsigned int fb_size;
} sunxi_display;
#ifdef CONFIG_VIDEO_HDMI
@@ -591,7 +593,7 @@ static void sunxi_lcdc_enable(void)
static void sunxi_lcdc_panel_enable(void)
{
- int pin;
+ int pin, reset_pin;
/*
* Start with backlight disabled to avoid the screen flashing to
@@ -609,6 +611,12 @@ static void sunxi_lcdc_panel_enable(void)
gpio_direction_output(pin, PWM_OFF);
}
+ reset_pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_RESET);
+ if (reset_pin != -1) {
+ gpio_request(reset_pin, "lcd_reset");
+ gpio_direction_output(reset_pin, 0); /* Assert reset */
+ }
+
/* Give the backlight some time to turn off and power up the panel. */
mdelay(40);
pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_POWER);
@@ -616,6 +624,9 @@ static void sunxi_lcdc_panel_enable(void)
gpio_request(pin, "lcd_power");
gpio_direction_output(pin, 1);
}
+
+ if (reset_pin != -1)
+ gpio_direction_output(reset_pin, 1); /* De-assert reset */
}
static void sunxi_lcdc_backlight_enable(void)
@@ -1020,6 +1031,12 @@ static void sunxi_mode_set(const struct ctfb_res_modes *mode,
mdelay(50); /* Wait for lcd controller power on */
hitachi_tx18d42vm_init();
}
+ if (IS_ENABLED(CONFIG_VIDEO_LCD_TL059WV5C0)) {
+ unsigned int orig_i2c_bus = i2c_get_bus_num();
+ i2c_set_bus_num(CONFIG_VIDEO_LCD_I2C_BUS);
+ i2c_reg_write(0x5c, 0x04, 0x42); /* Turn on the LCD */
+ i2c_set_bus_num(orig_i2c_bus);
+ }
sunxi_composer_mode_set(mode, address);
sunxi_lcdc_tcon0_mode_set(mode, false);
sunxi_composer_enable();
@@ -1060,6 +1077,11 @@ static const char *sunxi_get_mon_desc(enum sunxi_monitor monitor)
return NULL; /* never reached */
}
+ulong board_get_usable_ram_top(ulong total_size)
+{
+ return gd->ram_top - CONFIG_SUNXI_MAX_FB_SIZE;
+}
+
void *video_hw_init(void)
{
static GraphicDevice *graphic_device = &sunxi_display.graphic_device;
@@ -1075,10 +1097,6 @@ void *video_hw_init(void)
memset(&sunxi_display, 0, sizeof(struct sunxi_display));
- printf("Reserved %dkB of RAM for Framebuffer.\n",
- CONFIG_SUNXI_FB_SIZE >> 10);
- gd->fb_base = gd->ram_top;
-
video_get_ctfb_res_modes(RES_MODE_1024x768, 24, &mode,
&sunxi_display.depth, &options);
#ifdef CONFIG_VIDEO_HDMI
@@ -1169,6 +1187,17 @@ void *video_hw_init(void)
mode->yres, sunxi_get_mon_desc(sunxi_display.monitor));
}
+ sunxi_display.fb_size =
+ (mode->xres * mode->yres * 4 + 0xfff) & ~0xfff;
+ if (sunxi_display.fb_size > CONFIG_SUNXI_MAX_FB_SIZE) {
+ printf("Error need %dkB for fb, but only %dkB is reserved\n",
+ sunxi_display.fb_size >> 10,
+ CONFIG_SUNXI_MAX_FB_SIZE >> 10);
+ return NULL;
+ }
+
+ gd->fb_base = gd->bd->bi_dram[0].start +
+ gd->bd->bi_dram[0].size - sunxi_display.fb_size;
sunxi_engines_init();
sunxi_mode_set(mode, gd->fb_base - CONFIG_SYS_SDRAM_BASE);
@@ -1194,6 +1223,7 @@ int sunxi_simplefb_setup(void *blob)
{
static GraphicDevice *graphic_device = &sunxi_display.graphic_device;
int offset, ret;
+ u64 start, size;
const char *pipeline = NULL;
#ifdef CONFIG_MACH_SUN4I
@@ -1237,6 +1267,20 @@ int sunxi_simplefb_setup(void *blob)
return 0; /* Keep older kernels working */
}
+ /*
+ * Do not report the framebuffer as free RAM to the OS, note we cannot
+ * use fdt_add_mem_rsv() here, because then it is still seen as RAM,
+ * and e.g. Linux refuses to iomap RAM on ARM, see:
+ * linux/arch/arm/mm/ioremap.c around line 301.
+ */
+ start = gd->bd->bi_dram[0].start;
+ size = gd->bd->bi_dram[0].size - sunxi_display.fb_size;
+ ret = fdt_fixup_memory_banks(blob, &start, &size, 1);
+ if (ret) {
+ eprintf("Cannot setup simplefb: Error reserving memory\n");
+ return ret;
+ }
+
ret = fdt_setup_simplefb_node(blob, offset, gd->fb_base,
graphic_device->winSizeX, graphic_device->winSizeY,
graphic_device->winSizeX * graphic_device->gdfBytesPP,
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 1dc0f5aa10..482a4bd5be 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -10,7 +10,6 @@ obj-$(CONFIG_FTWDT010_WATCHDOG) += ftwdt010_wdt.o
ifneq (,$(filter $(SOC), mx31 mx35 mx5 mx6 vf610 ls102xa))
obj-y += imx_watchdog.o
endif
-obj-$(CONFIG_TNETV107X_WATCHDOG) += tnetv107x_wdt.o
obj-$(CONFIG_S5P) += s5p_wdt.o
obj-$(CONFIG_XILINX_TB_WATCHDOG) += xilinx_tb_wdt.o
obj-$(CONFIG_BFIN_WATCHDOG) += bfin_wdt.o
diff --git a/drivers/watchdog/tnetv107x_wdt.c b/drivers/watchdog/tnetv107x_wdt.c
deleted file mode 100644
index 3d3f366c02..0000000000
--- a/drivers/watchdog/tnetv107x_wdt.c
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * TNETV107X: Watchdog timer implementation (for reset)
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#include <common.h>
-#include <asm/io.h>
-#include <asm/arch/clock.h>
-
-#define MAX_DIV 0xFFFE0001
-
-struct wdt_regs {
- u32 kick_lock;
-#define KICK_LOCK_1 0x5555
-#define KICK_LOCK_2 0xaaaa
- u32 kick;
-
- u32 change_lock;
-#define CHANGE_LOCK_1 0x6666
-#define CHANGE_LOCK_2 0xbbbb
- u32 change;
-
- u32 disable_lock;
-#define DISABLE_LOCK_1 0x7777
-#define DISABLE_LOCK_2 0xcccc
-#define DISABLE_LOCK_3 0xdddd
- u32 disable;
-
- u32 prescale_lock;
-#define PRESCALE_LOCK_1 0x5a5a
-#define PRESCALE_LOCK_2 0xa5a5
- u32 prescale;
-};
-
-static struct wdt_regs* regs = (struct wdt_regs *)TNETV107X_WDT0_ARM_BASE;
-
-#define wdt_reg_read(reg) __raw_readl(&regs->reg)
-#define wdt_reg_write(reg, val) __raw_writel((val), &regs->reg)
-
-static int write_prescale_reg(unsigned long prescale_value)
-{
- wdt_reg_write(prescale_lock, PRESCALE_LOCK_1);
- if ((wdt_reg_read(prescale_lock) & 0x3) != 0x1)
- return -1;
-
- wdt_reg_write(prescale_lock, PRESCALE_LOCK_2);
- if ((wdt_reg_read(prescale_lock) & 0x3) != 0x3)
- return -1;
-
- wdt_reg_write(prescale, prescale_value);
-
- return 0;
-}
-
-static int write_change_reg(unsigned long initial_timer_value)
-{
- wdt_reg_write(change_lock, CHANGE_LOCK_1);
- if ((wdt_reg_read(change_lock) & 0x3) != 0x1)
- return -1;
-
- wdt_reg_write(change_lock, CHANGE_LOCK_2);
- if ((wdt_reg_read(change_lock) & 0x3) != 0x3)
- return -1;
-
- wdt_reg_write(change, initial_timer_value);
-
- return 0;
-}
-
-static int wdt_control(unsigned long disable_value)
-{
- wdt_reg_write(disable_lock, DISABLE_LOCK_1);
- if ((wdt_reg_read(disable_lock) & 0x3) != 0x1)
- return -1;
-
- wdt_reg_write(disable_lock, DISABLE_LOCK_2);
- if ((wdt_reg_read(disable_lock) & 0x3) != 0x2)
- return -1;
-
- wdt_reg_write(disable_lock, DISABLE_LOCK_3);
- if ((wdt_reg_read(disable_lock) & 0x3) != 0x3)
- return -1;
-
- wdt_reg_write(disable, disable_value);
- return 0;
-}
-
-static int wdt_set_period(unsigned long msec)
-{
- unsigned long change_value, count_value;
- unsigned long prescale_value = 1;
- unsigned long refclk_khz, maxdiv;
- int ret;
-
- refclk_khz = clk_get_rate(TNETV107X_LPSC_WDT_ARM);
- maxdiv = (MAX_DIV / refclk_khz);
-
- if ((!msec) || (msec > maxdiv))
- return -1;
-
- count_value = refclk_khz * msec;
- if (count_value > 0xffff) {
- change_value = count_value / 0xffff + 1;
- prescale_value = count_value / change_value;
- } else {
- change_value = count_value;
- }
-
- ret = write_prescale_reg(prescale_value - 1);
- if (ret)
- return ret;
-
- ret = write_change_reg(change_value);
- if (ret)
- return ret;
-
- return 0;
-}
-
-unsigned long last_wdt = -1;
-
-int wdt_start(unsigned long msecs)
-{
- int ret;
- ret = wdt_control(0);
- if (ret)
- return ret;
- ret = wdt_set_period(msecs);
- if (ret)
- return ret;
- ret = wdt_control(1);
- if (ret)
- return ret;
- ret = wdt_kick();
- last_wdt = msecs;
- return ret;
-}
-
-int wdt_stop(void)
-{
- last_wdt = -1;
- return wdt_control(0);
-}
-
-int wdt_kick(void)
-{
- wdt_reg_write(kick_lock, KICK_LOCK_1);
- if ((wdt_reg_read(kick_lock) & 0x3) != 0x1)
- return -1;
-
- wdt_reg_write(kick_lock, KICK_LOCK_2);
- if ((wdt_reg_read(kick_lock) & 0x3) != 0x3)
- return -1;
-
- wdt_reg_write(kick, 1);
- return 0;
-}
-
-void reset_cpu(ulong addr)
-{
- clk_enable(TNETV107X_LPSC_WDT_ARM);
- wdt_start(1);
- wdt_kick();
-}
OpenPOWER on IntegriCloud