drm/amd/display: DMCU Compile and Load

Signed-off-by: Anthony Koo <anthony.koo@amd.com>
Reviewed-by: Aric Cyr <Aric.Cyr@amd.com>
Acked-by: Harry Wentland <Harry.Wentland@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Anthony Koo 2017-01-23 16:55:20 -05:00 committed by Alex Deucher
parent bb9042da8e
commit 5e7773a219
16 changed files with 788 additions and 70 deletions

View File

@ -268,19 +268,6 @@ static bool init_dmcu_backlight_settings(struct dc *dc)
return true;
}
static bool set_abm_level(struct dc *dc, unsigned int abm_level)
{
struct core_dc *core_dc = DC_TO_CORE(dc);
int i;
for (i = 0; i < core_dc->link_count; i++)
dc_link_set_abm_level(&core_dc->links[i]->public,
abm_level);
return true;
}
static bool set_psr_enable(struct dc *dc, bool enable)
{
struct core_dc *core_dc = DC_TO_CORE(dc);
@ -409,9 +396,6 @@ static void allocate_dc_stream_funcs(struct core_dc *core_dc)
core_dc->public.stream_funcs.init_dmcu_backlight_settings =
init_dmcu_backlight_settings;
core_dc->public.stream_funcs.set_abm_level =
set_abm_level;
core_dc->public.stream_funcs.set_psr_enable =
set_psr_enable;

View File

@ -1432,18 +1432,6 @@ bool dc_link_init_dmcu_backlight_settings(const struct dc_link *dc_link)
return true;
}
bool dc_link_set_abm_level(const struct dc_link *dc_link, uint32_t level)
{
struct core_link *link = DC_LINK_TO_CORE(dc_link);
struct dc_context *ctx = link->ctx;
dm_logger_write(ctx->logger, LOG_BACKLIGHT,
"New abm level: %d (0x%X)\n", level, level);
link->link_enc->funcs->set_dmcu_abm_level(link->link_enc, level);
return true;
}
bool dc_link_set_psr_enable(const struct dc_link *dc_link, bool enable)
{
struct core_link *link = DC_LINK_TO_CORE(dc_link);

View File

@ -103,7 +103,6 @@ struct dc_stream_funcs {
bool (*set_backlight)(struct dc *dc, unsigned int backlight_level,
unsigned int frame_ramp, const struct dc_stream *stream);
bool (*init_dmcu_backlight_settings)(struct dc *dc);
bool (*set_abm_level)(struct dc *dc, unsigned int abm_level);
bool (*set_psr_enable)(struct dc *dc, bool enable);
bool (*setup_psr)(struct dc *dc, const struct dc_stream *stream);
};
@ -575,8 +574,6 @@ bool dc_link_set_backlight_level(const struct dc_link *dc_link, uint32_t level,
bool dc_link_init_dmcu_backlight_settings(const struct dc_link *dc_link);
bool dc_link_set_abm_level(const struct dc_link *dc_link, uint32_t level);
bool dc_link_set_psr_enable(const struct dc_link *dc_link, bool enable);
bool dc_link_setup_psr(const struct dc_link *dc_link,
@ -730,4 +727,5 @@ bool dc_submit_i2c(
uint32_t link_index,
struct i2c_command *cmd);
#endif /* DC_INTERFACE_H_ */

View File

@ -7,7 +7,7 @@
DCE = dce_audio.o dce_stream_encoder.o dce_link_encoder.o dce_hwseq.o \
dce_mem_input.o dce_clock_source.o dce_scl_filters.o dce_transform.o \
dce_clocks.o dce_opp.o
dce_clocks.o dce_opp.o dce_dmcu.o dce_abm.o
AMD_DAL_DCE = $(addprefix $(AMDDALPATH)/dc/dce/,$(DCE))

View File

@ -0,0 +1,214 @@
/*
* Copyright 2012-16 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#include "dce_abm.h"
#include "dm_services.h"
#include "reg_helper.h"
#include "fixed32_32.h"
#include "dc.h"
#define TO_DCE_ABM(abm)\
container_of(abm, struct dce_abm, base)
#define REG(reg) \
(abm_dce->regs->reg)
#undef FN
#define FN(reg_name, field_name) \
abm_dce->abm_shift->field_name, abm_dce->abm_mask->field_name
#define CTX \
abm_dce->base.ctx
#define MCP_ABM_LEVEL_SET 0x65
static unsigned int get_current_backlight(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 /= 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);
}
void dce_abm_init(struct abm *abm)
{
struct dce_abm *abm_dce = TO_DCE_ABM(abm);
unsigned int backlight = get_current_backlight(abm_dce);
REG_WRITE(DC_ABM1_HG_SAMPLE_RATE, 0x103);
REG_WRITE(DC_ABM1_HG_SAMPLE_RATE, 0x101);
REG_WRITE(DC_ABM1_LS_SAMPLE_RATE, 0x103);
REG_WRITE(DC_ABM1_LS_SAMPLE_RATE, 0x101);
REG_WRITE(BL1_PWM_BL_UPDATE_SAMPLE_RATE, 0x101);
REG_SET_3(DC_ABM1_HG_MISC_CTRL, 0,
ABM1_HG_NUM_OF_BINS_SEL, 0,
ABM1_HG_VMAX_SEL, 1,
ABM1_HG_BIN_BITWIDTH_SIZE_SEL, 0);
REG_SET_3(DC_ABM1_IPCSC_COEFF_SEL, 0,
ABM1_IPCSC_COEFF_SEL_R, 2,
ABM1_IPCSC_COEFF_SEL_G, 4,
ABM1_IPCSC_COEFF_SEL_B, 2);
REG_UPDATE(BL1_PWM_CURRENT_ABM_LEVEL,
BL1_PWM_CURRENT_ABM_LEVEL, backlight);
REG_UPDATE(BL1_PWM_TARGET_ABM_LEVEL,
BL1_PWM_TARGET_ABM_LEVEL, backlight);
REG_UPDATE(BL1_PWM_USER_LEVEL,
BL1_PWM_USER_LEVEL, backlight);
REG_UPDATE_2(DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES,
ABM1_LS_MIN_PIXEL_VALUE_THRES, 0,
ABM1_LS_MAX_PIXEL_VALUE_THRES, 1000);
REG_SET_3(DC_ABM1_HGLS_REG_READ_PROGRESS, 0,
ABM1_HG_REG_READ_MISSED_FRAME_CLEAR, 1,
ABM1_LS_REG_READ_MISSED_FRAME_CLEAR, 1,
ABM1_BL_REG_READ_MISSED_FRAME_CLEAR, 1);
}
bool dce_abm_set_level(struct abm *abm, uint32_t level)
{
struct dce_abm *abm_dce = TO_DCE_ABM(abm);
struct dc_context *ctx = abm_dce->base.ctx;
unsigned int dmcu_max_retry_on_wait_reg_ready = 801;
unsigned int dmcu_wait_reg_ready_interval = 100;
unsigned int value;
/* waitDMCUReadyForCmd */
do {
dm_delay_in_microseconds(ctx, dmcu_wait_reg_ready_interval);
REG_GET(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, &value);
dmcu_max_retry_on_wait_reg_ready--;
} while
/* expected value is 0, loop while not 0*/
((value & abm_dce->abm_mask->MASTER_COMM_INTERRUPT) &&
dmcu_max_retry_on_wait_reg_ready > 0);
/* setDMCUParam_ABMLevel */
REG_UPDATE_2(MASTER_COMM_CMD_REG,
MASTER_COMM_CMD_REG_BYTE0, MCP_ABM_LEVEL_SET,
MASTER_COMM_CMD_REG_BYTE2, level);
/* notifyDMCUMsg */
REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);
return true;
}
static const struct abm_funcs dce_funcs = {
.abm_init = dce_abm_init,
.set_abm_level = dce_abm_set_level,
};
static void dce_abm_construct(
struct dce_abm *abm_dce,
struct dc_context *ctx,
const struct dce_abm_registers *regs,
const struct dce_abm_shift *abm_shift,
const struct dce_abm_mask *abm_mask)
{
struct abm *base = &abm_dce->base;
base->ctx = ctx;
base->funcs = &dce_funcs;
abm_dce->regs = regs;
abm_dce->abm_shift = abm_shift;
abm_dce->abm_mask = abm_mask;
}
struct abm *dce_abm_create(
struct dc_context *ctx,
const struct dce_abm_registers *regs,
const struct dce_abm_shift *abm_shift,
const struct dce_abm_mask *abm_mask)
{
struct dce_abm *abm_dce = dm_alloc(sizeof(*abm_dce));
if (abm_dce == NULL) {
BREAK_TO_DEBUGGER();
return NULL;
}
dce_abm_construct(abm_dce, ctx, regs, abm_shift, abm_mask);
abm_dce->base.funcs = &dce_funcs;
return &abm_dce->base;
}
void dce_abm_destroy(struct abm **abm)
{
struct dce_abm *abm_dce = TO_DCE_ABM(*abm);
dm_free(abm_dce);
*abm = NULL;
}

View File

@ -0,0 +1,157 @@
/*
* Copyright 2012-16 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#ifndef _DCE_ABM_H_
#define _DCE_ABM_H_
#include "abm.h"
#define ABM_COMMON_REG_LIST_DCE_BASE() \
SR(BL_PWM_PERIOD_CNTL), \
SR(BL_PWM_CNTL), \
SR(MASTER_COMM_CNTL_REG), \
SR(MASTER_COMM_CMD_REG)
#define ABM_DCE110_COMMON_REG_LIST() \
ABM_COMMON_REG_LIST_DCE_BASE(), \
SR(DC_ABM1_HG_SAMPLE_RATE), \
SR(DC_ABM1_LS_SAMPLE_RATE), \
SR(BL1_PWM_BL_UPDATE_SAMPLE_RATE), \
SR(DC_ABM1_HG_MISC_CTRL), \
SR(DC_ABM1_IPCSC_COEFF_SEL), \
SR(BL1_PWM_CURRENT_ABM_LEVEL), \
SR(BL1_PWM_TARGET_ABM_LEVEL), \
SR(BL1_PWM_USER_LEVEL), \
SR(DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES), \
SR(DC_ABM1_HGLS_REG_READ_PROGRESS)
#define ABM_SF(reg_name, field_name, post_fix)\
.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(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_BYTE2, mask_sh)
#define ABM_MASK_SH_LIST_DCE110(mask_sh) \
ABM_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(mask_sh), \
ABM_SF(DC_ABM1_HG_MISC_CTRL, \
ABM1_HG_NUM_OF_BINS_SEL, mask_sh), \
ABM_SF(DC_ABM1_HG_MISC_CTRL, \
ABM1_HG_VMAX_SEL, mask_sh), \
ABM_SF(DC_ABM1_HG_MISC_CTRL, \
ABM1_HG_BIN_BITWIDTH_SIZE_SEL, mask_sh), \
ABM_SF(DC_ABM1_IPCSC_COEFF_SEL, \
ABM1_IPCSC_COEFF_SEL_R, mask_sh), \
ABM_SF(DC_ABM1_IPCSC_COEFF_SEL, \
ABM1_IPCSC_COEFF_SEL_G, mask_sh), \
ABM_SF(DC_ABM1_IPCSC_COEFF_SEL, \
ABM1_IPCSC_COEFF_SEL_B, mask_sh), \
ABM_SF(BL1_PWM_CURRENT_ABM_LEVEL, \
BL1_PWM_CURRENT_ABM_LEVEL, mask_sh), \
ABM_SF(BL1_PWM_TARGET_ABM_LEVEL, \
BL1_PWM_TARGET_ABM_LEVEL, mask_sh), \
ABM_SF(BL1_PWM_USER_LEVEL, \
BL1_PWM_USER_LEVEL, mask_sh), \
ABM_SF(DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES, \
ABM1_LS_MIN_PIXEL_VALUE_THRES, mask_sh), \
ABM_SF(DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES, \
ABM1_LS_MAX_PIXEL_VALUE_THRES, mask_sh), \
ABM_SF(DC_ABM1_HGLS_REG_READ_PROGRESS, \
ABM1_HG_REG_READ_MISSED_FRAME_CLEAR, mask_sh), \
ABM_SF(DC_ABM1_HGLS_REG_READ_PROGRESS, \
ABM1_LS_REG_READ_MISSED_FRAME_CLEAR, mask_sh), \
ABM_SF(DC_ABM1_HGLS_REG_READ_PROGRESS, \
ABM1_BL_REG_READ_MISSED_FRAME_CLEAR, mask_sh)
#define ABM_REG_FIELD_LIST(type) \
type ABM1_HG_NUM_OF_BINS_SEL; \
type ABM1_HG_VMAX_SEL; \
type ABM1_HG_BIN_BITWIDTH_SIZE_SEL; \
type ABM1_IPCSC_COEFF_SEL_R; \
type ABM1_IPCSC_COEFF_SEL_G; \
type ABM1_IPCSC_COEFF_SEL_B; \
type BL1_PWM_CURRENT_ABM_LEVEL; \
type BL1_PWM_TARGET_ABM_LEVEL; \
type BL1_PWM_USER_LEVEL; \
type ABM1_LS_MIN_PIXEL_VALUE_THRES; \
type ABM1_LS_MAX_PIXEL_VALUE_THRES; \
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_BYTE2
struct dce_abm_shift {
ABM_REG_FIELD_LIST(uint8_t);
};
struct dce_abm_mask {
ABM_REG_FIELD_LIST(uint32_t);
};
struct dce_abm_registers {
uint32_t BL_PWM_PERIOD_CNTL;
uint32_t BL_PWM_CNTL;
uint32_t DC_ABM1_HG_SAMPLE_RATE;
uint32_t DC_ABM1_LS_SAMPLE_RATE;
uint32_t BL1_PWM_BL_UPDATE_SAMPLE_RATE;
uint32_t DC_ABM1_HG_MISC_CTRL;
uint32_t DC_ABM1_IPCSC_COEFF_SEL;
uint32_t BL1_PWM_CURRENT_ABM_LEVEL;
uint32_t BL1_PWM_TARGET_ABM_LEVEL;
uint32_t BL1_PWM_USER_LEVEL;
uint32_t DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES;
uint32_t DC_ABM1_HGLS_REG_READ_PROGRESS;
uint32_t MASTER_COMM_CNTL_REG;
uint32_t MASTER_COMM_CMD_REG;
};
struct dce_abm {
struct abm base;
const struct dce_abm_registers *regs;
const struct dce_abm_shift *abm_shift;
const struct dce_abm_mask *abm_mask;
};
struct abm *dce_abm_create(
struct dc_context *ctx,
const struct dce_abm_registers *regs,
const struct dce_abm_shift *abm_shift,
const struct dce_abm_mask *abm_mask);
void dce_abm_destroy(struct abm **abm);
#endif /* _DCE_ABM_H_ */

View File

@ -0,0 +1,127 @@
/*
* Copyright 2012-16 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#include "dce_dmcu.h"
#include "dm_services.h"
#include "reg_helper.h"
#include "fixed32_32.h"
#include "dc.h"
#define TO_DCE_DMCU(dmcu)\
container_of(dmcu, struct dce_dmcu, base)
#define REG(reg) \
(dmcu_dce->regs->reg)
#undef FN
#define FN(reg_name, field_name) \
dmcu_dce->dmcu_shift->field_name, dmcu_dce->dmcu_mask->field_name
#define CTX \
dmcu_dce->base.ctx
bool dce_dmcu_load_iram(struct dmcu *dmcu,
unsigned int start_offset,
const char *src,
unsigned int bytes)
{
struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);
unsigned int count = 0;
uint32_t status;
/* Enable write access to IRAM */
REG_UPDATE_2(DMCU_RAM_ACCESS_CTRL,
IRAM_HOST_ACCESS_EN, 1,
IRAM_WR_ADDR_AUTO_INC, 1);
do {
dm_delay_in_microseconds(dmcu->ctx, 2);
REG_GET(DCI_MEM_PWR_STATUS, DMCU_IRAM_MEM_PWR_STATE, &status);
count++;
} while
((status & dmcu_dce->dmcu_mask->DMCU_IRAM_MEM_PWR_STATE) && count < 10);
REG_WRITE(DMCU_IRAM_WR_CTRL, start_offset);
for (count = 0; count < bytes; count++)
REG_WRITE(DMCU_IRAM_WR_DATA, src[count]);
/* Disable write access to IRAM to allow dynamic sleep state */
REG_UPDATE_2(DMCU_RAM_ACCESS_CTRL,
IRAM_HOST_ACCESS_EN, 0,
IRAM_WR_ADDR_AUTO_INC, 0);
return true;
}
static const struct dmcu_funcs dce_funcs = {
.load_iram = dce_dmcu_load_iram,
};
static void dce_dmcu_construct(
struct dce_dmcu *dmcu_dce,
struct dc_context *ctx,
const struct dce_dmcu_registers *regs,
const struct dce_dmcu_shift *dmcu_shift,
const struct dce_dmcu_mask *dmcu_mask)
{
struct dmcu *base = &dmcu_dce->base;
base->ctx = ctx;
base->funcs = &dce_funcs;
dmcu_dce->regs = regs;
dmcu_dce->dmcu_shift = dmcu_shift;
dmcu_dce->dmcu_mask = dmcu_mask;
}
struct dmcu *dce_dmcu_create(
struct dc_context *ctx,
const struct dce_dmcu_registers *regs,
const struct dce_dmcu_shift *dmcu_shift,
const struct dce_dmcu_mask *dmcu_mask)
{
struct dce_dmcu *dmcu_dce = dm_alloc(sizeof(*dmcu_dce));
if (dmcu_dce == NULL) {
BREAK_TO_DEBUGGER();
return NULL;
}
dce_dmcu_construct(
dmcu_dce, ctx, regs, dmcu_shift, dmcu_mask);
dmcu_dce->base.funcs = &dce_funcs;
return &dmcu_dce->base;
}
void dce_dmcu_destroy(struct dmcu **dmcu)
{
struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(*dmcu);
dm_free(dmcu_dce);
*dmcu = NULL;
}

