sunxi: H6: move LPDDR3 timing definition into separate file
authorAndre Przywara <andre.przywara@arm.com>
Mon, 15 Jul 2019 01:27:06 +0000 (02:27 +0100)
committerJagan Teki <jagan@amarulasolutions.com>
Tue, 16 Jul 2019 11:39:31 +0000 (17:09 +0530)
Currently the H6 DRAM driver only supports one kind of LPDDR3 DRAM.
Split the timing parameters for this LPDDR3 configuration  into a
separate file, to allow selecting an alternative later at compile time
(as the sunxi-dw driver does).

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Tested-by: Jernej Skrabec <jernej.skrabec@siol.net>
Reviewed-by: Jernej Skrabec <jernej.skrabec@siol.net>
Reviewed-by: Jagan Teki <jagan@amarulasolutions.com>
arch/arm/include/asm/arch-sunxi/dram_sun50i_h6.h
arch/arm/mach-sunxi/Kconfig
arch/arm/mach-sunxi/Makefile
arch/arm/mach-sunxi/dram_sun50i_h6.c
arch/arm/mach-sunxi/dram_timings/Makefile
arch/arm/mach-sunxi/dram_timings/h6_lpddr3.c [new file with mode: 0644]
configs/beelink_gs1_defconfig
configs/orangepi_lite2_defconfig
configs/orangepi_one_plus_defconfig
configs/pine_h64_defconfig

index eeb4da5c3f341c5d6e492d73432639388caee35a..54c475555663881999ec12685348438cf948dc8c 100644 (file)
@@ -287,6 +287,31 @@ check_member(sunxi_mctl_phy_reg, dx[3].reserved_0xf0, 0xaf0);
 #define DCR_DDR4       (4 << 0)
 #define DCR_DDR8BANK   BIT(3)
 
+/*
+ * The delay parameters allow to allegedly specify delay times of some
+ * unknown unit for each individual bit trace in each of the four data bytes
+ * the 32-bit wide access consists of. Also three control signals can be
+ * adjusted individually.
+ */
+#define NR_OF_BYTE_LANES       (32 / BITS_PER_BYTE)
+/* The eight data lines (DQn) plus DM, DQS, DQS/DM/DQ Output Enable and DQSN */
+#define WR_LINES_PER_BYTE_LANE (BITS_PER_BYTE + 4)
+/*
+ * The eight data lines (DQn) plus DM, DQS, DQS/DM/DQ Output Enable, DQSN,
+ * Termination and Power down
+ */
+#define RD_LINES_PER_BYTE_LANE (BITS_PER_BYTE + 6)
+struct dram_para {
+       u32 clk;
+       enum sunxi_dram_type type;
+       u8 cols;
+       u8 rows;
+       u8 ranks;
+       const u8 dx_read_delays[NR_OF_BYTE_LANES][RD_LINES_PER_BYTE_LANE];
+       const u8 dx_write_delays[NR_OF_BYTE_LANES][WR_LINES_PER_BYTE_LANE];
+};
+
+
 static inline int ns_to_t(int nanoseconds)
 {
        const unsigned int ctrl_freq = CONFIG_DRAM_CLK / 2;
@@ -294,4 +319,6 @@ static inline int ns_to_t(int nanoseconds)
        return DIV_ROUND_UP(ctrl_freq * nanoseconds, 1000);
 }
 
+void mctl_set_timing_params(struct dram_para *para);
+
 #endif /* _SUNXI_DRAM_SUN50I_H6_H */
index 1669e62a6d2e3dea7974dd91f421a90e625f03a3..d588936850da5c363580a09179bd0834eba1c274 100644 (file)
@@ -340,7 +340,7 @@ config ARM_BOOT_HOOK_RMR
        This allows both the SPL and the U-Boot proper to be entered in
        either mode and switch to AArch64 if needed.
 
-if SUNXI_DRAM_DW
+if SUNXI_DRAM_DW || DRAM_SUN50I_H6
 config SUNXI_DRAM_DDR3
        bool
 
@@ -370,6 +370,14 @@ config SUNXI_DRAM_LPDDR3_STOCK
        This option is the LPDDR3 timing used by the stock boot0 by
        Allwinner.
 
