u32 ddr3_init(void) { struct ddr3_spd_cb spd_cb; if (ddr3_get_dimm_params_from_spd(&spd_cb)) { printf("Sorry, I don't know how to configure DDR3A.\n" "Bye :(\n"); for (;;) ; } printf("Detected SO-DIMM [%s]\n", spd_cb.dimm_name); printf("DDR3 speed %d\n", spd_cb.ddrspdclock); if (spd_cb.ddrspdclock == 1600) init_pll(&ddr3_400); else init_pll(&ddr3_333); /* Reset DDR3 PHY after PLL enabled */ ddr3_reset_ddrphy(); spd_cb.phy_cfg.zq0cr1 |= 0x10000; spd_cb.phy_cfg.zq1cr1 |= 0x10000; spd_cb.phy_cfg.zq2cr1 |= 0x10000; ddr3_init_ddrphy(KS2_DDR3A_DDRPHYC, &spd_cb.phy_cfg); ddr3_init_ddremif(KS2_DDR3A_EMIF_CTRL_BASE, &spd_cb.emif_cfg); printf("DRAM: %d GiB\n", spd_cb.ddr_size_gbyte); return (u32)spd_cb.ddr_size_gbyte; }
void clock_init(void) { u32 osc = clock_get_osc_bits(); /* Set PLLC dynramp_step A to 0x2b and B to 0xb (from U-Boot -- why? */ write32(&clk_rst->pllc_misc2, 0x2b << 17 | 0xb << 9); /* Max out the AVP clock before everything else (need PLLC for that). */ init_pll(&clk_rst->pllc_base, &clk_rst->pllc_misc, osc_table[osc].pllc, PLLC_MISC_LOCK_ENABLE); /* Typical ratios are 1:2:2 or 1:2:3 sclk:hclk:pclk (See: APB DMA * features section in the TRM). */ write32(&clk_rst->clk_sys_rate, TEGRA_HCLK_RATIO << HCLK_DIVISOR_SHIFT | TEGRA_PCLK_RATIO << PCLK_DIVISOR_SHIFT); write32(&clk_rst->pllc_out, CLK_DIVIDER(TEGRA_PLLC_KHZ, TEGRA_SCLK_KHZ) << PLL_OUT_RATIO_SHIFT | PLL_OUT_CLKEN | PLL_OUT_RSTN); write32(&clk_rst->sclk_brst_pol, /* sclk = 300 MHz */ SCLK_SYS_STATE_RUN << SCLK_SYS_STATE_SHIFT | SCLK_SOURCE_PLLC_OUT1 << SCLK_RUN_SHIFT); /* Change the oscillator drive strength (from U-Boot -- why?) */ clrsetbits_le32(&clk_rst->osc_ctrl, OSC_XOFS_MASK, OSC_DRIVE_STRENGTH << OSC_XOFS_SHIFT); /* * Ambiguous quote from u-boot. TODO: what's this mean? * "should update same value in PMC_OSC_EDPD_OVER XOFS * field for warmboot " */ clrsetbits_le32(&pmc->osc_edpd_over, PMC_OSC_EDPD_OVER_XOFS_MASK, OSC_DRIVE_STRENGTH << PMC_OSC_EDPD_OVER_XOFS_SHIFT); /* Disable IDDQ for PLLX before we set it up (from U-Boot -- why?) */ clrbits_le32(&clk_rst->pllx_misc3, PLLX_IDDQ_MASK); /* Set up PLLP_OUT(1|2|3|4) divisor to generate (9.6|48|102|204)MHz */ write32(&clk_rst->pllp_outa, (CLK_DIVIDER(TEGRA_PLLP_KHZ, 9600) << PLL_OUT_RATIO_SHIFT | PLL_OUT_OVR | PLL_OUT_CLKEN | PLL_OUT_RSTN) << PLL_OUT1_SHIFT | (CLK_DIVIDER(TEGRA_PLLP_KHZ, 48000) << PLL_OUT_RATIO_SHIFT | PLL_OUT_OVR | PLL_OUT_CLKEN | PLL_OUT_RSTN) << PLL_OUT2_SHIFT); write32(&clk_rst->pllp_outb, (CLK_DIVIDER(TEGRA_PLLP_KHZ, 102000) << PLL_OUT_RATIO_SHIFT | PLL_OUT_OVR | PLL_OUT_CLKEN | PLL_OUT_RSTN) << PLL_OUT3_SHIFT | (CLK_DIVIDER(TEGRA_PLLP_KHZ, 204000) << PLL_OUT_RATIO_SHIFT | PLL_OUT_OVR | PLL_OUT_CLKEN | PLL_OUT_RSTN) << PLL_OUT4_SHIFT); /* init pllx */ init_pll(&clk_rst->pllx_base, &clk_rst->pllx_misc, osc_table[osc].pllx, PLLPAXS_MISC_LOCK_ENABLE); /* init pllu */ init_pll(&clk_rst->pllu_base, &clk_rst->pllu_misc, osc_table[osc].pllu, PLLUD_MISC_LOCK_ENABLE); init_utmip_pll(); graphics_pll(); }
/** * The T124 requires some special clock initialization, including setting up * the DVC I2C, turning on MSELECT and selecting the G CPU cluster */ void clock_init(void) { u32 val; u32 osc = clock_get_osc_bits(); /* * On poweron, AVP clock source (also called system clock) is set to * PLLP_out0 with frequency set at 1MHz. Before initializing PLLP, we * need to move the system clock's source to CLK_M temporarily. And * then switch it to PLLP_out4 (204MHz) at a later time. */ val = (SCLK_SOURCE_CLKM << SCLK_SWAKEUP_FIQ_SOURCE_SHIFT) | (SCLK_SOURCE_CLKM << SCLK_SWAKEUP_IRQ_SOURCE_SHIFT) | (SCLK_SOURCE_CLKM << SCLK_SWAKEUP_RUN_SOURCE_SHIFT) | (SCLK_SOURCE_CLKM << SCLK_SWAKEUP_IDLE_SOURCE_SHIFT) | (SCLK_SYS_STATE_RUN << SCLK_SYS_STATE_SHIFT); writel(val, &clk_rst->sclk_brst_pol); udelay(2); /* Set active CPU cluster to G */ clrbits_le32(&flow->cluster_control, 1); /* Change the oscillator drive strength */ val = readl(&clk_rst->osc_ctrl); val &= ~OSC_XOFS_MASK; val |= (OSC_DRIVE_STRENGTH << OSC_XOFS_SHIFT); writel(val, &clk_rst->osc_ctrl); /* Ambiguous quote from u-boot. TODO: what's this mean? * "should update same value in PMC_OSC_EDPD_OVER XOFS field for warmboot "*/ val = readl(&pmc->osc_edpd_over); val &= ~PMC_OSC_EDPD_OVER_XOFS_MASK; val |= (OSC_DRIVE_STRENGTH << PMC_OSC_EDPD_OVER_XOFS_SHIFT); writel(val, &pmc->osc_edpd_over); /* Disable IDDQ for PLLX before we set it up (from U-Boot -- why?) */ val = readl(&clk_rst->pllx_misc3); val &= ~PLLX_IDDQ_MASK; writel(val, &clk_rst->pllx_misc3); udelay(2); /* Set PLLC dynramp_step A to 0x2b and B to 0xb (from U-Boot -- why? */ writel(0x2b << 17 | 0xb << 9, &clk_rst->pllc_misc2); adjust_pllp_out_freqs(); init_pll(&clk_rst->pllx_base, &clk_rst->pllx_misc, osc_table[osc].pllx); init_pll(&clk_rst->pllp_base, &clk_rst->pllp_misc, osc_table[osc].pllp); init_pll(&clk_rst->pllc_base, &clk_rst->pllc_misc, osc_table[osc].pllc); init_pll(&clk_rst->plld_base, &clk_rst->plld_misc, osc_table[osc].plld); init_pll(&clk_rst->pllu_base, &clk_rst->pllu_misc, osc_table[osc].pllu); init_utmip_pll(); val = (1 << CLK_SYS_RATE_AHB_RATE_SHIFT); writel(val, &clk_rst->clk_sys_rate); }
u32 ddr3_init(void) { u32 ddr3_size; struct ddr3_spd_cb spd_cb; if (ddr3_get_dimm_params_from_spd(&spd_cb)) { printf("Sorry, I don't know how to configure DDR3A.\n" "Bye :(\n"); for (;;) ; } printf("Detected SO-DIMM [%s]\n", spd_cb.dimm_name); if ((cpu_revision() > 1) || (__raw_readl(KS2_RSTCTRL_RSTYPE) & 0x1)) { printf("DDR3 speed %d\n", spd_cb.ddrspdclock); if (spd_cb.ddrspdclock == 1600) init_pll(&ddr3a_400); else init_pll(&ddr3a_333); } if (cpu_revision() > 0) { if (cpu_revision() > 1) { /* PG 2.0 */ /* Reset DDR3A PHY after PLL enabled */ ddr3_reset_ddrphy(); spd_cb.phy_cfg.zq0cr1 |= 0x10000; spd_cb.phy_cfg.zq1cr1 |= 0x10000; spd_cb.phy_cfg.zq2cr1 |= 0x10000; } ddr3_init_ddrphy(KS2_DDR3A_DDRPHYC, &(spd_cb.phy_cfg)); ddr3_init_ddremif(KS2_DDR3A_EMIF_CTRL_BASE, &(spd_cb.emif_cfg)); ddr3_size = spd_cb.ddr_size_gbyte; } else { ddr3_init_ddrphy(KS2_DDR3A_DDRPHYC, &(spd_cb.phy_cfg)); spd_cb.emif_cfg.sdcfg |= 0x1000; ddr3_init_ddremif(KS2_DDR3A_EMIF_CTRL_BASE, &(spd_cb.emif_cfg)); ddr3_size = spd_cb.ddr_size_gbyte / 2; } printf("DRAM: %d GiB (includes reported below)\n", ddr3_size); /* Apply the workaround for PG 1.0 and 1.1 Silicons */ if (cpu_revision() <= 1) ddr3_err_reset_workaround(); return ddr3_size; }
/* Graphics just has to be different. There's a few more bits we * need to set in here, but it makes sense just to restrict all the * special bits to this one function. */ static void graphics_pll(void) { int osc = clock_get_osc_bits(); u32 *cfg = &clk_rst->plldp_ss_cfg; /* the vendor code sets the dither bit (28) * an undocumented bit (24) * and clamp while we mess with it (22) * Dither is pretty important to display port * so we really do need to handle these bits. * I'm not willing to not clamp it, even if * it might "mostly work" with it not set, * I don't want to find out in a few months * that it is needed. */ u32 scfg = (1<<28) | (1<<24) | (1<<22); write32(cfg, scfg); init_pll(&clk_rst->plldp_base, &clk_rst->plldp_misc, osc_table[osc].plldp, PLLDPD2_MISC_LOCK_ENABLE); /* leave dither and undoc bits set, release clamp */ scfg = (1<<28) | (1<<24); write32(cfg, scfg); /* disp1 will be set when panel information (pixel clock) is * retrieved (clock_display). */ }
void init_all(void) { init_uart(); init_pll(); act8600_setting(); init_ddr(); // init_lcd(); init_i2c(); // init_pwm(); }
void ddr3_init(void) { init_pll(&ddr3_400); /* No SO-DIMM, 2GB discreet DDR */ printf("DRAM: 2 GiB\n"); ddr3_size = 2; /* Reset DDR3 PHY after PLL enabled */ ddr3_reset_ddrphy(); ddr3_init_ddrphy(KS2_DDR3A_DDRPHYC, &ddr3phy_1600_2g); ddr3_init_ddremif(KS2_DDR3A_EMIF_CTRL_BASE, &ddr3_1600_2g); }
void init_ddr3(void) { char dimm_name[32]; u32 tmp; if (~(readl(K2L_PLL_CNTRL_BASE + MAIN_PLL_CTRL_RSTYPE) & 0x1)) init_pll(&ddr3_400); /* No SO-DIMM, 2GB discreet DDR */ printf("DRAM: 2 GiB\n"); /* Reset DDR3 PHY after PLL enabled */ reset_ddrphy(KS2_DEVICE_STATE_CTRL_BASE); init_ddrphy(K2L_DDR3_DDRPHYC, &ddr3phy_1600_2g); init_ddremif(K2L_DDR3_EMIF_CTRL_BASE, &ddr3_1600_2g); }
void hi6220_pll_init(void) { uint32_t data; init_pll(); init_freq(); /* * Init DDR with 533MHz. Otherwise, DDR initialization * may fail on 800MHz on some boards. */ ddr_phy_reset(); init_ddr(0); /* Init DDR with 800MHz. */ ddr_phy_reset(); init_ddr(1); ddrc_common_init(1); dienum_det_and_rowcol_cfg(); detect_ddr_chip_info(); data = mmio_read_32(0xf7032000 + 0x010); data &= ~0x1; mmio_write_32(0xf7032000 + 0x010, data); data = mmio_read_32(0xf7032000 + 0x010); /* * Test memory access. Do not use address 0x0 because the compiler * may assume it is not a valid address and generate incorrect code * (GCC 4.9.1 without -fno-delete-null-pointer-checks for instance). */ mmio_write_32(0x4, 0xa5a55a5a); INFO("ddr test value:0x%x\n", mmio_read_32(0x4)); init_ddrc_qos(); init_mmc0_pll(); reset_mmc0_clk(); init_media_clk(); dsb(); init_mmc1_pll(); reset_mmc1_clk(); }
int main() { TRISA = 0; TRISB = BIT(0)|BIT(1)|BIT(3)|BIT(7)|BIT(12); TRISC = 0; OUTER_LED = OFF; INNER_LED = OFF; init_pll(); peripheral_pin_config(); init_uart1(); init_spi(); init_adc(); init_timer1(); TX_string("Wait\r\n"); delay(1000); TX_string("Start\r\n"); T1CONbits.TON = 1; //remove first trash reading tiltX = accelRead(XINCL); gRead = gyroRead(GRATE); while(1) { if( newData == TRUE) { TX_snum5(gRead); TX('\t'); TX_snum5(tilt); TX('\t'); TX_snum5(x_00); TX_string("\r\n"); OUTER_LED = OFF; newData = FALSE; } } return 0; };
AMD newAMD (REAL samprate, REAL f_initial, REAL f_lobound, REAL f_hibound, REAL f_bandwid, int size, COMPLEX * ivec, COMPLEX * ovec, AMMode mode, char *tag) { AMD am = (AMD) safealloc (1, sizeof (AMDDesc), tag); am->size = size; am->ibuf = newCXB (size, ivec, tag); am->obuf = newCXB (size, ovec, tag); am->mode = mode; init_pll (am, samprate, f_initial, f_lobound, f_hibound, f_bandwid); am->lock.curr = 0.5; am->lock.prev = 1.0; am->dc = 0.0; return am; }
void clock_cpu0_config(void) { u32 reg; u32 osc = clock_get_osc_bits(); u32 timeout = 0; /* disable IDDQ */ reg = read32(&clst_clk->pllx_misc3); reg &= ~PLLX_IDDQ; write32(&clst_clk->pllx_misc3, reg); /* init pllx */ init_pll(&clst_clk->pllx_base, &clst_clk->pllx_misc, osc_table[osc].pllx, PLLPAXS_MISC_LOCK_ENABLE); /* * Change CPU clock source to PLLX_OUT0_LJ * when above pllx programming has taken effect. */ do { if (read32(&clst_clk->misc_ctrl) & CLK_SWITCH_MATCH) { write32(&clst_clk->cclk_brst_pol, (CC_CCLK_BRST_POL_PLLX_OUT0_LJ << 28)); break; } /* wait and try again */ if (timeout >= CLK_SWITCH_TIMEOUT_US) { printk(BIOS_ERR, "%s: PLLX programming timeout. " "Switching cpu clock has falied.\n", __func__); break; } udelay(10); timeout += 10; } while (1); }
int do_pll_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { if (argc != 5) goto pll_cmd_usage; if (strncmp(argv[1], "pa", 2) == 0) cmd_pll_data.pll = PASS_PLL; #ifndef CONFIG_SOC_K2E else if (strncmp(argv[1], "arm", 3) == 0) cmd_pll_data.pll = TETRIS_PLL; #endif #ifdef CONFIG_SOC_K2HK else if (strncmp(argv[1], "ddr3a", 5) == 0) cmd_pll_data.pll = DDR3A_PLL; else if (strncmp(argv[1], "ddr3b", 5) == 0) cmd_pll_data.pll = DDR3B_PLL; #else else if (strncmp(argv[1], "ddr3", 4) == 0) cmd_pll_data.pll = DDR3_PLL; #endif else goto pll_cmd_usage; cmd_pll_data.pll_m = simple_strtoul(argv[2], NULL, 10); cmd_pll_data.pll_d = simple_strtoul(argv[3], NULL, 10); cmd_pll_data.pll_od = simple_strtoul(argv[4], NULL, 10); printf("Trying to set pll %d; mult %d; div %d; OD %d\n", cmd_pll_data.pll, cmd_pll_data.pll_m, cmd_pll_data.pll_d, cmd_pll_data.pll_od); init_pll(&cmd_pll_data); return 0; pll_cmd_usage: return cmd_usage(cmdtp); }
/* ---------------------------------------------------------------------------- */ FMD newFMD(REAL samprate, REAL f_initial, REAL f_lobound, REAL f_hibound, REAL f_bandwid, int size, COMPLEX *ivec, COMPLEX *ovec, char *tag) { FMD fm = (FMD) safealloc(1, sizeof(FMDDesc), tag); fm->size = size; fm->ibuf = newCXB(size, ivec, tag); fm->obuf = newCXB(size, ovec, tag); init_pll(fm, samprate, f_initial, f_lobound, f_hibound, f_bandwid); fm->lock = 0.5; fm->afc = 0.0; fm->cvt = (REAL) (0.45 * samprate / (M_PI * f_bandwid)); return fm; }
void main(void) { // Have to init the clock first init_clock(); // These initialize variables // Mostly just zeroing them okay_to_transmit = FALSE; server_wants_header = FALSE; inside_non_blocking_interrupt = FALSE; last_connect_time = 0; check_in_period = 0; setup_button_pressed = FALSE; setup_button_time_trigger = 0; setup_button_time_duration = 0; main_mode = MAIN_MODE_INIT; init_internal_wattage_sensor(); init_temperature_sensor(); init_audio_sensor(); init_light_sensor(); uint8_t itor = 0; for (itor = 0; itor < NUMBER_OF_AUX_PORTS; itor++) { aux_sensor[itor] = 0; } // These initialize functions and interrupts init_timer(); init_time(); init_leds(); init_relay(); init_uart(); init_transmits(); init_buttons(); init_roving(&roving_call_back); setup_button_time_trigger = new_time(); setup_button_time_duration = new_time(); time_set_seconds(setup_button_time_duration, 2); _enable_interrupts(); // confirm roving works while (!enter_command_mode()) { reset_roving(); wait(500); } init_adc(); init_pll(); // This is for the check in // If we are disconnected, we wait 5 seconds before trying to reconnect last_connect_time = new_time(); check_in_period = new_time(); time_set_seconds(check_in_period, 5); // And go!!! set_led_anim(led_start); // MAIN LOOP while(1) { handle_roving_input(); // Check if it a long hold if(setup_button_pressed) { // If the button is pressed down if(time_cmp(global_time(), setup_button_time_trigger) >= 0) { // If enough time has passed if(in_setup_mode()) { leave_setup_mode(); } else { start_setup_mode(); } // Only want to check this once setup_button_pressed = FALSE; } } // MAIN BEHAVIOR // There is setup_mode and main_mode. // Setup mode is for configuring WiFi SSID and PASS // Main mode is for sampling if (in_setup_mode()) { if(main_mode != MAIN_MODE_SETUP) { stop_sampling(); set_led_anim(led_setup_start); main_mode = MAIN_MODE_SETUP; } do_setup(); } else if (in_main_mode()) { //regular mode if(main_mode != MAIN_MODE_SAMPLE) { set_led_anim(led_main_start); start_sampling(); main_mode = MAIN_MODE_SAMPLE; } if(!is_associated()) { associate(); } else if (!have_dhcp()) { get_dhcp(); } else { if(is_connected()) set_led_anim(led_main_connected); else set_led_anim(led_main_assoc); if(!is_connected() && (time_cmp(global_time(), last_connect_time) >= 0) ) { // If we are not connected, and enough time has passed, connect connect(); add_time_to_time(last_connect_time, check_in_period); } if(server_wants_header) { led_ping(); exit_command_mode(); transmit_header(); wait(100); } if(okay_to_transmit && have_data_to_transmit()) { led_ping(); exit_command_mode(); transmit_data(); } } } else { main_mode = MAIN_MODE_INIT; set_led_anim(led_error); stop_sampling(); } } }
/* * Init PLLD clock source. * * @frequency: the requested plld frequency * * Return the plld frequency if success, otherwise return 0. */ u32 clock_display(u32 frequency) { /** * plld (fo) = vco >> p, where 500MHz < vco < 1000MHz * = (cf * n) >> p, where 1MHz < cf < 6MHz * = ((ref / m) * n) >> p * * Iterate the possible values of p (3 bits, 2^7) to find out a minimum * safe vco, then find best (m, n). since m has only 5 bits, we can * iterate all possible values. Note Tegra 124 supports 11 bits for n, * but our pll_fields has only 10 bits for n. * * Note values undershoot or overshoot target output frequency may not * work if the values are not in "safe" range by panel specification. */ struct pllpad_dividers plld = { 0 }; u32 ref = clock_get_pll_input_khz() * 1000, m, n, p = 0; u32 cf, vco, rounded_rate = frequency; u32 diff, best_diff; const u32 max_m = 1 << 5, max_n = 1 << 10, max_p = 1 << 3, mhz = 1000 * 1000, min_vco = 500 * mhz, max_vco = 1000 * mhz, min_cf = 1 * mhz, max_cf = 6 * mhz; for (vco = frequency; vco < min_vco && p < max_p; p++) vco <<= 1; if (vco < min_vco || vco > max_vco) { printk(BIOS_ERR, "%s: Cannot find out a supported VCO" " for Frequency (%u).\n", __func__, frequency); return 0; } plld.p = p; best_diff = vco; for (m = 1; m < max_m && best_diff; m++) { cf = ref / m; if (cf < min_cf) break; if (cf > max_cf) continue; n = vco / cf; if (n >= max_n) continue; diff = vco - n * cf; if (n + 1 < max_n && diff > cf / 2) { n++; diff = cf - diff; } if (diff >= best_diff) continue; best_diff = diff; plld.m = m; plld.n = n; } if (plld.n < 50) plld.cpcon = 2; else if (plld.n < 300) plld.cpcon = 3; else if (plld.n < 600) plld.cpcon = 8; else plld.cpcon = 12; if (best_diff) { printk(BIOS_WARNING, "%s: Failed to match output frequency %u, " "best difference is %u.\n", __func__, frequency, best_diff); rounded_rate = (ref / plld.m * plld.n) >> plld.p; } printk(BIOS_DEBUG, "%s: PLLD=%u ref=%u, m/n/p/cpcon=%u/%u/%u/%u\n", __func__, rounded_rate, ref, plld.m, plld.n, plld.p, plld.cpcon); init_pll(&clk_rst->plld_base, &clk_rst->plld_misc, plld, (PLLUD_MISC_LOCK_ENABLE | PLLD_MISC_CLK_ENABLE)); return rounded_rate; }
void ddr3_init(void) { char dimm_name[32]; ddr3_get_dimm_params(dimm_name); printf("Detected SO-DIMM [%s]\n", dimm_name); if (!strcmp(dimm_name, "18KSF1G72HZ-1G6E2 ")) { init_pll(&ddr3a_400); if (cpu_revision() > 0) { if (cpu_revision() > 1) { /* PG 2.0 */ /* Reset DDR3A PHY after PLL enabled */ ddr3_reset_ddrphy(); ddr3phy_1600_8g.zq0cr1 |= 0x10000; ddr3phy_1600_8g.zq1cr1 |= 0x10000; ddr3phy_1600_8g.zq2cr1 |= 0x10000; ddr3_init_ddrphy(KS2_DDR3A_DDRPHYC, &ddr3phy_1600_8g); } else { /* PG 1.1 */ ddr3_init_ddrphy(KS2_DDR3A_DDRPHYC, &ddr3phy_1600_8g); } ddr3_init_ddremif(KS2_DDR3A_EMIF_CTRL_BASE, &ddr3_1600_8g); printf("DRAM: Capacity 8 GiB (includes reported below)\n"); ddr3_size = 8; } else { ddr3_init_ddrphy(KS2_DDR3A_DDRPHYC, &ddr3phy_1600_8g); ddr3_1600_8g.sdcfg |= 0x1000; ddr3_init_ddremif(KS2_DDR3A_EMIF_CTRL_BASE, &ddr3_1600_8g); printf("DRAM: Capacity 4 GiB (includes reported below)\n"); ddr3_size = 4; } } else if (!strcmp(dimm_name, "SQR-SD3T-2G1333SED")) { init_pll(&ddr3a_333); if (cpu_revision() > 0) { if (cpu_revision() > 1) { /* PG 2.0 */ /* Reset DDR3A PHY after PLL enabled */ ddr3_reset_ddrphy(); ddr3phy_1333_2g.zq0cr1 |= 0x10000; ddr3phy_1333_2g.zq1cr1 |= 0x10000; ddr3phy_1333_2g.zq2cr1 |= 0x10000; ddr3_init_ddrphy(KS2_DDR3A_DDRPHYC, &ddr3phy_1333_2g); } else { /* PG 1.1 */ ddr3_init_ddrphy(KS2_DDR3A_DDRPHYC, &ddr3phy_1333_2g); } ddr3_init_ddremif(KS2_DDR3A_EMIF_CTRL_BASE, &ddr3_1333_2g); ddr3_size = 2; printf("DRAM: 2 GiB"); } else { ddr3_init_ddrphy(KS2_DDR3A_DDRPHYC, &ddr3phy_1333_2g); ddr3_1333_2g.sdcfg |= 0x1000; ddr3_init_ddremif(KS2_DDR3A_EMIF_CTRL_BASE, &ddr3_1333_2g); ddr3_size = 1; printf("DRAM: 1 GiB"); } } else { printf("Unknown SO-DIMM. Cannot configure DDR3\n"); while (1) ; } /* Apply the workaround for PG 1.0 and 1.1 Silicons */ if (cpu_revision() <= 1) ddr3_err_reset_workaround(); }