static void request_ram_repair(void) { struct flow_ctlr * const flow = (void *)(uintptr_t)TEGRA_FLOW_BASE; const uint32_t req = 1 << 0; const uint32_t sts = 1 << 1; uint32_t reg; struct stopwatch sw; printk(BIOS_DEBUG, "Requesting RAM repair.\n"); stopwatch_init(&sw); /* Perform cluster 0 ram repair */ reg = read32(&flow->ram_repair); reg |= req; write32(&flow->ram_repair, reg); while ((read32(&flow->ram_repair) & sts) != sts) ; /* Perform cluster 1 ram repair */ reg = read32(&flow->ram_repair_cluster1); reg |= req; write32(&flow->ram_repair_cluster1, reg); while ((read32(&flow->ram_repair_cluster1) & sts) != sts) ; printk(BIOS_DEBUG, "RAM repair complete in %ld usecs.\n", stopwatch_duration_usecs(&sw)); }
/* * Configure DP in slave mode and wait for video stream. * * param dp pointer to main s5p-dp structure * param video_info pointer to main video_info structure. * return status */ static int s5p_dp_config_video(struct s5p_dp_device *dp, struct video_info *video_info) { int timeout = 0; struct exynos5_dp *base = dp->base; struct stopwatch sw; s5p_dp_config_video_slave_mode(dp, video_info); s5p_dp_set_video_color_format(dp, video_info->color_depth, video_info->color_space, video_info->dynamic_range, video_info->ycbcr_coeff); if (s5p_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) { printk(BIOS_DEBUG, "PLL is not locked yet.\n"); return -ERR_PLL_NOT_UNLOCKED; } stopwatch_init_msecs_expire(&sw, STREAM_ON_TIMEOUT); do { if (s5p_dp_is_slave_video_stream_clock_on(dp) == 0) { timeout++; break; } } while (!stopwatch_expired(&sw)); if (!timeout) { printk(BIOS_ERR, "Video Clock Not ok after %ldus.\n", stopwatch_duration_usecs(&sw)); return -ERR_VIDEO_CLOCK_BAD; } /* Set to use the register calculated M/N video */ s5p_dp_set_video_cr_mn(dp, CALCULATED_M, 0, 0); clrbits_le32(&base->video_ctl_10, FORMAT_SEL); /* Disable video mute */ clrbits_le32(&base->video_ctl_1, HDCP_VIDEO_MUTE); /* Configure video slave mode */ s5p_dp_enable_video_master(dp); /* Enable video */ setbits_le32(&base->video_ctl_1, VIDEO_EN); timeout = s5p_dp_is_video_stream_on(dp); if (timeout) { printk(BIOS_DEBUG, "Video Stream Not on\n"); return -ERR_VIDEO_STREAM_BAD; } return 0; }
int ccplex_load_mts(void) { ssize_t nread; struct stopwatch sw; struct cbfsf mts_file; struct region_device fh; /* * MTS location is hard coded to this magic address. The hardware will * take the MTS from this location and place it in the final resting * place in the carveout region. */ void * const mts = (void *)(uintptr_t)MTS_LOAD_ADDRESS; stopwatch_init(&sw); if (cbfs_boot_locate(&mts_file, MTS_FILE_NAME, NULL)) { printk(BIOS_DEBUG, "MTS file not found: %s\n", MTS_FILE_NAME); return -1; } cbfs_file_data(&fh, &mts_file); /* Read MTS file into the carveout region. */ nread = rdev_readat(&fh, mts, 0, region_device_sz(&fh)); if (nread != region_device_sz(&fh)) { printk(BIOS_DEBUG, "MTS bytes read (%zu) != file length(%u)!\n", nread, region_device_sz(&fh)); return -1; } printk(BIOS_DEBUG, "MTS: %zu bytes loaded @ %p in %ld usecs.\n", nread, mts, stopwatch_duration_usecs(&sw)); return ccplex_start(); }
static int ccplex_start(void) { struct stopwatch sw; const long timeout_ms = 1500; const uint32_t handshake_mask = 1; const uint32_t cxreset1_mask = 1 << 21; uint32_t reg; struct tegra_pmc_regs * const pmc = PMC_REGS; /* Set the handshake bit to be knocked down. */ write32(&pmc->scratch118, handshake_mask); /* Assert nCXRSET[1] */ reg = read32(CLK_RST_REG(rst_cpu_cmplx_set)); reg |= cxreset1_mask; write32(CLK_RST_REG(rst_cpu_cmplx_set), reg); stopwatch_init_msecs_expire(&sw, timeout_ms); while (1) { reg = read32(&pmc->scratch118); /* Wait for the bit to be knocked down. */ if ((reg & handshake_mask) != handshake_mask) break; if (stopwatch_expired(&sw)) { printk(BIOS_DEBUG, "MTS handshake timeout.\n"); return -1; } } printk(BIOS_DEBUG, "MTS handshake took %ld usecs.\n", stopwatch_duration_usecs(&sw)); return 0; }
void arch_initialize_cpus(device_t cluster, struct cpu_control_ops *cntrl_ops) { size_t max_cpus; size_t i; struct cpu_info *ci; void (*entry)(void); struct bus *bus; if (cluster->path.type != DEVICE_PATH_CPU_CLUSTER) { printk(BIOS_ERR, "CPU init failed. Device is not a CPU_CLUSTER: %s\n", dev_path(cluster)); return; } bus = cluster->link_list; /* Check if no children under this device. */ if (bus == NULL) return; /* * el3_init must be performed prior to prepare_secondary_cpu_startup. * This is important since el3_init initializes SCR values on BSP CPU * and then prepare_secondary_cpu_startup reads the initialized SCR * value and saves it for use by non-BSP CPUs. */ el3_init(); /* Mark current cpu online. */ cpu_mark_online(cpu_info()); entry = prepare_secondary_cpu_startup(); /* Initialize the cpu_info structures. */ init_cpu_info(bus); max_cpus = cntrl_ops->total_cpus(); if (max_cpus > CONFIG_MAX_CPUS) { printk(BIOS_WARNING, "max_cpus (%zu) exceeds CONFIG_MAX_CPUS (%zu).\n", max_cpus, (size_t)CONFIG_MAX_CPUS); max_cpus = CONFIG_MAX_CPUS; } for (i = 0; i < max_cpus; i++) { device_t dev; struct cpu_action action; struct stopwatch sw; ci = cpu_info_for_cpu(i); dev = ci->cpu; /* Disregard CPUs not in device tree. */ if (dev == NULL) continue; /* Skip disabled CPUs. */ if (!dev->enabled) continue; if (!cpu_online(ci)) { /* Start the CPU. */ printk(BIOS_DEBUG, "Starting CPU%x\n", ci->id); if (cntrl_ops->start_cpu(ci->id, entry)) { printk(BIOS_ERR, "Failed to start CPU%x\n", ci->id); continue; } stopwatch_init_msecs_expire(&sw, 1000); /* Wait for CPU to come online. */ while (!stopwatch_expired(&sw)) { if (!cpu_online(ci)) continue; printk(BIOS_DEBUG, "CPU%x online in %ld usecs.\n", ci->id, stopwatch_duration_usecs(&sw)); break; } } if (!cpu_online(ci)) { printk(BIOS_DEBUG, "CPU%x failed to come online in %ld usecs.\n", ci->id, stopwatch_duration_usecs(&sw)); continue; } /* Send it the init action. */ action.run = init_this_cpu; action.arg = ci; arch_run_on_cpu(ci->id, &action); } }