
On 3/8/23 21:26, Ralph Siemsen wrote:
[...]
+#define FUNCCTRL 0x00 +#define FUNCCTRL_MASKSDLOFS (0x18 << 16) +#define FUNCCTRL_DVDDQ_1_5V (1 << 8) +#define FUNCCTRL_RESET_N (1 << 0) +#define DLLCTRL 0x04 +#define DLLCTRL_ASDLLOCK (1 << 26) +#define DLLCTRL_MFSL_500MHz (2 << 1) +#define DLLCTRL_MDLLSTBY (1 << 0)
Use BIT() macro where applicable.
+#define ZQCALCTRL 0x08 +#define ZQCALCTRL_ZQCALEND (1 << 30) +#define ZQCALCTRL_ZQCALRSTB (1 << 0) +#define ZQODTCTRL 0x0c +#define RDCTRL 0x10 +#define RDTMG 0x14 +#define FIFOINIT 0x18 +#define FIFOINIT_RDPTINITEXE (1 << 8) +#define FIFOINIT_WRPTINITEXE (1 << 0) +#define OUTCTRL 0x1c +#define OUTCTRL_ADCMDOE (1 << 0) +#define WLCTRL1 0x40 +#define WLCTRL1_WLSTR (1 << 24) +#define DQCALOFS1 0xe8
+/* DDR PHY setup */ +void ddr_phy_init(struct cadence_ddr_info *priv, int ddr_type) +{
- u32 val;
- /* Disable DDR Controller clock and FlexWAY connection */
- clk_disable(&priv->hclk_ddrc);
- clk_disable(&priv->clk_ddrc);
- clk_rzn1_reset_state(&priv->hclk_ddrc, 0);
- clk_rzn1_reset_state(&priv->clk_ddrc, 0);
- /* Enable DDR Controller clock and FlexWAY connection */
- clk_enable(&priv->clk_ddrc);
- clk_enable(&priv->hclk_ddrc);
- /* DDR PHY Soft reset assert */
- ddrc_writel(FUNCCTRL_MASKSDLOFS | FUNCCTRL_DVDDQ_1_5V, FUNCCTRL);
- clk_rzn1_reset_state(&priv->hclk_ddrc, 1);
- clk_rzn1_reset_state(&priv->clk_ddrc, 1);
- /* DDR PHY setup */
- phy_writel(DLLCTRL_MFSL_500MHz | DLLCTRL_MDLLSTBY, DLLCTRL);
- phy_writel(0x00000182, ZQCALCTRL);
- if (ddr_type == RZN1_DDR3_DUAL_BANK)
phy_writel(0xAB330031, ZQODTCTRL);
- else if (ddr_type == RZN1_DDR3_SINGLE_BANK)
phy_writel(0xAB320051, ZQODTCTRL);
- else /* DDR2 */
phy_writel(0xAB330071, ZQODTCTRL);
- phy_writel(0xB545B544, RDCTRL);
- phy_writel(0x000000B0, RDTMG);
- phy_writel(0x020A0806, OUTCTRL);
- if (ddr_type == RZN1_DDR3_DUAL_BANK)
phy_writel(0x80005556, WLCTRL1);
- else
phy_writel(0x80005C5D, WLCTRL1);
- phy_writel(0x00000101, FIFOINIT);
- phy_writel(0x00004545, DQCALOFS1);
Is there any macro which defines those magic bits in magic numbers ? If so, please use them.
- /* Step 9 MDLL reset release */
- val = phy_readl(DLLCTRL);
- val &= ~DLLCTRL_MDLLSTBY;
- phy_writel(val, DLLCTRL);
- /* Step 12 Soft reset release */
- val = phy_readl(FUNCCTRL);
- val |= FUNCCTRL_RESET_N;
- phy_writel(val, FUNCCTRL);
- /* Step 13 FIFO pointer initialize */
- phy_writel(FIFOINIT_RDPTINITEXE | FIFOINIT_WRPTINITEXE, FIFOINIT);
- /* Step 14 Execute ZQ Calibration */
- val = phy_readl(ZQCALCTRL);
- val |= ZQCALCTRL_ZQCALRSTB;
- phy_writel(val, ZQCALCTRL);
- /* Step 15 Wait for 200us or more, or wait for DFIINITCOMPLETE to be "1" */
- while (!(phy_readl(DLLCTRL) & DLLCTRL_ASDLLOCK))
;
- while (!(phy_readl(ZQCALCTRL) & ZQCALCTRL_ZQCALEND))
;
- /* Step 16 Enable Address and Command output */
- val = phy_readl(OUTCTRL);
- val |= OUTCTRL_ADCMDOE;
- phy_writel(val, OUTCTRL);
- /* Step 17 Wait for 200us or more(from MRESETB=0) */
- udelay(200);
+}
[...]
+int rzn1_dram_init(struct cadence_ddr_info *priv) +{
- u32 version;
- u32 ddr_start_addr = 0;
- ddr_phy_init(priv, RZN1_DDR3_SINGLE_BANK);
- /*
* Override DDR PHY Interface (DFI) related settings
* DFI is the internal interface between the DDR controller and the DDR PHY.
* These settings are specific to the board and can't be known by the settings
* provided for each DDR model within the generated include.
*/
- ddr_350_374_async[351 - 350] = 0x001e0000;
- ddr_350_374_async[352 - 350] = 0x1e680000;
- ddr_350_374_async[353 - 350] = 0x02000020;
- ddr_350_374_async[354 - 350] = 0x02000200;
- ddr_350_374_async[355 - 350] = 0x00000c30;
- ddr_350_374_async[356 - 350] = 0x00009808;
- ddr_350_374_async[357 - 350] = 0x020a0706;
- ddr_350_374_async[372 - 350] = 0x01000000;
- /*
* On ES1.0 devices, the DDR start address that the DDR Controller sees
* is the physical address of the DDR. However, later devices changed it
* to be 0 in order to fix an issue with DDR out-of-range detection.
*/
+#define RZN1_SYSCTRL_REG_VERSION 412
- regmap_read(priv->syscon, RZN1_SYSCTRL_REG_VERSION, &version);
- if (version == 0x10)
ddr_start_addr = RZN1_V_DDR_BASE;
- /* DDR Controller is always in ASYNC mode */
- cdns_ddr_ctrl_init((void *)RZN1_DDR_BASE, 1,
ddr_00_87_async, ddr_350_374_async,
ddr_start_addr, CFG_SYS_SDRAM_SIZE,
priv->enable_ecc, priv->enable_8bit);
- rzn1_ddr3_single_bank((void *)RZN1_DDR_BASE);
Can you obtain the DRAM base from DT ?
- cdns_ddr_set_diff_cs_delays((void *)RZN1_DDR_BASE, 2, 7, 2, 2);
- cdns_ddr_set_same_cs_delays((void *)RZN1_DDR_BASE, 0, 7, 0, 0);
- cdns_ddr_set_odt_times((void *)RZN1_DDR_BASE, 5, 6, 6, 0, 4);
- cdns_ddr_ctrl_start((void *)RZN1_DDR_BASE);
- ddr_phy_enable_wl(priv);
- if (priv->enable_ecc) {
/*
* Any read before a write will trigger an ECC un-correctable error,
* causing a data abort. However, this is also true for any read with a
* size less than the AXI bus width. So, the only sensible solution is
* to write to all of DDR now and take the hit...
*/
memset((void *)RZN1_V_DDR_BASE, 0xff, CFG_SYS_SDRAM_SIZE);
- }
- return 0;
+}
+static int cadence_ddr_get_info(struct udevice *udev, struct ram_info *info) +{
- info->base = 0;
- info->size = gd->ram_size;
- return 0;
+}
+static struct ram_ops cadence_ddr_ops = {
- .get_info = cadence_ddr_get_info,
+};
+static int cadence_ddr_probe(struct udevice *dev) +{
- struct cadence_ddr_info *priv = dev_get_priv(dev);
- int ret;
- priv->ddrc = dev_remap_addr_name(dev, "ddrc");
- if (!priv->ddrc) {
dev_err(dev, "No reg property for Cadence DDR CTRL\n");
return -EINVAL;
- }
- priv->phy = dev_remap_addr_name(dev, "phy");
- if (!priv->phy) {
dev_err(dev, "No reg property for Cadence DDR PHY\n");
return -EINVAL;
- }
- ret = clk_get_by_name(dev, "clk_ddrc", &priv->clk_ddrc);
- if (ret) {
dev_err(dev, "No clock for Cadence DDR\n");
return ret;
- }
- ret = clk_get_by_name(dev, "hclk_ddrc", &priv->hclk_ddrc);
- if (ret) {
dev_err(dev, "No HCLK for Cadence DDR\n");
return ret;
- }
- priv->syscon = syscon_regmap_lookup_by_phandle(dev, "syscon");
- if (IS_ERR(priv->syscon)) {
dev_err(dev, "No syscon node found\n");
//return PTR_ERR(priv->syscon);
This shouldn't be commented out, right ?
- }
- priv->enable_ecc = dev_read_bool(dev, "enable-ecc");
- priv->enable_8bit = dev_read_bool(dev, "enable-8bit");
- rzn1_dram_init(priv);
- return 0;
+}
+static const struct udevice_id cadence_ddr_ids[] = {
- { .compatible = "cadence,ddr-ctrl" },
- { }
+};
+U_BOOT_DRIVER(cadence_ddr) = {
- .name = "cadence_ddr",
- .id = UCLASS_RAM,
- .of_match = cadence_ddr_ids,
- .ops = &cadence_ddr_ops,
- .probe = cadence_ddr_probe,
- .priv_auto = sizeof(struct cadence_ddr_info),
- .flags = DM_FLAG_PRE_RELOC,
+};
[...]