View File

@ -0,0 +1,91 @@
/*
* Copyright 2012-16 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#ifndef _DCE_DMCU_H_
#define _DCE_DMCU_H_
#include "dmcu.h"
#define DMCU_COMMON_REG_LIST_DCE_BASE() \
SR(DMCU_RAM_ACCESS_CTRL), \
SR(DMCU_IRAM_WR_CTRL), \
SR(DMCU_IRAM_WR_DATA)
#define DMCU_DCE110_COMMON_REG_LIST() \
DMCU_COMMON_REG_LIST_DCE_BASE(), \
SR(DCI_MEM_PWR_STATUS)
#define DMCU_SF(reg_name, field_name, post_fix)\
.field_name = reg_name ## __ ## field_name ## post_fix
#define DMCU_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(mask_sh) \
DMCU_SF(DMCU_RAM_ACCESS_CTRL, \
IRAM_HOST_ACCESS_EN, mask_sh), \
DMCU_SF(DMCU_RAM_ACCESS_CTRL, \
IRAM_WR_ADDR_AUTO_INC, mask_sh)
#define DMCU_MASK_SH_LIST_DCE110(mask_sh) \
DMCU_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(mask_sh), \
DMCU_SF(DCI_MEM_PWR_STATUS, \
DMCU_IRAM_MEM_PWR_STATE, mask_sh)
#define DMCU_REG_FIELD_LIST(type) \
type DMCU_IRAM_MEM_PWR_STATE; \
type IRAM_HOST_ACCESS_EN; \
type IRAM_WR_ADDR_AUTO_INC
struct dce_dmcu_shift {
DMCU_REG_FIELD_LIST(uint8_t);
};
struct dce_dmcu_mask {
DMCU_REG_FIELD_LIST(uint32_t);
};
struct dce_dmcu_registers {
uint32_t DMCU_RAM_ACCESS_CTRL;
uint32_t DCI_MEM_PWR_STATUS;
uint32_t DMU_MEM_PWR_CNTL;
uint32_t DMCU_IRAM_WR_CTRL;
uint32_t DMCU_IRAM_WR_DATA;
};
struct dce_dmcu {
struct dmcu base;
const struct dce_dmcu_registers *regs;
const struct dce_dmcu_shift *dmcu_shift;
const struct dce_dmcu_mask *dmcu_mask;
};
struct dmcu *dce_dmcu_create(
struct dc_context *ctx,
const struct dce_dmcu_registers *regs,
const struct dce_dmcu_shift *dmcu_shift,
const struct dce_dmcu_mask *dmcu_mask);
void dce_dmcu_destroy(struct dmcu **dmcu);
#endif /* _DCE_ABM_H_ */

