/* * dcn351_update_bw_bounding_box * * This would override some dcn3_51 ip_or_soc initial parameters hardcoded from * spreadsheet with actual values as per dGPU SKU: * - with passed few options from dc->config * - with dentist_vco_frequency from Clk Mgr (currently hardcoded, but might * need to get it from PM FW) * - with passed latency values (passed in ns units) in dc-> bb override for * debugging purposes * - with passed latencies from VBIOS (in 100_ns units) if available for * certain dGPU SKU * - with number of DRAM channels from VBIOS (which differ for certain dGPU SKU * of the same ASIC) * - clocks levels with passed clk_table entries from Clk Mgr as reported by PM * FW for different clocks (which might differ for certain dGPU SKU of the * same ASIC)
*/ void dcn351_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_params)
{ unsignedint i, closest_clk_lvl; int j; struct clk_limit_table *clk_table = &bw_params->clk_table; struct _vcs_dpi_voltage_scaling_st *clock_limits =
dc->scratch.update_bw_bounding_box.clock_limits; int max_dispclk_mhz = 0, max_dppclk_mhz = 0;
/* Prepass to find max clocks independent of voltage level. */ for (i = 0; i < clk_table->num_entries; ++i) { if (clk_table->entries[i].dispclk_mhz > max_dispclk_mhz)
max_dispclk_mhz = clk_table->entries[i].dispclk_mhz; if (clk_table->entries[i].dppclk_mhz > max_dppclk_mhz)
max_dppclk_mhz = clk_table->entries[i].dppclk_mhz;
}
for (i = 0; i < clk_table->num_entries; i++) { /* loop backwards*/ for (closest_clk_lvl = 0, j = dcn3_51_soc.num_states - 1;
j >= 0; j--) { if (dcn3_51_soc.clock_limits[j].dcfclk_mhz <=
clk_table->entries[i].dcfclk_mhz) {
closest_clk_lvl = j; break;
}
} if (clk_table->num_entries == 1) { /*smu gives one DPM level, let's take the highest one*/
closest_clk_lvl = dcn3_51_soc.num_states - 1;
}
clock_limits[i].state = i;
/* Clocks dependent on voltage level. */
clock_limits[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz; if (clk_table->num_entries == 1 &&
clock_limits[i].dcfclk_mhz <
dcn3_51_soc.clock_limits[closest_clk_lvl].dcfclk_mhz) { /*SMU fix not released yet*/
clock_limits[i].dcfclk_mhz =
dcn3_51_soc.clock_limits[closest_clk_lvl].dcfclk_mhz;
}
staticbool is_dual_plane(enum surface_pixel_format format)
{ return format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN ||
format == SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA;
}
/* * micro_sec_to_vert_lines () - converts time to number of vertical lines for a given timing * * @param: num_us: number of microseconds * @return: number of vertical lines. If exact number of vertical lines is not found then * it will round up to next number of lines to guarantee num_us
*/ staticunsignedint micro_sec_to_vert_lines(unsignedint num_us, struct dc_crtc_timing *timing)
{ unsignedint num_lines = 0; unsignedint lines_time_in_ns = 1000.0 *
(((float)timing->h_total * 1000.0) /
((float)timing->pix_clk_100hz / 10.0));
pipes[pipe_cnt].pipe.dest.vblank_nom = timing->v_total - pipes[pipe_cnt].pipe.dest.vactive;
pipes[pipe_cnt].pipe.dest.vblank_nom = min(pipes[pipe_cnt].pipe.dest.vblank_nom, num_lines); // vblank_nom should not smaller than (VSync (timing->v_sync_width + v_back_porch) + 2) // + 2 is because // 1 -> VStartup_start should be 1 line before VSync // 1 -> always reserve 1 line between start of vblank to vstartup signal
pipes[pipe_cnt].pipe.dest.vblank_nom =
max(pipes[pipe_cnt].pipe.dest.vblank_nom, timing->v_sync_width + v_back_porch + 2);
pipes[pipe_cnt].pipe.dest.vblank_nom = min(pipes[pipe_cnt].pipe.dest.vblank_nom, max_allowed_vblank_nom);
/* * Immediate flip can be set dynamically after enabling the * plane. We need to require support for immediate flip or * underflow can be intermittently experienced depending on peak * b/w requirements.
*/
pipes[pipe_cnt].pipe.src.immediate_flip = true;
void dcn351_decide_zstate_support(struct dc *dc, struct dc_state *context)
{ enum dcn_zstate_support_state support = DCN_ZSTATE_SUPPORT_DISALLOW; unsignedint i, plane_count = 0;
for (i = 0; i < dc->res_pool->pipe_count; i++) { if (context->res_ctx.pipe_ctx[i].plane_state)
plane_count++;
}
/*dcn351 does not support z9/z10*/ if (context->stream_count == 0 || plane_count == 0) {
support = DCN_ZSTATE_SUPPORT_ALLOW_Z8_ONLY;
} elseif (context->stream_count == 1 && context->streams[0]->signal == SIGNAL_TYPE_EDP) { struct dc_link *link = context->streams[0]->sink->link; bool is_pwrseq0 = link && link->link_index == 0; bool is_psr = (link && (link->psr_settings.psr_version == DC_PSR_VERSION_1 ||
link->psr_settings.psr_version == DC_PSR_VERSION_SU_1) && !link->panel_config.psr.disable_psr); bool is_replay = link && link->replay_settings.replay_feature_enabled; int minmum_z8_residency =
dc->debug.minimum_z8_residency_time > 0 ? dc->debug.minimum_z8_residency_time : 1000; bool allow_z8 = context->bw_ctx.dml.vba.StutterPeriod > (double)minmum_z8_residency;
/*for psr1/psr-su, we allow z8 and z10 based on latency, for replay with IPS enabled, it will enter ips2*/ if (is_pwrseq0 && (is_psr || is_replay))
support = allow_z8 ? allow_z8 : DCN_ZSTATE_SUPPORT_DISALLOW;
}
context->bw_ctx.bw.dcn.clk.zstate_support = support;
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.