static int stm32mp1_ddr_setup(void) { struct ddr_info *priv = &ddr_priv_data; int ret; struct stm32mp1_ddr_config config; int node, len; uint32_t uret, idx; void *fdt; #define PARAM(x, y) \ { \ .name = x, \ .offset = offsetof(struct stm32mp1_ddr_config, y), \ .size = sizeof(config.y) / sizeof(uint32_t) \ } #define CTL_PARAM(x) PARAM("st,ctl-"#x, c_##x) #define PHY_PARAM(x) PARAM("st,phy-"#x, p_##x) const struct { const char *name; /* Name in DT */ const uint32_t offset; /* Offset in config struct */ const uint32_t size; /* Size of parameters */ } param[] = { CTL_PARAM(reg), CTL_PARAM(timing), CTL_PARAM(map), CTL_PARAM(perf), PHY_PARAM(reg), PHY_PARAM(timing), PHY_PARAM(cal) }; if (fdt_get_address(&fdt) == 0) { return -ENOENT; } node = fdt_node_offset_by_compatible(fdt, -1, DT_DDR_COMPAT); if (node < 0) { ERROR("%s: Cannot read DDR node in DT\n", __func__); return -EINVAL; } config.info.speed = fdt_read_uint32_default(node, "st,mem-speed", 0); if (!config.info.speed) { VERBOSE("%s: no st,mem-speed\n", __func__); return -EINVAL; } config.info.size = fdt_read_uint32_default(node, "st,mem-size", 0); if (!config.info.size) { VERBOSE("%s: no st,mem-size\n", __func__); return -EINVAL; } config.info.name = fdt_getprop(fdt, node, "st,mem-name", &len); if (config.info.name == NULL) { VERBOSE("%s: no st,mem-name\n", __func__); return -EINVAL; } INFO("RAM: %s\n", config.info.name); for (idx = 0; idx < ARRAY_SIZE(param); idx++) { ret = fdt_read_uint32_array(node, param[idx].name, (void *)((uintptr_t)&config + param[idx].offset), param[idx].size); VERBOSE("%s: %s[0x%x] = %d\n", __func__, param[idx].name, param[idx].size, ret); if (ret != 0) { ERROR("%s: Cannot read %s\n", __func__, param[idx].name); return -EINVAL; } } /* Disable axidcg clock gating during init */ mmio_clrbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_AXIDCGEN); stm32mp1_ddr_init(priv, &config); /* Enable axidcg clock gating */ mmio_setbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_AXIDCGEN); priv->info.size = config.info.size; VERBOSE("%s : ram size(%x, %x)\n", __func__, (uint32_t)priv->info.base, (uint32_t)priv->info.size); write_sctlr(read_sctlr() & ~SCTLR_C_BIT); dcsw_op_all(DC_OP_CISW); uret = ddr_test_data_bus(); if (uret != 0U) { ERROR("DDR data bus test: can't access memory @ 0x%x\n", uret); panic(); } uret = ddr_test_addr_bus(); if (uret != 0U) { ERROR("DDR addr bus test: can't access memory @ 0x%x\n", uret); panic(); } uret = ddr_check_size(); if (uret < config.info.size) { ERROR("DDR size: 0x%x does not match DT config: 0x%x\n", uret, config.info.size); panic(); } write_sctlr(read_sctlr() | SCTLR_C_BIT); return 0; }
static int stm32_sdmmc2_dt_get_config(void) { int sdmmc_node; void *fdt = NULL; const fdt32_t *cuint; if (fdt_get_address(&fdt) == 0) { return -FDT_ERR_NOTFOUND; } if (fdt == NULL) { return -FDT_ERR_NOTFOUND; } sdmmc_node = fdt_node_offset_by_compatible(fdt, -1, DT_SDMMC2_COMPAT); while (sdmmc_node != -FDT_ERR_NOTFOUND) { cuint = fdt_getprop(fdt, sdmmc_node, "reg", NULL); if (cuint == NULL) { continue; } if (fdt32_to_cpu(*cuint) == sdmmc2_params.reg_base) { break; } sdmmc_node = fdt_node_offset_by_compatible(fdt, sdmmc_node, DT_SDMMC2_COMPAT); } if (sdmmc_node == -FDT_ERR_NOTFOUND) { return -FDT_ERR_NOTFOUND; } if (fdt_get_status(sdmmc_node) == DT_DISABLED) { return -FDT_ERR_NOTFOUND; } if (dt_set_pinctrl_config(sdmmc_node) != 0) { return -FDT_ERR_BADVALUE; } cuint = fdt_getprop(fdt, sdmmc_node, "clocks", NULL); if (cuint == NULL) { return -FDT_ERR_NOTFOUND; } cuint++; sdmmc2_params.clock_id = fdt32_to_cpu(*cuint); cuint = fdt_getprop(fdt, sdmmc_node, "resets", NULL); if (cuint == NULL) { return -FDT_ERR_NOTFOUND; } cuint++; sdmmc2_params.reset_id = fdt32_to_cpu(*cuint); if ((fdt_getprop(fdt, sdmmc_node, "st,use-ckin", NULL)) != NULL) { sdmmc2_params.pin_ckin = SDMMC_CLKCR_SELCLKRX_0; } if ((fdt_getprop(fdt, sdmmc_node, "st,sig-dir", NULL)) != NULL) { sdmmc2_params.dirpol = SDMMC_POWER_DIRPOL; } if ((fdt_getprop(fdt, sdmmc_node, "st,neg-edge", NULL)) != NULL) { sdmmc2_params.negedge = SDMMC_CLKCR_NEGEDGE; } cuint = fdt_getprop(fdt, sdmmc_node, "bus-width", NULL); if (cuint != NULL) { switch (fdt32_to_cpu(*cuint)) { case 4: sdmmc2_params.bus_width = MMC_BUS_WIDTH_4; break; case 8: sdmmc2_params.bus_width = MMC_BUS_WIDTH_8; break; default: break; } } return 0; }