View File

@ -142,7 +142,6 @@ static const struct link_encoder_funcs dce110_lnk_enc_funcs = {
dce110_link_encoder_set_dmcu_backlight_level,
.init_dmcu_backlight_settings =
dce110_link_encoder_init_dmcu_backlight_settings,
.set_dmcu_abm_level = dce110_link_encoder_set_dmcu_abm_level,
.set_dmcu_psr_enable = dce110_link_encoder_set_dmcu_psr_enable,
.setup_dmcu_psr = dce110_link_encoder_setup_dmcu_psr,
.backlight_control = dce110_link_encoder_edp_backlight_control,
@ -1769,8 +1768,7 @@ void dce110_link_encoder_init_dmcu_backlight_settings(
* 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);
REG_GET(BL_PWM_CNTL, BL_ACTIVE_INT_FRAC_CNT, &value);
if (value == 0 || bl_pwm_cntl == 1) {
if (stored_backlight_registers.vBL_PWM_CNTL != 0) {
pwmCntl = stored_backlight_registers.vBL_PWM_CNTL;
@ -1810,36 +1808,6 @@ void dce110_link_encoder_init_dmcu_backlight_settings(
/* Enable the backlight output */
REG_UPDATE(BL_PWM_CNTL, BL_PWM_EN, 1);
}
void dce110_link_encoder_set_dmcu_abm_level(
struct link_encoder *enc, uint32_t level)
{
struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
struct dc_context *ctx = enc110->base.ctx;
unsigned int dmcu_max_retry_on_wait_reg_ready = 801;
unsigned int dmcu_wait_reg_ready_interval = 100;
unsigned int regValue;
/* waitDMCUReadyForCmd */
do {
dm_delay_in_microseconds(ctx, dmcu_wait_reg_ready_interval);
regValue = REG_READ(MASTER_COMM_CNTL_REG);
dmcu_max_retry_on_wait_reg_ready--;
} while
/* expected value is 0, loop while not 0*/
((MASTER_COMM_CNTL_REG__MASTER_COMM_INTERRUPT_MASK & regValue) &&
dmcu_max_retry_on_wait_reg_ready > 0);
/* setDMCUParam_ABMLevel */
REG_UPDATE_2(MASTER_COMM_CMD_REG,
MASTER_COMM_CMD_REG_BYTE0, MCP_ABM_LEVEL_SET,
MASTER_COMM_CMD_REG_BYTE2, level);
/* notifyDMCUMsg */
REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);
}
static void get_dmcu_psr_state(struct link_encoder *enc, uint32_t *psr_state)
@ -1856,10 +1824,8 @@ static void get_dmcu_psr_state(struct link_encoder *enc, uint32_t *psr_state)
do {
dm_delay_in_microseconds(ctx, 2);
REG_GET(DCI_MEM_PWR_STATUS,
DMCU_IRAM_MEM_PWR_STATE, &value);
} while
(value != 0 && count++ < 10);
REG_GET(DCI_MEM_PWR_STATUS, DMCU_IRAM_MEM_PWR_STATE, &value);
} while (value != 0 && count++ < 10);
/* Write address to IRAM_RD_ADDR in DMCU_IRAM_RD_CTRL */
REG_WRITE(DMCU_IRAM_RD_CTRL, psrStateOffset);

View File

@ -42,6 +42,7 @@
#include "stream_encoder.h"
#include "link_encoder.h"
#include "clock_source.h"
#include "abm.h"
#include "audio.h"
#include "dce/dce_hwseq.h"
@ -2166,6 +2167,7 @@ static void init_hw(struct core_dc *dc)
int i;
struct dc_bios *bp;
struct transform *xfm;
struct abm *abm;
bp = dc->ctx->dc_bios;
for (i = 0; i < dc->res_pool->pipe_count; i++) {
@ -2210,6 +2212,10 @@ static void init_hw(struct core_dc *dc)
struct audio *audio = dc->res_pool->audios[i];
audio->funcs->hw_init(audio);
}
abm = dc->res_pool->abm;
if (abm != NULL)
abm->funcs->abm_init(abm);
}
/* TODO: move this to apply_ctx_tohw some how?*/

