Merge tag 'amd-drm-next-5.8-2020-05-12' of git://people.freedesktop.org/~agd5f/linux into drm-next
amd-drm-next-5.8-2020-05-12: amdgpu: - Misc cleanups - RAS fixes - Expose FP16 for modesetting - DP 1.4 compliance test fixes - Clockgating fixes - MAINTAINERS update - Soft recovery for gfx10 - Runtime PM cleanups - PSP code cleanups amdkfd: - Track GPU memory utilization per process - Report PCI domain in topology Signed-off-by: Dave Airlie <airlied@redhat.com> From: Alex Deucher <alexdeucher@gmail.com> Link: https://patchwork.freedesktop.org/patch/msgid/20200512213703.4039-1-alexander.deucher@amd.com
This commit is contained in:
@@ -66,7 +66,7 @@
|
||||
|
||||
#include "dce/dce_i2c.h"
|
||||
|
||||
#include "dmub/inc/dmub_cmd_dal.h"
|
||||
#include "dmub/dmub_srv.h"
|
||||
|
||||
#define CTX \
|
||||
dc->ctx
|
||||
@@ -839,11 +839,10 @@ static void disable_dangling_plane(struct dc *dc, struct dc_state *context)
|
||||
static void wait_for_no_pipes_pending(struct dc *dc, struct dc_state *context)
|
||||
{
|
||||
int i;
|
||||
int count = 0;
|
||||
struct pipe_ctx *pipe;
|
||||
PERF_TRACE();
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe = &context->res_ctx.pipe_ctx[i];
|
||||
int count = 0;
|
||||
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
|
||||
|
||||
if (!pipe->plane_state)
|
||||
continue;
|
||||
@@ -2210,9 +2209,7 @@ static void commit_planes_do_stream_update(struct dc *dc,
|
||||
|
||||
if (should_program_abm) {
|
||||
if (*stream_update->abm_level == ABM_LEVEL_IMMEDIATE_DISABLE) {
|
||||
pipe_ctx->stream_res.abm->funcs->set_abm_immediate_disable(
|
||||
pipe_ctx->stream_res.abm,
|
||||
pipe_ctx->stream->link->panel_cntl->inst);
|
||||
dc->hwss.set_abm_immediate_disable(pipe_ctx);
|
||||
} else {
|
||||
pipe_ctx->stream_res.abm->funcs->set_abm_level(
|
||||
pipe_ctx->stream_res.abm, stream->abm_level);
|
||||
|
@@ -26,7 +26,7 @@
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "dm_services.h"
|
||||
#include "atom.h"
|
||||
#include "atomfirmware.h"
|
||||
#include "dm_helpers.h"
|
||||
#include "dc.h"
|
||||
#include "grph_object_id.h"
|
||||
@@ -46,7 +46,7 @@
|
||||
#include "dmcu.h"
|
||||
#include "hw/clk_mgr.h"
|
||||
#include "dce/dmub_psr.h"
|
||||
#include "dmub/inc/dmub_cmd_dal.h"
|
||||
#include "dmub/dmub_srv.h"
|
||||
#include "inc/hw/panel_cntl.h"
|
||||
|
||||
#define DC_LOGGER_INIT(logger)
|
||||
@@ -1552,7 +1552,7 @@ static bool dc_link_construct(struct dc_link *link,
|
||||
*/
|
||||
program_hpd_filter(link);
|
||||
|
||||
link->psr_settings.psr_version = PSR_VERSION_UNSUPPORTED;
|
||||
link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED;
|
||||
|
||||
return true;
|
||||
device_tag_fail:
|
||||
@@ -2504,59 +2504,56 @@ int dc_link_get_target_backlight_pwm(const struct dc_link *link)
|
||||
return (int) abm->funcs->get_target_backlight(abm);
|
||||
}
|
||||
|
||||
static struct pipe_ctx *get_pipe_from_link(const struct dc_link *link)
|
||||
{
|
||||
int i;
|
||||
struct dc *dc = link->ctx->dc;
|
||||
struct pipe_ctx *pipe_ctx = NULL;
|
||||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
if (dc->current_state->res_ctx.pipe_ctx[i].stream) {
|
||||
if (dc->current_state->res_ctx.pipe_ctx[i].stream->link == link) {
|
||||
pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pipe_ctx;
|
||||
}
|
||||
|
||||
bool dc_link_set_backlight_level(const struct dc_link *link,
|
||||
uint32_t backlight_pwm_u16_16,
|
||||
uint32_t frame_ramp)
|
||||
{
|
||||
struct dc *dc = link->ctx->dc;
|
||||
int i;
|
||||
|
||||
DC_LOGGER_INIT(link->ctx->logger);
|
||||
DC_LOG_BACKLIGHT("New Backlight level: %d (0x%X)\n",
|
||||
backlight_pwm_u16_16, backlight_pwm_u16_16);
|
||||
|
||||
if (dc_is_embedded_signal(link->connector_signal)) {
|
||||
struct pipe_ctx *pipe_ctx = NULL;
|
||||
struct pipe_ctx *pipe_ctx = get_pipe_from_link(link);
|
||||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
if (dc->current_state->res_ctx.pipe_ctx[i].stream) {
|
||||
if (dc->current_state->res_ctx.
|
||||
pipe_ctx[i].stream->link
|
||||
== link) {
|
||||
pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
|
||||
|
||||
/* Disable brightness ramping when the display is blanked
|
||||
* as it can hang the DMCU
|
||||
*/
|
||||
if (dc->current_state->res_ctx.pipe_ctx[i].plane_state == NULL)
|
||||
frame_ramp = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pipe_ctx == NULL)
|
||||
if (pipe_ctx) {
|
||||
/* Disable brightness ramping when the display is blanked
|
||||
* as it can hang the DMCU
|
||||
*/
|
||||
if (pipe_ctx->plane_state == NULL)
|
||||
frame_ramp = 0;
|
||||
} else {
|
||||
ASSERT(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
dc->hwss.set_backlight_level(
|
||||
pipe_ctx,
|
||||
backlight_pwm_u16_16,
|
||||
frame_ramp);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool dc_link_set_abm_disable(const struct dc_link *link)
|
||||
{
|
||||
struct abm *abm = get_abm_from_stream_res(link);
|
||||
bool success = false;
|
||||
|
||||
if (abm)
|
||||
success = abm->funcs->set_abm_immediate_disable(abm, link->panel_cntl->inst);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool dc_link_set_psr_allow_active(struct dc_link *link, bool allow_active, bool wait)
|
||||
{
|
||||
struct dc *dc = link->ctx->dc;
|
||||
|
@@ -13,7 +13,6 @@
|
||||
#include "core_status.h"
|
||||
#include "dpcd_defs.h"
|
||||
|
||||
#include "resource.h"
|
||||
#define DC_LOGGER \
|
||||
link->ctx->logger
|
||||
|
||||
|
@@ -1547,35 +1547,6 @@ bool dc_add_all_planes_for_stream(
|
||||
return add_all_planes_for_stream(dc, stream, &set, 1, context);
|
||||
}
|
||||
|
||||
|
||||
static bool is_hdr_static_meta_changed(struct dc_stream_state *cur_stream,
|
||||
struct dc_stream_state *new_stream)
|
||||
{
|
||||
if (cur_stream == NULL)
|
||||
return true;
|
||||
|
||||
if (memcmp(&cur_stream->hdr_static_metadata,
|
||||
&new_stream->hdr_static_metadata,
|
||||
sizeof(struct dc_info_packet)) != 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool is_vsc_info_packet_changed(struct dc_stream_state *cur_stream,
|
||||
struct dc_stream_state *new_stream)
|
||||
{
|
||||
if (cur_stream == NULL)
|
||||
return true;
|
||||
|
||||
if (memcmp(&cur_stream->vsc_infopacket,
|
||||
&new_stream->vsc_infopacket,
|
||||
sizeof(struct dc_info_packet)) != 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool is_timing_changed(struct dc_stream_state *cur_stream,
|
||||
struct dc_stream_state *new_stream)
|
||||
{
|
||||
@@ -1610,15 +1581,9 @@ static bool are_stream_backends_same(
|
||||
if (is_timing_changed(stream_a, stream_b))
|
||||
return false;
|
||||
|
||||
if (is_hdr_static_meta_changed(stream_a, stream_b))
|
||||
return false;
|
||||
|
||||
if (stream_a->dpms_off != stream_b->dpms_off)
|
||||
return false;
|
||||
|
||||
if (is_vsc_info_packet_changed(stream_a, stream_b))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1758,21 +1723,6 @@ static struct audio *find_first_free_audio(
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool resource_is_stream_unchanged(
|
||||
struct dc_state *old_context, struct dc_stream_state *stream)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < old_context->stream_count; i++) {
|
||||
struct dc_stream_state *old_stream = old_context->streams[i];
|
||||
|
||||
if (are_stream_backends_same(old_stream, stream))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* dc_add_stream_to_ctx() - Add a new dc_stream_state to a dc_state.
|
||||
*/
|
||||
@@ -2027,17 +1977,6 @@ enum dc_status resource_map_pool_resources(
|
||||
int pipe_idx = -1;
|
||||
struct dc_bios *dcb = dc->ctx->dc_bios;
|
||||
|
||||
/* TODO Check if this is needed */
|
||||
/*if (!resource_is_stream_unchanged(old_context, stream)) {
|
||||
if (stream != NULL && old_context->streams[i] != NULL) {
|
||||
stream->bit_depth_params =
|
||||
old_context->streams[i]->bit_depth_params;
|
||||
stream->clamping = old_context->streams[i]->clamping;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
calculate_phy_pix_clks(stream);
|
||||
|
||||
/* TODO: Check Linux */
|
||||
@@ -2720,15 +2659,9 @@ bool pipe_need_reprogram(
|
||||
if (is_timing_changed(pipe_ctx_old->stream, pipe_ctx->stream))
|
||||
return true;
|
||||
|
||||
if (is_hdr_static_meta_changed(pipe_ctx_old->stream, pipe_ctx->stream))
|
||||
return true;
|
||||
|
||||
if (pipe_ctx_old->stream->dpms_off != pipe_ctx->stream->dpms_off)
|
||||
return true;
|
||||
|
||||
if (is_vsc_info_packet_changed(pipe_ctx_old->stream, pipe_ctx->stream))
|
||||
return true;
|
||||
|
||||
if (false == pipe_ctx_old->stream->link->link_state_valid &&
|
||||
false == pipe_ctx_old->stream->dpms_off)
|
||||
return true;
|
||||
|
@@ -42,7 +42,7 @@
|
||||
#include "inc/hw/dmcu.h"
|
||||
#include "dml/display_mode_lib.h"
|
||||
|
||||
#define DC_VER "3.2.83.1"
|
||||
#define DC_VER "3.2.84"
|
||||
|
||||
#define MAX_SURFACES 3
|
||||
#define MAX_PLANES 6
|
||||
@@ -277,6 +277,7 @@ struct dc_config {
|
||||
bool disable_extended_timeout_support; // Used to disable extended timeout and lttpr feature as well
|
||||
bool multi_mon_pp_mclk_switch;
|
||||
bool disable_dmcu;
|
||||
bool enable_4to1MPC;
|
||||
};
|
||||
|
||||
enum visual_confirm {
|
||||
@@ -476,6 +477,7 @@ struct dc_debug_options {
|
||||
bool enable_dmcub_surface_flip;
|
||||
bool usbc_combo_phy_reset_wa;
|
||||
bool disable_dsc;
|
||||
bool enable_dram_clock_change_one_display_vactive;
|
||||
};
|
||||
|
||||
struct dc_debug_data {
|
||||
|
@@ -25,7 +25,7 @@
|
||||
|
||||
#include "dc.h"
|
||||
#include "dc_dmub_srv.h"
|
||||
#include "../dmub/inc/dmub_srv.h"
|
||||
#include "../dmub/dmub_srv.h"
|
||||
|
||||
static void dc_dmub_srv_construct(struct dc_dmub_srv *dc_srv, struct dc *dc,
|
||||
struct dmub_srv *dmub)
|
||||
|
@@ -27,7 +27,7 @@
|
||||
#define _DMUB_DC_SRV_H_
|
||||
|
||||
#include "os_types.h"
|
||||
#include "dmub/inc/dmub_cmd.h"
|
||||
#include "dmub/dmub_srv.h"
|
||||
|
||||
struct dmub_srv;
|
||||
|
||||
|
@@ -29,7 +29,6 @@
|
||||
#include "dc.h"
|
||||
#include "dc_types.h"
|
||||
#include "grph_object_defs.h"
|
||||
#include "dmub/inc/dmub_cmd_dal.h"
|
||||
|
||||
enum dc_link_fec_state {
|
||||
dc_link_fec_not_ready,
|
||||
@@ -72,7 +71,7 @@ struct link_trace {
|
||||
struct psr_settings {
|
||||
bool psr_feature_enabled; // PSR is supported by sink
|
||||
bool psr_allow_active; // PSR is currently active
|
||||
enum psr_version psr_version; // Internal PSR version, determined based on DPCD
|
||||
enum dc_psr_version psr_version; // Internal PSR version, determined based on DPCD
|
||||
|
||||
/* These parameters are calculated in Driver,
|
||||
* based on display timing and Sink capabilities.
|
||||
@@ -220,8 +219,6 @@ int dc_link_get_backlight_level(const struct dc_link *dc_link);
|
||||
|
||||
int dc_link_get_target_backlight_pwm(const struct dc_link *link);
|
||||
|
||||
bool dc_link_set_abm_disable(const struct dc_link *dc_link);
|
||||
|
||||
bool dc_link_set_psr_allow_active(struct dc_link *dc_link, bool enable, bool wait);
|
||||
|
||||
bool dc_link_get_psr_state(const struct dc_link *dc_link, uint32_t *psr_state);
|
||||
|
@@ -862,4 +862,9 @@ struct dsc_dec_dpcd_caps {
|
||||
uint32_t branch_max_line_width;
|
||||
};
|
||||
|
||||
enum dc_psr_version {
|
||||
DC_PSR_VERSION_1 = 0,
|
||||
DC_PSR_VERSION_UNSUPPORTED = 0xFFFFFFFF,
|
||||
};
|
||||
|
||||
#endif /* DC_TYPES_H_ */
|
||||
|
@@ -83,120 +83,6 @@ static bool dce_abm_set_pipe(struct abm *abm, uint32_t controller_id, uint32_t p
|
||||
return true;
|
||||
}
|
||||
|
||||
static unsigned int calculate_16_bit_backlight_from_pwm(struct dce_abm *abm_dce)
|
||||
{
|
||||
uint64_t current_backlight;
|
||||
uint32_t round_result;
|
||||
uint32_t pwm_period_cntl, bl_period, bl_int_count;
|
||||
uint32_t bl_pwm_cntl, bl_pwm, fractional_duty_cycle_en;
|
||||
uint32_t bl_period_mask, bl_pwm_mask;
|
||||
|
||||
pwm_period_cntl = REG_READ(BL_PWM_PERIOD_CNTL);
|
||||
REG_GET(BL_PWM_PERIOD_CNTL, BL_PWM_PERIOD, &bl_period);
|
||||
REG_GET(BL_PWM_PERIOD_CNTL, BL_PWM_PERIOD_BITCNT, &bl_int_count);
|
||||
|
||||
bl_pwm_cntl = REG_READ(BL_PWM_CNTL);
|
||||
REG_GET(BL_PWM_CNTL, BL_ACTIVE_INT_FRAC_CNT, (uint32_t *)(&bl_pwm));
|
||||
REG_GET(BL_PWM_CNTL, BL_PWM_FRACTIONAL_EN, &fractional_duty_cycle_en);
|
||||
|
||||
if (bl_int_count == 0)
|
||||
bl_int_count = 16;
|
||||
|
||||
bl_period_mask = (1 << bl_int_count) - 1;
|
||||
bl_period &= bl_period_mask;
|
||||
|
||||
bl_pwm_mask = bl_period_mask << (16 - bl_int_count);
|
||||
|
||||
if (fractional_duty_cycle_en == 0)
|
||||
bl_pwm &= bl_pwm_mask;
|
||||
else
|
||||
bl_pwm &= 0xFFFF;
|
||||
|
||||
current_backlight = bl_pwm << (1 + bl_int_count);
|
||||
|
||||
if (bl_period == 0)
|
||||
bl_period = 0xFFFF;
|
||||
|
||||
current_backlight = div_u64(current_backlight, bl_period);
|
||||
current_backlight = (current_backlight + 1) >> 1;
|
||||
|
||||
current_backlight = (uint64_t)(current_backlight) * bl_period;
|
||||
|
||||
round_result = (uint32_t)(current_backlight & 0xFFFFFFFF);
|
||||
|
||||
round_result = (round_result >> (bl_int_count-1)) & 1;
|
||||
|
||||
current_backlight >>= bl_int_count;
|
||||
current_backlight += round_result;
|
||||
|
||||
return (uint32_t)(current_backlight);
|
||||
}
|
||||
|
||||
static void driver_set_backlight_level(struct dce_abm *abm_dce,
|
||||
uint32_t backlight_pwm_u16_16)
|
||||
{
|
||||
uint32_t backlight_16bit;
|
||||
uint32_t masked_pwm_period;
|
||||
uint8_t bit_count;
|
||||
uint64_t active_duty_cycle;
|
||||
uint32_t pwm_period_bitcnt;
|
||||
|
||||
/*
|
||||
* 1. Find 16 bit backlight active duty cycle, where 0 <= backlight
|
||||
* active duty cycle <= backlight period
|
||||
*/
|
||||
|
||||
/* 1.1 Apply bitmask for backlight period value based on value of BITCNT
|
||||
*/
|
||||
REG_GET_2(BL_PWM_PERIOD_CNTL,
|
||||
BL_PWM_PERIOD_BITCNT, &pwm_period_bitcnt,
|
||||
BL_PWM_PERIOD, &masked_pwm_period);
|
||||
|
||||
if (pwm_period_bitcnt == 0)
|
||||
bit_count = 16;
|
||||
else
|
||||
bit_count = pwm_period_bitcnt;
|
||||
|
||||
/* e.g. maskedPwmPeriod = 0x24 when bitCount is 6 */
|
||||
masked_pwm_period = masked_pwm_period & ((1 << bit_count) - 1);
|
||||
|
||||
/* 1.2 Calculate integer active duty cycle required upper 16 bits
|
||||
* contain integer component, lower 16 bits contain fractional component
|
||||
* of active duty cycle e.g. 0x21BDC0 = 0xEFF0 * 0x24
|
||||
*/
|
||||
active_duty_cycle = backlight_pwm_u16_16 * masked_pwm_period;
|
||||
|
||||
/* 1.3 Calculate 16 bit active duty cycle from integer and fractional
|
||||
* components shift by bitCount then mask 16 bits and add rounding bit
|
||||
* from MSB of fraction e.g. 0x86F7 = ((0x21BDC0 >> 6) & 0xFFF) + 0
|
||||
*/
|
||||
backlight_16bit = active_duty_cycle >> bit_count;
|
||||
backlight_16bit &= 0xFFFF;
|
||||
backlight_16bit += (active_duty_cycle >> (bit_count - 1)) & 0x1;
|
||||
|
||||
/*
|
||||
* 2. Program register with updated value
|
||||
*/
|
||||
|
||||
/* 2.1 Lock group 2 backlight registers */
|
||||
|
||||
REG_UPDATE_2(BL_PWM_GRP1_REG_LOCK,
|
||||
BL_PWM_GRP1_IGNORE_MASTER_LOCK_EN, 1,
|
||||
BL_PWM_GRP1_REG_LOCK, 1);
|
||||
|
||||
// 2.2 Write new active duty cycle
|
||||
REG_UPDATE(BL_PWM_CNTL, BL_ACTIVE_INT_FRAC_CNT, backlight_16bit);
|
||||
|
||||
/* 2.3 Unlock group 2 backlight registers */
|
||||
REG_UPDATE(BL_PWM_GRP1_REG_LOCK,
|
||||
BL_PWM_GRP1_REG_LOCK, 0);
|
||||
|
||||
/* 3 Wait for pending bit to be cleared */
|
||||
REG_WAIT(BL_PWM_GRP1_REG_LOCK,
|
||||
BL_PWM_GRP1_REG_UPDATE_PENDING, 0,
|
||||
1, 10000);
|
||||
}
|
||||
|
||||
static void dmcu_set_backlight_level(
|
||||
struct dce_abm *abm_dce,
|
||||
uint32_t backlight_pwm_u16_16,
|
||||
@@ -249,10 +135,9 @@ static void dmcu_set_backlight_level(
|
||||
0, 1, 80000);
|
||||
}
|
||||
|
||||
static void dce_abm_init(struct abm *abm)
|
||||
static void dce_abm_init(struct abm *abm, uint32_t backlight)
|
||||
{
|
||||
struct dce_abm *abm_dce = TO_DCE_ABM(abm);
|
||||
unsigned int backlight = calculate_16_bit_backlight_from_pwm(abm_dce);
|
||||
|
||||
REG_WRITE(DC_ABM1_HG_SAMPLE_RATE, 0x103);
|
||||
REG_WRITE(DC_ABM1_HG_SAMPLE_RATE, 0x101);
|
||||
@@ -334,85 +219,11 @@ static bool dce_abm_set_level(struct abm *abm, uint32_t level)
|
||||
|
||||
static bool dce_abm_immediate_disable(struct abm *abm, uint32_t panel_inst)
|
||||
{
|
||||
struct dce_abm *abm_dce = TO_DCE_ABM(abm);
|
||||
|
||||
if (abm->dmcu_is_running == false)
|
||||
return true;
|
||||
|
||||
dce_abm_set_pipe(abm, MCP_DISABLE_ABM_IMMEDIATELY, panel_inst);
|
||||
|
||||
abm->stored_backlight_registers.BL_PWM_CNTL =
|
||||
REG_READ(BL_PWM_CNTL);
|
||||
abm->stored_backlight_registers.BL_PWM_CNTL2 =
|
||||
REG_READ(BL_PWM_CNTL2);
|
||||
abm->stored_backlight_registers.BL_PWM_PERIOD_CNTL =
|
||||
REG_READ(BL_PWM_PERIOD_CNTL);
|
||||
|
||||
REG_GET(LVTMA_PWRSEQ_REF_DIV, BL_PWM_REF_DIV,
|
||||
&abm->stored_backlight_registers.LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool dce_abm_init_backlight(struct abm *abm)
|
||||
{
|
||||
struct dce_abm *abm_dce = TO_DCE_ABM(abm);
|
||||
uint32_t value;
|
||||
|
||||
/* It must not be 0, so we have to restore them
|
||||
* Bios bug w/a - period resets to zero,
|
||||
* restoring to cache values which is always correct
|
||||
*/
|
||||
REG_GET(BL_PWM_CNTL, BL_ACTIVE_INT_FRAC_CNT, &value);
|
||||
if (value == 0 || value == 1) {
|
||||
if (abm->stored_backlight_registers.BL_PWM_CNTL != 0) {
|
||||
REG_WRITE(BL_PWM_CNTL,
|
||||
abm->stored_backlight_registers.BL_PWM_CNTL);
|
||||
REG_WRITE(BL_PWM_CNTL2,
|
||||
abm->stored_backlight_registers.BL_PWM_CNTL2);
|
||||
REG_WRITE(BL_PWM_PERIOD_CNTL,
|
||||
abm->stored_backlight_registers.BL_PWM_PERIOD_CNTL);
|
||||
REG_UPDATE(LVTMA_PWRSEQ_REF_DIV,
|
||||
BL_PWM_REF_DIV,
|
||||
abm->stored_backlight_registers.
|
||||
LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV);
|
||||
} else {
|
||||
/* TODO: Note: This should not really happen since VBIOS
|
||||
* should have initialized PWM registers on boot.
|
||||
*/
|
||||
REG_WRITE(BL_PWM_CNTL, 0xC000FA00);
|
||||
REG_WRITE(BL_PWM_PERIOD_CNTL, 0x000C0FA0);
|
||||
}
|
||||
} else {
|
||||
abm->stored_backlight_registers.BL_PWM_CNTL =
|
||||
REG_READ(BL_PWM_CNTL);
|
||||
abm->stored_backlight_registers.BL_PWM_CNTL2 =
|
||||
REG_READ(BL_PWM_CNTL2);
|
||||
abm->stored_backlight_registers.BL_PWM_PERIOD_CNTL =
|
||||
REG_READ(BL_PWM_PERIOD_CNTL);
|
||||
|
||||
REG_GET(LVTMA_PWRSEQ_REF_DIV, BL_PWM_REF_DIV,
|
||||
&abm->stored_backlight_registers.
|
||||
LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV);
|
||||
}
|
||||
|
||||
/* Have driver take backlight control
|
||||
* TakeBacklightControl(true)
|
||||
*/
|
||||
value = REG_READ(BIOS_SCRATCH_2);
|
||||
value |= ATOM_S2_VRI_BRIGHT_ENABLE;
|
||||
REG_WRITE(BIOS_SCRATCH_2, value);
|
||||
|
||||
/* Enable the backlight output */
|
||||
REG_UPDATE(BL_PWM_CNTL, BL_PWM_EN, 1);
|
||||
|
||||
/* Disable fractional pwm if configured */
|
||||
REG_UPDATE(BL_PWM_CNTL, BL_PWM_FRACTIONAL_EN,
|
||||
abm->ctx->dc->config.disable_fractional_pwm ? 0 : 1);
|
||||
|
||||
/* Unlock group 2 backlight registers */
|
||||
REG_UPDATE(BL_PWM_GRP1_REG_LOCK,
|
||||
BL_PWM_GRP1_REG_LOCK, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -421,23 +232,18 @@ static bool dce_abm_set_backlight_level_pwm(
|
||||
unsigned int backlight_pwm_u16_16,
|
||||
unsigned int frame_ramp,
|
||||
unsigned int controller_id,
|
||||
unsigned int panel_inst,
|
||||
bool fw_set_brightness)
|
||||
unsigned int panel_inst)
|
||||
{
|
||||
struct dce_abm *abm_dce = TO_DCE_ABM(abm);
|
||||
|
||||
DC_LOG_BACKLIGHT("New Backlight level: %d (0x%X)\n",
|
||||
backlight_pwm_u16_16, backlight_pwm_u16_16);
|
||||
|
||||
/* If DMCU is in reset state, DMCU is uninitialized */
|
||||
if (fw_set_brightness)
|
||||
dmcu_set_backlight_level(abm_dce,
|
||||
backlight_pwm_u16_16,
|
||||
frame_ramp,
|
||||
controller_id,
|
||||
panel_inst);
|
||||
else
|
||||
driver_set_backlight_level(abm_dce, backlight_pwm_u16_16);
|
||||
dmcu_set_backlight_level(abm_dce,
|
||||
backlight_pwm_u16_16,
|
||||
frame_ramp,
|
||||
controller_id,
|
||||
panel_inst);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -445,13 +251,12 @@ static bool dce_abm_set_backlight_level_pwm(
|
||||
static const struct abm_funcs dce_funcs = {
|
||||
.abm_init = dce_abm_init,
|
||||
.set_abm_level = dce_abm_set_level,
|
||||
.init_backlight = dce_abm_init_backlight,
|
||||
.set_pipe = dce_abm_set_pipe,
|
||||
.set_backlight_level_pwm = dce_abm_set_backlight_level_pwm,
|
||||
.get_current_backlight = dce_abm_get_current_backlight,
|
||||
.get_target_backlight = dce_abm_get_target_backlight,
|
||||
.init_abm_config = NULL,
|
||||
.set_abm_immediate_disable = dce_abm_immediate_disable
|
||||
.set_abm_immediate_disable = dce_abm_immediate_disable,
|
||||
};
|
||||
|
||||
static void dce_abm_construct(
|
||||
@@ -465,10 +270,6 @@ static void dce_abm_construct(
|
||||
|
||||
base->ctx = ctx;
|
||||
base->funcs = &dce_funcs;
|
||||
base->stored_backlight_registers.BL_PWM_CNTL = 0;
|
||||
base->stored_backlight_registers.BL_PWM_CNTL2 = 0;
|
||||
base->stored_backlight_registers.BL_PWM_PERIOD_CNTL = 0;
|
||||
base->stored_backlight_registers.LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV = 0;
|
||||
base->dmcu_is_running = false;
|
||||
|
||||
abm_dce->regs = regs;
|
||||
|
@@ -30,11 +30,6 @@
|
||||
#include "abm.h"
|
||||
|
||||
#define ABM_COMMON_REG_LIST_DCE_BASE() \
|
||||
SR(BL_PWM_PERIOD_CNTL), \
|
||||
SR(BL_PWM_CNTL), \
|
||||
SR(BL_PWM_CNTL2), \
|
||||
SR(BL_PWM_GRP1_REG_LOCK), \
|
||||
SR(LVTMA_PWRSEQ_REF_DIV), \
|
||||
SR(MASTER_COMM_CNTL_REG), \
|
||||
SR(MASTER_COMM_CMD_REG), \
|
||||
SR(MASTER_COMM_DATA_REG1)
|
||||
@@ -85,15 +80,6 @@
|
||||
.field_name = reg_name ## __ ## field_name ## post_fix
|
||||
|
||||
#define ABM_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(mask_sh) \
|
||||
ABM_SF(BL_PWM_PERIOD_CNTL, BL_PWM_PERIOD, mask_sh), \
|
||||
ABM_SF(BL_PWM_PERIOD_CNTL, BL_PWM_PERIOD_BITCNT, mask_sh), \
|
||||
ABM_SF(BL_PWM_CNTL, BL_ACTIVE_INT_FRAC_CNT, mask_sh), \
|
||||
ABM_SF(BL_PWM_CNTL, BL_PWM_FRACTIONAL_EN, mask_sh), \
|
||||
ABM_SF(BL_PWM_CNTL, BL_PWM_EN, mask_sh), \
|
||||
ABM_SF(BL_PWM_GRP1_REG_LOCK, BL_PWM_GRP1_IGNORE_MASTER_LOCK_EN, mask_sh), \
|
||||
ABM_SF(BL_PWM_GRP1_REG_LOCK, BL_PWM_GRP1_REG_LOCK, mask_sh), \
|
||||
ABM_SF(BL_PWM_GRP1_REG_LOCK, BL_PWM_GRP1_REG_UPDATE_PENDING, mask_sh), \
|
||||
ABM_SF(LVTMA_PWRSEQ_REF_DIV, BL_PWM_REF_DIV, mask_sh), \
|
||||
ABM_SF(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, mask_sh), \
|
||||
ABM_SF(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0, mask_sh), \
|
||||
ABM_SF(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE1, mask_sh), \
|
||||
@@ -178,19 +164,10 @@
|
||||
type ABM1_HG_REG_READ_MISSED_FRAME_CLEAR; \
|
||||
type ABM1_LS_REG_READ_MISSED_FRAME_CLEAR; \
|
||||
type ABM1_BL_REG_READ_MISSED_FRAME_CLEAR; \
|
||||
type BL_PWM_PERIOD; \
|
||||
type BL_PWM_PERIOD_BITCNT; \
|
||||
type BL_ACTIVE_INT_FRAC_CNT; \
|
||||
type BL_PWM_FRACTIONAL_EN; \
|
||||
type MASTER_COMM_INTERRUPT; \
|
||||
type MASTER_COMM_CMD_REG_BYTE0; \
|
||||
type MASTER_COMM_CMD_REG_BYTE1; \
|
||||
type MASTER_COMM_CMD_REG_BYTE2; \
|
||||
type BL_PWM_REF_DIV; \
|
||||
type BL_PWM_EN; \
|
||||
type BL_PWM_GRP1_IGNORE_MASTER_LOCK_EN; \
|
||||
type BL_PWM_GRP1_REG_LOCK; \
|
||||
type BL_PWM_GRP1_REG_UPDATE_PENDING
|
||||
type MASTER_COMM_CMD_REG_BYTE2
|
||||
|
||||
struct dce_abm_shift {
|
||||
ABM_REG_FIELD_LIST(uint8_t);
|
||||
@@ -201,10 +178,6 @@ struct dce_abm_mask {
|
||||
};
|
||||
|
||||
struct dce_abm_registers {
|
||||
uint32_t BL_PWM_PERIOD_CNTL;
|
||||
uint32_t BL_PWM_CNTL;
|
||||
uint32_t BL_PWM_CNTL2;
|
||||
uint32_t LVTMA_PWRSEQ_REF_DIV;
|
||||
uint32_t DC_ABM1_HG_SAMPLE_RATE;
|
||||
uint32_t DC_ABM1_LS_SAMPLE_RATE;
|
||||
uint32_t BL1_PWM_BL_UPDATE_SAMPLE_RATE;
|
||||
@@ -219,7 +192,6 @@ struct dce_abm_registers {
|
||||
uint32_t MASTER_COMM_CMD_REG;
|
||||
uint32_t MASTER_COMM_DATA_REG1;
|
||||
uint32_t BIOS_SCRATCH_2;
|
||||
uint32_t BL_PWM_GRP1_REG_LOCK;
|
||||
};
|
||||
|
||||
struct dce_abm {
|
||||
|
@@ -28,6 +28,7 @@
|
||||
#include "dc_dmub_srv.h"
|
||||
#include "panel_cntl.h"
|
||||
#include "dce_panel_cntl.h"
|
||||
#include "atom.h"
|
||||
|
||||
#define TO_DCE_PANEL_CNTL(panel_cntl)\
|
||||
container_of(panel_cntl, struct dce_panel_cntl, base)
|
||||
@@ -45,9 +46,113 @@
|
||||
#define FN(reg_name, field_name) \
|
||||
dce_panel_cntl->shift->field_name, dce_panel_cntl->mask->field_name
|
||||
|
||||
void dce_panel_cntl_hw_init(struct panel_cntl *panel_cntl)
|
||||
static unsigned int calculate_16_bit_backlight_from_pwm(struct dce_panel_cntl *dce_panel_cntl)
|
||||
{
|
||||
uint64_t current_backlight;
|
||||
uint32_t round_result;
|
||||
uint32_t pwm_period_cntl, bl_period, bl_int_count;
|
||||
uint32_t bl_pwm_cntl, bl_pwm, fractional_duty_cycle_en;
|
||||
uint32_t bl_period_mask, bl_pwm_mask;
|
||||
|
||||
pwm_period_cntl = REG_READ(BL_PWM_PERIOD_CNTL);
|
||||
REG_GET(BL_PWM_PERIOD_CNTL, BL_PWM_PERIOD, &bl_period);
|
||||
REG_GET(BL_PWM_PERIOD_CNTL, BL_PWM_PERIOD_BITCNT, &bl_int_count);
|
||||
|
||||
bl_pwm_cntl = REG_READ(BL_PWM_CNTL);
|
||||
REG_GET(BL_PWM_CNTL, BL_ACTIVE_INT_FRAC_CNT, (uint32_t *)(&bl_pwm));
|
||||
REG_GET(BL_PWM_CNTL, BL_PWM_FRACTIONAL_EN, &fractional_duty_cycle_en);
|
||||
|
||||
if (bl_int_count == 0)
|
||||
bl_int_count = 16;
|
||||
|
||||
bl_period_mask = (1 << bl_int_count) - 1;
|
||||
bl_period &= bl_period_mask;
|
||||
|
||||
bl_pwm_mask = bl_period_mask << (16 - bl_int_count);
|
||||
|
||||
if (fractional_duty_cycle_en == 0)
|
||||
bl_pwm &= bl_pwm_mask;
|
||||
else
|
||||
bl_pwm &= 0xFFFF;
|
||||
|
||||
current_backlight = bl_pwm << (1 + bl_int_count);
|
||||
|
||||
if (bl_period == 0)
|
||||
bl_period = 0xFFFF;
|
||||
|
||||
current_backlight = div_u64(current_backlight, bl_period);
|
||||
current_backlight = (current_backlight + 1) >> 1;
|
||||
|
||||
current_backlight = (uint64_t)(current_backlight) * bl_period;
|
||||
|
||||
round_result = (uint32_t)(current_backlight & 0xFFFFFFFF);
|
||||
|
||||
round_result = (round_result >> (bl_int_count-1)) & 1;
|
||||
|
||||
current_backlight >>= bl_int_count;
|
||||
current_backlight += round_result;
|
||||
|
||||
return (uint32_t)(current_backlight);
|
||||
}
|
||||
|
||||
uint32_t dce_panel_cntl_hw_init(struct panel_cntl *panel_cntl)
|
||||
{
|
||||
struct dce_panel_cntl *dce_panel_cntl = TO_DCE_PANEL_CNTL(panel_cntl);
|
||||
uint32_t value;
|
||||
uint32_t current_backlight;
|
||||
|
||||
/* It must not be 0, so we have to restore them
|
||||
* Bios bug w/a - period resets to zero,
|
||||
* restoring to cache values which is always correct
|
||||
*/
|
||||
REG_GET(BL_PWM_CNTL, BL_ACTIVE_INT_FRAC_CNT, &value);
|
||||
|
||||
if (value == 0 || value == 1) {
|
||||
if (panel_cntl->stored_backlight_registers.BL_PWM_CNTL != 0) {
|
||||
REG_WRITE(BL_PWM_CNTL,
|
||||
panel_cntl->stored_backlight_registers.BL_PWM_CNTL);
|
||||
REG_WRITE(BL_PWM_CNTL2,
|
||||
panel_cntl->stored_backlight_registers.BL_PWM_CNTL2);
|
||||
REG_WRITE(BL_PWM_PERIOD_CNTL,
|
||||
panel_cntl->stored_backlight_registers.BL_PWM_PERIOD_CNTL);
|
||||
REG_UPDATE(PWRSEQ_REF_DIV,
|
||||
BL_PWM_REF_DIV,
|
||||
panel_cntl->stored_backlight_registers.LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV);
|
||||
} else {
|
||||
/* TODO: Note: This should not really happen since VBIOS
|
||||
* should have initialized PWM registers on boot.
|
||||
*/
|
||||
REG_WRITE(BL_PWM_CNTL, 0xC000FA00);
|
||||
REG_WRITE(BL_PWM_PERIOD_CNTL, 0x000C0FA0);
|
||||
}
|
||||
} else {
|
||||
panel_cntl->stored_backlight_registers.BL_PWM_CNTL =
|
||||
REG_READ(BL_PWM_CNTL);
|
||||
panel_cntl->stored_backlight_registers.BL_PWM_CNTL2 =
|
||||
REG_READ(BL_PWM_CNTL2);
|
||||
panel_cntl->stored_backlight_registers.BL_PWM_PERIOD_CNTL =
|
||||
REG_READ(BL_PWM_PERIOD_CNTL);
|
||||
|
||||
REG_GET(PWRSEQ_REF_DIV, BL_PWM_REF_DIV,
|
||||
&panel_cntl->stored_backlight_registers.LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV);
|
||||
}
|
||||
|
||||
// Have driver take backlight control
|
||||
// TakeBacklightControl(true)
|
||||
value = REG_READ(BIOS_SCRATCH_2);
|
||||
value |= ATOM_S2_VRI_BRIGHT_ENABLE;
|
||||
REG_WRITE(BIOS_SCRATCH_2, value);
|
||||
|
||||
// Enable the backlight output
|
||||
REG_UPDATE(BL_PWM_CNTL, BL_PWM_EN, 1);
|
||||
|
||||
// Unlock group 2 backlight registers
|
||||
REG_UPDATE(BL_PWM_GRP1_REG_LOCK,
|
||||
BL_PWM_GRP1_REG_LOCK, 0);
|
||||
|
||||
current_backlight = calculate_16_bit_backlight_from_pwm(dce_panel_cntl);
|
||||
|
||||
return current_backlight;
|
||||
}
|
||||
|
||||
bool dce_is_panel_backlight_on(struct panel_cntl *panel_cntl)
|
||||
@@ -55,7 +160,7 @@ bool dce_is_panel_backlight_on(struct panel_cntl *panel_cntl)
|
||||
struct dce_panel_cntl *dce_panel_cntl = TO_DCE_PANEL_CNTL(panel_cntl);
|
||||
uint32_t value;
|
||||
|
||||
REG_GET(PWRSEQ_CNTL, BLON, &value);
|
||||
REG_GET(PWRSEQ_CNTL, LVTMA_BLON, &value);
|
||||
|
||||
return value;
|
||||
}
|
||||
@@ -65,13 +170,94 @@ bool dce_is_panel_powered_on(struct panel_cntl *panel_cntl)
|
||||
struct dce_panel_cntl *dce_panel_cntl = TO_DCE_PANEL_CNTL(panel_cntl);
|
||||
uint32_t pwr_seq_state, dig_on, dig_on_ovrd;
|
||||
|
||||
REG_GET(PWRSEQ_STATE, PWRSEQ_TARGET_STATE_R, &pwr_seq_state);
|
||||
REG_GET(PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, &pwr_seq_state);
|
||||
|
||||
REG_GET_2(PWRSEQ_CNTL, DIGON, &dig_on, DIGON_OVRD, &dig_on_ovrd);
|
||||
REG_GET_2(PWRSEQ_CNTL, LVTMA_DIGON, &dig_on, LVTMA_DIGON_OVRD, &dig_on_ovrd);
|
||||
|
||||
return (pwr_seq_state == 1) || (dig_on == 1 && dig_on_ovrd == 1);
|
||||
}
|
||||
|
||||
void dce_store_backlight_level(struct panel_cntl *panel_cntl)
|
||||
{
|
||||
struct dce_panel_cntl *dce_panel_cntl = TO_DCE_PANEL_CNTL(panel_cntl);
|
||||
|
||||
panel_cntl->stored_backlight_registers.BL_PWM_CNTL =
|
||||
REG_READ(BL_PWM_CNTL);
|
||||
panel_cntl->stored_backlight_registers.BL_PWM_CNTL2 =
|
||||
REG_READ(BL_PWM_CNTL2);
|
||||
panel_cntl->stored_backlight_registers.BL_PWM_PERIOD_CNTL =
|
||||
REG_READ(BL_PWM_PERIOD_CNTL);
|
||||
|
||||
REG_GET(PWRSEQ_REF_DIV, BL_PWM_REF_DIV,
|
||||
&panel_cntl->stored_backlight_registers.LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV);
|
||||
}
|
||||
|
||||
void dce_driver_set_backlight(struct panel_cntl *panel_cntl,
|
||||
uint32_t backlight_pwm_u16_16)
|
||||
{
|
||||
uint32_t backlight_16bit;
|
||||
uint32_t masked_pwm_period;
|
||||
uint8_t bit_count;
|
||||
uint64_t active_duty_cycle;
|
||||
uint32_t pwm_period_bitcnt;
|
||||
struct dce_panel_cntl *dce_panel_cntl = TO_DCE_PANEL_CNTL(panel_cntl);
|
||||
|
||||
/*
|
||||
* 1. Find 16 bit backlight active duty cycle, where 0 <= backlight
|
||||
* active duty cycle <= backlight period
|
||||
*/
|
||||
|
||||
/* 1.1 Apply bitmask for backlight period value based on value of BITCNT
|
||||
*/
|
||||
REG_GET_2(BL_PWM_PERIOD_CNTL,
|
||||
BL_PWM_PERIOD_BITCNT, &pwm_period_bitcnt,
|
||||
BL_PWM_PERIOD, &masked_pwm_period);
|
||||
|
||||
if (pwm_period_bitcnt == 0)
|
||||
bit_count = 16;
|
||||
else
|
||||
bit_count = pwm_period_bitcnt;
|
||||
|
||||
/* e.g. maskedPwmPeriod = 0x24 when bitCount is 6 */
|
||||
masked_pwm_period = masked_pwm_period & ((1 << bit_count) - 1);
|
||||
|
||||
/* 1.2 Calculate integer active duty cycle required upper 16 bits
|
||||
* contain integer component, lower 16 bits contain fractional component
|
||||
* of active duty cycle e.g. 0x21BDC0 = 0xEFF0 * 0x24
|
||||
*/
|
||||
active_duty_cycle = backlight_pwm_u16_16 * masked_pwm_period;
|
||||
|
||||
/* 1.3 Calculate 16 bit active duty cycle from integer and fractional
|
||||
* components shift by bitCount then mask 16 bits and add rounding bit
|
||||
* from MSB of fraction e.g. 0x86F7 = ((0x21BDC0 >> 6) & 0xFFF) + 0
|
||||
*/
|
||||
backlight_16bit = active_duty_cycle >> bit_count;
|
||||
backlight_16bit &= 0xFFFF;
|
||||
backlight_16bit += (active_duty_cycle >> (bit_count - 1)) & 0x1;
|
||||
|
||||
/*
|
||||
* 2. Program register with updated value
|
||||
*/
|
||||
|
||||
/* 2.1 Lock group 2 backlight registers */
|
||||
|
||||
REG_UPDATE_2(BL_PWM_GRP1_REG_LOCK,
|
||||
BL_PWM_GRP1_IGNORE_MASTER_LOCK_EN, 1,
|
||||
BL_PWM_GRP1_REG_LOCK, 1);
|
||||
|
||||
// 2.2 Write new active duty cycle
|
||||
REG_UPDATE(BL_PWM_CNTL, BL_ACTIVE_INT_FRAC_CNT, backlight_16bit);
|
||||
|
||||
/* 2.3 Unlock group 2 backlight registers */
|
||||
REG_UPDATE(BL_PWM_GRP1_REG_LOCK,
|
||||
BL_PWM_GRP1_REG_LOCK, 0);
|
||||
|
||||
/* 3 Wait for pending bit to be cleared */
|
||||
REG_WAIT(BL_PWM_GRP1_REG_LOCK,
|
||||
BL_PWM_GRP1_REG_UPDATE_PENDING, 0,
|
||||
1, 10000);
|
||||
}
|
||||
|
||||
static void dce_panel_cntl_destroy(struct panel_cntl **panel_cntl)
|
||||
{
|
||||
struct dce_panel_cntl *dce_panel_cntl = TO_DCE_PANEL_CNTL(*panel_cntl);
|
||||
@@ -85,7 +271,8 @@ static const struct panel_cntl_funcs dce_link_panel_cntl_funcs = {
|
||||
.hw_init = dce_panel_cntl_hw_init,
|
||||
.is_panel_backlight_on = dce_is_panel_backlight_on,
|
||||
.is_panel_powered_on = dce_is_panel_powered_on,
|
||||
|
||||
.store_backlight_level = dce_store_backlight_level,
|
||||
.driver_set_backlight = dce_driver_set_backlight,
|
||||
};
|
||||
|
||||
void dce_panel_cntl_construct(
|
||||
@@ -95,6 +282,13 @@ void dce_panel_cntl_construct(
|
||||
const struct dce_panel_cntl_shift *shift,
|
||||
const struct dce_panel_cntl_mask *mask)
|
||||
{
|
||||
struct panel_cntl *base = &dce_panel_cntl->base;
|
||||
|
||||
base->stored_backlight_registers.BL_PWM_CNTL = 0;
|
||||
base->stored_backlight_registers.BL_PWM_CNTL2 = 0;
|
||||
base->stored_backlight_registers.BL_PWM_PERIOD_CNTL = 0;
|
||||
base->stored_backlight_registers.LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV = 0;
|
||||
|
||||
dce_panel_cntl->regs = regs;
|
||||
dce_panel_cntl->shift = shift;
|
||||
dce_panel_cntl->mask = mask;
|
||||
|
@@ -35,10 +35,12 @@
|
||||
#define DCE_PANEL_CNTL_REG_LIST()\
|
||||
DCE_PANEL_CNTL_SR(PWRSEQ_CNTL, LVTMA), \
|
||||
DCE_PANEL_CNTL_SR(PWRSEQ_STATE, LVTMA), \
|
||||
DCE_PANEL_CNTL_SR(PWRSEQ_REF_DIV, LVTMA), \
|
||||
SR(BL_PWM_CNTL), \
|
||||
SR(BL_PWM_CNTL2), \
|
||||
SR(BL_PWM_PERIOD_CNTL), \
|
||||
SR(BL_PWM_GRP1_REG_LOCK)
|
||||
SR(BL_PWM_GRP1_REG_LOCK), \
|
||||
SR(BIOS_SCRATCH_2)
|
||||
|
||||
#define DCN_PANEL_CNTL_SR(reg_name, block)\
|
||||
.reg_name = BASE(mm ## block ## _ ## reg_name ## _BASE_IDX) + \
|
||||
@@ -47,33 +49,37 @@
|
||||
#define DCN_PANEL_CNTL_REG_LIST()\
|
||||
DCN_PANEL_CNTL_SR(PWRSEQ_CNTL, LVTMA), \
|
||||
DCN_PANEL_CNTL_SR(PWRSEQ_STATE, LVTMA), \
|
||||
DCE_PANEL_CNTL_SR(PWRSEQ_REF_DIV, LVTMA), \
|
||||
SR(BL_PWM_CNTL), \
|
||||
SR(BL_PWM_CNTL2), \
|
||||
SR(BL_PWM_PERIOD_CNTL), \
|
||||
SR(BL_PWM_GRP1_REG_LOCK)
|
||||
SR(BL_PWM_GRP1_REG_LOCK), \
|
||||
SR(BIOS_SCRATCH_2)
|
||||
|
||||
#define DCE_PANEL_CNTL_SF(block, reg_name, field_name, post_fix)\
|
||||
.field_name = block ## reg_name ## __ ## block ## field_name ## post_fix
|
||||
#define DCE_PANEL_CNTL_SF(reg_name, field_name, post_fix)\
|
||||
.field_name = reg_name ## __ ## field_name ## post_fix
|
||||
|
||||
#define DCE_PANEL_CNTL_MASK_SH_LIST(mask_sh) \
|
||||
DCE_PANEL_CNTL_SF(LVTMA_, PWRSEQ_CNTL, BLON, mask_sh),\
|
||||
DCE_PANEL_CNTL_SF(LVTMA_, PWRSEQ_CNTL, DIGON, mask_sh),\
|
||||
DCE_PANEL_CNTL_SF(LVTMA_, PWRSEQ_CNTL, DIGON_OVRD, mask_sh),\
|
||||
DCE_PANEL_CNTL_SF(LVTMA_, PWRSEQ_STATE, PWRSEQ_TARGET_STATE_R, mask_sh), \
|
||||
DCE_PANEL_CNTL_SF(, BL_PWM_PERIOD_CNTL, BL_PWM_PERIOD, mask_sh), \
|
||||
DCE_PANEL_CNTL_SF(, BL_PWM_PERIOD_CNTL, BL_PWM_PERIOD_BITCNT, mask_sh), \
|
||||
DCE_PANEL_CNTL_SF(, BL_PWM_CNTL, BL_ACTIVE_INT_FRAC_CNT, mask_sh), \
|
||||
DCE_PANEL_CNTL_SF(, BL_PWM_CNTL, BL_PWM_FRACTIONAL_EN, mask_sh), \
|
||||
DCE_PANEL_CNTL_SF(, BL_PWM_CNTL, BL_PWM_EN, mask_sh), \
|
||||
DCE_PANEL_CNTL_SF(, BL_PWM_GRP1_REG_LOCK, BL_PWM_GRP1_IGNORE_MASTER_LOCK_EN, mask_sh), \
|
||||
DCE_PANEL_CNTL_SF(, BL_PWM_GRP1_REG_LOCK, BL_PWM_GRP1_REG_LOCK, mask_sh), \
|
||||
DCE_PANEL_CNTL_SF(, BL_PWM_GRP1_REG_LOCK, BL_PWM_GRP1_REG_UPDATE_PENDING, mask_sh)
|
||||
DCE_PANEL_CNTL_SF(LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh),\
|
||||
DCE_PANEL_CNTL_SF(LVTMA_PWRSEQ_CNTL, LVTMA_DIGON, mask_sh),\
|
||||
DCE_PANEL_CNTL_SF(LVTMA_PWRSEQ_CNTL, LVTMA_DIGON_OVRD, mask_sh),\
|
||||
DCE_PANEL_CNTL_SF(LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh), \
|
||||
DCE_PANEL_CNTL_SF(LVTMA_PWRSEQ_REF_DIV, BL_PWM_REF_DIV, mask_sh), \
|
||||
DCE_PANEL_CNTL_SF(BL_PWM_PERIOD_CNTL, BL_PWM_PERIOD, mask_sh), \
|
||||
DCE_PANEL_CNTL_SF(BL_PWM_PERIOD_CNTL, BL_PWM_PERIOD_BITCNT, mask_sh), \
|
||||
DCE_PANEL_CNTL_SF(BL_PWM_CNTL, BL_ACTIVE_INT_FRAC_CNT, mask_sh), \
|
||||
DCE_PANEL_CNTL_SF(BL_PWM_CNTL, BL_PWM_FRACTIONAL_EN, mask_sh), \
|
||||
DCE_PANEL_CNTL_SF(BL_PWM_CNTL, BL_PWM_EN, mask_sh), \
|
||||
DCE_PANEL_CNTL_SF(BL_PWM_GRP1_REG_LOCK, BL_PWM_GRP1_IGNORE_MASTER_LOCK_EN, mask_sh), \
|
||||
DCE_PANEL_CNTL_SF(BL_PWM_GRP1_REG_LOCK, BL_PWM_GRP1_REG_LOCK, mask_sh), \
|
||||
DCE_PANEL_CNTL_SF(BL_PWM_GRP1_REG_LOCK, BL_PWM_GRP1_REG_UPDATE_PENDING, mask_sh)
|
||||
|
||||
#define DCE_PANEL_CNTL_REG_FIELD_LIST(type) \
|
||||
type BLON;\
|
||||
type DIGON;\
|
||||
type DIGON_OVRD;\
|
||||
type PWRSEQ_TARGET_STATE_R; \
|
||||
type LVTMA_BLON;\
|
||||
type LVTMA_DIGON;\
|
||||
type LVTMA_DIGON_OVRD;\
|
||||
type LVTMA_PWRSEQ_TARGET_STATE_R; \
|
||||
type BL_PWM_REF_DIV; \
|
||||
type BL_PWM_EN; \
|
||||
type BL_ACTIVE_INT_FRAC_CNT; \
|
||||
type BL_PWM_FRACTIONAL_EN; \
|
||||
@@ -98,6 +104,8 @@ struct dce_panel_cntl_registers {
|
||||
uint32_t BL_PWM_CNTL2;
|
||||
uint32_t BL_PWM_PERIOD_CNTL;
|
||||
uint32_t BL_PWM_GRP1_REG_LOCK;
|
||||
uint32_t PWRSEQ_REF_DIV;
|
||||
uint32_t BIOS_SCRATCH_2;
|
||||
};
|
||||
|
||||
struct dce_panel_cntl {
|
||||
|
@@ -1336,7 +1336,6 @@ static void dce110_se_audio_setup(
|
||||
{
|
||||
struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc);
|
||||
|
||||
uint32_t speakers = 0;
|
||||
uint32_t channels = 0;
|
||||
|
||||
ASSERT(audio_info);
|
||||
@@ -1344,7 +1343,6 @@ static void dce110_se_audio_setup(
|
||||
/* This should not happen.it does so we don't get BSOD*/
|
||||
return;
|
||||
|
||||
speakers = audio_info->flags.info.ALLSPEAKERS;
|
||||
channels = speakers_to_channels(audio_info->flags.speaker_flags).all;
|
||||
|
||||
/* setup the audio stream source select (audio -> dig mapping) */
|
||||
|
@@ -27,7 +27,7 @@
|
||||
#include "dce_abm.h"
|
||||
#include "dc.h"
|
||||
#include "dc_dmub_srv.h"
|
||||
#include "dmub/inc/dmub_srv.h"
|
||||
#include "dmub/dmub_srv.h"
|
||||
#include "core_types.h"
|
||||
#include "dm_services.h"
|
||||
#include "reg_helper.h"
|
||||
@@ -70,53 +70,6 @@ static bool dmub_abm_set_pipe(struct abm *abm, uint32_t otg_inst, uint32_t panel
|
||||
return true;
|
||||
}
|
||||
|
||||
static unsigned int calculate_16_bit_backlight_from_pwm(struct dce_abm *dce_abm)
|
||||
{
|
||||
uint64_t current_backlight;
|
||||
uint32_t round_result;
|
||||
uint32_t bl_period, bl_int_count;
|
||||
uint32_t bl_pwm, fractional_duty_cycle_en;
|
||||
uint32_t bl_period_mask, bl_pwm_mask;
|
||||
|
||||
REG_GET(BL_PWM_PERIOD_CNTL, BL_PWM_PERIOD, &bl_period);
|
||||
REG_GET(BL_PWM_PERIOD_CNTL, BL_PWM_PERIOD_BITCNT, &bl_int_count);
|
||||
|
||||
REG_GET(BL_PWM_CNTL, BL_ACTIVE_INT_FRAC_CNT, &bl_pwm);
|
||||
REG_GET(BL_PWM_CNTL, BL_PWM_FRACTIONAL_EN, &fractional_duty_cycle_en);
|
||||
|
||||
if (bl_int_count == 0)
|
||||
bl_int_count = 16;
|
||||
|
||||
bl_period_mask = (1 << bl_int_count) - 1;
|
||||
bl_period &= bl_period_mask;
|
||||
|
||||
bl_pwm_mask = bl_period_mask << (16 - bl_int_count);
|
||||
|
||||
if (fractional_duty_cycle_en == 0)
|
||||
bl_pwm &= bl_pwm_mask;
|
||||
else
|
||||
bl_pwm &= 0xFFFF;
|
||||
|
||||
current_backlight = (uint64_t)bl_pwm << (1 + bl_int_count);
|
||||
|
||||
if (bl_period == 0)
|
||||
bl_period = 0xFFFF;
|
||||
|
||||
current_backlight = div_u64(current_backlight, bl_period);
|
||||
current_backlight = (current_backlight + 1) >> 1;
|
||||
|
||||
current_backlight = (uint64_t)(current_backlight) * bl_period;
|
||||
|
||||
round_result = (uint32_t)(current_backlight & 0xFFFFFFFF);
|
||||
|
||||
round_result = (round_result >> (bl_int_count-1)) & 1;
|
||||
|
||||
current_backlight >>= bl_int_count;
|
||||
current_backlight += round_result;
|
||||
|
||||
return (uint32_t)(current_backlight);
|
||||
}
|
||||
|
||||
static void dmcub_set_backlight_level(
|
||||
struct dce_abm *dce_abm,
|
||||
uint32_t backlight_pwm_u16_16,
|
||||
@@ -178,10 +131,9 @@ static void dmub_abm_enable_fractional_pwm(struct dc_context *dc)
|
||||
dc_dmub_srv_wait_idle(dc->dmub_srv);
|
||||
}
|
||||
|
||||
static void dmub_abm_init(struct abm *abm)
|
||||
static void dmub_abm_init(struct abm *abm, uint32_t backlight)
|
||||
{
|
||||
struct dce_abm *dce_abm = TO_DMUB_ABM(abm);
|
||||
unsigned int backlight = calculate_16_bit_backlight_from_pwm(dce_abm);
|
||||
|
||||
REG_WRITE(DC_ABM1_HG_SAMPLE_RATE, 0x103);
|
||||
REG_WRITE(DC_ABM1_HG_SAMPLE_RATE, 0x101);
|
||||
@@ -261,77 +213,8 @@ static bool dmub_abm_set_level(struct abm *abm, uint32_t level)
|
||||
|
||||
static bool dmub_abm_immediate_disable(struct abm *abm, uint32_t panel_inst)
|
||||
{
|
||||
struct dce_abm *dce_abm = TO_DMUB_ABM(abm);
|
||||
|
||||
dmub_abm_set_pipe(abm, DISABLE_ABM_IMMEDIATELY, panel_inst);
|
||||
|
||||
abm->stored_backlight_registers.BL_PWM_CNTL =
|
||||
REG_READ(BL_PWM_CNTL);
|
||||
abm->stored_backlight_registers.BL_PWM_CNTL2 =
|
||||
REG_READ(BL_PWM_CNTL2);
|
||||
abm->stored_backlight_registers.BL_PWM_PERIOD_CNTL =
|
||||
REG_READ(BL_PWM_PERIOD_CNTL);
|
||||
|
||||
REG_GET(LVTMA_PWRSEQ_REF_DIV, BL_PWM_REF_DIV,
|
||||
&abm->stored_backlight_registers.LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool dmub_abm_init_backlight(struct abm *abm)
|
||||
{
|
||||
struct dce_abm *dce_abm = TO_DMUB_ABM(abm);
|
||||
uint32_t value;
|
||||
|
||||
/* It must not be 0, so we have to restore them
|
||||
* Bios bug w/a - period resets to zero,
|
||||
* restoring to cache values which is always correct
|
||||
*/
|
||||
REG_GET(BL_PWM_CNTL, BL_ACTIVE_INT_FRAC_CNT, &value);
|
||||
|
||||
if (value == 0 || value == 1) {
|
||||
if (abm->stored_backlight_registers.BL_PWM_CNTL != 0) {
|
||||
REG_WRITE(BL_PWM_CNTL,
|
||||
abm->stored_backlight_registers.BL_PWM_CNTL);
|
||||
REG_WRITE(BL_PWM_CNTL2,
|
||||
abm->stored_backlight_registers.BL_PWM_CNTL2);
|
||||
REG_WRITE(BL_PWM_PERIOD_CNTL,
|
||||
abm->stored_backlight_registers.BL_PWM_PERIOD_CNTL);
|
||||
REG_UPDATE(LVTMA_PWRSEQ_REF_DIV,
|
||||
BL_PWM_REF_DIV,
|
||||
abm->stored_backlight_registers.LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV);
|
||||
} else {
|
||||
/* TODO: Note: This should not really happen since VBIOS
|
||||
* should have initialized PWM registers on boot.
|
||||
*/
|
||||
REG_WRITE(BL_PWM_CNTL, 0xC000FA00);
|
||||
REG_WRITE(BL_PWM_PERIOD_CNTL, 0x000C0FA0);
|
||||
}
|
||||
} else {
|
||||
abm->stored_backlight_registers.BL_PWM_CNTL =
|
||||
REG_READ(BL_PWM_CNTL);
|
||||
abm->stored_backlight_registers.BL_PWM_CNTL2 =
|
||||
REG_READ(BL_PWM_CNTL2);
|
||||
abm->stored_backlight_registers.BL_PWM_PERIOD_CNTL =
|
||||
REG_READ(BL_PWM_PERIOD_CNTL);
|
||||
|
||||
REG_GET(LVTMA_PWRSEQ_REF_DIV, BL_PWM_REF_DIV,
|
||||
&abm->stored_backlight_registers.LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV);
|
||||
}
|
||||
|
||||
// Have driver take backlight control
|
||||
// TakeBacklightControl(true)
|
||||
value = REG_READ(BIOS_SCRATCH_2);
|
||||
value |= ATOM_S2_VRI_BRIGHT_ENABLE;
|
||||
REG_WRITE(BIOS_SCRATCH_2, value);
|
||||
|
||||
// Enable the backlight output
|
||||
REG_UPDATE(BL_PWM_CNTL, BL_PWM_EN, 1);
|
||||
|
||||
// Unlock group 2 backlight registers
|
||||
REG_UPDATE(BL_PWM_GRP1_REG_LOCK,
|
||||
BL_PWM_GRP1_REG_LOCK, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -340,8 +223,7 @@ static bool dmub_abm_set_backlight_level_pwm(
|
||||
unsigned int backlight_pwm_u16_16,
|
||||
unsigned int frame_ramp,
|
||||
unsigned int otg_inst,
|
||||
uint32_t panel_inst,
|
||||
bool fw_set_brightness)
|
||||
uint32_t panel_inst)
|
||||
{
|
||||
struct dce_abm *dce_abm = TO_DMUB_ABM(abm);
|
||||
|
||||
@@ -384,7 +266,6 @@ static bool dmub_abm_init_config(struct abm *abm,
|
||||
static const struct abm_funcs abm_funcs = {
|
||||
.abm_init = dmub_abm_init,
|
||||
.set_abm_level = dmub_abm_set_level,
|
||||
.init_backlight = dmub_abm_init_backlight,
|
||||
.set_pipe = dmub_abm_set_pipe,
|
||||
.set_backlight_level_pwm = dmub_abm_set_backlight_level_pwm,
|
||||
.get_current_backlight = dmub_abm_get_current_backlight,
|
||||
@@ -404,10 +285,6 @@ static void dmub_abm_construct(
|
||||
|
||||
base->ctx = ctx;
|
||||
base->funcs = &abm_funcs;
|
||||
base->stored_backlight_registers.BL_PWM_CNTL = 0;
|
||||
base->stored_backlight_registers.BL_PWM_CNTL2 = 0;
|
||||
base->stored_backlight_registers.BL_PWM_PERIOD_CNTL = 0;
|
||||
base->stored_backlight_registers.LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV = 0;
|
||||
base->dmcu_is_running = false;
|
||||
|
||||
abm_dce->regs = regs;
|
||||
|
@@ -26,8 +26,7 @@
|
||||
#include "dmub_psr.h"
|
||||
#include "dc.h"
|
||||
#include "dc_dmub_srv.h"
|
||||
#include "dmub/inc/dmub_srv.h"
|
||||
#include "dmub/inc/dmub_gpint_cmd.h"
|
||||
#include "dmub/dmub_srv.h"
|
||||
#include "core_types.h"
|
||||
|
||||
#define MAX_PIPES 6
|
||||
@@ -94,12 +93,20 @@ static bool dmub_psr_set_version(struct dmub_psr *dmub, struct dc_stream_state *
|
||||
union dmub_rb_cmd cmd;
|
||||
struct dc_context *dc = dmub->ctx;
|
||||
|
||||
if (stream->link->psr_settings.psr_version == PSR_VERSION_UNSUPPORTED)
|
||||
if (stream->link->psr_settings.psr_version == DC_PSR_VERSION_UNSUPPORTED)
|
||||
return false;
|
||||
|
||||
cmd.psr_set_version.header.type = DMUB_CMD__PSR;
|
||||
cmd.psr_set_version.header.sub_type = DMUB_CMD__PSR_SET_VERSION;
|
||||
cmd.psr_set_version.psr_set_version_data.version = stream->link->psr_settings.psr_version;
|
||||
switch (stream->link->psr_settings.psr_version) {
|
||||
case DC_PSR_VERSION_1:
|
||||
cmd.psr_set_version.psr_set_version_data.version = PSR_VERSION_1;
|
||||
break;
|
||||
case DC_PSR_VERSION_UNSUPPORTED:
|
||||
default:
|
||||
cmd.psr_set_version.psr_set_version_data.version = PSR_VERSION_UNSUPPORTED;
|
||||
break;
|
||||
}
|
||||
cmd.psr_set_version.header.payload_bytes = sizeof(struct dmub_cmd_psr_set_version_data);
|
||||
|
||||
dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd);
|
||||
|
@@ -1066,7 +1066,7 @@ void dce110_blank_stream(struct pipe_ctx *pipe_ctx)
|
||||
|
||||
if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) {
|
||||
hws->funcs.edp_backlight_control(link, false);
|
||||
dc_link_set_abm_disable(link);
|
||||
link->dc->hwss.set_abm_immediate_disable(pipe_ctx);
|
||||
}
|
||||
|
||||
if (dc_is_dp_signal(pipe_ctx->stream->signal))
|
||||
@@ -2355,6 +2355,7 @@ static void init_hw(struct dc *dc)
|
||||
struct abm *abm;
|
||||
struct dmcu *dmcu;
|
||||
struct dce_hwseq *hws = dc->hwseq;
|
||||
uint32_t backlight = MAX_BACKLIGHT_LEVEL;
|
||||
|
||||
bp = dc->ctx->dc_bios;
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
@@ -2401,12 +2402,17 @@ static void init_hw(struct dc *dc)
|
||||
audio->funcs->hw_init(audio);
|
||||
}
|
||||
|
||||
abm = dc->res_pool->abm;
|
||||
if (abm != NULL) {
|
||||
abm->funcs->init_backlight(abm);
|
||||
abm->funcs->abm_init(abm);
|
||||
for (i = 0; i < dc->link_count; i++) {
|
||||
struct dc_link *link = dc->links[i];
|
||||
|
||||
if (link->panel_cntl)
|
||||
backlight = link->panel_cntl->funcs->hw_init(link->panel_cntl);
|
||||
}
|
||||
|
||||
abm = dc->res_pool->abm;
|
||||
if (abm != NULL)
|
||||
abm->funcs->abm_init(abm, backlight);
|
||||
|
||||
dmcu = dc->res_pool->dmcu;
|
||||
if (dmcu != NULL && abm != NULL)
|
||||
abm->dmcu_is_running = dmcu->funcs->is_dmcu_initialized(dmcu);
|
||||
@@ -2721,6 +2727,7 @@ bool dce110_set_backlight_level(struct pipe_ctx *pipe_ctx,
|
||||
struct dc_link *link = pipe_ctx->stream->link;
|
||||
struct dc *dc = link->ctx->dc;
|
||||
struct abm *abm = pipe_ctx->stream_res.abm;
|
||||
struct panel_cntl *panel_cntl = link->panel_cntl;
|
||||
struct dmcu *dmcu = dc->res_pool->dmcu;
|
||||
bool fw_set_brightness = true;
|
||||
/* DMCU -1 for all controller id values,
|
||||
@@ -2728,23 +2735,38 @@ bool dce110_set_backlight_level(struct pipe_ctx *pipe_ctx,
|
||||
*/
|
||||
uint32_t controller_id = pipe_ctx->stream_res.tg->inst + 1;
|
||||
|
||||
if (abm == NULL || (abm->funcs->set_backlight_level_pwm == NULL))
|
||||
if (abm == NULL || panel_cntl == NULL || (abm->funcs->set_backlight_level_pwm == NULL))
|
||||
return false;
|
||||
|
||||
if (dmcu)
|
||||
fw_set_brightness = dmcu->funcs->is_dmcu_initialized(dmcu);
|
||||
|
||||
abm->funcs->set_backlight_level_pwm(
|
||||
abm,
|
||||
backlight_pwm_u16_16,
|
||||
frame_ramp,
|
||||
controller_id,
|
||||
link->panel_cntl->inst,
|
||||
fw_set_brightness);
|
||||
if (!fw_set_brightness && panel_cntl->funcs->driver_set_backlight)
|
||||
panel_cntl->funcs->driver_set_backlight(panel_cntl, backlight_pwm_u16_16);
|
||||
else
|
||||
abm->funcs->set_backlight_level_pwm(
|
||||
abm,
|
||||
backlight_pwm_u16_16,
|
||||
frame_ramp,
|
||||
controller_id,
|
||||
link->panel_cntl->inst);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void dce110_set_abm_immediate_disable(struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
struct abm *abm = pipe_ctx->stream_res.abm;
|
||||
struct panel_cntl *panel_cntl = pipe_ctx->stream->link->panel_cntl;
|
||||
|
||||
if (abm)
|
||||
abm->funcs->set_abm_immediate_disable(abm,
|
||||
pipe_ctx->stream->link->panel_cntl->inst);
|
||||
|
||||
if (panel_cntl)
|
||||
panel_cntl->funcs->store_backlight_level(panel_cntl);
|
||||
}
|
||||
|
||||
static const struct hw_sequencer_funcs dce110_funcs = {
|
||||
.program_gamut_remap = program_gamut_remap,
|
||||
.program_output_csc = program_output_csc,
|
||||
@@ -2781,6 +2803,7 @@ static const struct hw_sequencer_funcs dce110_funcs = {
|
||||
.set_cursor_position = dce110_set_cursor_position,
|
||||
.set_cursor_attribute = dce110_set_cursor_attribute,
|
||||
.set_backlight_level = dce110_set_backlight_level,
|
||||
.set_abm_immediate_disable = dce110_set_abm_immediate_disable,
|
||||
};
|
||||
|
||||
static const struct hwseq_private_funcs dce110_private_funcs = {
|
||||
|
@@ -88,6 +88,7 @@ void dce110_edp_wait_for_hpd_ready(
|
||||
bool dce110_set_backlight_level(struct pipe_ctx *pipe_ctx,
|
||||
uint32_t backlight_pwm_u16_16,
|
||||
uint32_t frame_ramp);
|
||||
void dce110_set_abm_immediate_disable(struct pipe_ctx *pipe_ctx);
|
||||
|
||||
#endif /* __DC_HWSS_DCE110_H__ */
|
||||
|
||||
|
@@ -134,13 +134,6 @@ bool dpp1_get_optimal_number_of_taps(
|
||||
struct scaler_data *scl_data,
|
||||
const struct scaling_taps *in_taps)
|
||||
{
|
||||
uint32_t pixel_width;
|
||||
|
||||
if (scl_data->viewport.width > scl_data->recout.width)
|
||||
pixel_width = scl_data->recout.width;
|
||||
else
|
||||
pixel_width = scl_data->viewport.width;
|
||||
|
||||
/* Some ASICs does not support FP16 scaling, so we reject modes require this*/
|
||||
if (scl_data->format == PIXEL_FORMAT_FP16 &&
|
||||
dpp->caps->dscl_data_proc_format == DSCL_DATA_PRCESSING_FIXED_FORMAT &&
|
||||
|
@@ -826,6 +826,14 @@ enum dc_status dcn10_enable_stream_timing(
|
||||
color_space = stream->output_color_space;
|
||||
color_space_to_black_color(dc, color_space, &black_color);
|
||||
|
||||
/*
|
||||
* The way 420 is packed, 2 channels carry Y component, 1 channel
|
||||
* alternate between Cb and Cr, so both channels need the pixel
|
||||
* value for Y
|
||||
*/
|
||||
if (stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420)
|
||||
black_color.color_r_cr = black_color.color_g_y;
|
||||
|
||||
if (pipe_ctx->stream_res.tg->funcs->set_blank_color)
|
||||
pipe_ctx->stream_res.tg->funcs->set_blank_color(
|
||||
pipe_ctx->stream_res.tg,
|
||||
@@ -903,8 +911,7 @@ static void dcn10_reset_back_end_for_pipe(
|
||||
if (pipe_ctx->top_pipe == NULL) {
|
||||
|
||||
if (pipe_ctx->stream_res.abm)
|
||||
pipe_ctx->stream_res.abm->funcs->set_abm_immediate_disable(pipe_ctx->stream_res.abm,
|
||||
pipe_ctx->stream->link->panel_cntl->inst);
|
||||
dc->hwss.set_abm_immediate_disable(pipe_ctx);
|
||||
|
||||
pipe_ctx->stream_res.tg->funcs->disable_crtc(pipe_ctx->stream_res.tg);
|
||||
|
||||
@@ -1245,6 +1252,7 @@ void dcn10_init_hw(struct dc *dc)
|
||||
struct dce_hwseq *hws = dc->hwseq;
|
||||
struct dc_bios *dcb = dc->ctx->dc_bios;
|
||||
struct resource_pool *res_pool = dc->res_pool;
|
||||
uint32_t backlight = MAX_BACKLIGHT_LEVEL;
|
||||
|
||||
if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)
|
||||
dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
|
||||
@@ -1411,11 +1419,16 @@ void dcn10_init_hw(struct dc *dc)
|
||||
audio->funcs->hw_init(audio);
|
||||
}
|
||||
|
||||
if (abm != NULL) {
|
||||
abm->funcs->init_backlight(abm);
|
||||
abm->funcs->abm_init(abm);
|
||||
for (i = 0; i < dc->link_count; i++) {
|
||||
struct dc_link *link = dc->links[i];
|
||||
|
||||
if (link->panel_cntl)
|
||||
backlight = link->panel_cntl->funcs->hw_init(link->panel_cntl);
|
||||
}
|
||||
|
||||
if (abm != NULL)
|
||||
abm->funcs->abm_init(abm, backlight);
|
||||
|
||||
if (dmcu != NULL && !dmcu->auto_load_dmcu)
|
||||
dmcu->funcs->dmcu_init(dmcu);
|
||||
|
||||
@@ -2249,6 +2262,14 @@ void dcn10_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx)
|
||||
&blnd_cfg.black_color);
|
||||
}
|
||||
|
||||
/*
|
||||
* The way 420 is packed, 2 channels carry Y component, 1 channel
|
||||
* alternate between Cb and Cr, so both channels need the pixel
|
||||
* value for Y
|
||||
*/
|
||||
if (pipe_ctx->stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420)
|
||||
blnd_cfg.black_color.color_r_cr = blnd_cfg.black_color.color_g_y;
|
||||
|
||||
if (per_pixel_alpha)
|
||||
blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA;
|
||||
else
|
||||
@@ -2490,9 +2511,7 @@ void dcn10_blank_pixel_data(
|
||||
stream_res->abm->funcs->set_abm_level(stream_res->abm, stream->abm_level);
|
||||
}
|
||||
} else if (blank) {
|
||||
if (stream_res->abm)
|
||||
stream_res->abm->funcs->set_abm_immediate_disable(stream_res->abm,
|
||||
stream->link->panel_cntl->inst);
|
||||
dc->hwss.set_abm_immediate_disable(pipe_ctx);
|
||||
if (stream_res->tg->funcs->set_blank)
|
||||
stream_res->tg->funcs->set_blank(stream_res->tg, blank);
|
||||
}
|
||||
|
@@ -73,6 +73,7 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
|
||||
.get_clock = dcn10_get_clock,
|
||||
.get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync,
|
||||
.set_backlight_level = dce110_set_backlight_level,
|
||||
.set_abm_immediate_disable = dce110_set_abm_immediate_disable,
|
||||
};
|
||||
|
||||
static const struct hwseq_private_funcs dcn10_private_funcs = {
|
||||
|
@@ -1121,24 +1121,6 @@ static enum dc_status build_mapped_resource(
|
||||
{
|
||||
struct pipe_ctx *pipe_ctx = resource_get_head_pipe_for_stream(&context->res_ctx, stream);
|
||||
|
||||
/*TODO Seems unneeded anymore */
|
||||
/* if (old_context && resource_is_stream_unchanged(old_context, stream)) {
|
||||
if (stream != NULL && old_context->streams[i] != NULL) {
|
||||
todo: shouldn't have to copy missing parameter here
|
||||
resource_build_bit_depth_reduction_params(stream,
|
||||
&stream->bit_depth_params);
|
||||
stream->clamping.pixel_encoding =
|
||||
stream->timing.pixel_encoding;
|
||||
|
||||
resource_build_bit_depth_reduction_params(stream,
|
||||
&stream->bit_depth_params);
|
||||
build_clamping_params(stream);
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
if (!pipe_ctx)
|
||||
return DC_ERROR_UNEXPECTED;
|
||||
|
||||
|
@@ -1274,7 +1274,6 @@ static void enc1_se_audio_setup(
|
||||
{
|
||||
struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
|
||||
|
||||
uint32_t speakers = 0;
|
||||
uint32_t channels = 0;
|
||||
|
||||
ASSERT(audio_info);
|
||||
@@ -1282,7 +1281,6 @@ static void enc1_se_audio_setup(
|
||||
/* This should not happen.it does so we don't get BSOD*/
|
||||
return;
|
||||
|
||||
speakers = audio_info->flags.info.ALLSPEAKERS;
|
||||
channels = speakers_to_channels(audio_info->flags.speaker_flags).all;
|
||||
|
||||
/* setup the audio stream source select (audio -> dig mapping) */
|
||||
|
@@ -961,9 +961,7 @@ void dcn20_blank_pixel_data(
|
||||
width = width / odm_cnt;
|
||||
|
||||
if (blank) {
|
||||
if (stream_res->abm)
|
||||
stream_res->abm->funcs->set_abm_immediate_disable(stream_res->abm,
|
||||
stream->link->panel_cntl->inst);
|
||||
dc->hwss.set_abm_immediate_disable(pipe_ctx);
|
||||
|
||||
if (dc->debug.visual_confirm != VISUAL_CONFIRM_DISABLE) {
|
||||
test_pattern = CONTROLLER_DP_TEST_PATTERN_COLORSQUARES;
|
||||
@@ -2042,9 +2040,7 @@ static void dcn20_reset_back_end_for_pipe(
|
||||
*/
|
||||
if (pipe_ctx->top_pipe == NULL) {
|
||||
|
||||
if (pipe_ctx->stream_res.abm)
|
||||
pipe_ctx->stream_res.abm->funcs->set_abm_immediate_disable(pipe_ctx->stream_res.abm,
|
||||
pipe_ctx->stream->link->panel_cntl->inst);
|
||||
dc->hwss.set_abm_immediate_disable(pipe_ctx);
|
||||
|
||||
pipe_ctx->stream_res.tg->funcs->disable_crtc(pipe_ctx->stream_res.tg);
|
||||
|
||||
|
@@ -84,6 +84,7 @@ static const struct hw_sequencer_funcs dcn20_funcs = {
|
||||
.set_flip_control_gsl = dcn20_set_flip_control_gsl,
|
||||
.get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync,
|
||||
.set_backlight_level = dce110_set_backlight_level,
|
||||
.set_abm_immediate_disable = dce110_set_abm_immediate_disable,
|
||||
};
|
||||
|
||||
static const struct hwseq_private_funcs dcn20_private_funcs = {
|
||||
|
@@ -1653,24 +1653,6 @@ enum dc_status dcn20_build_mapped_resource(const struct dc *dc, struct dc_state
|
||||
enum dc_status status = DC_OK;
|
||||
struct pipe_ctx *pipe_ctx = resource_get_head_pipe_for_stream(&context->res_ctx, stream);
|
||||
|
||||
/*TODO Seems unneeded anymore */
|
||||
/* if (old_context && resource_is_stream_unchanged(old_context, stream)) {
|
||||
if (stream != NULL && old_context->streams[i] != NULL) {
|
||||
todo: shouldn't have to copy missing parameter here
|
||||
resource_build_bit_depth_reduction_params(stream,
|
||||
&stream->bit_depth_params);
|
||||
stream->clamping.pixel_encoding =
|
||||
stream->timing.pixel_encoding;
|
||||
|
||||
resource_build_bit_depth_reduction_params(stream,
|
||||
&stream->bit_depth_params);
|
||||
build_clamping_params(stream);
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
if (!pipe_ctx)
|
||||
return DC_ERROR_UNEXPECTED;
|
||||
|
||||
@@ -1940,7 +1922,7 @@ bool dcn20_split_stream_for_odm(
|
||||
return true;
|
||||
}
|
||||
|
||||
bool dcn20_split_stream_for_mpc(
|
||||
void dcn20_split_stream_for_mpc(
|
||||
struct resource_context *res_ctx,
|
||||
const struct resource_pool *pool,
|
||||
struct pipe_ctx *primary_pipe,
|
||||
@@ -1969,11 +1951,6 @@ bool dcn20_split_stream_for_mpc(
|
||||
secondary_pipe->top_pipe = primary_pipe;
|
||||
|
||||
ASSERT(primary_pipe->plane_state);
|
||||
if (!resource_build_scaling_params(primary_pipe) ||
|
||||
!resource_build_scaling_params(secondary_pipe))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void dcn20_populate_dml_writeback_from_context(
|
||||
@@ -2599,11 +2576,32 @@ static void dcn20_merge_pipes_for_validate(
|
||||
}
|
||||
}
|
||||
|
||||
int dcn20_find_previous_split_count(struct pipe_ctx *pipe)
|
||||
{
|
||||
int previous_split = 1;
|
||||
struct pipe_ctx *current_pipe = pipe;
|
||||
|
||||
while (current_pipe->bottom_pipe) {
|
||||
if (current_pipe->plane_state != current_pipe->bottom_pipe->plane_state)
|
||||
break;
|
||||
previous_split++;
|
||||
current_pipe = current_pipe->bottom_pipe;
|
||||
}
|
||||
current_pipe = pipe;
|
||||
while (current_pipe->top_pipe) {
|
||||
if (current_pipe->plane_state != current_pipe->top_pipe->plane_state)
|
||||
break;
|
||||
previous_split++;
|
||||
current_pipe = current_pipe->top_pipe;
|
||||
}
|
||||
return previous_split;
|
||||
}
|
||||
|
||||
int dcn20_validate_apply_pipe_split_flags(
|
||||
struct dc *dc,
|
||||
struct dc_state *context,
|
||||
int vlevel,
|
||||
bool *split,
|
||||
int *split,
|
||||
bool *merge)
|
||||
{
|
||||
int i, pipe_idx, vlevel_split;
|
||||
@@ -2658,8 +2656,14 @@ int dcn20_validate_apply_pipe_split_flags(
|
||||
if (!context->res_ctx.pipe_ctx[i].stream)
|
||||
continue;
|
||||
|
||||
if (force_split || context->bw_ctx.dml.vba.NoOfDPP[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_plane] > 1)
|
||||
split[i] = true;
|
||||
if (force_split
|
||||
|| context->bw_ctx.dml.vba.NoOfDPP[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_plane] > 1) {
|
||||
if (context->stream_count == 1 && plane_count == 1
|
||||
&& dc->config.enable_4to1MPC && dc->res_pool->pipe_count >= 4)
|
||||
split[i] = 4;
|
||||
else
|
||||
split[i] = 2;
|
||||
}
|
||||
if ((pipe->stream->view_format ==
|
||||
VIEW_3D_FORMAT_SIDE_BY_SIDE ||
|
||||
pipe->stream->view_format ==
|
||||
@@ -2668,9 +2672,9 @@ int dcn20_validate_apply_pipe_split_flags(
|
||||
TIMING_3D_FORMAT_TOP_AND_BOTTOM ||
|
||||
pipe->stream->timing.timing_3d_format ==
|
||||
TIMING_3D_FORMAT_SIDE_BY_SIDE))
|
||||
split[i] = true;
|
||||
split[i] = 2;
|
||||
if (dc->debug.force_odm_combine & (1 << pipe->stream_res.tg->inst)) {
|
||||
split[i] = true;
|
||||
split[i] = 2;
|
||||
context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel][pipe_plane] = dm_odm_combine_mode_2to1;
|
||||
}
|
||||
context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_plane] =
|
||||
@@ -2678,39 +2682,58 @@ int dcn20_validate_apply_pipe_split_flags(
|
||||
|
||||
if (pipe->prev_odm_pipe && context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_plane] != dm_odm_combine_mode_disabled) {
|
||||
/*Already split odm pipe tree, don't try to split again*/
|
||||
split[i] = false;
|
||||
split[pipe->prev_odm_pipe->pipe_idx] = false;
|
||||
split[i] = 0;
|
||||
split[pipe->prev_odm_pipe->pipe_idx] = 0;
|
||||
} else if (pipe->top_pipe && pipe->plane_state == pipe->top_pipe->plane_state
|
||||
&& context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_plane] == dm_odm_combine_mode_disabled) {
|
||||
/*Already split mpc tree, don't try to split again, assumes only 2x mpc combine*/
|
||||
split[i] = false;
|
||||
split[pipe->top_pipe->pipe_idx] = false;
|
||||
} else if (pipe->prev_odm_pipe || (pipe->top_pipe && pipe->plane_state == pipe->top_pipe->plane_state)) {
|
||||
if (split[i] == false) {
|
||||
/*If 2 way split but can support 4 way split, then split each pipe again*/
|
||||
if (context->stream_count == 1 && plane_count == 1
|
||||
&& dc->config.enable_4to1MPC && dc->res_pool->pipe_count >= 4) {
|
||||
split[i] = 2;
|
||||
} else {
|
||||
split[i] = 0;
|
||||
split[pipe->top_pipe->pipe_idx] = 0;
|
||||
}
|
||||
} else if (pipe->prev_odm_pipe || (dcn20_find_previous_split_count(pipe) == 2 && pipe->top_pipe)) {
|
||||
if (split[i] == 0) {
|
||||
/*Exiting mpc/odm combine*/
|
||||
merge[i] = true;
|
||||
if (pipe->prev_odm_pipe) {
|
||||
ASSERT(0); /*should not actually happen yet*/
|
||||
merge[pipe->prev_odm_pipe->pipe_idx] = true;
|
||||
} else
|
||||
merge[pipe->top_pipe->pipe_idx] = true;
|
||||
} else {
|
||||
/*Transition from mpc combine to odm combine or vice versa*/
|
||||
ASSERT(0); /*should not actually happen yet*/
|
||||
split[i] = true;
|
||||
split[i] = 2;
|
||||
merge[i] = true;
|
||||
if (pipe->prev_odm_pipe) {
|
||||
split[pipe->prev_odm_pipe->pipe_idx] = true;
|
||||
split[pipe->prev_odm_pipe->pipe_idx] = 2;
|
||||
merge[pipe->prev_odm_pipe->pipe_idx] = true;
|
||||
} else {
|
||||
split[pipe->top_pipe->pipe_idx] = true;
|
||||
split[pipe->top_pipe->pipe_idx] = 2;
|
||||
merge[pipe->top_pipe->pipe_idx] = true;
|
||||
}
|
||||
}
|
||||
} else if (dcn20_find_previous_split_count(pipe) == 3) {
|
||||
if (split[i] == 0 && !pipe->top_pipe) {
|
||||
merge[pipe->bottom_pipe->pipe_idx] = true;
|
||||
merge[pipe->bottom_pipe->bottom_pipe->pipe_idx] = true;
|
||||
} else if (split[i] == 2 && !pipe->top_pipe) {
|
||||
merge[pipe->bottom_pipe->bottom_pipe->pipe_idx] = true;
|
||||
split[i] = 0;
|
||||
}
|
||||
} else if (dcn20_find_previous_split_count(pipe) == 4) {
|
||||
if (split[i] == 0 && !pipe->top_pipe) {
|
||||
merge[pipe->bottom_pipe->pipe_idx] = true;
|
||||
merge[pipe->bottom_pipe->bottom_pipe->pipe_idx] = true;
|
||||
merge[pipe->bottom_pipe->bottom_pipe->bottom_pipe->pipe_idx] = true;
|
||||
} else if (split[i] == 2 && !pipe->top_pipe) {
|
||||
merge[pipe->bottom_pipe->bottom_pipe->pipe_idx] = true;
|
||||
merge[pipe->bottom_pipe->bottom_pipe->bottom_pipe->pipe_idx] = true;
|
||||
split[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Adjust dppclk when split is forced, do not bother with dispclk */
|
||||
if (split[i] && context->bw_ctx.dml.vba.NoOfDPP[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx] == 1)
|
||||
if (split[i] != 0
|
||||
&& context->bw_ctx.dml.vba.NoOfDPP[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx] == 1)
|
||||
context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx] /= 2;
|
||||
pipe_idx++;
|
||||
}
|
||||
@@ -2727,7 +2750,7 @@ bool dcn20_fast_validate_bw(
|
||||
int *vlevel_out)
|
||||
{
|
||||
bool out = false;
|
||||
bool split[MAX_PIPES] = { false };
|
||||
int split[MAX_PIPES] = { 0 };
|
||||
int pipe_cnt, i, pipe_idx, vlevel;
|
||||
|
||||
ASSERT(pipes);
|
||||
@@ -2787,7 +2810,7 @@ bool dcn20_fast_validate_bw(
|
||||
&& context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_idx])
|
||||
goto validate_fail;
|
||||
|
||||
if (split[i]) {
|
||||
if (split[i] == 2) {
|
||||
if (!hsplit_pipe || hsplit_pipe->plane_state != pipe->plane_state) {
|
||||
/* pipe not split previously needs split */
|
||||
hsplit_pipe = dcn20_find_secondary_pipe(dc, &context->res_ctx, dc->res_pool, pipe);
|
||||
@@ -2802,11 +2825,13 @@ bool dcn20_fast_validate_bw(
|
||||
pipe, hsplit_pipe))
|
||||
goto validate_fail;
|
||||
dcn20_build_mapped_resource(dc, context, pipe->stream);
|
||||
} else
|
||||
if (!dcn20_split_stream_for_mpc(
|
||||
} else {
|
||||
dcn20_split_stream_for_mpc(
|
||||
&context->res_ctx, dc->res_pool,
|
||||
pipe, hsplit_pipe))
|
||||
pipe, hsplit_pipe);
|
||||
if (!resource_build_scaling_params(pipe) || !resource_build_scaling_params(hsplit_pipe))
|
||||
goto validate_fail;
|
||||
}
|
||||
pipe_split_from[hsplit_pipe->pipe_idx] = pipe_idx;
|
||||
}
|
||||
} else if (hsplit_pipe && hsplit_pipe->plane_state == pipe->plane_state) {
|
||||
@@ -3107,25 +3132,34 @@ validate_out:
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context,
|
||||
bool fast_validate)
|
||||
/*
|
||||
* This must be noinline to ensure anything that deals with FP registers
|
||||
* is contained within this call; previously our compiling with hard-float
|
||||
* would result in fp instructions being emitted outside of the boundaries
|
||||
* of the DC_FP_START/END macros, which makes sense as the compiler has no
|
||||
* idea about what is wrapped and what is not
|
||||
*
|
||||
* This is largely just a workaround to avoid breakage introduced with 5.6,
|
||||
* ideally all fp-using code should be moved into its own file, only that
|
||||
* should be compiled with hard-float, and all code exported from there
|
||||
* should be strictly wrapped with DC_FP_START/END
|
||||
*/
|
||||
static noinline bool dcn20_validate_bandwidth_fp(struct dc *dc,
|
||||
struct dc_state *context, bool fast_validate)
|
||||
{
|
||||
bool voltage_supported = false;
|
||||
bool full_pstate_supported = false;
|
||||
bool dummy_pstate_supported = false;
|
||||
double p_state_latency_us;
|
||||
|
||||
DC_FP_START();
|
||||
p_state_latency_us = context->bw_ctx.dml.soc.dram_clock_change_latency_us;
|
||||
context->bw_ctx.dml.soc.disable_dram_clock_change_vactive_support =
|
||||
dc->debug.disable_dram_clock_change_vactive_support;
|
||||
context->bw_ctx.dml.soc.allow_dram_clock_one_display_vactive =
|
||||
dc->debug.enable_dram_clock_change_one_display_vactive;
|
||||
|
||||
if (fast_validate) {
|
||||
voltage_supported = dcn20_validate_bandwidth_internal(dc, context, true);
|
||||
|
||||
DC_FP_END();
|
||||
return voltage_supported;
|
||||
return dcn20_validate_bandwidth_internal(dc, context, true);
|
||||
}
|
||||
|
||||
// Best case, we support full UCLK switch latency
|
||||
@@ -3154,7 +3188,15 @@ bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context,
|
||||
|
||||
restore_dml_state:
|
||||
context->bw_ctx.dml.soc.dram_clock_change_latency_us = p_state_latency_us;
|
||||
return voltage_supported;
|
||||
}
|
||||
|
||||
bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context,
|
||||
bool fast_validate)
|
||||
{
|
||||
bool voltage_supported = false;
|
||||
DC_FP_START();
|
||||
voltage_supported = dcn20_validate_bandwidth_fp(dc, context, fast_validate);
|
||||
DC_FP_END();
|
||||
return voltage_supported;
|
||||
}
|
||||
@@ -3213,8 +3255,6 @@ static struct dc_cap_funcs cap_funcs = {
|
||||
|
||||
enum dc_status dcn20_patch_unknown_plane_state(struct dc_plane_state *plane_state)
|
||||
{
|
||||
enum dc_status result = DC_OK;
|
||||
|
||||
enum surface_pixel_format surf_pix_format = plane_state->format;
|
||||
unsigned int bpp = resource_pixel_format_to_bpp(surf_pix_format);
|
||||
|
||||
@@ -3226,7 +3266,7 @@ enum dc_status dcn20_patch_unknown_plane_state(struct dc_plane_state *plane_stat
|
||||
swizzle = DC_SW_64KB_S;
|
||||
|
||||
plane_state->tiling_info.gfx9.swizzle = swizzle;
|
||||
return result;
|
||||
return DC_OK;
|
||||
}
|
||||
|
||||
static struct resource_funcs dcn20_res_pool_funcs = {
|
||||
|
@@ -119,17 +119,18 @@ void dcn20_set_mcif_arb_params(
|
||||
display_e2e_pipe_params_st *pipes,
|
||||
int pipe_cnt);
|
||||
bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context, bool fast_validate);
|
||||
int dcn20_find_previous_split_count(struct pipe_ctx *pipe);
|
||||
int dcn20_validate_apply_pipe_split_flags(
|
||||
struct dc *dc,
|
||||
struct dc_state *context,
|
||||
int vlevel,
|
||||
bool *split,
|
||||
int *split,
|
||||
bool *merge);
|
||||
void dcn20_release_dsc(struct resource_context *res_ctx,
|
||||
const struct resource_pool *pool,
|
||||
struct display_stream_compressor **dsc);
|
||||
bool dcn20_validate_dsc(struct dc *dc, struct dc_state *new_ctx);
|
||||
bool dcn20_split_stream_for_mpc(
|
||||
void dcn20_split_stream_for_mpc(
|
||||
struct resource_context *res_ctx,
|
||||
const struct resource_pool *pool,
|
||||
struct pipe_ctx *primary_pipe,
|
||||
|
@@ -86,13 +86,9 @@ static const struct hw_sequencer_funcs dcn21_funcs = {
|
||||
.optimize_pwr_state = dcn21_optimize_pwr_state,
|
||||
.exit_optimized_pwr_state = dcn21_exit_optimized_pwr_state,
|
||||
.get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync,
|
||||
.set_cursor_position = dcn10_set_cursor_position,
|
||||
.set_cursor_attribute = dcn10_set_cursor_attribute,
|
||||
.set_cursor_sdr_white_level = dcn10_set_cursor_sdr_white_level,
|
||||
.optimize_pwr_state = dcn21_optimize_pwr_state,
|
||||
.exit_optimized_pwr_state = dcn21_exit_optimized_pwr_state,
|
||||
.power_down = dce110_power_down,
|
||||
.set_backlight_level = dce110_set_backlight_level,
|
||||
.set_abm_immediate_disable = dce110_set_abm_immediate_disable,
|
||||
};
|
||||
|
||||
static const struct hwseq_private_funcs dcn21_private_funcs = {
|
||||
|
@@ -1384,7 +1384,8 @@ static void update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_param
|
||||
struct dcn21_resource_pool *pool = TO_DCN21_RES_POOL(dc->res_pool);
|
||||
struct clk_limit_table *clk_table = &bw_params->clk_table;
|
||||
struct _vcs_dpi_voltage_scaling_st clock_limits[DC__VOLTAGE_STATES];
|
||||
unsigned int i, j, closest_clk_lvl;
|
||||
unsigned int i, closest_clk_lvl;
|
||||
int j;
|
||||
|
||||
// Default clock levels are used for diags, which may lead to overclocking.
|
||||
if (!IS_DIAG_DC(dc->ctx->dce_environment)) {
|
||||
|
@@ -2599,18 +2599,40 @@ static void dml20v2_DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndP
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
float SecondMinActiveDRAMClockChangeMarginOneDisplayInVBLank = 999999;
|
||||
int PlaneWithMinActiveDRAMClockChangeMargin = -1;
|
||||
|
||||
mode_lib->vba.MinActiveDRAMClockChangeMargin = 999999;
|
||||
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
|
||||
if (mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k]
|
||||
< mode_lib->vba.MinActiveDRAMClockChangeMargin) {
|
||||
mode_lib->vba.MinActiveDRAMClockChangeMargin =
|
||||
mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k];
|
||||
if (mode_lib->vba.BlendingAndTiming[k] == k) {
|
||||
PlaneWithMinActiveDRAMClockChangeMargin = k;
|
||||
} else {
|
||||
for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) {
|
||||
if (mode_lib->vba.BlendingAndTiming[k] == j) {
|
||||
PlaneWithMinActiveDRAMClockChangeMargin = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mode_lib->vba.MinActiveDRAMClockChangeLatencySupported =
|
||||
mode_lib->vba.MinActiveDRAMClockChangeMargin
|
||||
+ mode_lib->vba.DRAMClockChangeLatency;
|
||||
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
|
||||
if (!((k == PlaneWithMinActiveDRAMClockChangeMargin) && (mode_lib->vba.BlendingAndTiming[k] == k))
|
||||
&& !(mode_lib->vba.BlendingAndTiming[k] == PlaneWithMinActiveDRAMClockChangeMargin)
|
||||
&& mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k]
|
||||
< SecondMinActiveDRAMClockChangeMarginOneDisplayInVBLank) {
|
||||
SecondMinActiveDRAMClockChangeMarginOneDisplayInVBLank =
|
||||
mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k];
|
||||
}
|
||||
}
|
||||
|
||||
if (mode_lib->vba.DRAMClockChangeSupportsVActive &&
|
||||
mode_lib->vba.MinActiveDRAMClockChangeMargin > 60) {
|
||||
@@ -2629,7 +2651,11 @@ static void dml20v2_DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndP
|
||||
mode_lib->vba.MinActiveDRAMClockChangeMargin > 0) {
|
||||
mode_lib->vba.DRAMClockChangeSupport[0][0] = dm_dram_clock_change_vactive;
|
||||
} else {
|
||||
if (mode_lib->vba.SynchronizedVBlank || mode_lib->vba.NumberOfActivePlanes == 1) {
|
||||
if ((mode_lib->vba.SynchronizedVBlank
|
||||
|| mode_lib->vba.NumberOfActivePlanes == 1
|
||||
|| (SecondMinActiveDRAMClockChangeMarginOneDisplayInVBLank > 0 &&
|
||||
mode_lib->vba.AllowDramClockChangeOneDisplayVactive))
|
||||
&& mode_lib->vba.PrefetchMode[mode_lib->vba.VoltageLevel][mode_lib->vba.maxMpcComb] == 0) {
|
||||
mode_lib->vba.DRAMClockChangeSupport[0][0] = dm_dram_clock_change_vblank;
|
||||
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
|
||||
if (!mode_lib->vba.AllowDRAMClockChangeDuringVBlank[k]) {
|
||||
@@ -2641,6 +2667,7 @@ static void dml20v2_DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndP
|
||||
mode_lib->vba.DRAMClockChangeSupport[0][0] = dm_dram_clock_change_unsupported;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (k = 0; k <= mode_lib->vba.soc.num_states; k++)
|
||||
for (j = 0; j < 2; j++)
|
||||
mode_lib->vba.DRAMClockChangeSupport[k][j] = mode_lib->vba.DRAMClockChangeSupport[0][0];
|
||||
|
@@ -3190,6 +3190,7 @@ static void CalculateFlipSchedule(
|
||||
double TimeForFetchingRowInVBlankImmediateFlip;
|
||||
double ImmediateFlipBW;
|
||||
double HostVMInefficiencyFactor;
|
||||
double VRatioClamped;
|
||||
|
||||
if (GPUVMEnable == true && HostVMEnable == true) {
|
||||
HostVMInefficiencyFactor =
|
||||
@@ -3222,31 +3223,32 @@ static void CalculateFlipSchedule(
|
||||
|
||||
*DestinationLinesToRequestRowInImmediateFlip = dml_ceil(4.0 * (TimeForFetchingRowInVBlankImmediateFlip / LineTime), 1) / 4.0;
|
||||
*final_flip_bw = dml_max(PDEAndMetaPTEBytesPerFrame * HostVMInefficiencyFactor / (*DestinationLinesToRequestVMInImmediateFlip * LineTime), (MetaRowBytes + DPTEBytesPerRow) * HostVMInefficiencyFactor / (*DestinationLinesToRequestRowInImmediateFlip * LineTime));
|
||||
VRatioClamped = (VRatio < 1.0) ? 1.0 : VRatio;
|
||||
if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10) {
|
||||
if (GPUVMEnable == true && DCCEnable != true) {
|
||||
min_row_time = dml_min(
|
||||
dpte_row_height * LineTime / VRatio,
|
||||
dpte_row_height_chroma * LineTime / (VRatio / 2));
|
||||
dpte_row_height * LineTime / VRatioClamped,
|
||||
dpte_row_height_chroma * LineTime / (VRatioClamped / 2));
|
||||
} else if (GPUVMEnable != true && DCCEnable == true) {
|
||||
min_row_time = dml_min(
|
||||
meta_row_height * LineTime / VRatio,
|
||||
meta_row_height_chroma * LineTime / (VRatio / 2));
|
||||
meta_row_height * LineTime / VRatioClamped,
|
||||
meta_row_height_chroma * LineTime / (VRatioClamped / 2));
|
||||
} else {
|
||||
min_row_time = dml_min4(
|
||||
dpte_row_height * LineTime / VRatio,
|
||||
meta_row_height * LineTime / VRatio,
|
||||
dpte_row_height_chroma * LineTime / (VRatio / 2),
|
||||
meta_row_height_chroma * LineTime / (VRatio / 2));
|
||||
dpte_row_height * LineTime / VRatioClamped,
|
||||
meta_row_height * LineTime / VRatioClamped,
|
||||
dpte_row_height_chroma * LineTime / (VRatioClamped / 2),
|
||||
meta_row_height_chroma * LineTime / (VRatioClamped / 2));
|
||||
}
|
||||
} else {
|
||||
if (GPUVMEnable == true && DCCEnable != true) {
|
||||
min_row_time = dpte_row_height * LineTime / VRatio;
|
||||
min_row_time = dpte_row_height * LineTime / VRatioClamped;
|
||||
} else if (GPUVMEnable != true && DCCEnable == true) {
|
||||
min_row_time = meta_row_height * LineTime / VRatio;
|
||||
min_row_time = meta_row_height * LineTime / VRatioClamped;
|
||||
} else {
|
||||
min_row_time = dml_min(
|
||||
dpte_row_height * LineTime / VRatio,
|
||||
meta_row_height * LineTime / VRatio);
|
||||
dpte_row_height * LineTime / VRatioClamped,
|
||||
meta_row_height * LineTime / VRatioClamped);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1200,7 +1200,7 @@ static void dml_rq_dlg_get_dlg_params(
|
||||
min_hratio_fact_l = 1.0;
|
||||
min_hratio_fact_c = 1.0;
|
||||
|
||||
if (htaps_l <= 1)
|
||||
if (hratio_l <= 1)
|
||||
min_hratio_fact_l = 2.0;
|
||||
else if (htaps_l <= 6) {
|
||||
if ((hratio_l * 2.0) > 4.0)
|
||||
@@ -1216,7 +1216,7 @@ static void dml_rq_dlg_get_dlg_params(
|
||||
|
||||
hscale_pixel_rate_l = min_hratio_fact_l * dppclk_freq_in_mhz;
|
||||
|
||||
if (htaps_c <= 1)
|
||||
if (hratio_c <= 1)
|
||||
min_hratio_fact_c = 2.0;
|
||||
else if (htaps_c <= 6) {
|
||||
if ((hratio_c * 2.0) > 4.0)
|
||||
@@ -1533,8 +1533,8 @@ static void dml_rq_dlg_get_dlg_params(
|
||||
|
||||
disp_dlg_regs->refcyc_per_vm_group_vblank = get_refcyc_per_vm_group_vblank(mode_lib, e2e_pipe_param, num_pipes, pipe_idx) * refclk_freq_in_mhz;
|
||||
disp_dlg_regs->refcyc_per_vm_group_flip = get_refcyc_per_vm_group_flip(mode_lib, e2e_pipe_param, num_pipes, pipe_idx) * refclk_freq_in_mhz;
|
||||
disp_dlg_regs->refcyc_per_vm_req_vblank = get_refcyc_per_vm_req_vblank(mode_lib, e2e_pipe_param, num_pipes, pipe_idx) * refclk_freq_in_mhz;
|
||||
disp_dlg_regs->refcyc_per_vm_req_flip = get_refcyc_per_vm_req_flip(mode_lib, e2e_pipe_param, num_pipes, pipe_idx) * refclk_freq_in_mhz;
|
||||
disp_dlg_regs->refcyc_per_vm_req_vblank = get_refcyc_per_vm_req_vblank(mode_lib, e2e_pipe_param, num_pipes, pipe_idx) * refclk_freq_in_mhz * dml_pow(2, 10);
|
||||
disp_dlg_regs->refcyc_per_vm_req_flip = get_refcyc_per_vm_req_flip(mode_lib, e2e_pipe_param, num_pipes, pipe_idx) * refclk_freq_in_mhz * dml_pow(2, 10);
|
||||
|
||||
// Clamp to max for now
|
||||
if (disp_dlg_regs->refcyc_per_vm_group_vblank >= (unsigned int)dml_pow(2, 23))
|
||||
|
@@ -118,6 +118,7 @@ struct _vcs_dpi_soc_bounding_box_st {
|
||||
double urgent_latency_adjustment_fabric_clock_component_us;
|
||||
double urgent_latency_adjustment_fabric_clock_reference_mhz;
|
||||
bool disable_dram_clock_change_vactive_support;
|
||||
bool allow_dram_clock_one_display_vactive;
|
||||
};
|
||||
|
||||
struct _vcs_dpi_ip_params_st {
|
||||
|
@@ -224,6 +224,7 @@ static void fetch_socbb_params(struct display_mode_lib *mode_lib)
|
||||
mode_lib->vba.DummyPStateCheck = soc->dram_clock_change_latency_us == soc->dummy_pstate_latency_us;
|
||||
mode_lib->vba.DRAMClockChangeSupportsVActive = !soc->disable_dram_clock_change_vactive_support ||
|
||||
mode_lib->vba.DummyPStateCheck;
|
||||
mode_lib->vba.AllowDramClockChangeOneDisplayVactive = soc->allow_dram_clock_one_display_vactive;
|
||||
|
||||
mode_lib->vba.Downspreading = soc->downspread_percent;
|
||||
mode_lib->vba.DRAMChannelWidth = soc->dram_channel_width_bytes; // new!
|
||||
|
@@ -899,6 +899,7 @@ struct vba_vars_st {
|
||||
double BPP;
|
||||
enum odm_combine_policy ODMCombinePolicy;
|
||||
bool UseMinimumRequiredDCFCLK;
|
||||
bool AllowDramClockChangeOneDisplayVactive;
|
||||
};
|
||||
|
||||
bool CalculateMinAndMaxPrefetchMode(
|
||||
|
@@ -27,27 +27,17 @@
|
||||
|
||||
#include "dm_services_types.h"
|
||||
|
||||
struct abm_backlight_registers {
|
||||
unsigned int BL_PWM_CNTL;
|
||||
unsigned int BL_PWM_CNTL2;
|
||||
unsigned int BL_PWM_PERIOD_CNTL;
|
||||
unsigned int LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV;
|
||||
};
|
||||
|
||||
struct abm {
|
||||
struct dc_context *ctx;
|
||||
const struct abm_funcs *funcs;
|
||||
bool dmcu_is_running;
|
||||
/* registers setting needs to be saved and restored at InitBacklight */
|
||||
struct abm_backlight_registers stored_backlight_registers;
|
||||
};
|
||||
|
||||
struct abm_funcs {
|
||||
void (*abm_init)(struct abm *abm);
|
||||
void (*abm_init)(struct abm *abm, uint32_t back_light);
|
||||
bool (*set_abm_level)(struct abm *abm, unsigned int abm_level);
|
||||
bool (*set_abm_immediate_disable)(struct abm *abm, unsigned int panel_inst);
|
||||
bool (*set_pipe)(struct abm *abm, unsigned int controller_id, unsigned int panel_inst);
|
||||
bool (*init_backlight)(struct abm *abm);
|
||||
|
||||
/* backlight_pwm_u16_16 is unsigned 32 bit,
|
||||
* 16 bit integer + 16 fractional, where 1.0 is max backlight value.
|
||||
@@ -56,8 +46,7 @@ struct abm_funcs {
|
||||
unsigned int backlight_pwm_u16_16,
|
||||
unsigned int frame_ramp,
|
||||
unsigned int controller_id,
|
||||
unsigned int panel_inst,
|
||||
bool fw_set_brightness);
|
||||
unsigned int panel_inst);
|
||||
|
||||
unsigned int (*get_current_backlight)(struct abm *abm);
|
||||
unsigned int (*get_target_backlight)(struct abm *abm);
|
||||
|
@@ -32,11 +32,23 @@
|
||||
|
||||
#include "dc_types.h"
|
||||
|
||||
#define MAX_BACKLIGHT_LEVEL 0xFFFF
|
||||
|
||||
struct panel_cntl_backlight_registers {
|
||||
unsigned int BL_PWM_CNTL;
|
||||
unsigned int BL_PWM_CNTL2;
|
||||
unsigned int BL_PWM_PERIOD_CNTL;
|
||||
unsigned int LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV;
|
||||
};
|
||||
|
||||
struct panel_cntl_funcs {
|
||||
void (*destroy)(struct panel_cntl **panel_cntl);
|
||||
void (*hw_init)(struct panel_cntl *panel_cntl);
|
||||
uint32_t (*hw_init)(struct panel_cntl *panel_cntl);
|
||||
bool (*is_panel_backlight_on)(struct panel_cntl *panel_cntl);
|
||||
bool (*is_panel_powered_on)(struct panel_cntl *panel_cntl);
|
||||
void (*store_backlight_level)(struct panel_cntl *panel_cntl);
|
||||
void (*driver_set_backlight)(struct panel_cntl *panel_cntl,
|
||||
uint32_t backlight_pwm_u16_16);
|
||||
};
|
||||
|
||||
struct panel_cntl_init_data {
|
||||
@@ -48,6 +60,8 @@ struct panel_cntl {
|
||||
const struct panel_cntl_funcs *funcs;
|
||||
struct dc_context *ctx;
|
||||
uint32_t inst;
|
||||
/* registers setting needs to be saved and restored at InitBacklight */
|
||||
struct panel_cntl_backlight_registers stored_backlight_registers;
|
||||
};
|
||||
|
||||
#endif /* DC_PANEL_CNTL_H_ */
|
||||
|
@@ -196,6 +196,8 @@ struct hw_sequencer_funcs {
|
||||
uint32_t backlight_pwm_u16_16,
|
||||
uint32_t frame_ramp);
|
||||
|
||||
void (*set_abm_immediate_disable)(struct pipe_ctx *pipe_ctx);
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
@@ -138,9 +138,6 @@ struct pipe_ctx *find_idle_secondary_pipe(
|
||||
const struct resource_pool *pool,
|
||||
const struct pipe_ctx *primary_pipe);
|
||||
|
||||
bool resource_is_stream_unchanged(
|
||||
struct dc_state *old_context, struct dc_stream_state *stream);
|
||||
|
||||
bool resource_validate_attach_surfaces(
|
||||
const struct dc_validation_set set[],
|
||||
int set_count,
|
||||
|
@@ -108,7 +108,7 @@
|
||||
#define ASSERT(expr) ASSERT_CRITICAL(expr)
|
||||
|
||||
#else
|
||||
#define ASSERT(expr) WARN_ON(!(expr))
|
||||
#define ASSERT(expr) WARN_ON_ONCE(!(expr))
|
||||
#endif
|
||||
|
||||
#define BREAK_TO_DEBUGGER() ASSERT(0)
|
||||
|
Reference in New Issue
Block a user