+config SUNXI_DRAM_H6_LPDDR3
+       bool "LPDDR3 DRAM chips on the H6 DRAM controller"
+       select SUNXI_DRAM_LPDDR3
+       depends on DRAM_SUN50I_H6
+       ---help---
+       This option is the LPDDR3 timing used by the stock boot0 by
+       Allwinner.
+
 config SUNXI_DRAM_DDR2_V3S
        bool "DDR2 found in V3s chip"
        select SUNXI_DRAM_DDR2
index 43a93e3085724f4412bc72f6fb2b28c4b92530e8..d129f334798bb9e504516012055385088d6f8afa 100644 (file)
@@ -39,4 +39,5 @@ obj-$(CONFIG_SPL_SPI_SUNXI)   += spl_spi_sunxi.o
 obj-$(CONFIG_SUNXI_DRAM_DW)    += dram_sunxi_dw.o
 obj-$(CONFIG_SUNXI_DRAM_DW)    += dram_timings/
 obj-$(CONFIG_DRAM_SUN50I_H6)   += dram_sun50i_h6.o
+obj-$(CONFIG_DRAM_SUN50I_H6)   += dram_timings/
 endif
index 7a8b724f081c22cc78095b0e322ec247916d2734..697b8af4ce8e89cec7d47544b52f876f15cc2007 100644 (file)
  * similar PHY is ZynqMP.
  */
 
-/*
- * The delay parameters below allow to allegedly specify delay times of some
- * unknown unit for each individual bit trace in each of the four data bytes
- * the 32-bit wide access consists of. Also three control signals can be
- * adjusted individually.
- */
-#define NR_OF_BYTE_LANES       (32 / BITS_PER_BYTE)
-/* The eight data lines (DQn) plus DM, DQS, DQS/DM/DQ Output Enable and DQSN */
-#define WR_LINES_PER_BYTE_LANE (BITS_PER_BYTE + 4)
-/*
- * The eight data lines (DQn) plus DM, DQS, DQS/DM/DQ Output Enable, DQSN,
- * Termination and Power down
- */
-#define RD_LINES_PER_BYTE_LANE (BITS_PER_BYTE + 6)
-struct dram_para {
-       u32 clk;
-       enum sunxi_dram_type type;
-       u8 cols;
-       u8 rows;
-       u8 ranks;
-       const u8 dx_read_delays[NR_OF_BYTE_LANES][RD_LINES_PER_BYTE_LANE];
-       const u8 dx_write_delays[NR_OF_BYTE_LANES][WR_LINES_PER_BYTE_LANE];
-};
-
 static void mctl_sys_init(struct dram_para *para);
 static void mctl_com_init(struct dram_para *para);
-static void mctl_set_timing_lpddr3(struct dram_para *para);
 static void mctl_channel_init(struct dram_para *para);
 
 static void mctl_core_init(struct dram_para *para)
@@ -67,7 +42,7 @@ static void mctl_core_init(struct dram_para *para)
        mctl_com_init(para);
        switch (para->type) {
        case SUNXI_DRAM_TYPE_LPDDR3:
-               mctl_set_timing_lpddr3(para);
+               mctl_set_timing_params(para);
                break;
        default:
                panic("Unsupported DRAM type!");
@@ -171,127 +146,6 @@ static void mctl_set_master_priority(void)
        MBUS_CONF(HDCP2,  true,    HIGH, 2,  100,   64,   32);
 }
 