View File

@ -49,6 +49,8 @@
#include "dce/dce_clock_source.h"
#include "dce/dce_hwseq.h"
#include "dce110/dce110_hw_sequencer.h"
#include "dce/dce_abm.h"
#include "dce/dce_dmcu.h"
#include "reg_helper.h"
@ -200,6 +202,30 @@ static const struct dce_disp_clk_mask disp_clk_mask = {
CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK)
};
static const struct dce_dmcu_registers dmcu_regs = {
DMCU_DCE110_COMMON_REG_LIST()
};
static const struct dce_dmcu_shift dmcu_shift = {
DMCU_MASK_SH_LIST_DCE110(__SHIFT)
};
static const struct dce_dmcu_mask dmcu_mask = {
DMCU_MASK_SH_LIST_DCE110(_MASK)
};
static const struct dce_abm_registers abm_regs = {
ABM_DCE110_COMMON_REG_LIST()
};
static const struct dce_abm_shift abm_shift = {
ABM_MASK_SH_LIST_DCE110(__SHIFT)
};
static const struct dce_abm_mask abm_mask = {
ABM_MASK_SH_LIST_DCE110(_MASK)
};
#define transform_regs(id)\
[id] = {\
XFM_COMMON_REG_LIST_DCE110(id)\
@ -712,6 +738,12 @@ static void destruct(struct dce110_resource_pool *pool)
}
}
if (pool->base.abm != NULL)
dce_abm_destroy(&pool->base.abm);
if (pool->base.dmcu != NULL)
dce_dmcu_destroy(&pool->base.dmcu);
if (pool->base.display_clock != NULL)
dce_disp_clk_destroy(&pool->base.display_clock);
@ -1286,6 +1318,26 @@ static bool construct(
goto res_create_fail;
}
pool->base.dmcu = dce_dmcu_create(ctx,
&dmcu_regs,
&dmcu_shift,
&dmcu_mask);
if (pool->base.dmcu == NULL) {
dm_error("DC: failed to create dmcu!\n");
BREAK_TO_DEBUGGER();
goto res_create_fail;
}
pool->base.abm = dce_abm_create(ctx,
&abm_regs,
&abm_shift,
&abm_mask);
if (pool->base.abm == NULL) {
dm_error("DC: failed to create abm!\n");
BREAK_TO_DEBUGGER();
goto res_create_fail;
}
/* get static clock information for PPLIB or firmware, save
* max_clock_state
*/

