cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dce120_hw_sequencer.c (6879B)


      1/*
      2 * Copyright 2015 Advanced Micro Devices, Inc.
      3 *
      4 * Permission is hereby granted, free of charge, to any person obtaining a
      5 * copy of this software and associated documentation files (the "Software"),
      6 * to deal in the Software without restriction, including without limitation
      7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8 * and/or sell copies of the Software, and to permit persons to whom the
      9 * Software is furnished to do so, subject to the following conditions:
     10 *
     11 * The above copyright notice and this permission notice shall be included in
     12 * all copies or substantial portions of the Software.
     13 *
     14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     20 * OTHER DEALINGS IN THE SOFTWARE.
     21 *
     22 * Authors: AMD
     23 *
     24 */
     25
     26#include "dm_services.h"
     27#include "dc.h"
     28#include "core_types.h"
     29#include "dce120_hw_sequencer.h"
     30#include "dce/dce_hwseq.h"
     31
     32#include "dce110/dce110_hw_sequencer.h"
     33
     34#include "dce/dce_12_0_offset.h"
     35#include "dce/dce_12_0_sh_mask.h"
     36#include "soc15_hw_ip.h"
     37#include "vega10_ip_offset.h"
     38#include "reg_helper.h"
     39
     40#define CTX \
     41	hws->ctx
     42#define REG(reg)\
     43	hws->regs->reg
     44
     45#undef FN
     46#define FN(reg_name, field_name) \
     47	hws->shifts->field_name, hws->masks->field_name
     48
     49struct dce120_hw_seq_reg_offsets {
     50	uint32_t crtc;
     51};
     52
     53#if 0
     54static const struct dce120_hw_seq_reg_offsets reg_offsets[] = {
     55{
     56	.crtc = (mmCRTC0_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL),
     57},
     58{
     59	.crtc = (mmCRTC1_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL),
     60},
     61{
     62	.crtc = (mmCRTC2_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL),
     63},
     64{
     65	.crtc = (mmCRTC3_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL),
     66},
     67{
     68	.crtc = (mmCRTC4_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL),
     69},
     70{
     71	.crtc = (mmCRTC5_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL),
     72}
     73};
     74
     75#define HW_REG_CRTC(reg, id)\
     76	(reg + reg_offsets[id].crtc)
     77
     78#define CNTL_ID(controller_id)\
     79	controller_id
     80/*******************************************************************************
     81 * Private definitions
     82 ******************************************************************************/
     83static void dce120_init_pte(struct dc_context *ctx, uint8_t controller_id)
     84{
     85	uint32_t addr;
     86	uint32_t value = 0;
     87	uint32_t chunk_int = 0;
     88	uint32_t chunk_mul = 0;
     89/*
     90	addr = mmDCP0_DVMM_PTE_CONTROL + controller_id *
     91			(mmDCP1_DVMM_PTE_CONTROL- mmDCP0_DVMM_PTE_CONTROL);
     92
     93	value = dm_read_reg(ctx, addr);
     94
     95	set_reg_field_value(
     96			value, 0, DCP, controller_id,
     97			DVMM_PTE_CONTROL,
     98			DVMM_USE_SINGLE_PTE);
     99
    100	set_reg_field_value_soc15(
    101			value, 1, DCP, controller_id,
    102			DVMM_PTE_CONTROL,
    103			DVMM_PTE_BUFFER_MODE0);
    104
    105	set_reg_field_value_soc15(
    106			value, 1, DCP, controller_id,
    107			DVMM_PTE_CONTROL,
    108			DVMM_PTE_BUFFER_MODE1);
    109
    110	dm_write_reg(ctx, addr, value);*/
    111
    112	addr = mmDVMM_PTE_REQ;
    113	value = dm_read_reg(ctx, addr);
    114
    115	chunk_int = get_reg_field_value(
    116		value,
    117		DVMM_PTE_REQ,
    118		HFLIP_PTEREQ_PER_CHUNK_INT);
    119
    120	chunk_mul = get_reg_field_value(
    121		value,
    122		DVMM_PTE_REQ,
    123		HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER);
    124
    125	if (chunk_int != 0x4 || chunk_mul != 0x4) {
    126
    127		set_reg_field_value(
    128			value,
    129			255,
    130			DVMM_PTE_REQ,
    131			MAX_PTEREQ_TO_ISSUE);
    132
    133		set_reg_field_value(
    134			value,
    135			4,
    136			DVMM_PTE_REQ,
    137			HFLIP_PTEREQ_PER_CHUNK_INT);
    138
    139		set_reg_field_value(
    140			value,
    141			4,
    142			DVMM_PTE_REQ,
    143			HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER);
    144
    145		dm_write_reg(ctx, addr, value);
    146	}
    147}
    148#endif
    149
    150static bool dce120_enable_display_power_gating(
    151	struct dc *dc,
    152	uint8_t controller_id,
    153	struct dc_bios *dcb,
    154	enum pipe_gating_control power_gating)
    155{
    156	/* disable for bringup */
    157#if 0
    158	enum bp_result bp_result = BP_RESULT_OK;
    159	enum bp_pipe_control_action cntl;
    160	struct dc_context *ctx = dc->ctx;
    161
    162	if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment))
    163		return true;
    164
    165	if (power_gating == PIPE_GATING_CONTROL_INIT)
    166		cntl = ASIC_PIPE_INIT;
    167	else if (power_gating == PIPE_GATING_CONTROL_ENABLE)
    168		cntl = ASIC_PIPE_ENABLE;
    169	else
    170		cntl = ASIC_PIPE_DISABLE;
    171
    172	if (power_gating != PIPE_GATING_CONTROL_INIT || controller_id == 0) {
    173
    174		bp_result = dcb->funcs->enable_disp_power_gating(
    175						dcb, controller_id + 1, cntl);
    176
    177		/* Revert MASTER_UPDATE_MODE to 0 because bios sets it 2
    178		 * by default when command table is called
    179		 */
    180		dm_write_reg(ctx,
    181			HW_REG_CRTC(mmCRTC0_CRTC_MASTER_UPDATE_MODE, controller_id),
    182			0);
    183	}
    184
    185	if (power_gating != PIPE_GATING_CONTROL_ENABLE)
    186		dce120_init_pte(ctx, controller_id);
    187
    188	if (bp_result == BP_RESULT_OK)
    189		return true;
    190	else
    191		return false;
    192#endif
    193	return false;
    194}
    195
    196static void dce120_update_dchub(
    197	struct dce_hwseq *hws,
    198	struct dchub_init_data *dh_data)
    199{
    200	/* TODO: port code from dal2 */
    201	switch (dh_data->fb_mode) {
    202	case FRAME_BUFFER_MODE_ZFB_ONLY:
    203		/*For ZFB case need to put DCHUB FB BASE and TOP upside down to indicate ZFB mode*/
    204		REG_UPDATE_2(DCHUB_FB_LOCATION,
    205				FB_TOP, 0,
    206				FB_BASE, 0x0FFFF);
    207
    208		REG_UPDATE(DCHUB_AGP_BASE,
    209				AGP_BASE, dh_data->zfb_phys_addr_base >> 22);
    210
    211		REG_UPDATE(DCHUB_AGP_BOT,
    212				AGP_BOT, dh_data->zfb_mc_base_addr >> 22);
    213
    214		REG_UPDATE(DCHUB_AGP_TOP,
    215				AGP_TOP, (dh_data->zfb_mc_base_addr + dh_data->zfb_size_in_byte - 1) >> 22);
    216		break;
    217	case FRAME_BUFFER_MODE_MIXED_ZFB_AND_LOCAL:
    218		/*Should not touch FB LOCATION (done by VBIOS on AsicInit table)*/
    219		REG_UPDATE(DCHUB_AGP_BASE,
    220				AGP_BASE, dh_data->zfb_phys_addr_base >> 22);
    221
    222		REG_UPDATE(DCHUB_AGP_BOT,
    223				AGP_BOT, dh_data->zfb_mc_base_addr >> 22);
    224
    225		REG_UPDATE(DCHUB_AGP_TOP,
    226				AGP_TOP, (dh_data->zfb_mc_base_addr + dh_data->zfb_size_in_byte - 1) >> 22);
    227		break;
    228	case FRAME_BUFFER_MODE_LOCAL_ONLY:
    229		/*Should not touch FB LOCATION (done by VBIOS on AsicInit table)*/
    230		REG_UPDATE(DCHUB_AGP_BASE,
    231				AGP_BASE, 0);
    232
    233		REG_UPDATE(DCHUB_AGP_BOT,
    234				AGP_BOT, 0x03FFFF);
    235
    236		REG_UPDATE(DCHUB_AGP_TOP,
    237				AGP_TOP, 0);
    238		break;
    239	default:
    240		break;
    241	}
    242
    243	dh_data->dchub_initialzied = true;
    244	dh_data->dchub_info_valid = false;
    245}
    246
    247/**
    248 * dce121_xgmi_enabled() - Check if xGMI is enabled
    249 * @hws: DCE hardware sequencer object
    250 *
    251 * Return true if xGMI is enabled. False otherwise.
    252 */
    253bool dce121_xgmi_enabled(struct dce_hwseq *hws)
    254{
    255	uint32_t pf_max_region;
    256
    257	REG_GET(MC_VM_XGMI_LFB_CNTL, PF_MAX_REGION, &pf_max_region);
    258	/* PF_MAX_REGION == 0 means xgmi is disabled */
    259	return !!pf_max_region;
    260}
    261
    262void dce120_hw_sequencer_construct(struct dc *dc)
    263{
    264	/* All registers used by dce11.2 match those in dce11 in offset and
    265	 * structure
    266	 */
    267	dce110_hw_sequencer_construct(dc);
    268	dc->hwseq->funcs.enable_display_power_gating = dce120_enable_display_power_gating;
    269	dc->hwss.update_dchub = dce120_update_dchub;
    270}
    271