-static u32 mr_lpddr3[12] = {
-       0x00000000, 0x00000043, 0x0000001a, 0x00000001,
-       0x00000000, 0x00000000, 0x00000048, 0x00000000,
-       0x00000000, 0x00000000, 0x00000000, 0x00000003,
-};
-
-/* TODO: flexible timing */
-static void mctl_set_timing_lpddr3(struct dram_para *para)
-{
-       struct sunxi_mctl_ctl_reg * const mctl_ctl =
-                       (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
-       struct sunxi_mctl_phy_reg * const mctl_phy =
-                       (struct sunxi_mctl_phy_reg *)SUNXI_DRAM_PHY0_BASE;
-       int i;
-
-       u8 tccd         = 2;
-       u8 tfaw         = max(ns_to_t(50), 4);
-       u8 trrd         = max(ns_to_t(10), 2);
-       u8 trcd         = max(ns_to_t(24), 2);
-       u8 trc          = ns_to_t(70);
-       u8 txp          = max(ns_to_t(8), 2);
-       u8 twtr         = max(ns_to_t(8), 2);
-       u8 trtp         = max(ns_to_t(8), 2);
-       u8 twr          = max(ns_to_t(15), 2);
-       u8 trp          = ns_to_t(18);
-       u8 tras         = ns_to_t(42);
-       u8 twtr_sa      = ns_to_t(5);
-       u8 tcksrea      = ns_to_t(11);
-       u16 trefi       = ns_to_t(3900) / 32;
-       u16 trfc        = ns_to_t(210);
-       u16 txsr        = ns_to_t(220);
-
-       if (CONFIG_DRAM_CLK % 400 == 0) {
-               /* Round up these parameters */
-               twtr_sa++;
-               tcksrea++;
-       }
-
-       u8 tmrw         = 5;
-       u8 tmrd         = 5;
-       u8 tmod         = 12;
-       u8 tcke         = 3;
-       u8 tcksrx       = 5;
-       u8 tcksre       = 5;
-       u8 tckesr       = 5;
-       u8 trasmax      = CONFIG_DRAM_CLK / 60;
-       u8 txs          = 4;
-       u8 txsdll       = 4;
-       u8 txsabort     = 4;
-       u8 txsfast      = 4;
-
-       u8 tcl          = 5; /* CL 10 */
-       u8 tcwl         = 3; /* CWL 6 */
-       u8 t_rdata_en   = twtr_sa + 8;
-
-       u32 tdinit0     = (200 * CONFIG_DRAM_CLK) + 1;          /* 200us */
-       u32 tdinit1     = (100 * CONFIG_DRAM_CLK) / 1000 + 1;   /* 100ns */
-       u32 tdinit2     = (11 * CONFIG_DRAM_CLK) + 1;           /* 11us */
-       u32 tdinit3     = (1 * CONFIG_DRAM_CLK) + 1;            /* 1us */
-
-       u8 twtp         = tcwl + 4 + twr + 1;
-       /*
-        * The code below for twr2rd and trd2wr follows the IP core's
-        * document from ZynqMP and i.MX7. The BSP has both number
-        * substracted by 2.
-        */
-       u8 twr2rd       = tcwl + 4 + 1 + twtr;
-       u8 trd2wr       = tcl + 4 + (tcksrea >> 1) - tcwl + 1;
-
-       /* set mode registers */
-       for (i = 0; i < ARRAY_SIZE(mr_lpddr3); i++)
-               writel(mr_lpddr3[i], &mctl_phy->mr[i]);
-
-       /* set DRAM timing */
-       writel((twtp << 24) | (tfaw << 16) | (trasmax << 8) | tras,
-              &mctl_ctl->dramtmg[0]);
-       writel((txp << 16) | (trtp << 8) | trc, &mctl_ctl->dramtmg[1]);
-       writel((tcwl << 24) | (tcl << 16) | (trd2wr << 8) | twr2rd,
-              &mctl_ctl->dramtmg[2]);
-       writel((tmrw << 20) | (tmrd << 12) | tmod, &mctl_ctl->dramtmg[3]);
-       writel((trcd << 24) | (tccd << 16) | (trrd << 8) | trp,
-              &mctl_ctl->dramtmg[4]);
-       writel((tcksrx << 24) | (tcksre << 16) | (tckesr << 8) | tcke,
-              &mctl_ctl->dramtmg[5]);
-       /* Value suggested by ZynqMP manual and used by libdram */
-       writel((txp + 2) | 0x02020000, &mctl_ctl->dramtmg[6]);
-       writel((txsfast << 24) | (txsabort << 16) | (txsdll << 8) | txs,
-              &mctl_ctl->dramtmg[8]);
-       writel(txsr, &mctl_ctl->dramtmg[14]);
-
-       clrsetbits_le32(&mctl_ctl->init[0], (3 << 30), (1 << 30));
-       writel(0, &mctl_ctl->dfimisc);
-       clrsetbits_le32(&mctl_ctl->rankctl, 0xff0, 0x660);
-
-       /*
-        * Set timing registers of the PHY.
-        * Note: the PHY is clocked 2x from the DRAM frequency.
-        */
-       writel((trrd << 25) | (tras << 17) | (trp << 9) | (trtp << 1),
-              &mctl_phy->dtpr[0]);
-       writel((tfaw << 17) | 0x28000400 | (tmrd << 1), &mctl_phy->dtpr[1]);
-       writel(((txs << 6) - 1) | (tcke << 17), &mctl_phy->dtpr[2]);
-       writel(((txsdll << 22) - (0x1 << 16)) | twtr_sa | (tcksrea << 8),
-              &mctl_phy->dtpr[3]);
-       writel((txp << 1) | (trfc << 17) | 0x800, &mctl_phy->dtpr[4]);
-       writel((trc << 17) | (trcd << 9) | (twtr << 1), &mctl_phy->dtpr[5]);
-       writel(0x0505, &mctl_phy->dtpr[6]);
-
-       /* Configure DFI timing */
-       writel(tcl | 0x2000200 | (t_rdata_en << 16) | 0x808000,
-              &mctl_ctl->dfitmg0);
-       writel(0x040201, &mctl_ctl->dfitmg1);
-
-       /* Configure PHY timing */
-       writel(tdinit0 | (tdinit1 << 20), &mctl_phy->ptr[3]);
-       writel(tdinit2 | (tdinit3 << 18), &mctl_phy->ptr[4]);
-
-       /* set refresh timing */
-       writel((trefi << 16) | trfc, &mctl_ctl->rfshtmg);
-}
-
 static void mctl_sys_init(struct dram_para *para)
 {
        struct sunxi_ccm_reg * const ccm =
@@ -735,12 +589,14 @@ unsigned long sunxi_dram_init(void)
                        (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
        struct dram_para para = {
                .clk = CONFIG_DRAM_CLK,
+#ifdef CONFIG_SUNXI_DRAM_H6_LPDDR3
                .type = SUNXI_DRAM_TYPE_LPDDR3,
                .ranks = 2,
                .cols = 11,
                .rows = 14,
                .dx_read_delays  = SUN50I_H6_DX_READ_DELAYS,
                .dx_write_delays = SUN50I_H6_DX_WRITE_DELAYS,
+#endif
        };
 
        unsigned long size;
index 278a8a14cc2ff1d0d1d4131564ebcea96d79ef36..0886a95968bddd8a1b7499e017256d9b22432ab4 100644 (file)
@@ -1,3 +1,4 @@
 obj-$(CONFIG_SUNXI_DRAM_DDR3_1333)     += ddr3_1333.o
 obj-$(CONFIG_SUNXI_DRAM_LPDDR3_STOCK)  += lpddr3_stock.o
 obj-$(CONFIG_SUNXI_DRAM_DDR2_V3S)      += ddr2_v3s.o
+obj-$(CONFIG_SUNXI_DRAM_H6_LPDDR3)     += h6_lpddr3.o
diff --git a/arch/arm/mach-sunxi/dram_timings/h6_lpddr3.c b/arch/arm/mach-sunxi/dram_timings/h6_lpddr3.c
new file mode 100644 (file)
index 0000000..1000860
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * sun50i H6 LPDDR3 timings
+ *
+ * (C) Copyright 2017      Icenowy Zheng <icenowy@aosc.io>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/arch/dram.h>
+#include <asm/arch/cpu.h>
+
+static u32 mr_lpddr3[12] = {
+       0x00000000, 0x00000043, 0x0000001a, 0x00000001,
+       0x00000000, 0x00000000, 0x00000048, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000003,
+};
+
+/* TODO: flexible timing */
+void mctl_set_timing_params(struct dram_para *para)
+{
+       struct sunxi_mctl_ctl_reg * const mctl_ctl =
+                       (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
+       struct sunxi_mctl_phy_reg * const mctl_phy =
+                       (struct sunxi_mctl_phy_reg *)SUNXI_DRAM_PHY0_BASE;
+       int i;
+
+       u8 tccd         = 2;
+       u8 tfaw         = max(ns_to_t(50), 4);
+       u8 trrd         = max(ns_to_t(10), 2);
+       u8 trcd         = max(ns_to_t(24), 2);
+       u8 trc          = ns_to_t(70);
+       u8 txp          = max(ns_to_t(8), 2);
+       u8 twtr         = max(ns_to_t(8), 2);
+       u8 trtp         = max(ns_to_t(8), 2);
+       u8 twr          = max(ns_to_t(15), 2);
+       u8 trp          = ns_to_t(18);
+       u8 tras         = ns_to_t(42);
+       u8 twtr_sa      = ns_to_t(5);
+       u8 tcksrea      = ns_to_t(11);
+       u16 trefi       = ns_to_t(3900) / 32;
+       u16 trfc        = ns_to_t(210);
+       u16 txsr        = ns_to_t(220);
+
+       if (CONFIG_DRAM_CLK % 400 == 0) {
+               /* Round up these parameters */
+               twtr_sa++;
+               tcksrea++;
+       }
+
+       u8 tmrw         = 5;
+       u8 tmrd         = 5;
+       u8 tmod         = 12;
+       u8 tcke         = 3;
+       u8 tcksrx       = 5;
+       u8 tcksre       = 5;
+       u8 tckesr       = 5;
+       u8 trasmax      = CONFIG_DRAM_CLK / 60;
+       u8 txs          = 4;
+       u8 txsdll       = 4;
+       u8 txsabort     = 4;
+       u8 txsfast      = 4;
+
+       u8 tcl          = 5; /* CL 10 */
+       u8 tcwl         = 3; /* CWL 6 */
+       u8 t_rdata_en   = twtr_sa + 8;
+
+       u32 tdinit0     = (200 * CONFIG_DRAM_CLK) + 1;          /* 200us */
+       u32 tdinit1     = (100 * CONFIG_DRAM_CLK) / 1000 + 1;   /* 100ns */
+       u32 tdinit2     = (11 * CONFIG_DRAM_CLK) + 1;           /* 11us */
+       u32 tdinit3     = (1 * CONFIG_DRAM_CLK) + 1;            /* 1us */
+
+       u8 twtp         = tcwl + 4 + twr + 1;
+       /*
+        * The code below for twr2rd and trd2wr follows the IP core's
+        * document from ZynqMP and i.MX7. The BSP has both number
+        * substracted by 2.
+        */
+       u8 twr2rd       = tcwl + 4 + 1 + twtr;
+       u8 trd2wr       = tcl + 4 + (tcksrea >> 1) - tcwl + 1;
+
+       /* set mode registers */
+       for (i = 0; i < ARRAY_SIZE(mr_lpddr3); i++)
+               writel(mr_lpddr3[i], &mctl_phy->mr[i]);
+
+       /* set DRAM timing */
+       writel((twtp << 24) | (tfaw << 16) | (trasmax << 8) | tras,
+              &mctl_ctl->dramtmg[0]);
+       writel((txp << 16) | (trtp << 8) | trc, &mctl_ctl->dramtmg[1]);
+       writel((tcwl << 24) | (tcl << 16) | (trd2wr << 8) | twr2rd,
+              &mctl_ctl->dramtmg[2]);
+       writel((tmrw << 20) | (tmrd << 12) | tmod, &mctl_ctl->dramtmg[3]);
+       writel((trcd << 24) | (tccd << 16) | (trrd << 8) | trp,
+              &mctl_ctl->dramtmg[4]);
+       writel((tcksrx << 24) | (tcksre << 16) | (tckesr << 8) | tcke,
+              &mctl_ctl->dramtmg[5]);
+       /* Value suggested by ZynqMP manual and used by libdram */
+       writel((txp + 2) | 0x02020000, &mctl_ctl->dramtmg[6]);
+       writel((txsfast << 24) | (txsabort << 16) | (txsdll << 8) | txs,
+              &mctl_ctl->dramtmg[8]);
+       writel(txsr, &mctl_ctl->dramtmg[14]);
+
+       clrsetbits_le32(&mctl_ctl->init[0], (3 << 30), (1 << 30));
+       writel(0, &mctl_ctl->dfimisc);
+       clrsetbits_le32(&mctl_ctl->rankctl, 0xff0, 0x660);
+
+       /*
+        * Set timing registers of the PHY.
+        * Note: the PHY is clocked 2x from the DRAM frequency.
+        */
+       writel((trrd << 25) | (tras << 17) | (trp << 9) | (trtp << 1),
+              &mctl_phy->dtpr[0]);
+       writel((tfaw << 17) | 0x28000400 | (tmrd << 1), &mctl_phy->dtpr[1]);
+       writel(((txs << 6) - 1) | (tcke << 17), &mctl_phy->dtpr[2]);
+       writel(((txsdll << 22) - (0x1 << 16)) | twtr_sa | (tcksrea << 8),
+              &mctl_phy->dtpr[3]);
+       writel((txp << 1) | (trfc << 17) | 0x800, &mctl_phy->dtpr[4]);
+       writel((trc << 17) | (trcd << 9) | (twtr << 1), &mctl_phy->dtpr[5]);
+       writel(0x0505, &mctl_phy->dtpr[6]);
+
+       /* Configure DFI timing */
+       writel(tcl | 0x2000200 | (t_rdata_en << 16) | 0x808000,
+              &mctl_ctl->dfitmg0);
+       writel(0x040201, &mctl_ctl->dfitmg1);
+
+       /* Configure PHY timing */
+       writel(tdinit0 | (tdinit1 << 20), &mctl_phy->ptr[3]);
+       writel(tdinit2 | (tdinit3 << 18), &mctl_phy->ptr[4]);
+
+       /* set refresh timing */
+       writel((trefi << 16) | trfc, &mctl_ctl->rfshtmg);
+}
index f5de850d08b9f190a476610242d90e5181345ef0..eec4edd4c2dd60bae1c1ca864072dac8fce64996 100644 (file)
@@ -3,6 +3,7 @@ CONFIG_ARCH_SUNXI=y
 CONFIG_NR_DRAM_BANKS=1
 CONFIG_SPL=y
 CONFIG_MACH_SUN50I_H6=y
+CONFIG_SUNXI_DRAM_H6_LPDDR3=y
 CONFIG_MMC0_CD_PIN="PF6"
 CONFIG_MMC_SUNXI_SLOT_EXTRA=2
 # CONFIG_PSCI_RESET is not set
index f6d023eea712c1d93a4bfe5310ea5446843f4b64..2d74fc4053d36b82bb3bbfabfb8aa2c23f354b85 100644 (file)
@@ -3,6 +3,7 @@ CONFIG_ARCH_SUNXI=y
 CONFIG_NR_DRAM_BANKS=1
 CONFIG_SPL=y
 CONFIG_MACH_SUN50I_H6=y
+CONFIG_SUNXI_DRAM_H6_LPDDR3=y
 CONFIG_MMC0_CD_PIN="PF6"
 # CONFIG_PSCI_RESET is not set
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
index a9d560a9176191fb4ad4388f01baf5395519809d..3737ecd37890f8dcf2c9c38b495f6ccce154bbe8 100644 (file)
@@ -3,6 +3,7 @@ CONFIG_ARCH_SUNXI=y
 CONFIG_NR_DRAM_BANKS=1
 CONFIG_SPL=y
 CONFIG_MACH_SUN50I_H6=y
+CONFIG_SUNXI_DRAM_H6_LPDDR3=y
 CONFIG_MMC0_CD_PIN="PF6"
 # CONFIG_PSCI_RESET is not set
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
index 5fa279f2e78865071e3a13d1bec35fde655fda47..a49bd6618fc80c156825c223de0a31b276047913 100644 (file)
@@ -3,6 +3,7 @@ CONFIG_ARCH_SUNXI=y
 CONFIG_NR_DRAM_BANKS=1
 CONFIG_SPL=y
 CONFIG_MACH_SUN50I_H6=y
+CONFIG_SUNXI_DRAM_H6_LPDDR3=y
 CONFIG_MMC0_CD_PIN="PF6"
 CONFIG_MMC_SUNXI_SLOT_EXTRA=2
 # CONFIG_PSCI_RESET is not set