View File

@ -46,6 +46,8 @@
#include "dce/dce_hwseq.h"
#include "dce112/dce112_hw_sequencer.h"
#include "dce/dce_abm.h"
#include "dce/dce_dmcu.h"
#include "reg_helper.h"
@ -218,6 +220,30 @@ static const struct dce_disp_clk_mask disp_clk_mask = {
CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK)
};
static const struct dce_dmcu_registers dmcu_regs = {
DMCU_DCE110_COMMON_REG_LIST()
};
static const struct dce_dmcu_shift dmcu_shift = {
DMCU_MASK_SH_LIST_DCE110(__SHIFT)
};
static const struct dce_dmcu_mask dmcu_mask = {
DMCU_MASK_SH_LIST_DCE110(_MASK)
};
static const struct dce_abm_registers abm_regs = {
ABM_DCE110_COMMON_REG_LIST()
};
static const struct dce_abm_shift abm_shift = {
ABM_MASK_SH_LIST_DCE110(__SHIFT)
};
static const struct dce_abm_mask abm_mask = {
ABM_MASK_SH_LIST_DCE110(_MASK)
};
#define transform_regs(id)\
[id] = {\
XFM_COMMON_REG_LIST_DCE110(id)\
@ -719,6 +745,12 @@ static void destruct(struct dce110_resource_pool *pool)
}
}
if (pool->base.abm != NULL)
dce_abm_destroy(&pool->base.abm);
if (pool->base.dmcu != NULL)
dce_dmcu_destroy(&pool->base.dmcu);
if (pool->base.display_clock != NULL)
dce_disp_clk_destroy(&pool->base.display_clock);
@ -1283,6 +1315,25 @@ static bool construct(
goto res_create_fail;
}
pool->base.dmcu = dce_dmcu_create(ctx,
&dmcu_regs,
&dmcu_shift,
&dmcu_mask);
if (pool->base.dmcu == NULL) {
dm_error("DC: failed to create dmcu!\n");
BREAK_TO_DEBUGGER();
goto res_create_fail;
}
pool->base.abm = dce_abm_create(ctx,
&abm_regs,
&abm_shift,
&abm_mask);
if (pool->base.abm == NULL) {
dm_error("DC: failed to create abm!\n");
BREAK_TO_DEBUGGER();
goto res_create_fail;
}
/* get static clock information for PPLIB or firmware, save
* max_clock_state

View File

@ -259,6 +259,9 @@ struct resource_pool {
struct display_clock *display_clock;
struct irq_service *irqs;
struct abm *abm;
struct dmcu *dmcu;
const struct resource_funcs *funcs;
const struct resource_caps *res_cap;
};

View File

@ -0,0 +1,40 @@
/* Copyright 2012-15 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#ifndef __DC_ABM_H__
#define __DC_ABM_H__
#include "dm_services_types.h"
struct abm {
struct dc_context *ctx;
const struct abm_funcs *funcs;
};
struct abm_funcs {
void (*abm_init)(struct abm *abm);
bool (*set_abm_level)(struct abm *abm, unsigned int abm_level);
};
#endif

View File

@ -0,0 +1,42 @@
/* Copyright 2012-15 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#ifndef __DC_DMCU_H__
#define __DC_DMCU_H__
#include "dm_services_types.h"
struct dmcu {
struct dc_context *ctx;
const struct dmcu_funcs *funcs;
};
struct dmcu_funcs {
bool (*load_iram)(struct dmcu *dmcu,
unsigned int start_offset,
const char *src,
unsigned int bytes);
};
#endif

View File

@ -225,7 +225,6 @@ struct link_encoder_funcs {
void (*set_dmcu_backlight_level)(struct link_encoder *enc,
uint32_t level, uint32_t frame_ramp, uint32_t controller_id);
void (*init_dmcu_backlight_settings)(struct link_encoder *enc);
void (*set_dmcu_abm_level)(struct link_encoder *enc, uint32_t level);
void (*set_dmcu_psr_enable)(struct link_encoder *enc, bool enable);
void (*setup_dmcu_psr)(struct link_encoder *enc,
struct psr_dmcu_context *psr_context);