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

dce_hwseq.c (5894B)


      1/*
      2 * Copyright 2016 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 "dce_hwseq.h"
     27#include "reg_helper.h"
     28#include "hw_sequencer_private.h"
     29#include "core_types.h"
     30
     31#define CTX \
     32	hws->ctx
     33#define REG(reg)\
     34	hws->regs->reg
     35
     36#undef FN
     37#define FN(reg_name, field_name) \
     38	hws->shifts->field_name, hws->masks->field_name
     39
     40void dce_enable_fe_clock(struct dce_hwseq *hws,
     41		unsigned int fe_inst, bool enable)
     42{
     43	REG_UPDATE(DCFE_CLOCK_CONTROL[fe_inst],
     44			DCFE_CLOCK_ENABLE, enable);
     45}
     46
     47void dce_pipe_control_lock(struct dc *dc,
     48		struct pipe_ctx *pipe,
     49		bool lock)
     50{
     51	uint32_t lock_val = lock ? 1 : 0;
     52	uint32_t dcp_grph, scl, blnd, update_lock_mode, val;
     53	struct dce_hwseq *hws = dc->hwseq;
     54
     55	/* Not lock pipe when blank */
     56	if (lock && pipe->stream_res.tg->funcs->is_blanked &&
     57	    pipe->stream_res.tg->funcs->is_blanked(pipe->stream_res.tg))
     58		return;
     59
     60	val = REG_GET_4(BLND_V_UPDATE_LOCK[pipe->stream_res.tg->inst],
     61			BLND_DCP_GRPH_V_UPDATE_LOCK, &dcp_grph,
     62			BLND_SCL_V_UPDATE_LOCK, &scl,
     63			BLND_BLND_V_UPDATE_LOCK, &blnd,
     64			BLND_V_UPDATE_LOCK_MODE, &update_lock_mode);
     65
     66	dcp_grph = lock_val;
     67	scl = lock_val;
     68	blnd = lock_val;
     69	update_lock_mode = lock_val;
     70
     71	REG_SET_2(BLND_V_UPDATE_LOCK[pipe->stream_res.tg->inst], val,
     72			BLND_DCP_GRPH_V_UPDATE_LOCK, dcp_grph,
     73			BLND_SCL_V_UPDATE_LOCK, scl);
     74
     75	if (hws->masks->BLND_BLND_V_UPDATE_LOCK != 0)
     76		REG_SET_2(BLND_V_UPDATE_LOCK[pipe->stream_res.tg->inst], val,
     77				BLND_BLND_V_UPDATE_LOCK, blnd,
     78				BLND_V_UPDATE_LOCK_MODE, update_lock_mode);
     79
     80	if (hws->wa.blnd_crtc_trigger) {
     81		if (!lock) {
     82			uint32_t value = REG_READ(CRTC_H_BLANK_START_END[pipe->stream_res.tg->inst]);
     83			REG_WRITE(CRTC_H_BLANK_START_END[pipe->stream_res.tg->inst], value);
     84		}
     85	}
     86}
     87
     88#if defined(CONFIG_DRM_AMD_DC_SI)
     89void dce60_pipe_control_lock(struct dc *dc,
     90		struct pipe_ctx *pipe,
     91		bool lock)
     92{
     93	/* DCE6 has no BLND_V_UPDATE_LOCK register */
     94}
     95#endif
     96
     97void dce_set_blender_mode(struct dce_hwseq *hws,
     98	unsigned int blnd_inst,
     99	enum blnd_mode mode)
    100{
    101	uint32_t feedthrough = 1;
    102	uint32_t blnd_mode = 0;
    103	uint32_t multiplied_mode = 0;
    104	uint32_t alpha_mode = 2;
    105
    106	switch (mode) {
    107	case BLND_MODE_OTHER_PIPE:
    108		feedthrough = 0;
    109		blnd_mode = 1;
    110		alpha_mode = 0;
    111		break;
    112	case BLND_MODE_BLENDING:
    113		feedthrough = 0;
    114		blnd_mode = 2;
    115		alpha_mode = 0;
    116		multiplied_mode = 1;
    117		break;
    118	case BLND_MODE_CURRENT_PIPE:
    119	default:
    120		if (REG(BLND_CONTROL[blnd_inst]) == REG(BLNDV_CONTROL) ||
    121				blnd_inst == 0)
    122			feedthrough = 0;
    123		break;
    124	}
    125
    126	REG_UPDATE(BLND_CONTROL[blnd_inst],
    127		BLND_MODE, blnd_mode);
    128
    129	if (hws->masks->BLND_ALPHA_MODE != 0) {
    130		REG_UPDATE_3(BLND_CONTROL[blnd_inst],
    131			BLND_FEEDTHROUGH_EN, feedthrough,
    132			BLND_ALPHA_MODE, alpha_mode,
    133			BLND_MULTIPLIED_MODE, multiplied_mode);
    134	}
    135}
    136
    137
    138static void dce_disable_sram_shut_down(struct dce_hwseq *hws)
    139{
    140	if (REG(DC_MEM_GLOBAL_PWR_REQ_CNTL))
    141		REG_UPDATE(DC_MEM_GLOBAL_PWR_REQ_CNTL,
    142				DC_MEM_GLOBAL_PWR_REQ_DIS, 1);
    143}
    144
    145static void dce_underlay_clock_enable(struct dce_hwseq *hws)
    146{
    147	/* todo: why do we need this at boot? is dce_enable_fe_clock enough? */
    148	if (REG(DCFEV_CLOCK_CONTROL))
    149		REG_UPDATE(DCFEV_CLOCK_CONTROL,
    150				DCFEV_CLOCK_ENABLE, 1);
    151}
    152
    153static void enable_hw_base_light_sleep(void)
    154{
    155	/* TODO: implement */
    156}
    157
    158static void disable_sw_manual_control_light_sleep(void)
    159{
    160	/* TODO: implement */
    161}
    162
    163void dce_clock_gating_power_up(struct dce_hwseq *hws,
    164		bool enable)
    165{
    166	if (enable) {
    167		enable_hw_base_light_sleep();
    168		disable_sw_manual_control_light_sleep();
    169	} else {
    170		dce_disable_sram_shut_down(hws);
    171		dce_underlay_clock_enable(hws);
    172	}
    173}
    174
    175void dce_crtc_switch_to_clk_src(struct dce_hwseq *hws,
    176		struct clock_source *clk_src,
    177		unsigned int tg_inst)
    178{
    179	if (clk_src->id == CLOCK_SOURCE_ID_DP_DTO || clk_src->dp_clk_src) {
    180		REG_UPDATE(PIXEL_RATE_CNTL[tg_inst],
    181				DP_DTO0_ENABLE, 1);
    182
    183	} else if (clk_src->id >= CLOCK_SOURCE_COMBO_PHY_PLL0) {
    184		uint32_t rate_source = clk_src->id - CLOCK_SOURCE_COMBO_PHY_PLL0;
    185
    186		REG_UPDATE_2(PHYPLL_PIXEL_RATE_CNTL[tg_inst],
    187				PHYPLL_PIXEL_RATE_SOURCE, rate_source,
    188				PIXEL_RATE_PLL_SOURCE, 0);
    189
    190		REG_UPDATE(PIXEL_RATE_CNTL[tg_inst],
    191				DP_DTO0_ENABLE, 0);
    192
    193	} else if (clk_src->id <= CLOCK_SOURCE_ID_PLL2) {
    194		uint32_t rate_source = clk_src->id - CLOCK_SOURCE_ID_PLL0;
    195
    196		REG_UPDATE_2(PIXEL_RATE_CNTL[tg_inst],
    197				PIXEL_RATE_SOURCE, rate_source,
    198				DP_DTO0_ENABLE, 0);
    199
    200		if (REG(PHYPLL_PIXEL_RATE_CNTL[tg_inst]))
    201			REG_UPDATE(PHYPLL_PIXEL_RATE_CNTL[tg_inst],
    202					PIXEL_RATE_PLL_SOURCE, 1);
    203	} else {
    204		DC_ERR("Unknown clock source. clk_src id: %d, TG_inst: %d",
    205		       clk_src->id, tg_inst);
    206	}
    207}
    208
    209/* Only use LUT for 8 bit formats */
    210bool dce_use_lut(enum surface_pixel_format format)
    211{
    212	switch (format) {
    213	case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
    214	case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
    215		return true;
    216	default:
    217		return false;
    218	}
    219}