static void dce110_tg_v_program_blank_color(struct timing_generator *tg, const struct tg_color *black_color) { uint32_t addr = mmCRTCV_BLACK_COLOR; uint32_t value = dm_read_reg(tg->ctx, addr); set_reg_field_value( value, black_color->color_b_cb, CRTCV_BLACK_COLOR, CRTC_BLACK_COLOR_B_CB); set_reg_field_value( value, black_color->color_g_y, CRTCV_BLACK_COLOR, CRTC_BLACK_COLOR_G_Y); set_reg_field_value( value, black_color->color_r_cr, CRTCV_BLACK_COLOR, CRTC_BLACK_COLOR_R_CR); dm_write_reg(tg->ctx, addr, value); addr = mmCRTCV_BLANK_DATA_COLOR; dm_write_reg(tg->ctx, addr, value); }
static bool dce110_timing_generator_v_enable_crtc(struct timing_generator *tg) { /* * Set MASTER_UPDATE_MODE to 0 * This is needed for DRR, and also suggested to be default value by Syed. */ uint32_t value; value = 0; set_reg_field_value(value, 0, CRTCV_MASTER_UPDATE_MODE, MASTER_UPDATE_MODE); dm_write_reg(tg->ctx, mmCRTCV_MASTER_UPDATE_MODE, value); /* TODO: may want this on for looking for underflow */ value = 0; dm_write_reg(tg->ctx, mmCRTCV_MASTER_UPDATE_MODE, value); value = 0; set_reg_field_value(value, 1, CRTCV_MASTER_EN, CRTC_MASTER_EN); dm_write_reg(tg->ctx, mmCRTCV_MASTER_EN, value); return true; }
/* set the payload value for the unsolicited response */ static void set_unsolicited_response_payload( const struct hw_ctx_audio *hw_ctx, enum audio_payload payload) { /* set the payload value for the unsolicited response Jack presence is not required to be enabled */ uint32_t value = 0; value = read_indirect_azalia_reg( hw_ctx, ixAZALIA_F0_CODEC_PIN_CONTROL_UNSOLICITED_RESPONSE_FORCE); set_reg_field_value(value, payload, AZALIA_F0_CODEC_PIN_CONTROL_UNSOLICITED_RESPONSE_FORCE, UNSOLICITED_RESPONSE_PAYLOAD); set_reg_field_value(value, 1, AZALIA_F0_CODEC_PIN_CONTROL_UNSOLICITED_RESPONSE_FORCE, UNSOLICITED_RESPONSE_FORCE); write_indirect_azalia_reg( hw_ctx, ixAZALIA_F0_CODEC_PIN_CONTROL_UNSOLICITED_RESPONSE_FORCE, value); }
static void enable_alpha( struct line_buffer *base, bool enable) { struct line_buffer_dce110 *lb = LB110_FROM_BASE(base); struct dal_context *dal_ctx = base->dal_context; uint32_t value; uint32_t addr = lb->lbx_data_format; value = dal_read_reg(dal_ctx, addr); if (enable == 1) set_reg_field_value( value, 1, LB_DATA_FORMAT, ALPHA_EN); else set_reg_field_value( value, 0, LB_DATA_FORMAT, ALPHA_EN); dal_write_reg(dal_ctx, addr, value); }
static void dce110_timing_generator_v_set_overscan_color(struct timing_generator *tg, const struct tg_color *overscan_color) { struct dc_context *ctx = tg->ctx; uint32_t value = 0; uint32_t addr; set_reg_field_value( value, overscan_color->color_b_cb, CRTCV_OVERSCAN_COLOR, CRTC_OVERSCAN_COLOR_BLUE); set_reg_field_value( value, overscan_color->color_g_y, CRTCV_OVERSCAN_COLOR, CRTC_OVERSCAN_COLOR_GREEN); set_reg_field_value( value, overscan_color->color_r_cr, CRTCV_OVERSCAN_COLOR, CRTC_OVERSCAN_COLOR_RED); addr = mmCRTCV_OVERSCAN_COLOR; dm_write_reg(ctx, addr, value); }
void dce110_opp_power_on_regamma_lut_v( struct transform *xfm, bool power_on) { uint32_t value = dm_read_reg(xfm->ctx, mmDCFEV_MEM_PWR_CTRL); set_reg_field_value( value, 0, DCFEV_MEM_PWR_CTRL, COL_MAN_GAMMA_CORR_MEM_PWR_FORCE); set_reg_field_value( value, power_on, DCFEV_MEM_PWR_CTRL, COL_MAN_GAMMA_CORR_MEM_PWR_DIS); set_reg_field_value( value, 0, DCFEV_MEM_PWR_CTRL, COL_MAN_INPUT_GAMMA_MEM_PWR_FORCE); set_reg_field_value( value, power_on, DCFEV_MEM_PWR_CTRL, COL_MAN_INPUT_GAMMA_MEM_PWR_DIS); dm_write_reg(xfm->ctx, mmDCFEV_MEM_PWR_CTRL, value); }
/** * Function: * void program_overscan * * Purpose: Programs overscan border * Input: overscan * * Output: void */ static void program_overscan( struct dce110_transform *xfm110, const struct overscan_info *overscan) { uint32_t overscan_left_right = 0; uint32_t overscan_top_bottom = 0; set_reg_field_value(overscan_left_right, overscan->left, SCLV_EXT_OVERSCAN_LEFT_RIGHT, EXT_OVERSCAN_LEFT); set_reg_field_value(overscan_left_right, overscan->right, SCLV_EXT_OVERSCAN_LEFT_RIGHT, EXT_OVERSCAN_RIGHT); set_reg_field_value(overscan_top_bottom, overscan->top, SCLV_EXT_OVERSCAN_TOP_BOTTOM, EXT_OVERSCAN_TOP); set_reg_field_value(overscan_top_bottom, overscan->bottom, SCLV_EXT_OVERSCAN_TOP_BOTTOM, EXT_OVERSCAN_BOTTOM); dm_write_reg(xfm110->base.ctx, mmSCLV_EXT_OVERSCAN_LEFT_RIGHT, overscan_left_right); dm_write_reg(xfm110->base.ctx, mmSCLV_EXT_OVERSCAN_TOP_BOTTOM, overscan_top_bottom); }
static void setup_i2c_polling( struct dc_context *ctx, const uint32_t addr, bool enable_detect, bool detect_mode) { uint32_t value; value = dm_read_reg(ctx, addr); set_reg_field_value( value, enable_detect, DC_I2C_DDC1_SETUP, DC_I2C_DDC1_ENABLE); set_reg_field_value( value, enable_detect, DC_I2C_DDC1_SETUP, DC_I2C_DDC1_EDID_DETECT_ENABLE); if (enable_detect) set_reg_field_value( value, detect_mode, DC_I2C_DDC1_SETUP, DC_I2C_DDC1_EDID_DETECT_MODE); dm_write_reg(ctx, addr, value); }
/* enable DP audio */ static void enable_dp_audio( const struct hw_ctx_audio *hw_ctx, enum engine_id engine_id) { const uint32_t addr = mmDP_SEC_CNTL + engine_offset[engine_id]; uint32_t value; /* Enable Audio packets */ value = dal_read_reg(hw_ctx->ctx, addr); set_reg_field_value(value, 1, DP_SEC_CNTL, DP_SEC_ASP_ENABLE); dal_write_reg(hw_ctx->ctx, addr, value); /* Program the ATP and AIP next */ set_reg_field_value(value, 1, DP_SEC_CNTL, DP_SEC_ATP_ENABLE); set_reg_field_value(value, 1, DP_SEC_CNTL, DP_SEC_AIP_ENABLE); dal_write_reg(hw_ctx->ctx, addr, value); /* Program STREAM_ENABLE after all the other enables. */ set_reg_field_value(value, 1, DP_SEC_CNTL, DP_SEC_STREAM_ENABLE); dal_write_reg(hw_ctx->ctx, addr, value); }
static void enable_advanced_request( struct timing_generator *tg, bool enable, const struct hw_crtc_timing *timing) { uint32_t addr = tg->regs[IDX_CRTC_START_LINE_CONTROL]; uint32_t value = dal_read_reg(tg->ctx, addr); uint32_t start_line_position; if (enable) { if (get_vsync_and_front_porch_size(timing) <= 3) start_line_position = 3; else start_line_position = 4; } else start_line_position = 2; set_reg_field_value( value, start_line_position, CRTCV_START_LINE_CONTROL, CRTC_ADVANCED_START_LINE_POSITION); set_reg_field_value( value, enable ? 1 : 0, CRTCV_START_LINE_CONTROL, CRTC_LEGACY_REQUESTOR_EN); dal_write_reg(tg->ctx, addr, value); }
/* luma part */ static void program_pri_addr_l( struct dce_mem_input *mem_input110, PHYSICAL_ADDRESS_LOC address) { uint32_t value = 0; uint32_t temp = 0; /*high register MUST be programmed first*/ temp = address.high_part & UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L__GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L_MASK; set_reg_field_value(value, temp, UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L, GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L); dm_write_reg( mem_input110->base.ctx, mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L, value); temp = 0; value = 0; temp = address.low_part >> UNP_GRPH_PRIMARY_SURFACE_ADDRESS_L__GRPH_PRIMARY_SURFACE_ADDRESS_L__SHIFT; set_reg_field_value(value, temp, UNP_GRPH_PRIMARY_SURFACE_ADDRESS_L, GRPH_PRIMARY_SURFACE_ADDRESS_L); dm_write_reg( mem_input110->base.ctx, mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_L, value); }
/* initialize HW state */ void dce_aud_hw_init( struct audio *audio) { uint32_t value; struct dce_audio *aud = DCE_AUD(audio); /* we only need to program the following registers once, so we only do it for the inst 0*/ if (audio->inst != 0) return; /* Suport R5 - 32khz * Suport R6 - 44.1khz * Suport R7 - 48khz */ /*disable clock gating before write to endpoint register*/ value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL); set_reg_field_value(value, 1, AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, CLOCK_GATING_DISABLE); AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value); REG_UPDATE(AZALIA_F0_CODEC_FUNCTION_PARAMETER_SUPPORTED_SIZE_RATES, AUDIO_RATE_CAPABILITIES, 0x70); /*Keep alive bit to verify HW block in BU. */ REG_UPDATE_2(AZALIA_F0_CODEC_FUNCTION_PARAMETER_POWER_STATES, CLKSTOP, 1, EPSS, 1); set_reg_field_value(value, 0, AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, CLOCK_GATING_DISABLE); AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value); }
void dce110_compressor_set_fbc_invalidation_triggers( struct compressor *compressor, uint32_t fbc_trigger) { /* Disable region hit event, FBC_MEMORY_REGION_MASK = 0 (bits 16-19) * for DCE 11 regions cannot be used - does not work with S/G */ uint32_t addr = mmFBC_CLIENT_REGION_MASK; uint32_t value = dm_read_reg(compressor->ctx, addr); set_reg_field_value( value, 0, FBC_CLIENT_REGION_MASK, FBC_MEMORY_REGION_MASK); dm_write_reg(compressor->ctx, addr, value); /* Setup events when to clear all CSM entries (effectively marking * current compressed data invalid) * For DCE 11 CSM metadata 11111 means - "Not Compressed" * Used as the initial value of the metadata sent to the compressor * after invalidation, to indicate that the compressor should attempt * to compress all chunks on the current pass. Also used when the chunk * is not successfully written to memory. * When this CSM value is detected, FBC reads from the uncompressed * buffer. Set events according to passed in value, these events are * valid for DCE11: * - bit 0 - display register updated * - bit 28 - memory write from any client except from MCIF * - bit 29 - CG static screen signal is inactive * In addition, DCE11.1 also needs to set new DCE11.1 specific events * that are used to trigger invalidation on certain register changes, * for example enabling of Alpha Compression may trigger invalidation of * FBC once bit is set. These events are as follows: * - Bit 2 - FBC_GRPH_COMP_EN register updated * - Bit 3 - FBC_SRC_SEL register updated * - Bit 4 - FBC_MIN_COMPRESSION register updated * - Bit 5 - FBC_ALPHA_COMP_EN register updated * - Bit 6 - FBC_ZERO_ALPHA_CHUNK_SKIP_EN register updated * - Bit 7 - FBC_FORCE_COPY_TO_COMP_BUF register updated */ addr = mmFBC_IDLE_FORCE_CLEAR_MASK; value = dm_read_reg(compressor->ctx, addr); set_reg_field_value( value, fbc_trigger | FBC_IDLE_FORCE_GRPH_COMP_EN | FBC_IDLE_FORCE_SRC_SEL_CHANGE | FBC_IDLE_FORCE_MIN_COMPRESSION_CHANGE | FBC_IDLE_FORCE_ALPHA_COMP_EN | FBC_IDLE_FORCE_ZERO_ALPHA_CHUNK_SKIP_EN | FBC_IDLE_FORCE_FORCE_COPY_TO_COMP_BUF, FBC_IDLE_FORCE_CLEAR_MASK, FBC_IDLE_FORCE_CLEAR_MASK); dm_write_reg(compressor->ctx, addr, value); }
/* setup stream encoder in dvi mode */ void dce80_stream_encoder_dvi_set_stream_attribute( struct stream_encoder *enc, struct dc_crtc_timing *crtc_timing, bool is_dual_link) { struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc); struct dc_context *ctx = enc110->base.ctx; uint32_t addr = LINK_REG(TMDS_CNTL); uint32_t value = dm_read_reg(ctx, addr); struct bp_encoder_control cntl = {0}; cntl.action = ENCODER_CONTROL_SETUP; cntl.engine_id = enc110->base.id; cntl.signal = is_dual_link ? SIGNAL_TYPE_DVI_DUAL_LINK : SIGNAL_TYPE_DVI_SINGLE_LINK; cntl.enable_dp_audio = false; cntl.pixel_clock = crtc_timing->pix_clk_khz; cntl.lanes_number = (is_dual_link) ? LANE_COUNT_EIGHT : LANE_COUNT_FOUR; cntl.color_depth = crtc_timing->display_color_depth; if (enc110->base.bp->funcs->encoder_control( enc110->base.bp, &cntl) != BP_RESULT_OK) return; switch (crtc_timing->pixel_encoding) { case PIXEL_ENCODING_YCBCR422: set_reg_field_value(value, 1, TMDS_CNTL, TMDS_PIXEL_ENCODING); break; default: set_reg_field_value(value, 0, TMDS_CNTL, TMDS_PIXEL_ENCODING); break; } switch (crtc_timing->pixel_encoding) { case COLOR_DEPTH_101010: if (crtc_timing->pixel_encoding == PIXEL_ENCODING_RGB) set_reg_field_value( value, 2, TMDS_CNTL, TMDS_COLOR_FORMAT); else set_reg_field_value( value, 0, TMDS_CNTL, TMDS_COLOR_FORMAT); break; default: set_reg_field_value(value, 0, TMDS_CNTL, TMDS_COLOR_FORMAT); break; } dm_write_reg(ctx, addr, value); }
static void dce110_transform_v_set_scalerv_bypass(struct transform *xfm) { uint32_t addr = mmSCLV_MODE; uint32_t value = dm_read_reg(xfm->ctx, addr); set_reg_field_value(value, 0, SCLV_MODE, SCL_MODE); set_reg_field_value(value, 0, SCLV_MODE, SCL_MODE_C); set_reg_field_value(value, 0, SCLV_MODE, SCL_PSCL_EN); set_reg_field_value(value, 0, SCLV_MODE, SCL_PSCL_EN_C); dm_write_reg(xfm->ctx, addr, value); }
/* setup Azalia HW block */ static void setup_azalia( const struct hw_ctx_audio *hw_ctx, enum engine_id engine_id, enum signal_type signal, const struct audio_crtc_info *crtc_info, const struct audio_pll_info *pll_info, const struct audio_info *audio_info) { uint32_t speakers = 0; uint32_t channels = 0; if (audio_info == NULL) /* This should not happen.it does so we don't get BSOD*/ return; speakers = audio_info->flags.info.ALLSPEAKERS; channels = dal_audio_hw_ctx_speakers_to_channels( hw_ctx, audio_info->flags.speaker_flags).all; /* setup the audio stream source select (audio -> dig mapping) */ { const uint32_t addr = mmAFMT_AUDIO_SRC_CONTROL + engine_offset[engine_id]; uint32_t value = 0; /*convert one-based index to zero-based */ set_reg_field_value(value, FROM_BASE(hw_ctx)->azalia_stream_id - 1, AFMT_AUDIO_SRC_CONTROL, AFMT_AUDIO_SRC_SELECT); dal_write_reg(hw_ctx->ctx, addr, value); } /* Channel allocation */ { const uint32_t addr = mmAFMT_AUDIO_PACKET_CONTROL2 + engine_offset[engine_id]; uint32_t value = dal_read_reg(hw_ctx->ctx, addr); set_reg_field_value(value, channels, AFMT_AUDIO_PACKET_CONTROL2, AFMT_AUDIO_CHANNEL_ENABLE); dal_write_reg(hw_ctx->ctx, addr, value); } configure_azalia(hw_ctx, signal, crtc_info, audio_info); }
void dce80_stream_encoder_stop_dp_info_packets( struct stream_encoder *enc) { /* stop generic packets on DP */ struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc); struct dc_context *ctx = enc110->base.ctx; uint32_t addr = LINK_REG(DP_SEC_CNTL); uint32_t value = dm_read_reg(ctx, addr); set_reg_field_value(value, 0, DP_SEC_CNTL, DP_SEC_GSP0_ENABLE); set_reg_field_value(value, 0, DP_SEC_CNTL, DP_SEC_GSP1_ENABLE); set_reg_field_value(value, 0, DP_SEC_CNTL, DP_SEC_GSP2_ENABLE); set_reg_field_value(value, 0, DP_SEC_CNTL, DP_SEC_GSP3_ENABLE); set_reg_field_value(value, 0, DP_SEC_CNTL, DP_SEC_AVI_ENABLE); set_reg_field_value(value, 0, DP_SEC_CNTL, DP_SEC_MPG_ENABLE); set_reg_field_value(value, 0, DP_SEC_CNTL, DP_SEC_STREAM_ENABLE); /* this register shared with audio info frame. * therefore we need to keep master enabled * if at least one of the fields is not 0 */ if (value) set_reg_field_value( value, 1, DP_SEC_CNTL, DP_SEC_STREAM_ENABLE); dm_write_reg(ctx, addr, value); }
static void power_on_lut(struct transform *xfm, bool power_on, bool inputgamma, bool regamma) { uint32_t value = dm_read_reg(xfm->ctx, mmDCFEV_MEM_PWR_CTRL); int i; if (power_on) { if (inputgamma) set_reg_field_value( value, 1, DCFEV_MEM_PWR_CTRL, COL_MAN_INPUT_GAMMA_MEM_PWR_DIS); if (regamma) set_reg_field_value( value, 1, DCFEV_MEM_PWR_CTRL, COL_MAN_GAMMA_CORR_MEM_PWR_DIS); } else { if (inputgamma) set_reg_field_value( value, 0, DCFEV_MEM_PWR_CTRL, COL_MAN_INPUT_GAMMA_MEM_PWR_DIS); if (regamma) set_reg_field_value( value, 0, DCFEV_MEM_PWR_CTRL, COL_MAN_GAMMA_CORR_MEM_PWR_DIS); } dm_write_reg(xfm->ctx, mmDCFEV_MEM_PWR_CTRL, value); for (i = 0; i < 3; i++) { value = dm_read_reg(xfm->ctx, mmDCFEV_MEM_PWR_CTRL); if (get_reg_field_value(value, DCFEV_MEM_PWR_CTRL, COL_MAN_INPUT_GAMMA_MEM_PWR_DIS) && get_reg_field_value(value, DCFEV_MEM_PWR_CTRL, COL_MAN_GAMMA_CORR_MEM_PWR_DIS)) break; udelay(2); } }
/* LB_MEMORY_CONFIG * 00 - Use all three pieces of memory * 01 - Use only one piece of memory of total 720x144 bits * 10 - Use two pieces of memory of total 960x144 bits * 11 - reserved * * LB_MEMORY_SIZE * Total entries of LB memory. * This number should be larger than 960. The default value is 1712(0x6B0) */ static void power_up(struct line_buffer *base) { struct line_buffer_dce110 *lb = LB110_FROM_BASE(base); uint32_t value; value = dal_read_reg(base->dal_context, lb->lbx_memory_ctrl); /*Use all three pieces of memory always*/ set_reg_field_value(value, 0, LB_MEMORY_CTRL, LB_MEMORY_CONFIG); /*hard coded number DCE11 1712(0x6B0) Partitions: 720/960/1712*/ set_reg_field_value(value, LB_ENTRIES_TOTAL_NUMBER, LB_MEMORY_CTRL, LB_MEMORY_SIZE); dal_write_reg(base->dal_context, lb->lbx_memory_ctrl, value); }
static bool blank_crtc( struct timing_generator *tg, enum color_space color_space) { struct crtc_black_color black_color; uint32_t addr = tg->regs[IDX_CRTC_BLACK_COLOR]; uint32_t value = dal_read_reg(tg->ctx, addr); dal_timing_generator_color_space_to_black_color( color_space, &black_color); set_reg_field_value( value, black_color.black_color_b_cb, CRTCV_BLACK_COLOR, CRTC_BLACK_COLOR_B_CB); set_reg_field_value( value, black_color.black_color_g_y, CRTCV_BLACK_COLOR, CRTC_BLACK_COLOR_G_Y); set_reg_field_value( value, black_color.black_color_r_cr, CRTCV_BLACK_COLOR, CRTC_BLACK_COLOR_R_CR); dal_write_reg(tg->ctx, addr, value); addr = tg->regs[IDX_CRTC_BLANK_CONTROL]; value = dal_read_reg(tg->ctx, addr); set_reg_field_value( value, 1, CRTCV_BLANK_CONTROL, CRTC_BLANK_DATA_EN); set_reg_field_value( value, 1, CRTCV_BLANK_CONTROL, CRTC_BLANK_DE_MODE); dal_write_reg(tg->ctx, addr, value); return true; }
static void process_channel_reply( struct i2c_engine *engine, struct i2c_reply_transaction_data *reply) { uint8_t length = reply->length; uint8_t *buffer = reply->data; struct i2c_hw_engine_dce110 *i2c_hw_engine_dce110 = FROM_I2C_ENGINE(engine); uint32_t value = dal_read_reg(engine->base.ctx, mmDC_I2C_DATA); /*set index*/ set_reg_field_value( value, i2c_hw_engine_dce110->buffer_used_write, DC_I2C_DATA, DC_I2C_INDEX); set_reg_field_value( value, 1, DC_I2C_DATA, DC_I2C_DATA_RW); set_reg_field_value( value, 1, DC_I2C_DATA, DC_I2C_INDEX_WRITE); dal_write_reg(engine->base.ctx, mmDC_I2C_DATA, value); while (length) { /* after reading the status, * if the I2C operation executed successfully * (i.e. DC_I2C_STATUS_DONE = 1) then the I2C controller * should read data bytes from I2C circular data buffer */ value = dal_read_reg(engine->base.ctx, mmDC_I2C_DATA); *buffer++ = get_reg_field_value( value, DC_I2C_DATA, DC_I2C_DATA); --length; } }
/* set audio latency in in ms/2+1 */ static void set_audio_latency( const struct hw_ctx_audio *hw_ctx, int latency_in_ms) { uint32_t value = 0; if (latency_in_ms < 0) latency_in_ms = 0; if (latency_in_ms > 255) latency_in_ms = 255; value = read_indirect_azalia_reg( hw_ctx, ixAZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC); set_reg_field_value(value, latency_in_ms, AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC, AUDIO_LIPSYNC); write_indirect_azalia_reg( hw_ctx, ixAZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC, value); }
static void enable_afmt_clock( const struct hw_ctx_audio *hw_ctx, enum engine_id engine_id, bool enable_flag) { uint32_t engine_offs = engine_offset[engine_id]; uint32_t value; uint32_t count = 0; uint32_t enable = enable_flag ? 1:0; /* Enable Audio packets*/ value = dal_read_reg(hw_ctx->ctx, mmAFMT_CNTL + engine_offs); /*enable AFMT clock*/ set_reg_field_value(value, enable, AFMT_CNTL, AFMT_AUDIO_CLOCK_EN); dal_write_reg(hw_ctx->ctx, mmAFMT_CNTL + engine_offs, value); /*wait for AFMT clock to turn on, * the expectation is that this * should complete in 1-2 reads) */ do { /* Wait for 1us between subsequent register reads.*/ dal_delay_in_microseconds(1); value = dal_read_reg(hw_ctx->ctx, mmAFMT_CNTL + engine_offs); } while (get_reg_field_value(value, AFMT_CNTL, AFMT_AUDIO_CLOCK_ON) != enable && count++ < 10); }
static bool hpd_ack( struct irq_service *irq_service, const struct irq_source_info *info) { uint32_t addr = info->status_reg; uint32_t value = dm_read_reg(irq_service->ctx, addr); uint32_t current_status = get_reg_field_value( value, HPD0_DC_HPD_INT_STATUS, DC_HPD_SENSE_DELAYED); dal_irq_service_ack_generic(irq_service, info); value = dm_read_reg(irq_service->ctx, info->enable_reg); set_reg_field_value( value, current_status ? 0 : 1, HPD0_DC_HPD_INT_CONTROL, DC_HPD_INT_POLARITY); dm_write_reg(irq_service->ctx, info->enable_reg, value); return true; }
static bool set_pixel_storage_depth( struct line_buffer *base, enum lb_pixel_depth depth) { bool ret = true; struct line_buffer_dce110 *lb = LB110_FROM_BASE(base); uint32_t value; value = dal_read_reg( base->dal_context, lb->lbx_data_format); switch (depth) { case LB_PIXEL_DEPTH_18BPP: set_reg_field_value(value, 2, LB_DATA_FORMAT, PIXEL_DEPTH); set_reg_field_value(value, 1, LB_DATA_FORMAT, PIXEL_EXPAN_MODE); break; case LB_PIXEL_DEPTH_24BPP: set_reg_field_value(value, 1, LB_DATA_FORMAT, PIXEL_DEPTH); set_reg_field_value(value, 1, LB_DATA_FORMAT, PIXEL_EXPAN_MODE); break; case LB_PIXEL_DEPTH_30BPP: set_reg_field_value(value, 0, LB_DATA_FORMAT, PIXEL_DEPTH); set_reg_field_value(value, 1, LB_DATA_FORMAT, PIXEL_EXPAN_MODE); break; case LB_PIXEL_DEPTH_36BPP: set_reg_field_value(value, 3, LB_DATA_FORMAT, PIXEL_DEPTH); set_reg_field_value(value, 0, LB_DATA_FORMAT, PIXEL_EXPAN_MODE); break; default: ret = false; break; } if (ret == true) { set_reg_field_value(value, 0, LB_DATA_FORMAT, ALPHA_EN); dal_write_reg( base->dal_context, lb->lbx_data_format, value); if (!(lb->caps & depth)) { /*we should use unsupported capabilities * unless it is required by w/a*/ dal_logger_write(base->dal_context->logger, LOG_MAJOR_WARNING, LOG_MINOR_COMPONENT_GPU, "%s: Capability not supported", __func__); } } return ret; }
/* initialize HW state */ static void hw_initialize( const struct hw_ctx_audio *hw_ctx) { uint32_t stream_id = FROM_BASE(hw_ctx)->azalia_stream_id; uint32_t addr; /* we only need to program the following registers once, so we only do it for the first audio stream.*/ if (stream_id != FIRST_AUDIO_STREAM_ID) return; /* Suport R5 - 32khz * Suport R6 - 44.1khz * Suport R7 - 48khz */ addr = mmAZALIA_F0_CODEC_FUNCTION_PARAMETER_SUPPORTED_SIZE_RATES; { uint32_t value; value = dal_read_reg(hw_ctx->ctx, addr); set_reg_field_value(value, 0x70, AZALIA_F0_CODEC_FUNCTION_PARAMETER_SUPPORTED_SIZE_RATES, AUDIO_RATE_CAPABILITIES); dal_write_reg(hw_ctx->ctx, addr, value); } /*Keep alive bit to verify HW block in BU. */ addr = mmAZALIA_F0_CODEC_FUNCTION_PARAMETER_POWER_STATES; { uint32_t value; value = dal_read_reg(hw_ctx->ctx, addr); set_reg_field_value(value, 1, AZALIA_F0_CODEC_FUNCTION_PARAMETER_POWER_STATES, CLKSTOP); set_reg_field_value(value, 1, AZALIA_F0_CODEC_FUNCTION_PARAMETER_POWER_STATES, EPSS); dal_write_reg(hw_ctx->ctx, addr, value); } }
static bool dce110_transform_v_power_up_line_buffer(struct transform *xfm) { struct dce110_transform *xfm110 = TO_DCE110_TRANSFORM(xfm); uint32_t value; value = dm_read_reg(xfm110->base.ctx, mmLBV_MEMORY_CTRL); /*Use all three pieces of memory always*/ set_reg_field_value(value, 0, LBV_MEMORY_CTRL, LB_MEMORY_CONFIG); /*hard coded number DCE11 1712(0x6B0) Partitions: 720/960/1712*/ set_reg_field_value(value, LB_TOTAL_NUMBER_OF_ENTRIES, LBV_MEMORY_CTRL, LB_MEMORY_SIZE); dm_write_reg(xfm110->base.ctx, mmLBV_MEMORY_CTRL, value); return true; }
static void dce110_timing_generator_v_set_overscan_color_black( struct timing_generator *tg, const struct tg_color *color) { struct dc_context *ctx = tg->ctx; uint32_t addr; uint32_t value = 0; set_reg_field_value( value, color->color_b_cb, CRTC_OVERSCAN_COLOR, CRTC_OVERSCAN_COLOR_BLUE); set_reg_field_value( value, color->color_r_cr, CRTC_OVERSCAN_COLOR, CRTC_OVERSCAN_COLOR_RED); set_reg_field_value( value, color->color_g_y, CRTC_OVERSCAN_COLOR, CRTC_OVERSCAN_COLOR_GREEN); addr = mmCRTCV_OVERSCAN_COLOR; dm_write_reg(ctx, addr, value); addr = mmCRTCV_BLACK_COLOR; dm_write_reg(ctx, addr, value); /* This is desirable to have a constant DAC output voltage during the * blank time that is higher than the 0 volt reference level that the * DAC outputs when the NBLANK signal * is asserted low, such as for output to an analog TV. */ addr = mmCRTCV_BLANK_DATA_COLOR; dm_write_reg(ctx, addr, value); /* TO DO we have to program EXT registers and we need to know LB DATA * format because it is used when more 10 , i.e. 12 bits per color * * m_mmDxCRTC_OVERSCAN_COLOR_EXT * m_mmDxCRTC_BLACK_COLOR_EXT * m_mmDxCRTC_BLANK_DATA_COLOR_EXT */ }
static bool dce110_timing_generator_v_disable_crtc(struct timing_generator *tg) { uint32_t value; value = dm_read_reg(tg->ctx, mmCRTCV_CONTROL); set_reg_field_value(value, 0, CRTCV_CONTROL, CRTC_DISABLE_POINT_CNTL); set_reg_field_value(value, 0, CRTCV_CONTROL, CRTC_MASTER_EN); dm_write_reg(tg->ctx, mmCRTCV_CONTROL, value); /* * TODO: call this when adding stereo support * tg->funcs->disable_stereo(tg); */ return true; }
static inline void reset_hw_engine(struct engine *engine) { uint32_t value = dal_read_reg(engine->ctx, mmDC_I2C_CONTROL); set_reg_field_value( value, 1, DC_I2C_CONTROL, DC_I2C_SOFT_RESET); set_reg_field_value( value, 1, DC_I2C_CONTROL, DC_I2C_SW_STATUS_RESET); dal_write_reg(engine->ctx, mmDC_I2C_CONTROL, value); }