* [U-Boot] [PATCH v2 01/10] ram: Add driver for MPC83xx
@ 2018-04-27 12:52 Mario Six
2018-04-27 12:52 ` [U-Boot] [PATCH v2 02/10] sysreset: Add get_status method Mario Six
` (6 more replies)
0 siblings, 7 replies; 19+ messages in thread
From: Mario Six @ 2018-04-27 12:52 UTC (permalink / raw)
To: u-boot
Add a RAM driver for the MPC83xx architecture.
Signed-off-by: Mario Six <mario.six@gdsys.cc>
---
v1 -> v2:
No changes
---
arch/powerpc/cpu/mpc83xx/spd_sdram.c | 4 +
drivers/ram/Kconfig | 8 +
drivers/ram/Makefile | 1 +
drivers/ram/mpc83xx_sdram.c | 948 +++++++++++++++++++++++++++++
include/dt-bindings/memory/mpc83xx-sdram.h | 143 +++++
include/mpc83xx.h | 6 +
6 files changed, 1110 insertions(+)
create mode 100644 drivers/ram/mpc83xx_sdram.c
create mode 100644 include/dt-bindings/memory/mpc83xx-sdram.h
diff --git a/arch/powerpc/cpu/mpc83xx/spd_sdram.c b/arch/powerpc/cpu/mpc83xx/spd_sdram.c
index 21ab0153fc..f1e2dbf7c4 100644
--- a/arch/powerpc/cpu/mpc83xx/spd_sdram.c
+++ b/arch/powerpc/cpu/mpc83xx/spd_sdram.c
@@ -11,6 +11,8 @@
* SPDX-License-Identifier: GPL-2.0+
*/
+#ifndef CONFIG_MPC83XX_SDRAM
+
#include <common.h>
#include <asm/processor.h>
#include <asm/io.h>
@@ -925,3 +927,5 @@ void ddr_enable_ecc(unsigned int dram_size)
__asm__ __volatile__ ("isync");
}
#endif /* CONFIG_DDR_ECC */
+
+#endif /* !CONFIG_MPC83XX_SDRAM */
diff --git a/drivers/ram/Kconfig b/drivers/ram/Kconfig
index 496e2b793b..18532e71be 100644
--- a/drivers/ram/Kconfig
+++ b/drivers/ram/Kconfig
@@ -34,4 +34,12 @@ config STM32_SDRAM
support external memories like sdram, psram & nand.
This driver is for the sdram memory interface with the FMC.
+config MPC83XX_SDRAM
+ bool "Enable MPC83XX SDRAM support"
+ depends on RAM
+ help
+ Enable support for the internal DDR Memory Controller of the MPC83xx
+ family of SoCs. Both static configurations, as well as configuring
+ the RAM through the use of SPD is supported via device tree settings.
+
source "drivers/ram/stm32mp1/Kconfig"
diff --git a/drivers/ram/Makefile b/drivers/ram/Makefile
index 3820d03aa4..4ad3604d16 100644
--- a/drivers/ram/Makefile
+++ b/drivers/ram/Makefile
@@ -5,6 +5,7 @@
# SPDX-License-Identifier: GPL-2.0+
#
obj-$(CONFIG_RAM) += ram-uclass.o
+obj-$(CONFIG_MPC83XX_SDRAM) += mpc83xx_sdram.o
obj-$(CONFIG_SANDBOX) += sandbox_ram.o
obj-$(CONFIG_STM32MP1_DDR) += stm32mp1/
obj-$(CONFIG_STM32_SDRAM) += stm32_sdram.o
diff --git a/drivers/ram/mpc83xx_sdram.c b/drivers/ram/mpc83xx_sdram.c
new file mode 100644
index 0000000000..1a73f7b3da
--- /dev/null
+++ b/drivers/ram/mpc83xx_sdram.c
@@ -0,0 +1,948 @@
+#define DEBUG
+
+#include <common.h>
+#include <dm.h>
+#include <ram.h>
+#include <asm/io.h>
+#include <dt-bindings/memory/mpc83xx-sdram.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define CSCONFIG_ENABLE 0x80000000
+
+#define BANK_BITS_2 0x00000000
+#define BANK_BITS_3 0x00004000
+
+#define ROW_BITS_12 0x00000000
+#define ROW_BITS_13 0x00000100
+#define ROW_BITS_14 0x00000200
+
+#define COL_BITS_8 0x00000000
+#define COL_BITS_9 0x00000001
+#define COL_BITS_10 0x00000002
+#define COL_BITS_11 0x00000003
+
+#define TIMING_CFG3_EXT_REFREC_SHIFT 16
+
+#define TIMING_CFG0_RWT_SHIFT 30
+#define TIMING_CFG0_WRT_SHIFT 28
+#define TIMING_CFG0_RRT_SHIFT 26
+#define TIMING_CFG0_WWT_SHIFT 24
+#define TIMING_CFG0_ACT_PD_EXIT_SHIFT 20
+#define TIMING_CFG0_PRE_PD_EXIT_SHIFT 16
+#define TIMING_CFG0_ODT_PD_EXIT_SHIFT 8
+#define TIMING_CFG0_MRS_CYC_SHIFT 0
+
+#define TIMING_CFG1_PRETOACT_SHIFT 28
+#define TIMING_CFG1_ACTTOPRE_SHIFT 24
+#define TIMING_CFG1_ACTTORW_SHIFT 20
+#define TIMING_CFG1_CASLAT_SHIFT 16
+#define TIMING_CFG1_REFREC_SHIFT 12
+#define TIMING_CFG1_WRREC_SHIFT 8
+#define TIMING_CFG1_ACTTOACT_SHIFT 4
+#define TIMING_CFG1_WRTORD_SHIFT 0
+
+#define TIMING_CFG2_CPO_SHIFT 23
+#define TIMING_CFG2_WR_DATA_DELAY_SHIFT 10
+#define TIMING_CFG2_ADD_LAT_SHIFT 28
+#define TIMING_CFG2_WR_LAT_DELAY_SHIFT 19
+#define TIMING_CFG2_RD_TO_PRE_SHIFT 13
+#define TIMING_CFG2_CKE_PLS_SHIFT 6
+#define TIMING_CFG2_FOUR_ACT_SHIFT 0
+
+#define SDRAM_CFG_SREN_SHIFT (31 - 1)
+#define SDRAM_CFG_ECC_EN_SHIFT (31 - 2)
+#define SDRAM_CFG_RD_EN_SHIFT (31 - 3)
+#define SDRAM_CFG_SDRAM_TYPE_SHIFT (31 - 7)
+#define SDRAM_CFG_DYN_PWR_SHIFT (31 - 10)
+#define SDRAM_CFG_DBW_SHIFT (31 - 12)
+#define SDRAM_CFG_NCAP_SHIFT (31 - 14)
+#define SDRAM_CFG_2T_EN_SHIFT (31 - 16)
+#define SDRAM_CFG_BA_INTLV_CTL_SHIFT (31 - 23)
+#define SDRAM_CFG_PCHB8_SHIFT (31 - 27)
+#define SDRAM_CFG_HSE_SHIFT (31 - 28)
+#define SDRAM_CFG_BI_SHIFT (31 - 31)
+
+#define SDRAM_CFG2_FRC_SR_SHIFT (31 - 0)
+#define SDRAM_CFG2_DLL_RST_DIS (31 - 2)
+#define SDRAM_CFG2_DQS_CFG (31 - 5)
+#define SDRAM_CFG2_ODT_CFG (31 - 10)
+#define SDRAM_CFG2_NUM_PR (31 - 19)
+
+#define SDRAM_MODE_ESD_SHIFT 16
+#define SDRAM_MODE_SD_SHIFT 0
+
+#define SDRAM_MODE2_ESD2_SHIFT (31 - 15)
+#define SDRAM_MODE2_ESD3_SHIFT (31 - 31)
+
+#define SDRAM_INTERVAL_REFINT_SHIFT 16
+#define SDRAM_INTERVAL_BSTOPRE_SHIFT 0
+
+#define SDRAM_CFG_MEM_EN 0x80000000
+
+int dram_init(void)
+{
+ struct udevice *ram_ctrl;
+ int ret;
+
+ /* Current assumption: There is only one RAM controller */
+ ret = uclass_first_device_err(UCLASS_RAM, &ram_ctrl);
+
+ if (ret) {
+ debug("uclass_first_device_err failed: %d\n", ret);
+ return ret;
+ }
+
+ /* Set gd->ram_size? */
+
+ return 0;
+}
+
+phys_size_t get_effective_memsize(void)
+{
+#ifndef CONFIG_VERY_BIG_RAM
+ return gd->ram_size;
+#else
+ /* limit stack to what we can reasonable map */
+ return ((gd->ram_size > CONFIG_MAX_MEM_MAPPED) ?
+ CONFIG_MAX_MEM_MAPPED : gd->ram_size);
+#endif
+}
+
+struct mpc83xx_sdram_priv {
+ ulong total_size;
+};
+
+int mpc83xx_sdram_static_init(ofnode node, u32 cs, u32 mapaddr, u32 size)
+{
+ immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
+ u32 msize = size;
+ u32 msize_log2 = __ilog2(msize);
+ u32 auto_precharge, odt_rd_cfg, odt_wr_cfg, bank_bits, row_bits,
+ col_bits;
+ u32 bank_bits_mask, row_bits_mask, col_bits_mask;
+
+ /* Configure the DDR local access window */
+ out_be32(&im->sysconf.ddrlaw[cs].bar, mapaddr & 0xfffff000);
+ out_be32(&im->sysconf.ddrlaw[cs].ar, LBLAWAR_EN | (msize_log2 - 1));
+
+ out_be32(&im->ddr.csbnds[cs].csbnds, (msize - 1) >> 24);
+
+ auto_precharge = ofnode_read_u32_default(node, "auto_precharge", 0);
+ switch (auto_precharge) {
+ case AUTO_PRECHARGE_ENABLE:
+ case AUTO_PRECHARGE_DISABLE:
+ break;
+ default:
+ debug("auto_precharge value invalid.\n");
+ return -EINVAL;
+ }
+
+ odt_rd_cfg = ofnode_read_u32_default(node, "odt_rd_cfg", 0);
+ switch (odt_rd_cfg) {
+#if defined(CONFIG_MPC830x) || defined(CONFIG_MPC831x) || \
+ defined(CONFIG_MPC8360) || defined(CONFIG_MPC837x)
+ case ODT_RD_NEVER:
+ case ODT_RD_ONLY_CURRENT:
+ case ODT_RD_ONLY_OTHER_CS:
+#if defined(CONFIG_MPC8360) || defined(CONFIG_MPC837x)
+ case ODT_RD_ONLY_OTHER_DIMM:
+#endif
+#endif
+ /* MPC832x only knows this value */
+ case ODT_RD_ALL:
+ break;
+ default:
+ debug("odt_rd_cfg value invalid.\n");
+ return -EINVAL;
+ }
+
+ odt_wr_cfg = ofnode_read_u32_default(node, "odt_wr_cfg", 0);
+ switch (odt_wr_cfg) {
+#if defined(CONFIG_MPC830x) || defined(CONFIG_MPC831x) || \
+ defined(CONFIG_MPC8360) || defined(CONFIG_MPC837x)
+ case ODT_WR_NEVER:
+ case ODT_WR_ONLY_CURRENT:
+ case ODT_WR_ONLY_OTHER_CS:
+#if defined(CONFIG_MPC8360) || defined(CONFIG_MPC837x)
+ case ODT_WR_ONLY_OTHER_DIMM:
+#endif
+#endif
+ /* MPC832x only knows this value */
+ case ODT_WR_ALL:
+ break;
+ default:
+ debug("odt_wr_cfg value invalid.\n");
+ return -EINVAL;
+ }
+
+ bank_bits = ofnode_read_u32_default(node, "bank_bits", 0);
+ switch (bank_bits) {
+ case 2:
+ bank_bits_mask = BANK_BITS_2;
+ break;
+ case 3:
+ bank_bits_mask = BANK_BITS_3;
+ break;
+ default:
+ debug("bank_bits value invalid.\n");
+ return -EINVAL;
+ }
+
+ row_bits = ofnode_read_u32_default(node, "row_bits", 0);
+ switch (row_bits) {
+ case 12:
+ row_bits_mask = ROW_BITS_12;
+ break;
+ case 13:
+ row_bits_mask = ROW_BITS_13;
+ break;
+ case 14:
+ row_bits_mask = ROW_BITS_14;
+ break;
+ default:
+ debug("row_bits value invalid.\n");
+ return -EINVAL;
+ }
+
+ col_bits = ofnode_read_u32_default(node, "col_bits", 0);
+ switch (col_bits) {
+ case 8:
+ col_bits_mask = COL_BITS_8;
+ break;
+ case 9:
+ col_bits_mask = COL_BITS_9;
+ break;
+ case 10:
+ col_bits_mask = COL_BITS_10;
+ break;
+ case 11:
+ col_bits_mask = COL_BITS_11;
+ break;
+ default:
+ debug("col_bits value invalid.\n");
+ return -EINVAL;
+ }
+
+ /* Write CS config value */
+ out_be32(&im->ddr.cs_config[cs], CSCONFIG_ENABLE | auto_precharge |
+ odt_rd_cfg | odt_wr_cfg |
+ bank_bits_mask | row_bits_mask |
+ col_bits_mask);
+ return 0;
+}
+
+int mpc83xx_sdram_spd_init(ofnode node, u32 cs, u32 mapaddr, u32 size)
+{
+ return 0;
+}
+
+static int mpc83xx_sdram_ofdata_to_platdata(struct udevice *dev)
+{
+ return 0;
+}
+
+static int mpc83xx_sdram_probe(struct udevice *dev)
+{
+ struct mpc83xx_sdram_priv *priv = dev_get_priv(dev);
+ immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
+ int res = 0;
+ ofnode subnode;
+ u32 dso, pz_override, nz_override, odt_term, ddr_type, mvref_sel, m_odr;
+ u32 ddrcdr;
+ u32 clock_adjust;
+ u32 ext_refresh_rec, ext_refresh_rec_mask;
+ u32 read_to_write, write_to_read, read_to_read, write_to_write,
+ active_powerdown_exit, precharge_powerdown_exit,
+ odt_powerdown_exit, mode_reg_set_cycle;
+ u32 timing_cfg_0;
+ u32 precharge_to_activate, activate_to_precharge,
+ activate_to_readwrite, mcas_latency, refresh_recovery,
+ last_data_to_precharge, activate_to_activate,
+ last_write_data_to_read;
+ u32 timing_cfg_1;
+ u32 additive_latency, mcas_to_preamble_override, write_latency,
+ read_to_precharge, write_cmd_to_write_data,
+ minimum_cke_pulse_width, four_activates_window;
+ u32 timing_cfg_2;
+ u32 self_refresh, ecc, registered_dram, sdram_type,
+ dynamic_power_management, databus_width, nc_auto_precharge,
+ timing_2t, bank_interleaving_ctrl, precharge_bit_8, half_strength,
+ bypass_initialization;
+ u32 sdram_cfg;
+ u32 force_self_refresh, dll_reset, dqs_config, odt_config,
+ posted_refreshes;
+ u32 sdram_cfg2;
+ u32 refresh_interval, precharge_interval, sdmode, esdmode, esdmode2,
+ esdmode3;
+ u32 sdram_interval;
+ u32 sdram_mode;
+ u32 sdram_mode2;
+
+ priv->total_size = 0;
+
+ /* Disable both banks initially (might be re-enabled in loop below) */
+ out_be32(&im->ddr.cs_config[0], 0);
+ out_be32(&im->ddr.cs_config[1], 0);
+
+ dso = dev_read_u32_default(dev, "driver_software_override", 0);
+ if (dso > 1) {
+ debug("driver_software_override value invalid.\n");
+ return -EINVAL;
+ }
+
+ pz_override = dev_read_u32_default(dev, "p_impedance_override", 0);
+
+ switch (pz_override) {
+ case DSO_P_IMPEDANCE_HIGHEST_Z:
+ case DSO_P_IMPEDANCE_MUCH_HIGHER_Z:
+ case DSO_P_IMPEDANCE_HIGHER_Z:
+ case DSO_P_IMPEDANCE_NOMINAL:
+ case DSO_P_IMPEDANCE_LOWER_Z:
+ break;
+ default:
+ debug("p_impedance_override value invalid.\n");
+ return -EINVAL;
+ }
+
+ nz_override = dev_read_u32_default(dev, "n_impedance_override", 0);
+
+ switch (nz_override) {
+ case DSO_N_IMPEDANCE_HIGHEST_Z:
+ case DSO_N_IMPEDANCE_MUCH_HIGHER_Z:
+ case DSO_N_IMPEDANCE_HIGHER_Z:
+ case DSO_N_IMPEDANCE_NOMINAL:
+ case DSO_N_IMPEDANCE_LOWER_Z:
+ break;
+ default:
+ debug("n_impedance_override value invalid.\n");
+ return -EINVAL;
+ }
+
+ odt_term = dev_read_u32_default(dev, "odt_termination_value", 0);
+ if (odt_term > 1) {
+ debug("odt_termination_value value invalid.\n");
+ return -EINVAL;
+ }
+
+ ddr_type = dev_read_u32_default(dev, "ddr_type", 0);
+ if (ddr_type > 1) {
+ debug("ddr_type value invalid.\n");
+ return -EINVAL;
+ }
+
+ mvref_sel = dev_read_u32_default(dev, "mvref_sel", 0);
+ if (mvref_sel > 1) {
+ debug("mvref_sel value invalid.\n");
+ return -EINVAL;
+ }
+
+ m_odr = dev_read_u32_default(dev, "m_odr", 0);
+ if (mvref_sel > 1) {
+ debug("m_odr value invalid.\n");
+ return -EINVAL;
+ }
+
+ ddrcdr = dso << (31 - 1) |
+ pz_override << (31 - 5) |
+ nz_override << (31 - 9) |
+ odt_term << (31 - 12) |
+ ddr_type << (31 - 13) |
+ mvref_sel << (31 - 29) |
+ m_odr << (31 - 30) | 1;
+
+ /* Configure the DDR control driver register */
+ out_be32(&im->sysconf.ddrcdr, ddrcdr);
+
+ dev_for_each_subnode(subnode, dev) {
+ u32 val[3];
+ u32 cs, addr, size;
+
+ /* CS, map address, size -> three values */
+ ofnode_read_u32_array(subnode, "reg", val, 3);
+
+ cs = val[0];
+ addr = val[1];
+ size = val[2];
+
+ if (cs > 1) {
+ debug("chip select value invalid.\n");
+ return -EINVAL;
+ }
+
+ /* TODO: Sanity check for size. */
+
+ if (ofnode_read_bool(subnode, "read-spd"))
+ res = mpc83xx_sdram_spd_init(subnode, cs, addr, size);
+ else
+ res = mpc83xx_sdram_static_init(subnode, cs, addr,
+ size);
+ if (res)
+ return res;
+ };
+
+ /* TODO: This should only occur for static configuration */
+
+ clock_adjust = dev_read_u32_default(dev, "clock_adjust", 0);
+ switch (clock_adjust) {
+ case CLOCK_ADJUST_025:
+ case CLOCK_ADJUST_05:
+ case CLOCK_ADJUST_075:
+ case CLOCK_ADJUST_1:
+ break;
+ default:
+ debug("clock_adjust value invalid.\n");
+ return -EINVAL;
+ }
+
+ /* Configure the DDR SDRAM Clock Control register */
+ out_be32(&im->ddr.sdram_clk_cntl, clock_adjust);
+
+ ext_refresh_rec = dev_read_u32_default(dev, "ext_refresh_rec", 0);
+ switch (ext_refresh_rec) {
+ case 0:
+ ext_refresh_rec_mask = 0 << TIMING_CFG3_EXT_REFREC_SHIFT;
+ break;
+ case 16:
+ ext_refresh_rec_mask = 1 << TIMING_CFG3_EXT_REFREC_SHIFT;
+ break;
+ case 32:
+ ext_refresh_rec_mask = 2 << TIMING_CFG3_EXT_REFREC_SHIFT;
+ break;
+ case 48:
+ ext_refresh_rec_mask = 3 << TIMING_CFG3_EXT_REFREC_SHIFT;
+ break;
+ case 64:
+ ext_refresh_rec_mask = 4 << TIMING_CFG3_EXT_REFREC_SHIFT;
+ break;
+ case 80:
+ ext_refresh_rec_mask = 5 << TIMING_CFG3_EXT_REFREC_SHIFT;
+ break;
+ case 96:
+ ext_refresh_rec_mask = 6 << TIMING_CFG3_EXT_REFREC_SHIFT;
+ break;
+ case 112:
+ ext_refresh_rec_mask = 7 << TIMING_CFG3_EXT_REFREC_SHIFT;
+ break;
+ default:
+ debug("ext_refresh_rec value invalid.\n");
+ return -EINVAL;
+ }
+
+ /* Configure the DDR SDRAM Timing Configuration 3 register */
+ out_be32(&im->ddr.timing_cfg_3, ext_refresh_rec_mask);
+
+ read_to_write = dev_read_u32_default(dev, "read_to_write", 0);
+ if (read_to_write > 3) {
+ debug("read_to_write value invalid.\n");
+ return -EINVAL;
+ }
+
+ write_to_read = dev_read_u32_default(dev, "write_to_read", 0);
+ if (write_to_read > 3) {
+ debug("write_to_read value invalid.\n");
+ return -EINVAL;
+ }
+
+ read_to_read = dev_read_u32_default(dev, "read_to_read", 0);
+ if (read_to_read > 3) {
+ debug("read_to_read value invalid.\n");
+ return -EINVAL;
+ }
+
+ write_to_write = dev_read_u32_default(dev, "write_to_write", 0);
+ if (write_to_write > 3) {
+ debug("write_to_write value invalid.\n");
+ return -EINVAL;
+ }
+
+ active_powerdown_exit =
+ dev_read_u32_default(dev, "active_powerdown_exit", 0);
+ if (active_powerdown_exit > 7) {
+ debug("active_powerdown_exit value invalid.\n");
+ return -EINVAL;
+ }
+
+ precharge_powerdown_exit =
+ dev_read_u32_default(dev, "precharge_powerdown_exit", 0);
+ if (precharge_powerdown_exit > 7) {
+ debug("precharge_powerdown_exit value invalid.\n");
+ return -EINVAL;
+ }
+
+ odt_powerdown_exit = dev_read_u32_default(dev, "odt_powerdown_exit", 0);
+ if (odt_powerdown_exit > 15) {
+ debug("odt_powerdown_exit value invalid.\n");
+ return -EINVAL;
+ }
+
+ mode_reg_set_cycle = dev_read_u32_default(dev, "mode_reg_set_cycle", 0);
+ if (mode_reg_set_cycle > 15) {
+ debug("mode_reg_set_cycle value invalid.\n");
+ return -EINVAL;
+ }
+
+ timing_cfg_0 = read_to_write << TIMING_CFG0_RWT_SHIFT |
+ write_to_read << TIMING_CFG0_WRT_SHIFT |
+ read_to_read << TIMING_CFG0_RRT_SHIFT |
+ write_to_write << TIMING_CFG0_WWT_SHIFT |
+ active_powerdown_exit << TIMING_CFG0_ACT_PD_EXIT_SHIFT |
+ precharge_powerdown_exit << TIMING_CFG0_PRE_PD_EXIT_SHIFT |
+ odt_powerdown_exit << TIMING_CFG0_ODT_PD_EXIT_SHIFT |
+ mode_reg_set_cycle << TIMING_CFG0_MRS_CYC_SHIFT;
+
+ out_be32(&im->ddr.timing_cfg_0, timing_cfg_0);
+
+ precharge_to_activate =
+ dev_read_u32_default(dev, "precharge_to_activate", 0);
+ if (precharge_to_activate > 7 || precharge_to_activate == 0) {
+ debug("precharge_to_activate value invalid.\n");
+ return -EINVAL;
+ }
+
+ activate_to_precharge =
+ dev_read_u32_default(dev, "activate_to_precharge", 0);
+ if (activate_to_precharge > 15 || activate_to_precharge == 0) {
+ debug("activate_to_precharge value invalid.\n");
+ return -EINVAL;
+ }
+
+ activate_to_readwrite =
+ dev_read_u32_default(dev, "activate_to_readwrite", 0);
+ if (activate_to_readwrite > 7 || activate_to_readwrite == 0) {
+ debug("activate_to_readwrite value invalid.\n");
+ return -EINVAL;
+ }
+
+ /* TODO: MPC8308 only supports caslat >= 3 clocks */
+ mcas_latency = dev_read_u32_default(dev, "mcas_latency", 0);
+ switch (mcas_latency) {
+ case CASLAT_20:
+ case CASLAT_25:
+ case CASLAT_30:
+ case CASLAT_35:
+ case CASLAT_40:
+ case CASLAT_45:
+ case CASLAT_50:
+ break;
+ default:
+ debug("ext_refresh_rec value invalid.\n");
+ return -EINVAL;
+ }
+
+ refresh_recovery = dev_read_u32_default(dev, "refresh_recovery", 0);
+ if (refresh_recovery > 23 || refresh_recovery < 8) {
+ debug("refresh_recovery value invalid.\n");
+ return -EINVAL;
+ }
+
+ last_data_to_precharge =
+ dev_read_u32_default(dev, "last_data_to_precharge", 0);
+ if (last_data_to_precharge > 7 || last_data_to_precharge == 0) {
+ debug("last_data_to_precharge value invalid.\n");
+ return -EINVAL;
+ }
+
+ activate_to_activate =
+ dev_read_u32_default(dev, "activate_to_activate", 0);
+ if (activate_to_activate > 7 || activate_to_activate == 0) {
+ debug("activate_to_activate value invalid.\n");
+ return -EINVAL;
+ }
+
+ last_write_data_to_read =
+ dev_read_u32_default(dev, "last_write_data_to_read", 0);
+ if (last_write_data_to_read > 7 || last_write_data_to_read == 0) {
+ debug("last_write_data_to_read value invalid.\n");
+ return -EINVAL;
+ }
+
+ timing_cfg_1 = precharge_to_activate << TIMING_CFG1_PRETOACT_SHIFT |
+ activate_to_precharge << TIMING_CFG1_ACTTOPRE_SHIFT |
+ activate_to_readwrite << TIMING_CFG1_ACTTORW_SHIFT |
+ mcas_latency << TIMING_CFG1_CASLAT_SHIFT |
+ (refresh_recovery - 8) << TIMING_CFG1_REFREC_SHIFT |
+ last_data_to_precharge << TIMING_CFG1_WRREC_SHIFT |
+ activate_to_activate << TIMING_CFG1_ACTTOACT_SHIFT |
+ last_write_data_to_read << TIMING_CFG1_WRTORD_SHIFT;
+
+ /* Configure the DDR SDRAM Timing Configuration 1 register */
+ out_be32(&im->ddr.timing_cfg_1, timing_cfg_1);
+
+ additive_latency = dev_read_u32_default(dev, "additive_latency", 0);
+ if (additive_latency > 5) {
+ debug("additive_latency value invalid.\n");
+ return -EINVAL;
+ }
+
+ mcas_to_preamble_override =
+ dev_read_u32_default(dev, "mcas_to_preamble_override", 0);
+ switch (mcas_to_preamble_override) {
+ case READ_LAT_PLUS_1:
+ case READ_LAT:
+ case READ_LAT_PLUS_1_4:
+ case READ_LAT_PLUS_1_2:
+ case READ_LAT_PLUS_3_4:
+ case READ_LAT_PLUS_5_4:
+ case READ_LAT_PLUS_3_2:
+ case READ_LAT_PLUS_7_4:
+ case READ_LAT_PLUS_2:
+ case READ_LAT_PLUS_9_4:
+ case READ_LAT_PLUS_5_2:
+ case READ_LAT_PLUS_11_4:
+ case READ_LAT_PLUS_3:
+ case READ_LAT_PLUS_13_4:
+ case READ_LAT_PLUS_7_2:
+ case READ_LAT_PLUS_15_4:
+ case READ_LAT_PLUS_4:
+ case READ_LAT_PLUS_17_4:
+ case READ_LAT_PLUS_9_2:
+ case READ_LAT_PLUS_19_4:
+ break;
+ default:
+ debug("mcas_to_preamble_override value invalid.\n");
+ return -EINVAL;
+ }
+
+ write_latency = dev_read_u32_default(dev, "write_latency", 0);
+ if (write_latency > 7 || write_latency == 0) {
+ debug("write_latency value invalid.\n");
+ return -EINVAL;
+ }
+
+ read_to_precharge = dev_read_u32_default(dev, "read_to_precharge", 0);
+ if (read_to_precharge > 4 || read_to_precharge == 0) {
+ debug("read_to_precharge value invalid.\n");
+ return -EINVAL;
+ }
+
+ write_cmd_to_write_data =
+ dev_read_u32_default(dev, "write_cmd_to_write_data", 0);
+ switch (write_cmd_to_write_data) {
+ case CLOCK_DELAY_0:
+ case CLOCK_DELAY_1_4:
+ case CLOCK_DELAY_1_2:
+ case CLOCK_DELAY_3_4:
+ case CLOCK_DELAY_1:
+ case CLOCK_DELAY_5_4:
+ case CLOCK_DELAY_3_2:
+ break;
+ default:
+ debug("write_cmd_to_write_data value invalid.\n");
+ return -EINVAL;
+ }
+
+ minimum_cke_pulse_width =
+ dev_read_u32_default(dev, "minimum_cke_pulse_width", 0);
+ if (minimum_cke_pulse_width > 4 || minimum_cke_pulse_width == 0) {
+ debug("minimum_cke_pulse_width value invalid.\n");
+ return -EINVAL;
+ }
+
+ four_activates_window =
+ dev_read_u32_default(dev, "four_activates_window", 0);
+ if (four_activates_window > 20 || four_activates_window == 0) {
+ debug("four_activates_window value invalid.\n");
+ return -EINVAL;
+ }
+
+ timing_cfg_2 = additive_latency << TIMING_CFG2_ADD_LAT_SHIFT |
+ mcas_to_preamble_override << TIMING_CFG2_CPO_SHIFT |
+ write_latency << TIMING_CFG2_WR_LAT_DELAY_SHIFT |
+ read_to_precharge << TIMING_CFG2_RD_TO_PRE_SHIFT |
+ write_cmd_to_write_data << TIMING_CFG2_WR_DATA_DELAY_SHIFT |
+ minimum_cke_pulse_width << TIMING_CFG2_CKE_PLS_SHIFT |
+ four_activates_window << TIMING_CFG2_FOUR_ACT_SHIFT;
+
+ out_be32(&im->ddr.timing_cfg_2, timing_cfg_2);
+
+ self_refresh = dev_read_u32_default(dev, "self_refresh", 0);
+ switch (self_refresh) {
+ case SREN_DISABLE:
+ case SREN_ENABLE:
+ break;
+ default:
+ debug("self_refresh value invalid.\n");
+ return -EINVAL;
+ }
+
+ ecc = dev_read_u32_default(dev, "ecc", 0);
+ switch (ecc) {
+ case ECC_DISABLE:
+ case ECC_ENABLE:
+ break;
+ default:
+ debug("ecc value invalid.\n");
+ return -EINVAL;
+ }
+
+ registered_dram = dev_read_u32_default(dev, "registered_dram", 0);
+ switch (registered_dram) {
+ case RD_DISABLE:
+ case RD_ENABLE:
+ break;
+ default:
+ debug("registered_dram value invalid.\n");
+ return -EINVAL;
+ }
+
+ sdram_type = dev_read_u32_default(dev, "sdram_type", 0);
+ switch (sdram_type) {
+ case TYPE_DDR1:
+ case TYPE_DDR2:
+ break;
+ default:
+ debug("sdram_type value invalid.\n");
+ return -EINVAL;
+ }
+
+ dynamic_power_management =
+ dev_read_u32_default(dev, "dynamic_power_management", 0);
+ switch (dynamic_power_management) {
+ case DYN_PWR_DISABLE:
+ case DYN_PWR_ENABLE:
+ break;
+ default:
+ debug("dynamic_power_management value invalid.\n");
+ return -EINVAL;
+ }
+
+ databus_width = dev_read_u32_default(dev, "databus_width", 0);
+ switch (databus_width) {
+ case DATA_BUS_WIDTH_16:
+ case DATA_BUS_WIDTH_32:
+ break;
+ default:
+ debug("databus_width value invalid.\n");
+ return -EINVAL;
+ }
+
+ nc_auto_precharge = dev_read_u32_default(dev, "nc_auto_precharge", 0);
+ switch (nc_auto_precharge) {
+ case NCAP_DISABLE:
+ case NCAP_ENABLE:
+ break;
+ default:
+ debug("nc_auto_precharge value invalid.\n");
+ return -EINVAL;
+ }
+
+ timing_2t = dev_read_u32_default(dev, "timing_2t", 0);
+ switch (timing_2t) {
+ case TIMING_1T:
+ case TIMING_2T:
+ break;
+ default:
+ debug("timing_2t value invalid.\n");
+ return -EINVAL;
+ }
+
+ bank_interleaving_ctrl =
+ dev_read_u32_default(dev, "bank_interleaving_ctrl", 0);
+ switch (bank_interleaving_ctrl) {
+ case INTERLEAVE_NONE:
+ case INTERLEAVE_1_AND_2:
+ break;
+ default:
+ debug("bank_interleaving_ctrl value invalid.\n");
+ return -EINVAL;
+ }
+
+ precharge_bit_8 = dev_read_u32_default(dev, "precharge_bit_8", 0);
+ switch (precharge_bit_8) {
+ case PRECHARGE_MA_10:
+ case PRECHARGE_MA_8:
+ break;
+ default:
+ debug("precharge_bit_8 value invalid.\n");
+ return -EINVAL;
+ }
+
+ half_strength = dev_read_u32_default(dev, "half_strength", 0);
+ switch (half_strength) {
+ case STRENGTH_FULL:
+ case STRENGTH_HALF:
+ break;
+ default:
+ debug("half_strength value invalid.\n");
+ return -EINVAL;
+ }
+
+ bypass_initialization =
+ dev_read_u32_default(dev, "bypass_initialization", 0);
+ switch (bypass_initialization) {
+ case INITIALIZATION_DONT_BYPASS:
+ case INITIALIZATION_BYPASS:
+ break;
+ default:
+ debug("bypass_initialization value invalid.\n");
+ return -EINVAL;
+ }
+
+ sdram_cfg = self_refresh << SDRAM_CFG_SREN_SHIFT |
+ ecc << SDRAM_CFG_ECC_EN_SHIFT |
+ registered_dram << SDRAM_CFG_RD_EN_SHIFT |
+ sdram_type << SDRAM_CFG_SDRAM_TYPE_SHIFT |
+ dynamic_power_management << SDRAM_CFG_DYN_PWR_SHIFT |
+ databus_width << SDRAM_CFG_DBW_SHIFT |
+ nc_auto_precharge << SDRAM_CFG_NCAP_SHIFT |
+ timing_2t << SDRAM_CFG_2T_EN_SHIFT |
+ bank_interleaving_ctrl << SDRAM_CFG_BA_INTLV_CTL_SHIFT |
+ precharge_bit_8 << SDRAM_CFG_PCHB8_SHIFT |
+ half_strength << SDRAM_CFG_HSE_SHIFT |
+ bypass_initialization << SDRAM_CFG_BI_SHIFT;
+
+ out_be32(&im->ddr.sdram_cfg, sdram_cfg);
+
+ force_self_refresh = dev_read_u32_default(dev, "force_self_refresh", 0);
+ switch (force_self_refresh) {
+ case MODE_NORMAL:
+ case MODE_REFRESH:
+ break;
+ default:
+ debug("force_self_refresh value invalid.\n");
+ return -EINVAL;
+ }
+
+ dll_reset = dev_read_u32_default(dev, "dll_reset", 0);
+ switch (dll_reset) {
+ case DLL_RESET_ENABLE:
+ case DLL_RESET_DISABLE:
+ break;
+ default:
+ debug("dll_reset value invalid.\n");
+ return -EINVAL;
+ }
+
+ dqs_config = dev_read_u32_default(dev, "dqs_config", 0);
+ switch (dqs_config) {
+ case DQS_TRUE:
+ break;
+ default:
+ debug("dqs_config value invalid.\n");
+ return -EINVAL;
+ }
+
+ odt_config = dev_read_u32_default(dev, "odt_config", 0);
+ switch (odt_config) {
+ case ODT_ASSERT_NEVER:
+ case ODT_ASSERT_WRITES:
+ case ODT_ASSERT_READS:
+ case ODT_ASSERT_ALWAYS:
+ break;
+ default:
+ debug("odt_config value invalid.\n");
+ return -EINVAL;
+ }
+
+ posted_refreshes = dev_read_u32_default(dev, "posted_refreshes", 0);
+ if (posted_refreshes > 8 || posted_refreshes == 0) {
+ debug("posted_refreshes value invalid.\n");
+ return -EINVAL;
+ }
+
+ sdram_cfg2 = force_self_refresh << SDRAM_CFG2_FRC_SR_SHIFT |
+ dll_reset << SDRAM_CFG2_DLL_RST_DIS |
+ dqs_config << SDRAM_CFG2_DQS_CFG |
+ odt_config << SDRAM_CFG2_ODT_CFG |
+ posted_refreshes << SDRAM_CFG2_NUM_PR;
+
+ out_be32(&im->ddr.sdram_cfg2, sdram_cfg2);
+
+ sdmode = dev_read_u32_default(dev, "sdmode", 0);
+ if (sdmode > 0xFFFF) {
+ debug("sdmode value invalid.\n");
+ return -EINVAL;
+ }
+
+ esdmode = dev_read_u32_default(dev, "esdmode", 0);
+ if (esdmode > 0xFFFF) {
+ debug("esdmode value invalid.\n");
+ return -EINVAL;
+ }
+
+ sdram_mode = sdmode << SDRAM_MODE_SD_SHIFT |
+ esdmode << SDRAM_MODE_ESD_SHIFT;
+
+ out_be32(&im->ddr.sdram_mode, sdram_mode);
+
+ esdmode2 = dev_read_u32_default(dev, "esdmode2", 0);
+ if (esdmode2 > 0xFFFF) {
+ debug("esdmode2 value invalid.\n");
+ return -EINVAL;
+ }
+
+ esdmode3 = dev_read_u32_default(dev, "esdmode3", 0);
+ if (esdmode3 > 0xFFFF) {
+ debug("esdmode3 value invalid.\n");
+ return -EINVAL;
+ }
+
+ sdram_mode2 = esdmode2 << SDRAM_MODE2_ESD2_SHIFT |
+ esdmode3 << SDRAM_MODE2_ESD3_SHIFT;
+
+ out_be32(&im->ddr.sdram_mode2, sdram_mode2);
+
+ refresh_interval = dev_read_u32_default(dev, "refresh_interval", 0);
+ if (refresh_interval > 0xFFFF) {
+ debug("refresh_interval value invalid.\n");
+ return -EINVAL;
+ }
+
+ precharge_interval = dev_read_u32_default(dev, "precharge_interval", 0);
+ if (precharge_interval > 0x3FFF) {
+ debug("precharge_interval value invalid.\n");
+ return -EINVAL;
+ }
+
+ sdram_interval = refresh_interval << SDRAM_INTERVAL_REFINT_SHIFT |
+ precharge_interval << SDRAM_INTERVAL_BSTOPRE_SHIFT;
+
+ out_be32(&im->ddr.sdram_interval, sdram_interval);
+ sync();
+
+ /* Enable DDR controller */
+ setbits_be32(&im->ddr.sdram_cfg, SDRAM_CFG_MEM_EN);
+ sync();
+
+ dev_for_each_subnode(subnode, dev) {
+ u32 val[3];
+ u32 addr, size;
+
+ /* CS, map address, size -> three values */
+ ofnode_read_u32_array(subnode, "reg", val, 3);
+
+ addr = val[1];
+ size = val[2];
+
+ priv->total_size += get_ram_size((long int *)addr, size);
+ };
+
+ gd->ram_size = priv->total_size;
+
+ return 0;
+}
+
+static int mpc83xx_sdram_get_info(struct udevice *dev, struct ram_info *info)
+{
+ return 0;
+}
+
+static struct ram_ops mpc83xx_sdram_ops = {
+ .get_info = mpc83xx_sdram_get_info,
+};
+
+static const struct udevice_id mpc83xx_sdram_ids[] = {
+ { .compatible = "fsl,mpc83xx-mem-controller" },
+ { /* sentinel */ }
+};
+
+U_BOOT_DRIVER(mpc83xx_sdram) = {
+ .name = "mpc83xx_sdram",
+ .id = UCLASS_RAM,
+ .of_match = mpc83xx_sdram_ids,
+ .ops = &mpc83xx_sdram_ops,
+ .ofdata_to_platdata = mpc83xx_sdram_ofdata_to_platdata,
+ .probe = mpc83xx_sdram_probe,
+ .priv_auto_alloc_size = sizeof(struct mpc83xx_sdram_priv),
+};
diff --git a/include/dt-bindings/memory/mpc83xx-sdram.h b/include/dt-bindings/memory/mpc83xx-sdram.h
new file mode 100644
index 0000000000..0f970008b6
--- /dev/null
+++ b/include/dt-bindings/memory/mpc83xx-sdram.h
@@ -0,0 +1,143 @@
+#ifndef DT_BINDINGS_MPC83XX_SDRAM_H
+#define DT_BINDINGS_MPC83XX_SDRAM_H
+
+#define DSO_DISABLE 0
+#define DSO_ENABLE 1
+
+#define DSO_P_IMPEDANCE_HIGHEST_Z 0x0
+#define DSO_P_IMPEDANCE_MUCH_HIGHER_Z 0x8
+#define DSO_P_IMPEDANCE_HIGHER_Z 0xC
+#define DSO_P_IMPEDANCE_NOMINAL 0xE
+#define DSO_P_IMPEDANCE_LOWER_Z 0xF
+
+#define DSO_N_IMPEDANCE_HIGHEST_Z 0x0
+#define DSO_N_IMPEDANCE_MUCH_HIGHER_Z 0x8
+#define DSO_N_IMPEDANCE_HIGHER_Z 0xC
+#define DSO_N_IMPEDANCE_NOMINAL 0xE
+#define DSO_N_IMPEDANCE_LOWER_Z 0xF
+
+#define ODT_TERMINATION_75_OHM 0
+#define ODT_TERMINATION_150_OHM 1
+
+#define DDR_TYPE_DDR2_1_8_VOLT 0
+#define DDR_TYPE_DDR1_2_5_VOLT 1
+
+#define MVREF_SEL_EXTERNAL 0
+#define MVREF_SEL_INTERNAL_GVDD 1
+
+#define M_ODR_ENABLE 0
+#define M_ODR_DISABLE 1
+
+/* CS config register */
+
+#define AUTO_PRECHARGE_ENABLE 0x00800000
+#define AUTO_PRECHARGE_DISABLE 0x00000000
+
+#define ODT_RD_NEVER 0x00000000
+#define ODT_RD_ONLY_CURRENT 0x00100000
+#define ODT_RD_ONLY_OTHER_CS 0x00200000
+#define ODT_RD_ALL 0x00400000
+#define ODT_WR_NEVER 0x00000000
+#define ODT_WR_ONLY_CURRENT 0x00010000
+#define ODT_WR_ONLY_OTHER_CS 0x00020000
+#define ODT_WR_ALL 0x00040000
+
+/* DDR SDRAM Clock Control register */
+
+#define CLOCK_ADJUST_025 0x01000000
+#define CLOCK_ADJUST_05 0x02000000
+#define CLOCK_ADJUST_075 0x03000000
+#define CLOCK_ADJUST_1 0x04000000
+
+#define CASLAT_20 0x3 /* CAS latency = 2.0 */
+#define CASLAT_25 0x4 /* CAS latency = 2.5 */
+#define CASLAT_30 0x5 /* CAS latency = 3.0 */
+#define CASLAT_35 0x6 /* CAS latency = 3.5 */
+#define CASLAT_40 0x7 /* CAS latency = 4.0 */
+#define CASLAT_45 0x8 /* CAS latency = 4.5 */
+#define CASLAT_50 0x9 /* CAS latency = 5.0 */
+
+#define READ_LAT_PLUS_1 0x0
+#define READ_LAT 0x2
+#define READ_LAT_PLUS_1_4 0x3
+#define READ_LAT_PLUS_1_2 0x4
+#define READ_LAT_PLUS_3_4 0x5
+/* #define READ_LAT_PLUS_1 0x6 */
+#define READ_LAT_PLUS_5_4 0x7
+#define READ_LAT_PLUS_3_2 0x8
+#define READ_LAT_PLUS_7_4 0x9
+#define READ_LAT_PLUS_2 0xA
+#define READ_LAT_PLUS_9_4 0xB
+#define READ_LAT_PLUS_5_2 0xC
+#define READ_LAT_PLUS_11_4 0xD
+#define READ_LAT_PLUS_3 0xE
+#define READ_LAT_PLUS_13_4 0xF
+#define READ_LAT_PLUS_7_2 0x10
+#define READ_LAT_PLUS_15_4 0x11
+#define READ_LAT_PLUS_4 0x12
+#define READ_LAT_PLUS_17_4 0x13
+#define READ_LAT_PLUS_9_2 0x14
+#define READ_LAT_PLUS_19_4 0x15
+
+#define CLOCK_DELAY_0 0x0
+#define CLOCK_DELAY_1_4 0x1
+#define CLOCK_DELAY_1_2 0x2
+#define CLOCK_DELAY_3_4 0x3
+#define CLOCK_DELAY_1 0x4
+#define CLOCK_DELAY_5_4 0x5
+#define CLOCK_DELAY_3_2 0x6
+
+/* DDR SDRAM Control Configuration */
+
+#define SREN_DISABLE 0x0
+#define SREN_ENABLE 0x1
+
+#define ECC_DISABLE 0x0
+#define ECC_ENABLE 0x1
+
+#define RD_DISABLE 0x0
+#define RD_ENABLE 0x1
+
+#define TYPE_DDR1 0x2
+#define TYPE_DDR2 0x3
+
+#define DYN_PWR_DISABLE 0x0
+#define DYN_PWR_ENABLE 0x1
+
+#define DATA_BUS_WIDTH_16 0x1
+#define DATA_BUS_WIDTH_32 0x2
+
+#define NCAP_DISABLE 0x0
+#define NCAP_ENABLE 0x1
+
+#define TIMING_1T 0x0
+#define TIMING_2T 0x1
+
+#define INTERLEAVE_NONE 0x0
+#define INTERLEAVE_1_AND_2 0x1
+
+#define PRECHARGE_MA_10 0x0
+#define PRECHARGE_MA_8 0x1
+
+#define STRENGTH_FULL 0x0
+#define STRENGTH_HALF 0x1
+
+#define INITIALIZATION_DONT_BYPASS 0x0
+#define INITIALIZATION_BYPASS 0x1
+
+/* DDR SDRAM Control Configuration 2 */
+
+#define MODE_NORMAL 0x0
+#define MODE_REFRESH 0x1
+
+#define DLL_RESET_ENABLE 0x0
+#define DLL_RESET_DISABLE 0x1
+
+#define DQS_TRUE 0x0
+
+#define ODT_ASSERT_NEVER 0x0
+#define ODT_ASSERT_WRITES 0x1
+#define ODT_ASSERT_READS 0x2
+#define ODT_ASSERT_ALWAYS 0x3
+
+#endif
diff --git a/include/mpc83xx.h b/include/mpc83xx.h
index b5a0bbf847..26258126d6 100644
--- a/include/mpc83xx.h
+++ b/include/mpc83xx.h
@@ -1111,6 +1111,8 @@
#define CSBNDS_EA 0x000000FF
#define CSBNDS_EA_SHIFT 24
+#ifndef CONFIG_MPC83XX_SDRAM
+
/*
* CSn_CONFIG - Chip Select Configuration Register
*/
@@ -1408,6 +1410,8 @@
#define ECC_ERROR_MAN_SBEC (0xff000000 >> 24)
#define ECC_ERROR_MAN_SBEC_SHIFT 0
+#endif /* !CONFIG_MPC83XX_SDRAM */
+
/*
* CONFIG_ADDRESS - PCI Config Address Register
*/
@@ -1511,6 +1515,7 @@
*/
#define PMCCR1_POWER_OFF 0x00000020
+#ifndef CONFIG_RAM
/*
* DDRCDR - DDR Control Driver Register
*/
@@ -1532,6 +1537,7 @@
#define DDRCDR_DDR_CFG 0x00040000
#define DDRCDR_M_ODR 0x00000002
#define DDRCDR_Q_DRN 0x00000001
+#endif /* !CONFIG_RAM */
/*
* PCIE Bridge Register
--
2.16.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [U-Boot] [PATCH v2 02/10] sysreset: Add get_status method
2018-04-27 12:52 [U-Boot] [PATCH v2 01/10] ram: Add driver for MPC83xx Mario Six
@ 2018-04-27 12:52 ` Mario Six
2018-05-03 19:01 ` Simon Glass
2018-04-27 12:52 ` [U-Boot] [PATCH v2 03/10] board_f: Add reset status printing Mario Six
` (5 subsequent siblings)
6 siblings, 1 reply; 19+ messages in thread
From: Mario Six @ 2018-04-27 12:52 UTC (permalink / raw)
To: u-boot
It's useful to have the reset status of the SoC printed out during reset
(e.g. to learn whether the reset was caused by software or a watchdog).
As a first step to implement this, add a get_status method to the
sysreset class, which enables the caller to get printable information
about the reset status (akin to get_desc in the CPU uclass).
Signed-off-by: Mario Six <mario.six@gdsys.cc>
---
v1 -> v2:
New in v2
---
drivers/sysreset/sysreset-uclass.c | 10 ++++++++++
include/sysreset.h | 17 +++++++++++++++++
2 files changed, 27 insertions(+)
diff --git a/drivers/sysreset/sysreset-uclass.c b/drivers/sysreset/sysreset-uclass.c
index 0747c52b60..771a325b46 100644
--- a/drivers/sysreset/sysreset-uclass.c
+++ b/drivers/sysreset/sysreset-uclass.c
@@ -25,6 +25,16 @@ int sysreset_request(struct udevice *dev, enum sysreset_t type)
return ops->request(dev, type);
}
+int sysreset_get_status(struct udevice *dev, char *buf, int size)
+{
+ struct sysreset_ops *ops = sysreset_get_ops(dev);
+
+ if (!ops->get_status)
+ return -ENOSYS;
+
+ return ops->get_status(dev, buf, size);
+}
+
int sysreset_walk(enum sysreset_t type)
{
struct udevice *dev;
diff --git a/include/sysreset.h b/include/sysreset.h
index 393c7be3d8..9e326fefeb 100644
--- a/include/sysreset.h
+++ b/include/sysreset.h
@@ -29,6 +29,14 @@ struct sysreset_ops {
* (in which case this method will not actually return)
*/
int (*request)(struct udevice *dev, enum sysreset_t type);
+ /**
+ * get_status() - get printable reset status information
+ *
+ * @buf: Buffer to receive the textual reset information
+ * @size: Size of the passed buffer
+ * @return 0 if OK, -ve on error
+ */
+ int (*get_status)(struct udevice *dev, char *buf, int size);
};
#define sysreset_get_ops(dev) ((struct sysreset_ops *)(dev)->driver->ops)
@@ -41,6 +49,15 @@ struct sysreset_ops {
*/
int sysreset_request(struct udevice *dev, enum sysreset_t type);
+/**
+ * get_status() - get printable reset status information
+ *
+ * @buf: Buffer to receive the textual reset information
+ * @size: Size of the passed buffer
+ * @return 0 if OK, -ve on error
+ */
+int sysreset_get_status(struct udevice *dev, char *buf, int size);
+
/**
* sysreset_walk() - cause a system reset
*
--
2.16.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [U-Boot] [PATCH v2 03/10] board_f: Add reset status printing
2018-04-27 12:52 [U-Boot] [PATCH v2 01/10] ram: Add driver for MPC83xx Mario Six
2018-04-27 12:52 ` [U-Boot] [PATCH v2 02/10] sysreset: Add get_status method Mario Six
@ 2018-04-27 12:52 ` Mario Six
2018-05-03 19:01 ` Simon Glass
2018-04-27 12:52 ` [U-Boot] [PATCH v2 04/10] mpc83xx: Add sysreset driver Mario Six
` (4 subsequent siblings)
6 siblings, 1 reply; 19+ messages in thread
From: Mario Six @ 2018-04-27 12:52 UTC (permalink / raw)
To: u-boot
To print the reset status during boot, add a method print_resetinfo to
board_f, which is called in init_sequence_f[], that gets the reset
information from the sysreset driver (assuming there is only one seems
reasonable), and prints it.
Signed-off-by: Mario Six <mario.six@gdsys.cc>
---
v1 -> v2:
New in v2
---
common/board_f.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/common/board_f.c b/common/board_f.c
index ae8bdb7c5c..2df30cd250 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -25,6 +25,7 @@
#include <relocate.h>
#include <spi.h>
#include <status_led.h>
+#include <sysreset.h>
#include <timer.h>
#include <trace.h>
#include <video.h>
@@ -141,6 +142,21 @@ static int display_text_info(void)
return 0;
}
+#ifdef CONFIG_SYSRESET
+static int print_resetinfo(void)
+{
+ struct udevice *dev;
+ char status[256];
+
+ uclass_first_device_err(UCLASS_SYSRESET, &dev);
+
+ if (!sysreset_get_status(dev, status, sizeof(status)))
+ printf("%s", status);
+
+ return 0;
+}
+#endif
+
static int announce_dram_init(void)
{
puts("DRAM: ");
@@ -789,6 +805,9 @@ static const init_fnc_t init_sequence_f[] = {
#if defined(CONFIG_PPC) || defined(CONFIG_SH) || defined(CONFIG_X86)
checkcpu,
#endif
+#if defined(CONFIG_SYSRESET)
+ print_resetinfo,
+#endif
#if defined(CONFIG_DISPLAY_CPUINFO)
print_cpuinfo, /* display cpu info (and speed) */
#endif
--
2.16.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [U-Boot] [PATCH v2 04/10] mpc83xx: Add sysreset driver
2018-04-27 12:52 [U-Boot] [PATCH v2 01/10] ram: Add driver for MPC83xx Mario Six
2018-04-27 12:52 ` [U-Boot] [PATCH v2 02/10] sysreset: Add get_status method Mario Six
2018-04-27 12:52 ` [U-Boot] [PATCH v2 03/10] board_f: Add reset status printing Mario Six
@ 2018-04-27 12:52 ` Mario Six
2018-05-03 19:01 ` Simon Glass
2018-04-27 12:52 ` [U-Boot] [PATCH v2 05/10] clk: Add MPC83xx clock driver Mario Six
` (3 subsequent siblings)
6 siblings, 1 reply; 19+ messages in thread
From: Mario Six @ 2018-04-27 12:52 UTC (permalink / raw)
To: u-boot
Add a sysreset driver for the MPC83xx platform.
Signed-off-by: Mario Six <mario.six@gdsys.cc>
---
v1 -> v2:
New in v2
---
arch/powerpc/cpu/mpc83xx/cpu.c | 3 +-
drivers/sysreset/Kconfig | 5 ++
drivers/sysreset/Makefile | 9 +-
drivers/sysreset/sysreset_mpc83xx.c | 160 ++++++++++++++++++++++++++++++++++++
4 files changed, 172 insertions(+), 5 deletions(-)
create mode 100644 drivers/sysreset/sysreset_mpc83xx.c
diff --git a/arch/powerpc/cpu/mpc83xx/cpu.c b/arch/powerpc/cpu/mpc83xx/cpu.c
index 3bdebd845c..9a5c1b7d55 100644
--- a/arch/powerpc/cpu/mpc83xx/cpu.c
+++ b/arch/powerpc/cpu/mpc83xx/cpu.c
@@ -116,6 +116,7 @@ int checkcpu(void)
return 0;
}
+#ifndef CONFIG_SYSRESET
int
do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
@@ -170,7 +171,7 @@ do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
return 1;
}
-
+#endif
/*
* Get timebase clock frequency (like cpu_clk in Hz)
diff --git a/drivers/sysreset/Kconfig b/drivers/sysreset/Kconfig
index a6d48e8a66..fd89e5f474 100644
--- a/drivers/sysreset/Kconfig
+++ b/drivers/sysreset/Kconfig
@@ -37,4 +37,9 @@ config SYSRESET_WATCHDOG
help
Reboot support for generic watchdog reset.
+config SYSRESET_MCP83XX
+ bool "Enable support MPC83xx SoC family reboot driver"
+ help
+ Reboot support for NXP MPC83xx SoCs.
+
endmenu
diff --git a/drivers/sysreset/Makefile b/drivers/sysreset/Makefile
index 000c288eeb..faeb4b679f 100644
--- a/drivers/sysreset/Makefile
+++ b/drivers/sysreset/Makefile
@@ -5,11 +5,12 @@
#
obj-$(CONFIG_SYSRESET) += sysreset-uclass.o
+obj-$(CONFIG_ARCH_ASPEED) += sysreset_ast.o
+obj-$(CONFIG_ARCH_ROCKCHIP) += sysreset_rockchip.o
+obj-$(CONFIG_ARCH_STI) += sysreset_sti.o
+obj-$(CONFIG_SANDBOX) += sysreset_sandbox.o
+obj-$(CONFIG_SYSRESET_MCP83XX) += sysreset_mpc83xx.o
obj-$(CONFIG_SYSRESET_PSCI) += sysreset_psci.o
obj-$(CONFIG_SYSRESET_SYSCON) += sysreset_syscon.o
obj-$(CONFIG_SYSRESET_WATCHDOG) += sysreset_watchdog.o
-obj-$(CONFIG_ARCH_ROCKCHIP) += sysreset_rockchip.o
-obj-$(CONFIG_SANDBOX) += sysreset_sandbox.o
-obj-$(CONFIG_ARCH_STI) += sysreset_sti.o
obj-$(CONFIG_TARGET_XTFPGA) += sysreset_xtfpga.o
-obj-$(CONFIG_ARCH_ASPEED) += sysreset_ast.o
diff --git a/drivers/sysreset/sysreset_mpc83xx.c b/drivers/sysreset/sysreset_mpc83xx.c
new file mode 100644
index 0000000000..110192065e
--- /dev/null
+++ b/drivers/sysreset/sysreset_mpc83xx.c
@@ -0,0 +1,160 @@
+/*
+ * (C) Copyright 2018
+ * Mario Six, Guntermann & Drunck GmbH, mario.six at gdsys.cc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <sysreset.h>
+
+static void __do_reset(void)
+{
+ ulong msr;
+
+ immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
+
+ puts("Resetting the board.\n");
+
+ /* Interrupts and MMU off */
+ msr = mfmsr();
+ msr &= ~(MSR_EE | MSR_IR | MSR_DR);
+ mtmsr(msr);
+
+ /* enable Reset Control Reg */
+ out_be32(&immap->reset.rpr, 0x52535445);
+ sync();
+ isync();
+
+ /* confirm Reset Control Reg is enabled */
+
+ while (!(in_be32(&immap->reset.rcer) & RCER_CRE))
+ ;
+
+ udelay(200);
+
+ /* perform reset, only one bit */
+ out_be32(&immap->reset.rcr, RCR_SWHR);
+}
+
+int mpc83xx_sysreset_request(struct udevice *dev, enum sysreset_t type)
+{
+ switch (type) {
+ case SYSRESET_WARM:
+ case SYSRESET_COLD:
+ __do_reset();
+ break;
+ default:
+ return -EPROTONOSUPPORT;
+ }
+
+ return -EINPROGRESS;
+}
+
+#if defined(CONFIG_DISPLAY_AER_FULL)
+static int print_83xx_arb_event(int force)
+{
+ int etype = (gd->arch.arbiter_event_attributes & AEATR_EVENT)
+ >> AEATR_EVENT_SHIFT;
+ int mstr_id = (gd->arch.arbiter_event_attributes & AEATR_MSTR_ID)
+ >> AEATR_MSTR_ID_SHIFT;
+ int tbst = (gd->arch.arbiter_event_attributes & AEATR_TBST)
+ >> AEATR_TBST_SHIFT;
+ int tsize = (gd->arch.arbiter_event_attributes & AEATR_TSIZE)
+ >> AEATR_TSIZE_SHIFT;
+ int ttype = (gd->arch.arbiter_event_attributes & AEATR_TTYPE)
+ >> AEATR_TTYPE_SHIFT;
+
+ if (!force && !gd->arch.arbiter_event_address)
+ return 0;
+
+ puts("Arbiter Event Status:\n");
+ printf(" Event Address: 0x%08lX\n",
+ gd->arch.arbiter_event_address);
+ printf(" Event Type: 0x%1x = %s\n", etype, event[etype]);
+ printf(" Master ID: 0x%02x = %s\n", mstr_id, master[mstr_id]);
+ printf(" Transfer Size: 0x%1x = %d bytes\n", (tbst << 3) | tsize,
+ tbst ? (tsize ? tsize : 8) : 16 + 8 * tsize);
+ printf(" Transfer Type: 0x%02x = %s\n", ttype, transfer[ttype]);
+
+ return gd->arch.arbiter_event_address;
+}
+
+#elif defined(CONFIG_DISPLAY_AER_BRIEF)
+
+static int print_83xx_arb_event(int force, char *buf, int size)
+{
+ int res;
+
+ if (!force && !gd->arch.arbiter_event_address)
+ return 0;
+
+ res = snprintf(buf, size,
+ "Arbiter Event Status: AEATR=0x%08lX, AEADR=0x%08lX\n",
+ gd->arch.arbiter_event_attributes,
+ gd->arch.arbiter_event_address);
+
+ return res;
+}
+#endif /* CONFIG_DISPLAY_AER_xxxx */
+
+int mpc83xx_sysreset_get_status(struct udevice *dev, char *buf, int size)
+{
+ int res;
+ static const struct {
+ ulong mask;
+ char *desc;
+ } bits[] = {
+ {
+ RSR_SWSR, "Software Soft"}, {
+ RSR_SWHR, "Software Hard"}, {
+ RSR_JSRS, "JTAG Soft"}, {
+ RSR_CSHR, "Check Stop"}, {
+ RSR_SWRS, "Software Watchdog"}, {
+ RSR_BMRS, "Bus Monitor"}, {
+ RSR_SRS, "External/Internal Soft"}, {
+ RSR_HRS, "External/Internal Hard"}
+ };
+ static int n = ARRAY_SIZE(bits);
+ ulong rsr = gd->arch.reset_status;
+ int i;
+ char *sep;
+
+ res = snprintf(buf, size, "Reset Status:");
+ if (!res)
+ return -EIO;
+
+ buf += res;
+ size -= res;
+
+ sep = " ";
+ for (i = 0; i < n; i++)
+ if (rsr & bits[i].mask) {
+ res = snprintf(buf, size, "%s%s%s", sep, bits[i].desc, (i == n - 1) ? "\n" : "");
+ buf += res;
+ size -= res;
+ sep = ", ";
+ }
+
+/* TODO(mario.six@gdsys.cc): Move this into a dedicated arbiter driver */
+#if defined(CONFIG_DISPLAY_AER_FULL) || defined(CONFIG_DISPLAY_AER_BRIEF)
+ res = print_83xx_arb_event(rsr & RSR_BMRS, buf, size);
+ buf += res;
+ size -= res;
+#endif
+ snprintf(buf, size, "\n");
+
+ return 0;
+}
+
+static struct sysreset_ops mpc83xx_sysreset = {
+ .request = mpc83xx_sysreset_request,
+ .get_status = mpc83xx_sysreset_get_status,
+};
+
+U_BOOT_DRIVER(sysreset_mpc83xx) = {
+ .name = "mpc83xx_sysreset",
+ .id = UCLASS_SYSRESET,
+ .ops = &mpc83xx_sysreset,
+};
--
2.16.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [U-Boot] [PATCH v2 05/10] clk: Add MPC83xx clock driver
2018-04-27 12:52 [U-Boot] [PATCH v2 01/10] ram: Add driver for MPC83xx Mario Six
` (2 preceding siblings ...)
2018-04-27 12:52 ` [U-Boot] [PATCH v2 04/10] mpc83xx: Add sysreset driver Mario Six
@ 2018-04-27 12:52 ` Mario Six
2018-04-27 12:52 ` [U-Boot] [PATCH v2 06/10] timer: Add MPC83xx timer driver Mario Six
` (2 subsequent siblings)
6 siblings, 0 replies; 19+ messages in thread
From: Mario Six @ 2018-04-27 12:52 UTC (permalink / raw)
To: u-boot
Add a clock driver for the MPC83xx architecture.
Signed-off-by: Mario Six <mario.six@gdsys.cc>
---
v1 -> v2:
* Added binding of sysreset driver
---
arch/powerpc/cpu/mpc83xx/speed.c | 4 +
arch/powerpc/include/asm/config.h | 2 +-
drivers/clk/Kconfig | 6 +
drivers/clk/Makefile | 1 +
drivers/clk/mpc83xx_clk.c | 430 ++++++++++++++++++++++++++++++++++
drivers/clk/mpc83xx_clk.h | 115 +++++++++
include/dt-bindings/clk/mpc83xx-clk.h | 27 +++
7 files changed, 584 insertions(+), 1 deletion(-)
create mode 100644 drivers/clk/mpc83xx_clk.c
create mode 100644 drivers/clk/mpc83xx_clk.h
create mode 100644 include/dt-bindings/clk/mpc83xx-clk.h
diff --git a/arch/powerpc/cpu/mpc83xx/speed.c b/arch/powerpc/cpu/mpc83xx/speed.c
index 5498c19e25..c9bdec0bc0 100644
--- a/arch/powerpc/cpu/mpc83xx/speed.c
+++ b/arch/powerpc/cpu/mpc83xx/speed.c
@@ -7,6 +7,8 @@
* SPDX-License-Identifier: GPL-2.0+
*/
+#ifndef CONFIG_CLK_MPC83XX
+
#include <common.h>
#include <mpc83xx.h>
#include <command.h>
@@ -591,3 +593,5 @@ U_BOOT_CMD(clocks, 1, 0, do_clocks,
"print clock configuration",
" clocks"
);
+
+#endif
diff --git a/arch/powerpc/include/asm/config.h b/arch/powerpc/include/asm/config.h
index 39eeb39901..d9dfb670af 100644
--- a/arch/powerpc/include/asm/config.h
+++ b/arch/powerpc/include/asm/config.h
@@ -79,7 +79,7 @@
/* All PPC boards must swap IDE bytes */
#define CONFIG_IDE_SWAP_IO
-#if defined(CONFIG_DM_SERIAL)
+#if defined(CONFIG_DM_SERIAL) && !defined(CONFIG_CLK_MPC83XX)
/*
* TODO: Convert this to a clock driver exists that can give us the UART
* clock here.
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index c382e8865f..787c061e44 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -89,4 +89,10 @@ source "drivers/clk/exynos/Kconfig"
source "drivers/clk/at91/Kconfig"
source "drivers/clk/renesas/Kconfig"
+config CLK_MPC83XX
+ bool "Enable MPC83xx clock driver"
+ depends on CLK
+ help
+ Support for the clock driver of the MPC83xx series of SoCs.
+
endmenu
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index e05c607223..67da125669 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_CLK_BCM6345) += clk_bcm6345.o
obj-$(CONFIG_CLK_BOSTON) += clk_boston.o
obj-$(CONFIG_CLK_EXYNOS) += exynos/
obj-$(CONFIG_CLK_HSDK) += clk-hsdk-cgu.o
+obj-$(CONFIG_CLK_MPC83XX) += mpc83xx_clk.o
obj-$(CONFIG_CLK_RENESAS) += renesas/
obj-$(CONFIG_CLK_STM32F) += clk_stm32f.o
obj-$(CONFIG_CLK_STM32MP1) += clk_stm32mp1.o
diff --git a/drivers/clk/mpc83xx_clk.c b/drivers/clk/mpc83xx_clk.c
new file mode 100644
index 0000000000..96f762bfe1
--- /dev/null
+++ b/drivers/clk/mpc83xx_clk.c
@@ -0,0 +1,430 @@
+/*
+ * (C) Copyright 2017
+ * Mario Six, Guntermann & Drunck GmbH, mario.six at gdsys.cc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <dm/lists.h>
+#include <dt-bindings/clk/mpc83xx-clk.h>
+
+#include "mpc83xx_clk.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static u32 *speed;
+
+struct mpc83xx_clk_priv {
+ u32 *speed;
+};
+
+static const char * const names[] = {
+ [MPC83XX_CLK_CORE] = "Core",
+ [MPC83XX_CLK_CSB] = "Coherent System Bus",
+ [MPC83XX_CLK_QE] = "QE",
+ [MPC83XX_CLK_BRG] = "BRG",
+ [MPC83XX_CLK_LBIU] = "Local Bus Controller",
+ [MPC83XX_CLK_LCLK] = "Local Bus",
+ [MPC83XX_CLK_MEM] = "DDR",
+ [MPC83XX_CLK_MEM_SEC] = "DDR Secondary",
+ [MPC83XX_CLK_ENC] = "SEC",
+ [MPC83XX_CLK_I2C1] = "I2C1",
+ [MPC83XX_CLK_I2C2] = "I2C2",
+ [MPC83XX_CLK_TDM] = "TDM",
+ [MPC83XX_CLK_SDHC] = "SDHC",
+ [MPC83XX_CLK_TSEC1] = "TSEC1",
+ [MPC83XX_CLK_TSEC2] = "TSEC2",
+ [MPC83XX_CLK_USBDR] = "USB DR",
+ [MPC83XX_CLK_USBMPH] = "USB MPH",
+ [MPC83XX_CLK_PCIEXP1] = "PCIEXP1",
+ [MPC83XX_CLK_PCIEXP2] = "PCIEXP2",
+ [MPC83XX_CLK_SATA] = "SATA",
+ [MPC83XX_CLK_DMAC] = "DMAC",
+ [MPC83XX_CLK_PCI] = "PCI",
+};
+
+struct clk_mode {
+ u8 low;
+ u8 high;
+ int type;
+};
+
+const struct clk_mode modes[] = {
+
+ [MPC83XX_CLK_CORE] = {0, 0, TYPE_SPECIAL},
+ [MPC83XX_CLK_CSB] = {0, 0, TYPE_SPECIAL},
+ [MPC83XX_CLK_QE] = {0, 0, TYPE_SPECIAL},
+ [MPC83XX_CLK_BRG] = {0, 0, TYPE_SPECIAL},
+ [MPC83XX_CLK_MEM] = {1, 1, TYPE_SPMR_DIRECT_MULTIPLY },
+ [MPC83XX_CLK_LBIU] = {0, 0, TYPE_SPMR_DIRECT_MULTIPLY },
+ [MPC83XX_CLK_LCLK] = {0, 0, TYPE_SPECIAL},
+ [MPC83XX_CLK_MEM_SEC] = {0, 0, TYPE_SPMR_DIRECT_MULTIPLY }, /* The same as LBIU */
+#ifndef CONFIG_MPC8313
+ [MPC83XX_CLK_TSEC1] = {0, 1, TYPE_SCCR_STANDARD },
+ [MPC83XX_CLK_TSEC2] = {2, 3, TYPE_SCCR_STANDARD },
+#else
+ [MPC83XX_CLK_TSEC1] = {0, 1, TYPE_SCCR_STANDARD }, /* FIXME: This has separate enable/disable bit! */
+ [MPC83XX_CLK_TSEC2] = {0, 1, TYPE_SCCR_STANDARD }, /* FIXME: This has separate enable/disable bit! */
+#endif
+ [MPC83XX_CLK_SDHC] = {4, 5, TYPE_SCCR_STANDARD },
+#ifdef CONFIG_MPC834x
+ [MPC83XX_CLK_ENC] = {6, 7, TYPE_SCCR_STANDARD },
+ [MPC83XX_CLK_I2C1] = {2, 3, TYPE_SCCR_STANDARD }, /* I2C and TSEC2 are the same register */
+#else
+ [MPC83XX_CLK_ENC] = {6, 7, TYPE_SCCR_STANDARD },
+ [MPC83XX_CLK_I2C1] = {6, 7, TYPE_SCCR_STANDARD }, /* I2C and ENC are the same register */
+#endif
+ [MPC83XX_CLK_I2C2] = {0, 0, TYPE_SPECIAL },
+ [MPC83XX_CLK_PCIEXP1] = {10, 11, TYPE_SCCR_STANDARD },
+ [MPC83XX_CLK_PCIEXP2] = {12, 13, TYPE_SCCR_STANDARD },
+#if defined(CONFIG_MPC8313) || defined(CONFIG_MPC834x)
+ [MPC83XX_CLK_USBDR] = {10, 11, TYPE_SCCR_STANDARD },
+#else
+ [MPC83XX_CLK_USBDR] = {8, 9, TYPE_SCCR_STANDARD },
+#endif
+ [MPC83XX_CLK_USBMPH] = {8, 9, TYPE_SCCR_STANDARD },
+ [MPC83XX_CLK_PCI] = {15, 15, TYPE_SCCR_ONOFF },
+#if defined(CONFIG_MPC8308) || defined(CONFIG_MPC8309)
+ [MPC83XX_CLK_DMAC] = {26, 27, TYPE_SCCR_STANDARD },
+#endif
+#if 0
+/* FIXME: All SATA controllers must have the same clock ratio */
+#ifdef CONFIG_MPC83XX_SATA_SUPPORT
+#ifdef CONFIG_MPC8379
+ [MPC83XX_CLK_SATA] = {24, 25, TYPE_SCCR_STANDARD },
+ [MPC83XX_CLK_SATA] = {26, 27, TYPE_SCCR_STANDARD },
+ [MPC83XX_CLK_SATA] = {28, 29, TYPE_SCCR_STANDARD },
+ [MPC83XX_CLK_SATA] = {30, 31, TYPE_SCCR_STANDARD },
+#else
+ [MPC83XX_CLK_SATA] = {18, 19, TYPE_SCCR_STANDARD },
+ [MPC83XX_CLK_SATA] = {20, 21, TYPE_SCCR_STANDARD },
+#endif
+#endif
+#endif
+ [MPC83XX_CLK_TDM] = {26, 27, TYPE_SCCR_STANDARD },
+};
+
+int get_clocks(void)
+{
+ return 0;
+}
+
+inline bool is_clk_valid(int id)
+{
+ switch (id) {
+ case MPC83XX_CLK_MEM:
+#if defined(CONFIG_MPC8360)
+ case MPC83XX_CLK_MEM_SEC:
+#endif
+#ifndef CONFIG_MPC830x
+ case MPC83XX_CLK_ENC:
+#endif
+ case MPC83XX_CLK_I2C1:
+#ifdef CONFIG_MPC8315
+ case MPC83XX_CLK_TDM:
+#endif
+#ifdef CONFIG_MPC83XX_SDHC_SUPPORT
+ case MPC83XX_CLK_SDHC:
+#endif
+#ifdef CONFIG_MPC83XX_TSEC1_SUPPORT
+ case MPC83XX_CLK_TSEC1:
+#endif
+#ifdef CONFIG_MPC83XX_TSEC2_SUPPORT
+ case MPC83XX_CLK_TSEC2:
+#endif
+#if !defined(CONFIG_MPC8360)
+ case MPC83XX_CLK_USBDR:
+#endif
+#ifdef CONFIG_MPC834x
+ case MPC83XX_CLK_USBMPH:
+#endif
+#ifdef CONFIG_MPC83XX_PCIE1_SUPPORT
+ case MPC83XX_CLK_PCIEXP1:
+#endif
+#ifdef CONFIG_MPC83XX_PCIE2_SUPPORT
+ case MPC83XX_CLK_PCIEXP2:
+#endif
+#ifdef CONFIG_MPC83XX_SATA_SUPPORT
+ case MPC83XX_CLK_SATA:
+#endif
+#ifdef CONFIG_MPC830x
+ case MPC83XX_CLK_DMAC:
+#endif
+#ifdef CONFIG_MPC83XX_PCI_SUPPORT
+ case MPC83XX_CLK_PCI:
+#endif
+ case MPC83XX_CLK_CSB:
+#ifdef CONFIG_MPC83XX_SECOND_I2C_SUPPORT
+ case MPC83XX_CLK_I2C2:
+#endif
+#if defined(CONFIG_MPC83XX_QUICC_ENGINE) && !defined(CONFIG_MPC8309)
+ case MPC83XX_CLK_QE:
+ case MPC83XX_CLK_BRG:
+#endif
+ case MPC83XX_CLK_LCLK:
+ case MPC83XX_CLK_LBIU:
+ case MPC83XX_CLK_CORE:
+ return true;
+ }
+
+ return false;
+}
+
+static int mpc83xx_clk_request(struct clk *clock)
+{
+ /* Reject requests of clocks that are not available */
+ if (is_clk_valid(clock->id))
+ return 0;
+ else
+ return -ENODEV;
+}
+
+static inline void init_clks(u32 *speed)
+{
+ int i;
+ immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
+ u32 csb_clk = get_csb_clk(im);
+
+ for (i = 0; i < MPC83XX_CLK_COUNT; i++) {
+ struct clk_mode mode = modes[i];
+ ulong mask;
+
+ if (mode.type == TYPE_INVALID)
+ continue;
+
+ if (mode.type == TYPE_SCCR_STANDARD) {
+ mask = GENMASK(31 - mode.low, 31 - mode.high);
+
+ switch (sccr_field(im, mask, 31 - mode.high)) {
+ case 0:
+ speed[i] = 0;
+ break;
+ case 1:
+ speed[i] = csb_clk;
+ break;
+ case 2:
+ speed[i] = csb_clk / 2;
+ break;
+ case 3:
+ speed[i] = csb_clk / 3;
+ break;
+ default:
+ speed[i] = 0;
+ }
+
+ continue;
+ }
+
+ if (mode.type == TYPE_SPMR_DIRECT_MULTIPLY) {
+ mask = GENMASK(31 - mode.low, 31 - mode.high);
+
+ speed[i] = csb_clk * (1 + sccr_field(im, mask, 31 - mode.high));
+ continue;
+ }
+
+ if (i == MPC83XX_CLK_CSB || i == MPC83XX_CLK_I2C2) {
+ speed[i] = csb_clk; /* i2c-2 clk is equal to csb clk */
+ continue;
+ }
+
+ if (i == MPC83XX_CLK_QE || i == MPC83XX_CLK_BRG) {
+ u32 pci_sync_in = get_pci_sync_in(im);
+ u32 qepmf = spmr_field(im, SPMR_CEPMF, SPMR_CEPMF_SHIFT);
+ u32 qepdf = spmr_field(im, SPMR_CEPDF, SPMR_CEPDF_SHIFT);
+ u32 qe_clk = (pci_sync_in * qepmf) / (1 + qepdf);
+
+ if (i == MPC83XX_CLK_QE)
+ speed[i] = qe_clk;
+ else
+ speed[i] = qe_clk / 2;
+
+ continue;
+ }
+
+ if (i == MPC83XX_CLK_LCLK || i == MPC83XX_CLK_LBIU) {
+ u32 lbiu_clk = csb_clk *
+ (1 + spmr_field(im, SPMR_LBIUCM, SPMR_LBIUCM_SHIFT));
+ u32 clkdiv = lcrr_field(im, LCRR_CLKDIV, LCRR_CLKDIV_SHIFT);
+
+ if (i == MPC83XX_CLK_LBIU)
+ speed[i] = lbiu_clk;
+
+ switch (clkdiv) {
+ case 2:
+ case 4:
+ case 8:
+ speed[i] = lbiu_clk / clkdiv;
+ break;
+ default:
+ /* unknown lcrr */
+ speed[i] = 0;
+ }
+
+ continue;
+ }
+
+ if (i == MPC83XX_CLK_CORE) {
+ u8 corepll = spmr_field(im, SPMR_COREPLL, SPMR_COREPLL_SHIFT);
+ u32 corecnf_tab_index = ((corepll & 0x1F) << 2) |
+ ((corepll & 0x60) >> 5);
+
+ if (corecnf_tab_index > (ARRAY_SIZE(corecnf_tab))) {
+ /* corecnf_tab_index is too high, possibly wrong value */
+ speed[i] = 0;
+ }
+
+ switch (corecnf_tab[corecnf_tab_index].core_csb_ratio) {
+ case _byp:
+ case _x1:
+ case _1x:
+ speed[i] = csb_clk;
+ break;
+ case _1_5x:
+ speed[i] = (3 * csb_clk) / 2;
+ break;
+ case _2x:
+ speed[i] = 2 * csb_clk;
+ break;
+ case _2_5x:
+ speed[i] = (5 * csb_clk) / 2;
+ break;
+ case _3x:
+ speed[i] = 3 * csb_clk;
+ break;
+ default:
+ /* unknown core to csb ratio */
+ speed[i] = 0;
+ }
+
+ continue;
+ }
+ }
+}
+
+static ulong mpc83xx_clk_get_rate(struct clk *clk)
+{
+ struct mpc83xx_clk_priv *priv = dev_get_priv(clk->dev);
+
+ return priv->speed[clk->id];
+}
+
+int get_serial_clock(void)
+{
+ return speed[MPC83XX_CLK_CSB];
+}
+
+const struct clk_ops mpc83xx_clk_ops = {
+ .request = mpc83xx_clk_request,
+ .get_rate = mpc83xx_clk_get_rate,
+};
+
+static const struct udevice_id mpc83xx_clk_match[] = {
+ { .compatible = "fsl,mpc83xx-clk", },
+ { /* sentinel */ }
+};
+
+static int mpc83xx_clk_probe(struct udevice *dev)
+{
+ struct mpc83xx_clk_priv *priv = dev_get_priv(dev);
+
+ speed = malloc((MPC83XX_CLK_COUNT + 1) * sizeof(u32));
+ priv->speed = speed;
+ init_clks(priv->speed);
+
+ gd->arch.csb_clk = speed[MPC83XX_CLK_CSB];
+#if defined(CONFIG_MPC8308) || defined(CONFIG_MPC831x) || \
+ defined(CONFIG_MPC834x) || defined(CONFIG_MPC837x)
+ gd->arch.tsec1_clk = speed[MPC83XX_CLK_TSEC1];
+ gd->arch.tsec2_clk = speed[MPC83XX_CLK_TSEC2];
+ gd->arch.usbdr_clk = speed[MPC83XX_CLK_USBDR];
+#elif defined(CONFIG_MPC8309)
+ gd->arch.usbdr_clk = speed[MPC83XX_CLK_USBDR];
+#endif
+#if defined(CONFIG_MPC834x)
+ gd->arch.usbmph_clk = speed[MPC83XX_CLK_USBMPH];
+#endif
+#if defined(CONFIG_MPC8315)
+ gd->arch.tdm_clk = speed[MPC83XX_CLK_TDM];
+#endif
+#if defined(CONFIG_FSL_ESDHC)
+ gd->arch.sdhc_clk = speed[MPC83XX_CLK_SDHC];
+#endif
+ gd->arch.core_clk = speed[MPC83XX_CLK_CORE];
+ gd->arch.i2c1_clk = speed[MPC83XX_CLK_I2C1];
+#if !defined(CONFIG_MPC832x)
+ gd->arch.i2c2_clk = speed[MPC83XX_CLK_I2C2];
+#endif
+#if !defined(CONFIG_MPC8309)
+ gd->arch.enc_clk = speed[MPC83XX_CLK_ENC];
+#endif
+ gd->arch.lbiu_clk = speed[MPC83XX_CLK_LBIU];
+ gd->arch.lclk_clk = speed[MPC83XX_CLK_LCLK];
+ gd->mem_clk = speed[MPC83XX_CLK_MEM];
+#if defined(CONFIG_MPC8360)
+ gd->arch.mem_sec_clk = speed[MPC83XX_CLK_MEM_SEC];
+#endif
+#if defined(CONFIG_QE)
+ gd->arch.qe_clk = speed[MPC83XX_CLK_QE];
+ gd->arch.brg_clk = speed[MPC83XX_CLK_BRG];
+#endif
+#if defined(CONFIG_MPC8308) || defined(CONFIG_MPC831x) || \
+ defined(CONFIG_MPC837x)
+ gd->arch.pciexp1_clk = speed[MPC83XX_CLK_PCIEXP1];
+ gd->arch.pciexp2_clk = speed[MPC83XX_CLK_PCIEXP2];
+#endif
+#if defined(CONFIG_MPC837x) || defined(CONFIG_MPC8315)
+ gd->arch.sata_clk = speed[MPC83XX_CLK_SATA];
+#endif
+ gd->pci_clk = speed[MPC83XX_CLK_PCI];
+ gd->cpu_clk = speed[MPC83XX_CLK_CORE];
+ gd->bus_clk = speed[MPC83XX_CLK_CSB];
+
+ return 0;
+}
+
+static int mpc83xx_clk_bind(struct udevice *dev)
+{
+ int ret;
+ struct udevice *sys_child;
+
+ ret = device_bind_driver(dev, "mpc83xx_sysreset", "sysreset",
+ &sys_child);
+ if (ret)
+ debug("Warning: No sysreset driver: ret=%d\n", ret);
+
+ return 0;
+}
+
+U_BOOT_DRIVER(mpc83xx_clk) = {
+ .name = "mpc83xx_clk",
+ .id = UCLASS_CLK,
+ .of_match = mpc83xx_clk_match,
+ .ops = &mpc83xx_clk_ops,
+ .probe = mpc83xx_clk_probe,
+ .priv_auto_alloc_size = sizeof(struct mpc83xx_clk_priv),
+ .bind = mpc83xx_clk_bind,
+};
+
+static int do_clocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ int i;
+ char buf[32];
+
+ for (i = 0; i < MPC83XX_CLK_COUNT; i++) {
+ if (!is_clk_valid(i))
+ continue;
+
+ printf("%s = %s MHz\n", names[i], strmhz(buf, speed[i]));
+ }
+
+ return 0;
+}
+
+U_BOOT_CMD(
+ clocks, 1, 1, do_clocks,
+ "display values of SoC's clocks",
+ ""
+);
diff --git a/drivers/clk/mpc83xx_clk.h b/drivers/clk/mpc83xx_clk.h
new file mode 100644
index 0000000000..75db2f3699
--- /dev/null
+++ b/drivers/clk/mpc83xx_clk.h
@@ -0,0 +1,115 @@
+enum {
+ _unk,
+ _off,
+ _byp,
+ _x8,
+ _x4,
+ _x2,
+ _x1,
+ _1x,
+ _1_5x,
+ _2x,
+ _2_5x,
+ _3x
+};
+
+struct corecnf {
+ int core_csb_ratio;
+ int vco_divider;
+};
+
+static struct corecnf corecnf_tab[] = {
+ {_byp, _byp}, /* 0x00 */
+ {_byp, _byp}, /* 0x01 */
+ {_byp, _byp}, /* 0x02 */
+ {_byp, _byp}, /* 0x03 */
+ {_byp, _byp}, /* 0x04 */
+ {_byp, _byp}, /* 0x05 */
+ {_byp, _byp}, /* 0x06 */
+ {_byp, _byp}, /* 0x07 */
+ {_1x, _x2}, /* 0x08 */
+ {_1x, _x4}, /* 0x09 */
+ {_1x, _x8}, /* 0x0A */
+ {_1x, _x8}, /* 0x0B */
+ {_1_5x, _x2}, /* 0x0C */
+ {_1_5x, _x4}, /* 0x0D */
+ {_1_5x, _x8}, /* 0x0E */
+ {_1_5x, _x8}, /* 0x0F */
+ {_2x, _x2}, /* 0x10 */
+ {_2x, _x4}, /* 0x11 */
+ {_2x, _x8}, /* 0x12 */
+ {_2x, _x8}, /* 0x13 */
+ {_2_5x, _x2}, /* 0x14 */
+ {_2_5x, _x4}, /* 0x15 */
+ {_2_5x, _x8}, /* 0x16 */
+ {_2_5x, _x8}, /* 0x17 */
+ {_3x, _x2}, /* 0x18 */
+ {_3x, _x4}, /* 0x19 */
+ {_3x, _x8}, /* 0x1A */
+ {_3x, _x8}, /* 0x1B */
+};
+
+enum reg_type {
+ REG_SCCR,
+ REG_SPMR,
+};
+
+enum mode_type {
+ TYPE_INVALID = 0,
+ TYPE_SCCR_STANDARD,
+ TYPE_SCCR_ONOFF,
+ TYPE_SPMR_DIRECT_MULTIPLY,
+ TYPE_SPECIAL,
+};
+
+static inline u32 get_spmr(immap_t *im)
+{
+ u32 res = in_be32(&im->clk.spmr);
+
+ return res;
+}
+
+static inline u32 get_sccr(immap_t *im)
+{
+ u32 res = in_be32(&im->clk.sccr);
+
+ return res;
+}
+
+static inline u32 get_lcrr(immap_t *im)
+{
+ u32 res = in_be32(&im->im_lbc.lcrr);
+
+ return res;
+}
+
+static inline u32 get_pci_sync_in(immap_t *im)
+{
+ u8 clkin_div;
+
+ clkin_div = (get_spmr(im) & SPMR_CKID) >> SPMR_CKID_SHIFT;
+ return CONFIG_SYS_CLK_FREQ / (1 + clkin_div);
+}
+
+static inline u32 get_csb_clk(immap_t *im)
+{
+ u8 spmf;
+
+ spmf = (get_spmr(im) & SPMR_SPMF) >> SPMR_SPMF_SHIFT;
+ return CONFIG_SYS_CLK_FREQ * spmf;
+}
+
+static inline uint spmr_field(immap_t *im, u32 mask, uint shift)
+{
+ return (get_spmr(im) & mask) >> shift;
+}
+
+static inline uint sccr_field(immap_t *im, u32 mask, uint shift)
+{
+ return (get_sccr(im) & mask) >> shift;
+}
+
+static inline uint lcrr_field(immap_t *im, u32 mask, uint shift)
+{
+ return (get_lcrr(im) & mask) >> shift;
+}
diff --git a/include/dt-bindings/clk/mpc83xx-clk.h b/include/dt-bindings/clk/mpc83xx-clk.h
new file mode 100644
index 0000000000..3e5b2858c0
--- /dev/null
+++ b/include/dt-bindings/clk/mpc83xx-clk.h
@@ -0,0 +1,27 @@
+#ifndef DT_BINDINGS_MPC83XX_CLK_H
+#define DT_BINDINGS_MPC83XX_CLK_H
+#define MPC83XX_CLK_CORE 0
+#define MPC83XX_CLK_CSB 1
+#define MPC83XX_CLK_QE 2
+#define MPC83XX_CLK_BRG 3
+#define MPC83XX_CLK_LBIU 4
+#define MPC83XX_CLK_LCLK 5
+#define MPC83XX_CLK_MEM 6
+#define MPC83XX_CLK_MEM_SEC 7
+#define MPC83XX_CLK_ENC 8
+#define MPC83XX_CLK_I2C1 9
+#define MPC83XX_CLK_I2C2 10
+#define MPC83XX_CLK_TDM 11
+#define MPC83XX_CLK_SDHC 12
+#define MPC83XX_CLK_TSEC1 13
+#define MPC83XX_CLK_TSEC2 14
+#define MPC83XX_CLK_USBDR 15
+#define MPC83XX_CLK_USBMPH 16
+#define MPC83XX_CLK_PCIEXP1 17
+#define MPC83XX_CLK_PCIEXP2 18
+#define MPC83XX_CLK_SATA 19
+#define MPC83XX_CLK_DMAC 20
+#define MPC83XX_CLK_PCI 21
+/* Count */
+#define MPC83XX_CLK_COUNT 22
+#endif /* DT_BINDINGS_MPC83XX_CLK_H */
--
2.16.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [U-Boot] [PATCH v2 06/10] timer: Add MPC83xx timer driver
2018-04-27 12:52 [U-Boot] [PATCH v2 01/10] ram: Add driver for MPC83xx Mario Six
` (3 preceding siblings ...)
2018-04-27 12:52 ` [U-Boot] [PATCH v2 05/10] clk: Add MPC83xx clock driver Mario Six
@ 2018-04-27 12:52 ` Mario Six
2018-04-30 23:13 ` Simon Glass
2018-04-27 12:52 ` [U-Boot] [PATCH v2 07/10] common: board_f: Sort includes Mario Six
2018-05-03 19:01 ` [U-Boot] [PATCH v2 01/10] ram: Add driver for MPC83xx Simon Glass
6 siblings, 1 reply; 19+ messages in thread
From: Mario Six @ 2018-04-27 12:52 UTC (permalink / raw)
To: u-boot
Add a timer driver for the MPC83xx architecture.
Signed-off-by: Mario Six <mario.six@gdsys.cc>
---
v1 -> v2:
* Removed now-superfluous comments
* Removed usage of uclass_{first,next}_device_compat
* Switched to usage of new board uclass (instead of devinfo)
---
arch/powerpc/cpu/mpc83xx/cpu.c | 4 +-
arch/powerpc/lib/Makefile | 4 ++
arch/powerpc/lib/interrupts.c | 5 +-
drivers/timer/Kconfig | 7 ++
drivers/timer/Makefile | 1 +
drivers/timer/mpc83xx_timer.c | 160 +++++++++++++++++++++++++++++++++++++++++
6 files changed, 178 insertions(+), 3 deletions(-)
create mode 100644 drivers/timer/mpc83xx_timer.c
diff --git a/arch/powerpc/cpu/mpc83xx/cpu.c b/arch/powerpc/cpu/mpc83xx/cpu.c
index 9a5c1b7d55..376483eda7 100644
--- a/arch/powerpc/cpu/mpc83xx/cpu.c
+++ b/arch/powerpc/cpu/mpc83xx/cpu.c
@@ -176,12 +176,12 @@ do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
/*
* Get timebase clock frequency (like cpu_clk in Hz)
*/
-
+#ifndef CONFIG_TIMER
unsigned long get_tbclk(void)
{
return (gd->bus_clk + 3L) / 4L;
}
-
+#endif
#if defined(CONFIG_WATCHDOG)
void watchdog_reset (void)
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
index 9a3043abf8..537693e3bc 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -19,13 +19,17 @@ endif
ifdef MINIMAL
obj-y += cache.o time.o
+ifndef CONFIG_TIMER
obj-y += ticks.o
+endif
else
obj-y += ppcstring.o
obj-y += ppccache.o
+ifndef CONFIG_TIMER
obj-y += ticks.o
+endif
obj-y += reloc.o
obj-$(CONFIG_BAT_RW) += bat_rw.o
diff --git a/arch/powerpc/lib/interrupts.c b/arch/powerpc/lib/interrupts.c
index e8784aa16e..56a697d28c 100644
--- a/arch/powerpc/lib/interrupts.c
+++ b/arch/powerpc/lib/interrupts.c
@@ -15,6 +15,7 @@
#include <status_led.h>
#endif
+#ifndef CONFIG_MPC83XX_TIMER
#ifdef CONFIG_SHOW_ACTIVITY
void board_show_activity (ulong) __attribute__((weak, alias("__board_show_activity")));
@@ -45,7 +46,7 @@ static __inline__ void set_dec (unsigned long val)
if (val)
asm volatile ("mtdec %0"::"r" (val));
}
-
+#endif /* !CONFIG_MPC83XX_TIMER */
void enable_interrupts (void)
{
@@ -61,6 +62,7 @@ int disable_interrupts (void)
return ((msr & MSR_EE) != 0);
}
+#ifndef CONFIG_MPC83XX_TIMER
int interrupt_init (void)
{
/* call cpu specific function from $(CPU)/interrupts.c */
@@ -103,3 +105,4 @@ ulong get_timer (ulong base)
{
return (timestamp - base);
}
+#endif /* !CONFIG_MPC83XX_TIMER */
diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig
index 2c96896726..1b78ce784a 100644
--- a/drivers/timer/Kconfig
+++ b/drivers/timer/Kconfig
@@ -126,4 +126,11 @@ config STM32_TIMER
Select this to enable support for the timer found on
STM32 devices.
+config MPC83XX_TIMER
+ bool "MPC83xx timer support"
+ depends on TIMER
+ help
+ Select this to enable support for the timer found on
+ devices based on the MPC83xx family of SoCs.
+
endmenu
diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile
index a6e7832154..d35d235195 100644
--- a/drivers/timer/Makefile
+++ b/drivers/timer/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_ATCPIT100_TIMER) += atcpit100_timer.o
obj-$(CONFIG_ROCKCHIP_TIMER) += rockchip_timer.o
obj-$(CONFIG_ATMEL_PIT_TIMER) += atmel_pit_timer.o
obj-$(CONFIG_STM32_TIMER) += stm32_timer.o
+obj-$(CONFIG_MPC83XX_TIMER) += mpc83xx_timer.o
diff --git a/drivers/timer/mpc83xx_timer.c b/drivers/timer/mpc83xx_timer.c
new file mode 100644
index 0000000000..c3dd306c5b
--- /dev/null
+++ b/drivers/timer/mpc83xx_timer.c
@@ -0,0 +1,160 @@
+/*
+ * (C) Copyright 2018
+ * Mario Six, Guntermann & Drunck GmbH, mario.six at gdsys.cc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <clk.h>
+#include <timer.h>
+#include <watchdog.h>
+#include <board.h>
+
+struct mpc83xx_timer_priv {
+};
+
+static uint decrementer_count; /* count value for 1e6/HZ microseconds */
+
+static inline unsigned long get_dec(void)
+{
+ unsigned long val;
+
+ asm volatile ("mfdec %0":"=r" (val):);
+
+ return val;
+}
+
+static inline void set_dec(unsigned long val)
+{
+ if (val)
+ asm volatile ("mtdec %0"::"r" (val));
+}
+
+/* TODO(mario.six at gdsys.cc): This should really be done by timer_init, and the
+ * interrupt init should go into a interrupt driver.
+ */
+int interrupt_init(void)
+{
+ immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
+ struct udevice *csb;
+ struct udevice *board;
+ struct clk clock;
+
+ if (get_board(&board))
+ return -ENOENT;
+
+ uclass_get_device_by_phandle(UCLASS_SIMPLE_BUS, board, "csb", &csb);
+ clk_get_by_index(csb, 0, &clock);
+
+ decrementer_count = (clk_get_rate(&clock) / 4) / CONFIG_SYS_HZ;
+
+ /* Enable e300 time base */
+
+ setbits_be32(&immr->sysconf.spcr, 0x00400000);
+
+ set_dec(decrementer_count);
+
+ set_msr(get_msr() | MSR_EE);
+
+ return 0;
+}
+
+static volatile ulong timestamp = 0;
+
+void timer_interrupt(struct pt_regs *regs)
+{
+ /* Restore Decrementer Count */
+ set_dec(decrementer_count);
+
+ timestamp++;
+
+#if defined(CONFIG_WATCHDOG) || defined(CONFIG_HW_WATCHDOG)
+ if ((timestamp % (CONFIG_SYS_WATCHDOG_FREQ)) == 0)
+ WATCHDOG_RESET();
+#endif /* CONFIG_WATCHDOG || CONFIG_HW_WATCHDOG */
+
+#ifdef CONFIG_LED_STATUS
+ status_led_tick(timestamp);
+#endif /* CONFIG_LED_STATUS */
+
+#ifdef CONFIG_SHOW_ACTIVITY
+ board_show_activity(timestamp);
+#endif /* CONFIG_SHOW_ACTIVITY */
+}
+
+ulong get_timer(ulong base)
+{
+ return (timestamp - base);
+}
+
+static inline u32 mftbu(void)
+{
+ u32 rval;
+
+ asm volatile("mftbu %0" : "=r" (rval));
+ return rval;
+}
+
+static inline u32 mftb(void)
+{
+ u32 rval;
+
+ asm volatile("mftb %0" : "=r" (rval));
+ return rval;
+}
+
+void wait_ticks(ulong ticks)
+{
+ ulong end = get_ticks() + ticks;
+
+ while (end > get_ticks())
+ WATCHDOG_RESET();
+}
+
+static int mpc83xx_timer_get_count(struct udevice *dev, u64 *count)
+{
+ u32 tbu, tbl;
+
+ do {
+ tbu = mftbu();
+ tbl = mftb();
+ } while (tbu != mftbu());
+
+ *count = (tbu * 0x10000ULL) + tbl;
+
+ return 0;
+}
+
+static int mpc83xx_timer_probe(struct udevice *dev)
+{
+ struct timer_dev_priv *uc_priv = dev->uclass_priv;
+ struct clk clock;
+
+ interrupt_init();
+
+ clk_get_by_index(dev, 0, &clock);
+
+ uc_priv->clock_rate = (clk_get_rate(&clock) + 3L) / 4L;
+
+ return 0;
+}
+
+static const struct timer_ops mpc83xx_timer_ops = {
+ .get_count = mpc83xx_timer_get_count,
+};
+
+static const struct udevice_id mpc83xx_timer_ids[] = {
+ { .compatible = "fsl,mpc83xx-timer" },
+ { /* sentinel */ }
+};
+
+U_BOOT_DRIVER(mpc83xx_timer) = {
+ .name = "mpc83xx_timer",
+ .id = UCLASS_TIMER,
+ .of_match = mpc83xx_timer_ids,
+ .probe = mpc83xx_timer_probe,
+ .ops = &mpc83xx_timer_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
--
2.16.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [U-Boot] [PATCH v2 07/10] common: board_f: Sort includes
2018-04-27 12:52 [U-Boot] [PATCH v2 01/10] ram: Add driver for MPC83xx Mario Six
` (4 preceding siblings ...)
2018-04-27 12:52 ` [U-Boot] [PATCH v2 06/10] timer: Add MPC83xx timer driver Mario Six
@ 2018-04-27 12:52 ` Mario Six
2018-05-03 19:01 ` Simon Glass
2018-05-03 19:01 ` [U-Boot] [PATCH v2 01/10] ram: Add driver for MPC83xx Simon Glass
6 siblings, 1 reply; 19+ messages in thread
From: Mario Six @ 2018-04-27 12:52 UTC (permalink / raw)
To: u-boot
Includes should be sorted.
Signed-off-by: Mario Six <mario.six@gdsys.cc>
---
v1 -> v2:
New in v2
---
common/board_f.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/common/board_f.c b/common/board_f.c
index 2df30cd250..ff7a52705e 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -12,8 +12,8 @@
#include <common.h>
#include <console.h>
-#include <environment.h>
#include <dm.h>
+#include <environment.h>
#include <fdtdec.h>
#include <fs.h>
#include <i2c.h>
--
2.16.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [U-Boot] [PATCH v2 06/10] timer: Add MPC83xx timer driver
2018-04-27 12:52 ` [U-Boot] [PATCH v2 06/10] timer: Add MPC83xx timer driver Mario Six
@ 2018-04-30 23:13 ` Simon Glass
2018-05-04 6:19 ` Mario Six
0 siblings, 1 reply; 19+ messages in thread
From: Simon Glass @ 2018-04-30 23:13 UTC (permalink / raw)
To: u-boot
Hi Mario,
On 27 April 2018 at 06:52, Mario Six <mario.six@gdsys.cc> wrote:
> Add a timer driver for the MPC83xx architecture.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>
> ---
>
> v1 -> v2:
> * Removed now-superfluous comments
> * Removed usage of uclass_{first,next}_device_compat
> * Switched to usage of new board uclass (instead of devinfo)
>
> ---
> arch/powerpc/cpu/mpc83xx/cpu.c | 4 +-
> arch/powerpc/lib/Makefile | 4 ++
> arch/powerpc/lib/interrupts.c | 5 +-
> drivers/timer/Kconfig | 7 ++
> drivers/timer/Makefile | 1 +
> drivers/timer/mpc83xx_timer.c | 160 +++++++++++++++++++++++++++++++++++++++++
> 6 files changed, 178 insertions(+), 3 deletions(-)
> create mode 100644 drivers/timer/mpc83xx_timer.c
Reviewed-by: Simon Glass <sjg@chromium.org>
Please see below.
>
> diff --git a/arch/powerpc/cpu/mpc83xx/cpu.c b/arch/powerpc/cpu/mpc83xx/cpu.c
> index 9a5c1b7d55..376483eda7 100644
> --- a/arch/powerpc/cpu/mpc83xx/cpu.c
> +++ b/arch/powerpc/cpu/mpc83xx/cpu.c
> @@ -176,12 +176,12 @@ do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
> /*
> * Get timebase clock frequency (like cpu_clk in Hz)
> */
> -
> +#ifndef CONFIG_TIMER
> unsigned long get_tbclk(void)
> {
> return (gd->bus_clk + 3L) / 4L;
> }
> -
> +#endif
>
> #if defined(CONFIG_WATCHDOG)
> void watchdog_reset (void)
> diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
> index 9a3043abf8..537693e3bc 100644
> --- a/arch/powerpc/lib/Makefile
> +++ b/arch/powerpc/lib/Makefile
> @@ -19,13 +19,17 @@ endif
>
> ifdef MINIMAL
> obj-y += cache.o time.o
> +ifndef CONFIG_TIMER
> obj-y += ticks.o
> +endif
> else
>
> obj-y += ppcstring.o
>
> obj-y += ppccache.o
> +ifndef CONFIG_TIMER
> obj-y += ticks.o
> +endif
> obj-y += reloc.o
>
> obj-$(CONFIG_BAT_RW) += bat_rw.o
> diff --git a/arch/powerpc/lib/interrupts.c b/arch/powerpc/lib/interrupts.c
> index e8784aa16e..56a697d28c 100644
> --- a/arch/powerpc/lib/interrupts.c
> +++ b/arch/powerpc/lib/interrupts.c
> @@ -15,6 +15,7 @@
> #include <status_led.h>
> #endif
>
> +#ifndef CONFIG_MPC83XX_TIMER
> #ifdef CONFIG_SHOW_ACTIVITY
> void board_show_activity (ulong) __attribute__((weak, alias("__board_show_activity")));
>
> @@ -45,7 +46,7 @@ static __inline__ void set_dec (unsigned long val)
> if (val)
> asm volatile ("mtdec %0"::"r" (val));
> }
> -
> +#endif /* !CONFIG_MPC83XX_TIMER */
>
> void enable_interrupts (void)
> {
> @@ -61,6 +62,7 @@ int disable_interrupts (void)
> return ((msr & MSR_EE) != 0);
> }
>
> +#ifndef CONFIG_MPC83XX_TIMER
> int interrupt_init (void)
> {
> /* call cpu specific function from $(CPU)/interrupts.c */
> @@ -103,3 +105,4 @@ ulong get_timer (ulong base)
> {
> return (timestamp - base);
> }
> +#endif /* !CONFIG_MPC83XX_TIMER */
> diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig
> index 2c96896726..1b78ce784a 100644
> --- a/drivers/timer/Kconfig
> +++ b/drivers/timer/Kconfig
> @@ -126,4 +126,11 @@ config STM32_TIMER
> Select this to enable support for the timer found on
> STM32 devices.
>
> +config MPC83XX_TIMER
> + bool "MPC83xx timer support"
> + depends on TIMER
> + help
> + Select this to enable support for the timer found on
> + devices based on the MPC83xx family of SoCs.
> +
> endmenu
> diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile
> index a6e7832154..d35d235195 100644
> --- a/drivers/timer/Makefile
> +++ b/drivers/timer/Makefile
> @@ -17,3 +17,4 @@ obj-$(CONFIG_ATCPIT100_TIMER) += atcpit100_timer.o
> obj-$(CONFIG_ROCKCHIP_TIMER) += rockchip_timer.o
> obj-$(CONFIG_ATMEL_PIT_TIMER) += atmel_pit_timer.o
> obj-$(CONFIG_STM32_TIMER) += stm32_timer.o
> +obj-$(CONFIG_MPC83XX_TIMER) += mpc83xx_timer.o
> diff --git a/drivers/timer/mpc83xx_timer.c b/drivers/timer/mpc83xx_timer.c
> new file mode 100644
> index 0000000000..c3dd306c5b
> --- /dev/null
> +++ b/drivers/timer/mpc83xx_timer.c
> @@ -0,0 +1,160 @@
> +/*
> + * (C) Copyright 2018
> + * Mario Six, Guntermann & Drunck GmbH, mario.six at gdsys.cc
> + *
> + * SPDX-License-Identifier: GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <clk.h>
> +#include <timer.h>
> +#include <watchdog.h>
> +#include <board.h>
> +
> +struct mpc83xx_timer_priv {
> +};
> +
> +static uint decrementer_count; /* count value for 1e6/HZ microseconds */
Have a static var in BSS means it cannot be used before relocation, or
in SPL, right?
> +
> +static inline unsigned long get_dec(void)
> +{
> + unsigned long val;
> +
> + asm volatile ("mfdec %0":"=r" (val):);
> +
> + return val;
> +}
> +
> +static inline void set_dec(unsigned long val)
> +{
> + if (val)
> + asm volatile ("mtdec %0"::"r" (val));
> +}
> +
> +/* TODO(mario.six at gdsys.cc): This should really be done by timer_init, and the
> + * interrupt init should go into a interrupt driver.
> + */
> +int interrupt_init(void)
> +{
> + immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
> + struct udevice *csb;
> + struct udevice *board;
> + struct clk clock;
> +
> + if (get_board(&board))
debug() ?
> + return -ENOENT;
> +
> + uclass_get_device_by_phandle(UCLASS_SIMPLE_BUS, board, "csb", &csb);
> + clk_get_by_index(csb, 0, &clock);
error checking
> +
> + decrementer_count = (clk_get_rate(&clock) / 4) / CONFIG_SYS_HZ;
> +
> + /* Enable e300 time base */
> +
Drop blank line
> + setbits_be32(&immr->sysconf.spcr, 0x00400000);
> +
> + set_dec(decrementer_count);
> +
> + set_msr(get_msr() | MSR_EE);
> +
> + return 0;
> +}
> +
> +static volatile ulong timestamp = 0;
> +
> +void timer_interrupt(struct pt_regs *regs)
> +{
> + /* Restore Decrementer Count */
> + set_dec(decrementer_count);
> +
> + timestamp++;
> +
> +#if defined(CONFIG_WATCHDOG) || defined(CONFIG_HW_WATCHDOG)
> + if ((timestamp % (CONFIG_SYS_WATCHDOG_FREQ)) == 0)
> + WATCHDOG_RESET();
> +#endif /* CONFIG_WATCHDOG || CONFIG_HW_WATCHDOG */
> +
> +#ifdef CONFIG_LED_STATUS
> + status_led_tick(timestamp);
> +#endif /* CONFIG_LED_STATUS */
> +
> +#ifdef CONFIG_SHOW_ACTIVITY
> + board_show_activity(timestamp);
> +#endif /* CONFIG_SHOW_ACTIVITY */
> +}
> +
> +ulong get_timer(ulong base)
> +{
> + return (timestamp - base);
> +}
> +
> +static inline u32 mftbu(void)
> +{
> + u32 rval;
> +
> + asm volatile("mftbu %0" : "=r" (rval));
> + return rval;
> +}
> +
> +static inline u32 mftb(void)
> +{
> + u32 rval;
> +
> + asm volatile("mftb %0" : "=r" (rval));
> + return rval;
> +}
> +
> +void wait_ticks(ulong ticks)
> +{
> + ulong end = get_ticks() + ticks;
> +
> + while (end > get_ticks())
> + WATCHDOG_RESET();
> +}
> +
> +static int mpc83xx_timer_get_count(struct udevice *dev, u64 *count)
> +{
> + u32 tbu, tbl;
> +
> + do {
> + tbu = mftbu();
> + tbl = mftb();
> + } while (tbu != mftbu());
> +
> + *count = (tbu * 0x10000ULL) + tbl;
> +
> + return 0;
> +}
> +
> +static int mpc83xx_timer_probe(struct udevice *dev)
> +{
> + struct timer_dev_priv *uc_priv = dev->uclass_priv;
> + struct clk clock;
> +
> + interrupt_init();
> +
> + clk_get_by_index(dev, 0, &clock);
> +
> + uc_priv->clock_rate = (clk_get_rate(&clock) + 3L) / 4L;
> +
> + return 0;
> +}
> +
> +static const struct timer_ops mpc83xx_timer_ops = {
> + .get_count = mpc83xx_timer_get_count,
> +};
> +
> +static const struct udevice_id mpc83xx_timer_ids[] = {
> + { .compatible = "fsl,mpc83xx-timer" },
> + { /* sentinel */ }
> +};
> +
> +U_BOOT_DRIVER(mpc83xx_timer) = {
> + .name = "mpc83xx_timer",
> + .id = UCLASS_TIMER,
> + .of_match = mpc83xx_timer_ids,
> + .probe = mpc83xx_timer_probe,
> + .ops = &mpc83xx_timer_ops,
> + .flags = DM_FLAG_PRE_RELOC,
> +};
> --
> 2.16.1
>
Regards,
Simon
^ permalink raw reply [flat|nested] 19+ messages in thread
* [U-Boot] [PATCH v2 01/10] ram: Add driver for MPC83xx
2018-04-27 12:52 [U-Boot] [PATCH v2 01/10] ram: Add driver for MPC83xx Mario Six
` (5 preceding siblings ...)
2018-04-27 12:52 ` [U-Boot] [PATCH v2 07/10] common: board_f: Sort includes Mario Six
@ 2018-05-03 19:01 ` Simon Glass
2018-05-04 8:04 ` Mario Six
6 siblings, 1 reply; 19+ messages in thread
From: Simon Glass @ 2018-05-03 19:01 UTC (permalink / raw)
To: u-boot
Hi Mario,
On 27 April 2018 at 06:52, Mario Six <mario.six@gdsys.cc> wrote:
> Add a RAM driver for the MPC83xx architecture.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>
> ---
>
> v1 -> v2:
> No changes
>
> ---
> arch/powerpc/cpu/mpc83xx/spd_sdram.c | 4 +
> drivers/ram/Kconfig | 8 +
> drivers/ram/Makefile | 1 +
> drivers/ram/mpc83xx_sdram.c | 948 +++++++++++++++++++++++++++++
> include/dt-bindings/memory/mpc83xx-sdram.h | 143 +++++
> include/mpc83xx.h | 6 +
> 6 files changed, 1110 insertions(+)
> create mode 100644 drivers/ram/mpc83xx_sdram.c
> create mode 100644 include/dt-bindings/memory/mpc83xx-sdram.h
>
Reviewed-by: Simon Glass <sjg@chromium.org>
Question below
[..]
> new file mode 100644
> index 0000000000..1a73f7b3da
> --- /dev/null
> +++ b/drivers/ram/mpc83xx_sdram.c
> @@ -0,0 +1,948 @@
> +#define DEBUG
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <ram.h>
> +#include <asm/io.h>
> +#include <dt-bindings/memory/mpc83xx-sdram.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +#define CSCONFIG_ENABLE 0x80000000
> +
> +#define BANK_BITS_2 0x00000000
> +#define BANK_BITS_3 0x00004000
> +
> +#define ROW_BITS_12 0x00000000
> +#define ROW_BITS_13 0x00000100
> +#define ROW_BITS_14 0x00000200
> +
> +#define COL_BITS_8 0x00000000
> +#define COL_BITS_9 0x00000001
> +#define COL_BITS_10 0x00000002
> +#define COL_BITS_11 0x00000003
> +
> +#define TIMING_CFG3_EXT_REFREC_SHIFT 16
> +
> +#define TIMING_CFG0_RWT_SHIFT 30
> +#define TIMING_CFG0_WRT_SHIFT 28
> +#define TIMING_CFG0_RRT_SHIFT 26
> +#define TIMING_CFG0_WWT_SHIFT 24
> +#define TIMING_CFG0_ACT_PD_EXIT_SHIFT 20
> +#define TIMING_CFG0_PRE_PD_EXIT_SHIFT 16
> +#define TIMING_CFG0_ODT_PD_EXIT_SHIFT 8
> +#define TIMING_CFG0_MRS_CYC_SHIFT 0
> +
> +#define TIMING_CFG1_PRETOACT_SHIFT 28
> +#define TIMING_CFG1_ACTTOPRE_SHIFT 24
> +#define TIMING_CFG1_ACTTORW_SHIFT 20
> +#define TIMING_CFG1_CASLAT_SHIFT 16
> +#define TIMING_CFG1_REFREC_SHIFT 12
> +#define TIMING_CFG1_WRREC_SHIFT 8
> +#define TIMING_CFG1_ACTTOACT_SHIFT 4
> +#define TIMING_CFG1_WRTORD_SHIFT 0
> +
> +#define TIMING_CFG2_CPO_SHIFT 23
> +#define TIMING_CFG2_WR_DATA_DELAY_SHIFT 10
> +#define TIMING_CFG2_ADD_LAT_SHIFT 28
> +#define TIMING_CFG2_WR_LAT_DELAY_SHIFT 19
> +#define TIMING_CFG2_RD_TO_PRE_SHIFT 13
> +#define TIMING_CFG2_CKE_PLS_SHIFT 6
> +#define TIMING_CFG2_FOUR_ACT_SHIFT 0
> +
> +#define SDRAM_CFG_SREN_SHIFT (31 - 1)
> +#define SDRAM_CFG_ECC_EN_SHIFT (31 - 2)
> +#define SDRAM_CFG_RD_EN_SHIFT (31 - 3)
> +#define SDRAM_CFG_SDRAM_TYPE_SHIFT (31 - 7)
> +#define SDRAM_CFG_DYN_PWR_SHIFT (31 - 10)
> +#define SDRAM_CFG_DBW_SHIFT (31 - 12)
> +#define SDRAM_CFG_NCAP_SHIFT (31 - 14)
> +#define SDRAM_CFG_2T_EN_SHIFT (31 - 16)
> +#define SDRAM_CFG_BA_INTLV_CTL_SHIFT (31 - 23)
> +#define SDRAM_CFG_PCHB8_SHIFT (31 - 27)
> +#define SDRAM_CFG_HSE_SHIFT (31 - 28)
> +#define SDRAM_CFG_BI_SHIFT (31 - 31)
> +
> +#define SDRAM_CFG2_FRC_SR_SHIFT (31 - 0)
> +#define SDRAM_CFG2_DLL_RST_DIS (31 - 2)
> +#define SDRAM_CFG2_DQS_CFG (31 - 5)
> +#define SDRAM_CFG2_ODT_CFG (31 - 10)
> +#define SDRAM_CFG2_NUM_PR (31 - 19)
> +
> +#define SDRAM_MODE_ESD_SHIFT 16
> +#define SDRAM_MODE_SD_SHIFT 0
> +
> +#define SDRAM_MODE2_ESD2_SHIFT (31 - 15)
> +#define SDRAM_MODE2_ESD3_SHIFT (31 - 31)
> +
> +#define SDRAM_INTERVAL_REFINT_SHIFT 16
> +#define SDRAM_INTERVAL_BSTOPRE_SHIFT 0
> +
> +#define SDRAM_CFG_MEM_EN 0x80000000
> +
> +int dram_init(void)
> +{
> + struct udevice *ram_ctrl;
> + int ret;
> +
> + /* Current assumption: There is only one RAM controller */
> + ret = uclass_first_device_err(UCLASS_RAM, &ram_ctrl);
> +
> + if (ret) {
> + debug("uclass_first_device_err failed: %d\n", ret);
> + return ret;
> + }
> +
> + /* Set gd->ram_size? */
> +
> + return 0;
> +}
> +
> +phys_size_t get_effective_memsize(void)
> +{
> +#ifndef CONFIG_VERY_BIG_RAM
Can this (and the #ifdefs below in this file) be converted to
if (IS_ENABLED(CONFIG_...))
instead, to increase build coverage?
Regards,
Simon
^ permalink raw reply [flat|nested] 19+ messages in thread
* [U-Boot] [PATCH v2 02/10] sysreset: Add get_status method
2018-04-27 12:52 ` [U-Boot] [PATCH v2 02/10] sysreset: Add get_status method Mario Six
@ 2018-05-03 19:01 ` Simon Glass
2018-05-04 8:06 ` Mario Six
0 siblings, 1 reply; 19+ messages in thread
From: Simon Glass @ 2018-05-03 19:01 UTC (permalink / raw)
To: u-boot
On 27 April 2018 at 06:52, Mario Six <mario.six@gdsys.cc> wrote:
> It's useful to have the reset status of the SoC printed out during reset
> (e.g. to learn whether the reset was caused by software or a watchdog).
>
> As a first step to implement this, add a get_status method to the
> sysreset class, which enables the caller to get printable information
> about the reset status (akin to get_desc in the CPU uclass).
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>
> ---
>
> v1 -> v2:
> New in v2
>
> ---
> drivers/sysreset/sysreset-uclass.c | 10 ++++++++++
> include/sysreset.h | 17 +++++++++++++++++
> 2 files changed, 27 insertions(+)
Reviewed-by: Simon Glass <sjg@chromium.org>
Can you add a test for sandbox?
^ permalink raw reply [flat|nested] 19+ messages in thread
* [U-Boot] [PATCH v2 03/10] board_f: Add reset status printing
2018-04-27 12:52 ` [U-Boot] [PATCH v2 03/10] board_f: Add reset status printing Mario Six
@ 2018-05-03 19:01 ` Simon Glass
2018-05-04 8:10 ` Mario Six
0 siblings, 1 reply; 19+ messages in thread
From: Simon Glass @ 2018-05-03 19:01 UTC (permalink / raw)
To: u-boot
Hi Mario,
On 27 April 2018 at 06:52, Mario Six <mario.six@gdsys.cc> wrote:
> To print the reset status during boot, add a method print_resetinfo to
> board_f, which is called in init_sequence_f[], that gets the reset
> information from the sysreset driver (assuming there is only one seems
> reasonable), and prints it.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>
> ---
>
> v1 -> v2:
> New in v2
>
> ---
> common/board_f.c | 19 +++++++++++++++++++
> 1 file changed, 19 insertions(+)
Reviewed-by: Simon Glass <sjg@chromium.org>
nit below
>
> diff --git a/common/board_f.c b/common/board_f.c
> index ae8bdb7c5c..2df30cd250 100644
> --- a/common/board_f.c
> +++ b/common/board_f.c
> @@ -25,6 +25,7 @@
> #include <relocate.h>
> #include <spi.h>
> #include <status_led.h>
> +#include <sysreset.h>
> #include <timer.h>
> #include <trace.h>
> #include <video.h>
> @@ -141,6 +142,21 @@ static int display_text_info(void)
> return 0;
> }
>
> +#ifdef CONFIG_SYSRESET
> +static int print_resetinfo(void)
> +{
> + struct udevice *dev;
> + char status[256];
> +
> + uclass_first_device_err(UCLASS_SYSRESET, &dev);
Should check the result and only call the function below if it is 0.
> +
> + if (!sysreset_get_status(dev, status, sizeof(status)))
> + printf("%s", status);
> +
> + return 0;
> +}
> +#endif
> +
Regards,
Simon
^ permalink raw reply [flat|nested] 19+ messages in thread
* [U-Boot] [PATCH v2 04/10] mpc83xx: Add sysreset driver
2018-04-27 12:52 ` [U-Boot] [PATCH v2 04/10] mpc83xx: Add sysreset driver Mario Six
@ 2018-05-03 19:01 ` Simon Glass
0 siblings, 0 replies; 19+ messages in thread
From: Simon Glass @ 2018-05-03 19:01 UTC (permalink / raw)
To: u-boot
On 27 April 2018 at 06:52, Mario Six <mario.six@gdsys.cc> wrote:
> Add a sysreset driver for the MPC83xx platform.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>
> ---
>
> v1 -> v2:
> New in v2
>
> ---
> arch/powerpc/cpu/mpc83xx/cpu.c | 3 +-
> drivers/sysreset/Kconfig | 5 ++
> drivers/sysreset/Makefile | 9 +-
> drivers/sysreset/sysreset_mpc83xx.c | 160 ++++++++++++++++++++++++++++++++++++
> 4 files changed, 172 insertions(+), 5 deletions(-)
> create mode 100644 drivers/sysreset/sysreset_mpc83xx.c
Reviewed-by: Simon Glass <sjg@chromium.org>
^ permalink raw reply [flat|nested] 19+ messages in thread
* [U-Boot] [PATCH v2 07/10] common: board_f: Sort includes
2018-04-27 12:52 ` [U-Boot] [PATCH v2 07/10] common: board_f: Sort includes Mario Six
@ 2018-05-03 19:01 ` Simon Glass
0 siblings, 0 replies; 19+ messages in thread
From: Simon Glass @ 2018-05-03 19:01 UTC (permalink / raw)
To: u-boot
On 27 April 2018 at 06:52, Mario Six <mario.six@gdsys.cc> wrote:
> Includes should be sorted.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>
> ---
>
> v1 -> v2:
> New in v2
>
> ---
> common/board_f.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
Reviewed-by: Simon Glass <sjg@chromium.org>
^ permalink raw reply [flat|nested] 19+ messages in thread
* [U-Boot] [PATCH v2 06/10] timer: Add MPC83xx timer driver
2018-04-30 23:13 ` Simon Glass
@ 2018-05-04 6:19 ` Mario Six
0 siblings, 0 replies; 19+ messages in thread
From: Mario Six @ 2018-05-04 6:19 UTC (permalink / raw)
To: u-boot
Hi Simon,
On Tue, May 1, 2018 at 1:13 AM, Simon Glass <sjg@chromium.org> wrote:
> Hi Mario,
>
> On 27 April 2018 at 06:52, Mario Six <mario.six@gdsys.cc> wrote:
>> Add a timer driver for the MPC83xx architecture.
>>
>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>>
>> ---
>>
>> v1 -> v2:
>> * Removed now-superfluous comments
>> * Removed usage of uclass_{first,next}_device_compat
>> * Switched to usage of new board uclass (instead of devinfo)
>>
>> ---
>> arch/powerpc/cpu/mpc83xx/cpu.c | 4 +-
>> arch/powerpc/lib/Makefile | 4 ++
>> arch/powerpc/lib/interrupts.c | 5 +-
>> drivers/timer/Kconfig | 7 ++
>> drivers/timer/Makefile | 1 +
>> drivers/timer/mpc83xx_timer.c | 160 +++++++++++++++++++++++++++++++++++++++++
>> 6 files changed, 178 insertions(+), 3 deletions(-)
>> create mode 100644 drivers/timer/mpc83xx_timer.c
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
>
> Please see below.
>
>>
>> diff --git a/arch/powerpc/cpu/mpc83xx/cpu.c b/arch/powerpc/cpu/mpc83xx/cpu.c
>> index 9a5c1b7d55..376483eda7 100644
>> --- a/arch/powerpc/cpu/mpc83xx/cpu.c
>> +++ b/arch/powerpc/cpu/mpc83xx/cpu.c
>> @@ -176,12 +176,12 @@ do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
>> /*
>> * Get timebase clock frequency (like cpu_clk in Hz)
>> */
>> -
>> +#ifndef CONFIG_TIMER
>> unsigned long get_tbclk(void)
>> {
>> return (gd->bus_clk + 3L) / 4L;
>> }
>> -
>> +#endif
>>
>> #if defined(CONFIG_WATCHDOG)
>> void watchdog_reset (void)
>> diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
>> index 9a3043abf8..537693e3bc 100644
>> --- a/arch/powerpc/lib/Makefile
>> +++ b/arch/powerpc/lib/Makefile
>> @@ -19,13 +19,17 @@ endif
>>
>> ifdef MINIMAL
>> obj-y += cache.o time.o
>> +ifndef CONFIG_TIMER
>> obj-y += ticks.o
>> +endif
>> else
>>
>> obj-y += ppcstring.o
>>
>> obj-y += ppccache.o
>> +ifndef CONFIG_TIMER
>> obj-y += ticks.o
>> +endif
>> obj-y += reloc.o
>>
>> obj-$(CONFIG_BAT_RW) += bat_rw.o
>> diff --git a/arch/powerpc/lib/interrupts.c b/arch/powerpc/lib/interrupts.c
>> index e8784aa16e..56a697d28c 100644
>> --- a/arch/powerpc/lib/interrupts.c
>> +++ b/arch/powerpc/lib/interrupts.c
>> @@ -15,6 +15,7 @@
>> #include <status_led.h>
>> #endif
>>
>> +#ifndef CONFIG_MPC83XX_TIMER
>> #ifdef CONFIG_SHOW_ACTIVITY
>> void board_show_activity (ulong) __attribute__((weak, alias("__board_show_activity")));
>>
>> @@ -45,7 +46,7 @@ static __inline__ void set_dec (unsigned long val)
>> if (val)
>> asm volatile ("mtdec %0"::"r" (val));
>> }
>> -
>> +#endif /* !CONFIG_MPC83XX_TIMER */
>>
>> void enable_interrupts (void)
>> {
>> @@ -61,6 +62,7 @@ int disable_interrupts (void)
>> return ((msr & MSR_EE) != 0);
>> }
>>
>> +#ifndef CONFIG_MPC83XX_TIMER
>> int interrupt_init (void)
>> {
>> /* call cpu specific function from $(CPU)/interrupts.c */
>> @@ -103,3 +105,4 @@ ulong get_timer (ulong base)
>> {
>> return (timestamp - base);
>> }
>> +#endif /* !CONFIG_MPC83XX_TIMER */
>> diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig
>> index 2c96896726..1b78ce784a 100644
>> --- a/drivers/timer/Kconfig
>> +++ b/drivers/timer/Kconfig
>> @@ -126,4 +126,11 @@ config STM32_TIMER
>> Select this to enable support for the timer found on
>> STM32 devices.
>>
>> +config MPC83XX_TIMER
>> + bool "MPC83xx timer support"
>> + depends on TIMER
>> + help
>> + Select this to enable support for the timer found on
>> + devices based on the MPC83xx family of SoCs.
>> +
>> endmenu
>> diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile
>> index a6e7832154..d35d235195 100644
>> --- a/drivers/timer/Makefile
>> +++ b/drivers/timer/Makefile
>> @@ -17,3 +17,4 @@ obj-$(CONFIG_ATCPIT100_TIMER) += atcpit100_timer.o
>> obj-$(CONFIG_ROCKCHIP_TIMER) += rockchip_timer.o
>> obj-$(CONFIG_ATMEL_PIT_TIMER) += atmel_pit_timer.o
>> obj-$(CONFIG_STM32_TIMER) += stm32_timer.o
>> +obj-$(CONFIG_MPC83XX_TIMER) += mpc83xx_timer.o
>> diff --git a/drivers/timer/mpc83xx_timer.c b/drivers/timer/mpc83xx_timer.c
>> new file mode 100644
>> index 0000000000..c3dd306c5b
>> --- /dev/null
>> +++ b/drivers/timer/mpc83xx_timer.c
>> @@ -0,0 +1,160 @@
>> +/*
>> + * (C) Copyright 2018
>> + * Mario Six, Guntermann & Drunck GmbH, mario.six at gdsys.cc
>> + *
>> + * SPDX-License-Identifier: GPL-2.0+
>> + */
>> +
>> +#include <common.h>
>> +#include <dm.h>
>> +#include <clk.h>
>> +#include <timer.h>
>> +#include <watchdog.h>
>> +#include <board.h>
>> +
>> +struct mpc83xx_timer_priv {
>> +};
>> +
>> +static uint decrementer_count; /* count value for 1e6/HZ microseconds */
>
> Have a static var in BSS means it cannot be used before relocation, or
> in SPL, right?
>
True; same with the timestamp variable a bit below. I copied that part verbatim
from arch/powerpc/lib/interrupts.c, so that's a general problem with the
powerpc arch. I see that x86 keeps, e.g. the clock rate in the global data. I
think this might be a way around this (two ulongs will hopefully still fit in
the GD).
>> +
>> +static inline unsigned long get_dec(void)
>> +{
>> + unsigned long val;
>> +
>> + asm volatile ("mfdec %0":"=r" (val):);
>> +
>> + return val;
>> +}
>> +
>> +static inline void set_dec(unsigned long val)
>> +{
>> + if (val)
>> + asm volatile ("mtdec %0"::"r" (val));
>> +}
>> +
>> +/* TODO(mario.six at gdsys.cc): This should really be done by timer_init, and the
>> + * interrupt init should go into a interrupt driver.
>> + */
>> +int interrupt_init(void)
>> +{
>> + immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
>> + struct udevice *csb;
>> + struct udevice *board;
>> + struct clk clock;
>> +
>> + if (get_board(&board))
>
> debug() ?
>
Indeed; will be fixed in v3.
>> + return -ENOENT;
>> +
>> + uclass_get_device_by_phandle(UCLASS_SIMPLE_BUS, board, "csb", &csb);
>> + clk_get_by_index(csb, 0, &clock);
>
> error checking
>
Will be fixed in v3.
>> +
>> + decrementer_count = (clk_get_rate(&clock) / 4) / CONFIG_SYS_HZ;
>> +
>> + /* Enable e300 time base */
>> +
>
> Drop blank line
>
Will be fixed in v3.
>> + setbits_be32(&immr->sysconf.spcr, 0x00400000);
>> +
>> + set_dec(decrementer_count);
>> +
>> + set_msr(get_msr() | MSR_EE);
>> +
>> + return 0;
>> +}
>> +
>> +static volatile ulong timestamp = 0;
>> +
>> +void timer_interrupt(struct pt_regs *regs)
>> +{
>> + /* Restore Decrementer Count */
>> + set_dec(decrementer_count);
>> +
>> + timestamp++;
>> +
>> +#if defined(CONFIG_WATCHDOG) || defined(CONFIG_HW_WATCHDOG)
>> + if ((timestamp % (CONFIG_SYS_WATCHDOG_FREQ)) == 0)
>> + WATCHDOG_RESET();
>> +#endif /* CONFIG_WATCHDOG || CONFIG_HW_WATCHDOG */
>> +
>> +#ifdef CONFIG_LED_STATUS
>> + status_led_tick(timestamp);
>> +#endif /* CONFIG_LED_STATUS */
>> +
>> +#ifdef CONFIG_SHOW_ACTIVITY
>> + board_show_activity(timestamp);
>> +#endif /* CONFIG_SHOW_ACTIVITY */
>> +}
>> +
>> +ulong get_timer(ulong base)
>> +{
>> + return (timestamp - base);
>> +}
>> +
>> +static inline u32 mftbu(void)
>> +{
>> + u32 rval;
>> +
>> + asm volatile("mftbu %0" : "=r" (rval));
>> + return rval;
>> +}
>> +
>> +static inline u32 mftb(void)
>> +{
>> + u32 rval;
>> +
>> + asm volatile("mftb %0" : "=r" (rval));
>> + return rval;
>> +}
>> +
>> +void wait_ticks(ulong ticks)
>> +{
>> + ulong end = get_ticks() + ticks;
>> +
>> + while (end > get_ticks())
>> + WATCHDOG_RESET();
>> +}
>> +
>> +static int mpc83xx_timer_get_count(struct udevice *dev, u64 *count)
>> +{
>> + u32 tbu, tbl;
>> +
>> + do {
>> + tbu = mftbu();
>> + tbl = mftb();
>> + } while (tbu != mftbu());
>> +
>> + *count = (tbu * 0x10000ULL) + tbl;
>> +
>> + return 0;
>> +}
>> +
>> +static int mpc83xx_timer_probe(struct udevice *dev)
>> +{
>> + struct timer_dev_priv *uc_priv = dev->uclass_priv;
>> + struct clk clock;
>> +
>> + interrupt_init();
>> +
>> + clk_get_by_index(dev, 0, &clock);
>> +
>> + uc_priv->clock_rate = (clk_get_rate(&clock) + 3L) / 4L;
>> +
>> + return 0;
>> +}
>> +
>> +static const struct timer_ops mpc83xx_timer_ops = {
>> + .get_count = mpc83xx_timer_get_count,
>> +};
>> +
>> +static const struct udevice_id mpc83xx_timer_ids[] = {
>> + { .compatible = "fsl,mpc83xx-timer" },
>> + { /* sentinel */ }
>> +};
>> +
>> +U_BOOT_DRIVER(mpc83xx_timer) = {
>> + .name = "mpc83xx_timer",
>> + .id = UCLASS_TIMER,
>> + .of_match = mpc83xx_timer_ids,
>> + .probe = mpc83xx_timer_probe,
>> + .ops = &mpc83xx_timer_ops,
>> + .flags = DM_FLAG_PRE_RELOC,
>> +};
>> --
>> 2.16.1
>>
>
> Regards,
> Simon
Best regards,
Mario
^ permalink raw reply [flat|nested] 19+ messages in thread
* [U-Boot] [PATCH v2 01/10] ram: Add driver for MPC83xx
2018-05-03 19:01 ` [U-Boot] [PATCH v2 01/10] ram: Add driver for MPC83xx Simon Glass
@ 2018-05-04 8:04 ` Mario Six
2018-05-04 21:37 ` Simon Glass
0 siblings, 1 reply; 19+ messages in thread
From: Mario Six @ 2018-05-04 8:04 UTC (permalink / raw)
To: u-boot
Hi Simon,
On Thu, May 3, 2018 at 9:01 PM, Simon Glass <sjg@chromium.org> wrote:
> Hi Mario,
>
> On 27 April 2018 at 06:52, Mario Six <mario.six@gdsys.cc> wrote:
>> Add a RAM driver for the MPC83xx architecture.
>>
>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>>
>> ---
>>
>> v1 -> v2:
>> No changes
>>
>> ---
>> arch/powerpc/cpu/mpc83xx/spd_sdram.c | 4 +
>> drivers/ram/Kconfig | 8 +
>> drivers/ram/Makefile | 1 +
>> drivers/ram/mpc83xx_sdram.c | 948 +++++++++++++++++++++++++++++
>> include/dt-bindings/memory/mpc83xx-sdram.h | 143 +++++
>> include/mpc83xx.h | 6 +
>> 6 files changed, 1110 insertions(+)
>> create mode 100644 drivers/ram/mpc83xx_sdram.c
>> create mode 100644 include/dt-bindings/memory/mpc83xx-sdram.h
>>
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
>
> Question below
>
> [..]
>
>> new file mode 100644
>> index 0000000000..1a73f7b3da
>> --- /dev/null
>> +++ b/drivers/ram/mpc83xx_sdram.c
>> @@ -0,0 +1,948 @@
>> +#define DEBUG
>> +
>> +#include <common.h>
>> +#include <dm.h>
>> +#include <ram.h>
>> +#include <asm/io.h>
>> +#include <dt-bindings/memory/mpc83xx-sdram.h>
>> +
>> +DECLARE_GLOBAL_DATA_PTR;
>> +
>> +#define CSCONFIG_ENABLE 0x80000000
>> +
>> +#define BANK_BITS_2 0x00000000
>> +#define BANK_BITS_3 0x00004000
>> +
>> +#define ROW_BITS_12 0x00000000
>> +#define ROW_BITS_13 0x00000100
>> +#define ROW_BITS_14 0x00000200
>> +
>> +#define COL_BITS_8 0x00000000
>> +#define COL_BITS_9 0x00000001
>> +#define COL_BITS_10 0x00000002
>> +#define COL_BITS_11 0x00000003
>> +
>> +#define TIMING_CFG3_EXT_REFREC_SHIFT 16
>> +
>> +#define TIMING_CFG0_RWT_SHIFT 30
>> +#define TIMING_CFG0_WRT_SHIFT 28
>> +#define TIMING_CFG0_RRT_SHIFT 26
>> +#define TIMING_CFG0_WWT_SHIFT 24
>> +#define TIMING_CFG0_ACT_PD_EXIT_SHIFT 20
>> +#define TIMING_CFG0_PRE_PD_EXIT_SHIFT 16
>> +#define TIMING_CFG0_ODT_PD_EXIT_SHIFT 8
>> +#define TIMING_CFG0_MRS_CYC_SHIFT 0
>> +
>> +#define TIMING_CFG1_PRETOACT_SHIFT 28
>> +#define TIMING_CFG1_ACTTOPRE_SHIFT 24
>> +#define TIMING_CFG1_ACTTORW_SHIFT 20
>> +#define TIMING_CFG1_CASLAT_SHIFT 16
>> +#define TIMING_CFG1_REFREC_SHIFT 12
>> +#define TIMING_CFG1_WRREC_SHIFT 8
>> +#define TIMING_CFG1_ACTTOACT_SHIFT 4
>> +#define TIMING_CFG1_WRTORD_SHIFT 0
>> +
>> +#define TIMING_CFG2_CPO_SHIFT 23
>> +#define TIMING_CFG2_WR_DATA_DELAY_SHIFT 10
>> +#define TIMING_CFG2_ADD_LAT_SHIFT 28
>> +#define TIMING_CFG2_WR_LAT_DELAY_SHIFT 19
>> +#define TIMING_CFG2_RD_TO_PRE_SHIFT 13
>> +#define TIMING_CFG2_CKE_PLS_SHIFT 6
>> +#define TIMING_CFG2_FOUR_ACT_SHIFT 0
>> +
>> +#define SDRAM_CFG_SREN_SHIFT (31 - 1)
>> +#define SDRAM_CFG_ECC_EN_SHIFT (31 - 2)
>> +#define SDRAM_CFG_RD_EN_SHIFT (31 - 3)
>> +#define SDRAM_CFG_SDRAM_TYPE_SHIFT (31 - 7)
>> +#define SDRAM_CFG_DYN_PWR_SHIFT (31 - 10)
>> +#define SDRAM_CFG_DBW_SHIFT (31 - 12)
>> +#define SDRAM_CFG_NCAP_SHIFT (31 - 14)
>> +#define SDRAM_CFG_2T_EN_SHIFT (31 - 16)
>> +#define SDRAM_CFG_BA_INTLV_CTL_SHIFT (31 - 23)
>> +#define SDRAM_CFG_PCHB8_SHIFT (31 - 27)
>> +#define SDRAM_CFG_HSE_SHIFT (31 - 28)
>> +#define SDRAM_CFG_BI_SHIFT (31 - 31)
>> +
>> +#define SDRAM_CFG2_FRC_SR_SHIFT (31 - 0)
>> +#define SDRAM_CFG2_DLL_RST_DIS (31 - 2)
>> +#define SDRAM_CFG2_DQS_CFG (31 - 5)
>> +#define SDRAM_CFG2_ODT_CFG (31 - 10)
>> +#define SDRAM_CFG2_NUM_PR (31 - 19)
>> +
>> +#define SDRAM_MODE_ESD_SHIFT 16
>> +#define SDRAM_MODE_SD_SHIFT 0
>> +
>> +#define SDRAM_MODE2_ESD2_SHIFT (31 - 15)
>> +#define SDRAM_MODE2_ESD3_SHIFT (31 - 31)
>> +
>> +#define SDRAM_INTERVAL_REFINT_SHIFT 16
>> +#define SDRAM_INTERVAL_BSTOPRE_SHIFT 0
>> +
>> +#define SDRAM_CFG_MEM_EN 0x80000000
>> +
>> +int dram_init(void)
>> +{
>> + struct udevice *ram_ctrl;
>> + int ret;
>> +
>> + /* Current assumption: There is only one RAM controller */
>> + ret = uclass_first_device_err(UCLASS_RAM, &ram_ctrl);
>> +
>> + if (ret) {
>> + debug("uclass_first_device_err failed: %d\n", ret);
>> + return ret;
>> + }
>> +
>> + /* Set gd->ram_size? */
>> +
>> + return 0;
>> +}
>> +
>> +phys_size_t get_effective_memsize(void)
>> +{
>> +#ifndef CONFIG_VERY_BIG_RAM
>
> Can this (and the #ifdefs below in this file) be converted to
>
> if (IS_ENABLED(CONFIG_...))
>
> instead, to increase build coverage?
>
Yes, no problem, will convert for v3.
By the way, is this a practice that's generally encouraged, or is it just
useful in special cases such as this one?
> Regards,
> Simon
Best regards,
Mario
^ permalink raw reply [flat|nested] 19+ messages in thread
* [U-Boot] [PATCH v2 02/10] sysreset: Add get_status method
2018-05-03 19:01 ` Simon Glass
@ 2018-05-04 8:06 ` Mario Six
0 siblings, 0 replies; 19+ messages in thread
From: Mario Six @ 2018-05-04 8:06 UTC (permalink / raw)
To: u-boot
Hi Simon,
On Thu, May 3, 2018 at 9:01 PM, Simon Glass <sjg@chromium.org> wrote:
> On 27 April 2018 at 06:52, Mario Six <mario.six@gdsys.cc> wrote:
>> It's useful to have the reset status of the SoC printed out during reset
>> (e.g. to learn whether the reset was caused by software or a watchdog).
>>
>> As a first step to implement this, add a get_status method to the
>> sysreset class, which enables the caller to get printable information
>> about the reset status (akin to get_desc in the CPU uclass).
>>
>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>>
>> ---
>>
>> v1 -> v2:
>> New in v2
>>
>> ---
>> drivers/sysreset/sysreset-uclass.c | 10 ++++++++++
>> include/sysreset.h | 17 +++++++++++++++++
>> 2 files changed, 27 insertions(+)
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
>
> Can you add a test for sandbox?
OK, will add a test in v3.
Best regards,
Mario
^ permalink raw reply [flat|nested] 19+ messages in thread
* [U-Boot] [PATCH v2 03/10] board_f: Add reset status printing
2018-05-03 19:01 ` Simon Glass
@ 2018-05-04 8:10 ` Mario Six
0 siblings, 0 replies; 19+ messages in thread
From: Mario Six @ 2018-05-04 8:10 UTC (permalink / raw)
To: u-boot
Hi Simon,
On Thu, May 3, 2018 at 9:01 PM, Simon Glass <sjg@chromium.org> wrote:
> Hi Mario,
>
> On 27 April 2018 at 06:52, Mario Six <mario.six@gdsys.cc> wrote:
>> To print the reset status during boot, add a method print_resetinfo to
>> board_f, which is called in init_sequence_f[], that gets the reset
>> information from the sysreset driver (assuming there is only one seems
>> reasonable), and prints it.
>>
>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>>
>> ---
>>
>> v1 -> v2:
>> New in v2
>>
>> ---
>> common/board_f.c | 19 +++++++++++++++++++
>> 1 file changed, 19 insertions(+)
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
>
> nit below
>
>>
>> diff --git a/common/board_f.c b/common/board_f.c
>> index ae8bdb7c5c..2df30cd250 100644
>> --- a/common/board_f.c
>> +++ b/common/board_f.c
>> @@ -25,6 +25,7 @@
>> #include <relocate.h>
>> #include <spi.h>
>> #include <status_led.h>
>> +#include <sysreset.h>
>> #include <timer.h>
>> #include <trace.h>
>> #include <video.h>
>> @@ -141,6 +142,21 @@ static int display_text_info(void)
>> return 0;
>> }
>>
>> +#ifdef CONFIG_SYSRESET
>> +static int print_resetinfo(void)
>> +{
>> + struct udevice *dev;
>> + char status[256];
>> +
>> + uclass_first_device_err(UCLASS_SYSRESET, &dev);
>
> Should check the result and only call the function below if it is 0.
>
Yes, I found that one myself when I tried to run the sandbox tests again.
Will be fixed in v3.
>> +
>> + if (!sysreset_get_status(dev, status, sizeof(status)))
>> + printf("%s", status);
>> +
>> + return 0;
>> +}
>> +#endif
>> +
>
> Regards,
> Simon
Best regards,
Mario
^ permalink raw reply [flat|nested] 19+ messages in thread
* [U-Boot] [PATCH v2 01/10] ram: Add driver for MPC83xx
2018-05-04 8:04 ` Mario Six
@ 2018-05-04 21:37 ` Simon Glass
2018-05-04 21:57 ` Tom Rini
0 siblings, 1 reply; 19+ messages in thread
From: Simon Glass @ 2018-05-04 21:37 UTC (permalink / raw)
To: u-boot
+Tom for question below
Hi Mario,
On 4 May 2018 at 02:04, Mario Six <mario.six@gdsys.cc> wrote:
> Hi Simon,
>
> On Thu, May 3, 2018 at 9:01 PM, Simon Glass <sjg@chromium.org> wrote:
>> Hi Mario,
>>
>> On 27 April 2018 at 06:52, Mario Six <mario.six@gdsys.cc> wrote:
>>> Add a RAM driver for the MPC83xx architecture.
>>>
>>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>>>
>>> ---
>>>
>>> v1 -> v2:
>>> No changes
>>>
>>> ---
>>> arch/powerpc/cpu/mpc83xx/spd_sdram.c | 4 +
>>> drivers/ram/Kconfig | 8 +
>>> drivers/ram/Makefile | 1 +
>>> drivers/ram/mpc83xx_sdram.c | 948
+++++++++++++++++++++++++++++
>>> include/dt-bindings/memory/mpc83xx-sdram.h | 143 +++++
>>> include/mpc83xx.h | 6 +
>>> 6 files changed, 1110 insertions(+)
>>> create mode 100644 drivers/ram/mpc83xx_sdram.c
>>> create mode 100644 include/dt-bindings/memory/mpc83xx-sdram.h
>>>
>>
>> Reviewed-by: Simon Glass <sjg@chromium.org>
>>
>> Question below
>>
[..]
>>> +
>>> +phys_size_t get_effective_memsize(void)
>>> +{
>>> +#ifndef CONFIG_VERY_BIG_RAM
>>
>> Can this (and the #ifdefs below in this file) be converted to
>>
>> if (IS_ENABLED(CONFIG_...))
>>
>> instead, to increase build coverage?
>>
>
> Yes, no problem, will convert for v3.
>
> By the way, is this a practice that's generally encouraged, or is it just
> useful in special cases such as this one?
I think it is better in most cases as I don't really like #ifdefs in the
code when they are easy to remove:
- visually confusing particularly where there is more than one term in the
#if
- creates multiple builds of the code, reducing build coverage for sandbox
- can sometimes be replaced with empty static inline functions, or even
build up logic (e.g. of_live_active() and its callers)
Tom, do you have any thoughts on this one?
Regards,
Simon
^ permalink raw reply [flat|nested] 19+ messages in thread
* [U-Boot] [PATCH v2 01/10] ram: Add driver for MPC83xx
2018-05-04 21:37 ` Simon Glass
@ 2018-05-04 21:57 ` Tom Rini
0 siblings, 0 replies; 19+ messages in thread
From: Tom Rini @ 2018-05-04 21:57 UTC (permalink / raw)
To: u-boot
On Fri, May 04, 2018 at 09:37:54PM +0000, Simon Glass wrote:
> +Tom for question below
>
> Hi Mario,
>
> On 4 May 2018 at 02:04, Mario Six <mario.six@gdsys.cc> wrote:
> > Hi Simon,
> >
> > On Thu, May 3, 2018 at 9:01 PM, Simon Glass <sjg@chromium.org> wrote:
> >> Hi Mario,
> >>
> >> On 27 April 2018 at 06:52, Mario Six <mario.six@gdsys.cc> wrote:
> >>> Add a RAM driver for the MPC83xx architecture.
> >>>
> >>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> >>>
> >>> ---
> >>>
> >>> v1 -> v2:
> >>> No changes
> >>>
> >>> ---
> >>> arch/powerpc/cpu/mpc83xx/spd_sdram.c | 4 +
> >>> drivers/ram/Kconfig | 8 +
> >>> drivers/ram/Makefile | 1 +
> >>> drivers/ram/mpc83xx_sdram.c | 948
> +++++++++++++++++++++++++++++
> >>> include/dt-bindings/memory/mpc83xx-sdram.h | 143 +++++
> >>> include/mpc83xx.h | 6 +
> >>> 6 files changed, 1110 insertions(+)
> >>> create mode 100644 drivers/ram/mpc83xx_sdram.c
> >>> create mode 100644 include/dt-bindings/memory/mpc83xx-sdram.h
> >>>
> >>
> >> Reviewed-by: Simon Glass <sjg@chromium.org>
> >>
> >> Question below
> >>
> [..]
>
> >>> +
> >>> +phys_size_t get_effective_memsize(void)
> >>> +{
> >>> +#ifndef CONFIG_VERY_BIG_RAM
> >>
> >> Can this (and the #ifdefs below in this file) be converted to
> >>
> >> if (IS_ENABLED(CONFIG_...))
> >>
> >> instead, to increase build coverage?
> >>
> >
> > Yes, no problem, will convert for v3.
> >
> > By the way, is this a practice that's generally encouraged, or is it just
> > useful in special cases such as this one?
>
> I think it is better in most cases as I don't really like #ifdefs in the
> code when they are easy to remove:
> - visually confusing particularly where there is more than one term in the
> #if
> - creates multiple builds of the code, reducing build coverage for sandbox
> - can sometimes be replaced with empty static inline functions, or even
> build up logic (e.g. of_live_active() and its callers)
>
> Tom, do you have any thoughts on this one?
Can this even be built for sandbox? If yes, we should do what we can to
increase build coverage (and coverity coverage). Otherwise I don't
think that if (CONFIG_IS_ENABLED(FOO)) is always better. If we're
talking about:
#ifdef FOO
if (bar) {
...
}
#endif
Then yes, testing for CONFIG_IS_ENABLED(FOO) && bar is great. Or:
#ifdef FOO
... a few lines ...
#endif
It's also good. But if we're talking about a lot of lines, I think the
added indent doesn't help and can start making it a bit harder with
additional wrap.
--
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20180504/245d0ac3/attachment.sig>
^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2018-05-04 21:57 UTC | newest]
Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-04-27 12:52 [U-Boot] [PATCH v2 01/10] ram: Add driver for MPC83xx Mario Six
2018-04-27 12:52 ` [U-Boot] [PATCH v2 02/10] sysreset: Add get_status method Mario Six
2018-05-03 19:01 ` Simon Glass
2018-05-04 8:06 ` Mario Six
2018-04-27 12:52 ` [U-Boot] [PATCH v2 03/10] board_f: Add reset status printing Mario Six
2018-05-03 19:01 ` Simon Glass
2018-05-04 8:10 ` Mario Six
2018-04-27 12:52 ` [U-Boot] [PATCH v2 04/10] mpc83xx: Add sysreset driver Mario Six
2018-05-03 19:01 ` Simon Glass
2018-04-27 12:52 ` [U-Boot] [PATCH v2 05/10] clk: Add MPC83xx clock driver Mario Six
2018-04-27 12:52 ` [U-Boot] [PATCH v2 06/10] timer: Add MPC83xx timer driver Mario Six
2018-04-30 23:13 ` Simon Glass
2018-05-04 6:19 ` Mario Six
2018-04-27 12:52 ` [U-Boot] [PATCH v2 07/10] common: board_f: Sort includes Mario Six
2018-05-03 19:01 ` Simon Glass
2018-05-03 19:01 ` [U-Boot] [PATCH v2 01/10] ram: Add driver for MPC83xx Simon Glass
2018-05-04 8:04 ` Mario Six
2018-05-04 21:37 ` Simon Glass
2018-05-04 21:57 ` Tom Rini
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.