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

dcn20_mmhubbub.c (14510B)


      1/*
      2 * Copyright 2012-15 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
     27#include "reg_helper.h"
     28#include "resource.h"
     29#include "mcif_wb.h"
     30#include "dcn20_mmhubbub.h"
     31
     32
     33#define REG(reg)\
     34	mcif_wb20->mcif_wb_regs->reg
     35
     36#define CTX \
     37	mcif_wb20->base.ctx
     38
     39#undef FN
     40#define FN(reg_name, field_name) \
     41	mcif_wb20->mcif_wb_shift->field_name, mcif_wb20->mcif_wb_mask->field_name
     42
     43#define MCIF_ADDR(addr) (((unsigned long long)addr & 0xffffffffff) + 0xFE) >> 8
     44#define MCIF_ADDR_HIGH(addr) (unsigned long long)addr >> 40
     45
     46/* wbif programming guide:
     47 * 1. set up wbif parameter:
     48 *    unsigned long long   luma_address[4];       //4 frame buffer
     49 *    unsigned long long   chroma_address[4];
     50 *    unsigned int	   luma_pitch;
     51 *    unsigned int	   chroma_pitch;
     52 *    unsigned int         warmup_pitch=0x10;     //256B align, the page size is 4KB when it is 0x10
     53 *    unsigned int	   slice_lines;           //slice size
     54 *    unsigned int         time_per_pixel;        // time per pixel, in ns
     55 *    unsigned int         arbitration_slice;     // 0: 512 bytes 1: 1024 bytes 2: 2048 Bytes
     56 *    unsigned int         max_scaled_time;       // used for QOS generation
     57 *    unsigned int         swlock=0x0;
     58 *    unsigned int         cli_watermark[4];      //4 group urgent watermark
     59 *    unsigned int         pstate_watermark[4];   //4 group pstate watermark
     60 *    unsigned int         sw_int_en;             // Software interrupt enable, frame end and overflow
     61 *    unsigned int         sw_slice_int_en;       // slice end interrupt enable
     62 *    unsigned int         sw_overrun_int_en;     // overrun error interrupt enable
     63 *    unsigned int         vce_int_en;            // VCE interrupt enable, frame end and overflow
     64 *    unsigned int         vce_slice_int_en;      // VCE slice end interrupt enable, frame end and overflow
     65 *
     66 * 2. configure wbif register
     67 *    a. call mmhubbub_config_wbif()
     68 *
     69 * 3. Enable wbif
     70 *    call set_wbif_bufmgr_enable();
     71 *
     72 * 4. wbif_dump_status(), option, for debug purpose
     73 *    the bufmgr status can show the progress of write back, can be used for debug purpose
     74 */
     75
     76static void mmhubbub2_config_mcif_buf(struct mcif_wb *mcif_wb,
     77		struct mcif_buf_params *params,
     78		unsigned int dest_height)
     79{
     80	struct dcn20_mmhubbub *mcif_wb20 = TO_DCN20_MMHUBBUB(mcif_wb);
     81
     82	/* sw lock buffer0~buffer3, default is 0 */
     83	REG_UPDATE(MCIF_WB_BUFMGR_SW_CONTROL, MCIF_WB_BUFMGR_SW_LOCK, params->swlock);
     84
     85	/* buffer address for packing mode or Luma in planar mode */
     86	REG_UPDATE(MCIF_WB_BUF_1_ADDR_Y, MCIF_WB_BUF_1_ADDR_Y, MCIF_ADDR(params->luma_address[0]));
     87	REG_UPDATE(MCIF_WB_BUF_1_ADDR_Y_HIGH, MCIF_WB_BUF_1_ADDR_Y_HIGH, MCIF_ADDR_HIGH(params->luma_address[0]));
     88	/* right eye sub-buffer address offset for packing mode or Luma in planar mode */
     89	REG_UPDATE(MCIF_WB_BUF_1_ADDR_Y_OFFSET, MCIF_WB_BUF_1_ADDR_Y_OFFSET, 0);
     90
     91	/* buffer address for Chroma in planar mode (unused in packing mode) */
     92	REG_UPDATE(MCIF_WB_BUF_1_ADDR_C, MCIF_WB_BUF_1_ADDR_C, MCIF_ADDR(params->chroma_address[0]));
     93	REG_UPDATE(MCIF_WB_BUF_1_ADDR_C_HIGH, MCIF_WB_BUF_1_ADDR_C_HIGH, MCIF_ADDR_HIGH(params->chroma_address[0]));
     94	/* right eye offset for packing mode or Luma in planar mode */
     95	REG_UPDATE(MCIF_WB_BUF_1_ADDR_C_OFFSET, MCIF_WB_BUF_1_ADDR_C_OFFSET, 0);
     96
     97	/* buffer address for packing mode or Luma in planar mode */
     98	REG_UPDATE(MCIF_WB_BUF_2_ADDR_Y, MCIF_WB_BUF_2_ADDR_Y, MCIF_ADDR(params->luma_address[1]));
     99	REG_UPDATE(MCIF_WB_BUF_2_ADDR_Y_HIGH, MCIF_WB_BUF_2_ADDR_Y_HIGH, MCIF_ADDR_HIGH(params->luma_address[1]));
    100	/* right eye sub-buffer address offset for packing mode or Luma in planar mode */
    101	REG_UPDATE(MCIF_WB_BUF_2_ADDR_Y_OFFSET, MCIF_WB_BUF_2_ADDR_Y_OFFSET, 0);
    102
    103	/* buffer address for Chroma in planar mode (unused in packing mode) */
    104	REG_UPDATE(MCIF_WB_BUF_2_ADDR_C, MCIF_WB_BUF_2_ADDR_C, MCIF_ADDR(params->chroma_address[1]));
    105	REG_UPDATE(MCIF_WB_BUF_2_ADDR_C_HIGH, MCIF_WB_BUF_2_ADDR_C_HIGH, MCIF_ADDR_HIGH(params->chroma_address[1]));
    106	/* right eye offset for packing mode or Luma in planar mode */
    107	REG_UPDATE(MCIF_WB_BUF_2_ADDR_C_OFFSET, MCIF_WB_BUF_2_ADDR_C_OFFSET, 0);
    108
    109	/* buffer address for packing mode or Luma in planar mode */
    110	REG_UPDATE(MCIF_WB_BUF_3_ADDR_Y, MCIF_WB_BUF_3_ADDR_Y, MCIF_ADDR(params->luma_address[2]));
    111	REG_UPDATE(MCIF_WB_BUF_3_ADDR_Y_HIGH, MCIF_WB_BUF_3_ADDR_Y_HIGH, MCIF_ADDR_HIGH(params->luma_address[2]));
    112	/* right eye sub-buffer address offset for packing mode or Luma in planar mode */
    113	REG_UPDATE(MCIF_WB_BUF_3_ADDR_Y_OFFSET, MCIF_WB_BUF_3_ADDR_Y_OFFSET, 0);
    114
    115	/* buffer address for Chroma in planar mode (unused in packing mode) */
    116	REG_UPDATE(MCIF_WB_BUF_3_ADDR_C, MCIF_WB_BUF_3_ADDR_C, MCIF_ADDR(params->chroma_address[2]));
    117	REG_UPDATE(MCIF_WB_BUF_3_ADDR_C_HIGH, MCIF_WB_BUF_3_ADDR_C_HIGH, MCIF_ADDR_HIGH(params->chroma_address[2]));
    118	/* right eye offset for packing mode or Luma in planar mode */
    119	REG_UPDATE(MCIF_WB_BUF_3_ADDR_C_OFFSET, MCIF_WB_BUF_3_ADDR_C_OFFSET, 0);
    120
    121	/* buffer address for packing mode or Luma in planar mode */
    122	REG_UPDATE(MCIF_WB_BUF_4_ADDR_Y, MCIF_WB_BUF_4_ADDR_Y, MCIF_ADDR(params->luma_address[3]));
    123	REG_UPDATE(MCIF_WB_BUF_4_ADDR_Y_HIGH, MCIF_WB_BUF_4_ADDR_Y_HIGH, MCIF_ADDR_HIGH(params->luma_address[3]));
    124	/* right eye sub-buffer address offset for packing mode or Luma in planar mode */
    125	REG_UPDATE(MCIF_WB_BUF_4_ADDR_Y_OFFSET, MCIF_WB_BUF_4_ADDR_Y_OFFSET, 0);
    126
    127	/* buffer address for Chroma in planar mode (unused in packing mode) */
    128	REG_UPDATE(MCIF_WB_BUF_4_ADDR_C, MCIF_WB_BUF_4_ADDR_C, MCIF_ADDR(params->chroma_address[3]));
    129	REG_UPDATE(MCIF_WB_BUF_4_ADDR_C_HIGH, MCIF_WB_BUF_4_ADDR_C_HIGH, MCIF_ADDR_HIGH(params->chroma_address[3]));
    130	/* right eye offset for packing mode or Luma in planar mode */
    131	REG_UPDATE(MCIF_WB_BUF_4_ADDR_C_OFFSET, MCIF_WB_BUF_4_ADDR_C_OFFSET, 0);
    132
    133	/* setup luma & chroma size
    134	 * should be enough to contain a whole frame Luma data,
    135	 * the programmed value is frame buffer size [27:8], 256-byte aligned
    136	 */
    137	REG_UPDATE(MCIF_WB_BUF_LUMA_SIZE, MCIF_WB_BUF_LUMA_SIZE, (params->luma_pitch>>8) * dest_height);
    138	REG_UPDATE(MCIF_WB_BUF_CHROMA_SIZE, MCIF_WB_BUF_CHROMA_SIZE, (params->chroma_pitch>>8) * dest_height);
    139
    140	/* enable address fence */
    141	REG_UPDATE(MCIF_WB_BUFMGR_SW_CONTROL, MCIF_WB_BUF_ADDR_FENCE_EN, 1);
    142
    143	/* setup pitch, the programmed value is [15:8], 256B align */
    144	REG_UPDATE_2(MCIF_WB_BUF_PITCH, MCIF_WB_BUF_LUMA_PITCH, params->luma_pitch >> 8,
    145			MCIF_WB_BUF_CHROMA_PITCH, params->chroma_pitch >> 8);
    146
    147	/* Set pitch for MC cache warm up mode */
    148	/* Pitch is 256 bytes aligned. The default pitch is 4K */
    149	/* default is 0x10 */
    150	REG_UPDATE(MCIF_WB_WARM_UP_CNTL, MCIF_WB_PITCH_SIZE_WARMUP, params->warmup_pitch);
    151}
    152
    153static void mmhubbub2_config_mcif_arb(struct mcif_wb *mcif_wb,
    154		struct mcif_arb_params *params)
    155{
    156	struct dcn20_mmhubbub *mcif_wb20 = TO_DCN20_MMHUBBUB(mcif_wb);
    157
    158	/* Programmed by the video driver based on the CRTC timing (for DWB) */
    159	REG_UPDATE(MCIF_WB_ARBITRATION_CONTROL, MCIF_WB_TIME_PER_PIXEL, params->time_per_pixel);
    160
    161	/* Programming dwb watermark */
    162	/* Watermark to generate urgent in MCIF_WB_CLI, value is determined by MCIF_WB_CLI_WATERMARK_MASK. */
    163	/* Program in ns. A formula will be provided in the pseudo code to calculate the value. */
    164	REG_UPDATE(MCIF_WB_SCLK_CHANGE, MCIF_WB_CLI_WATERMARK_MASK, 0x0);
    165	/* urgent_watermarkA */
    166	REG_UPDATE(MCIF_WB_WATERMARK, MCIF_WB_CLI_WATERMARK,  params->cli_watermark[0]);
    167	REG_UPDATE(MCIF_WB_SCLK_CHANGE, MCIF_WB_CLI_WATERMARK_MASK, 0x1);
    168	/* urgent_watermarkB */
    169	REG_UPDATE(MCIF_WB_WATERMARK, MCIF_WB_CLI_WATERMARK,  params->cli_watermark[1]);
    170	REG_UPDATE(MCIF_WB_SCLK_CHANGE, MCIF_WB_CLI_WATERMARK_MASK, 0x2);
    171	/* urgent_watermarkC */
    172	REG_UPDATE(MCIF_WB_WATERMARK, MCIF_WB_CLI_WATERMARK,  params->cli_watermark[2]);
    173	REG_UPDATE(MCIF_WB_SCLK_CHANGE, MCIF_WB_CLI_WATERMARK_MASK, 0x3);
    174	/* urgent_watermarkD */
    175	REG_UPDATE(MCIF_WB_WATERMARK, MCIF_WB_CLI_WATERMARK,  params->cli_watermark[3]);
    176
    177	/* Programming nb pstate watermark */
    178	/* nbp_state_change_watermarkA */
    179	REG_UPDATE(MCIF_WB_NB_PSTATE_CONTROL, NB_PSTATE_CHANGE_WATERMARK_MASK, 0x0);
    180	REG_UPDATE(MCIF_WB_NB_PSTATE_LATENCY_WATERMARK,
    181			NB_PSTATE_CHANGE_REFRESH_WATERMARK, params->pstate_watermark[0]);
    182	/* nbp_state_change_watermarkB */
    183	REG_UPDATE(MCIF_WB_NB_PSTATE_CONTROL, NB_PSTATE_CHANGE_WATERMARK_MASK, 0x1);
    184	REG_UPDATE(MCIF_WB_NB_PSTATE_LATENCY_WATERMARK,
    185			NB_PSTATE_CHANGE_REFRESH_WATERMARK, params->pstate_watermark[1]);
    186	/* nbp_state_change_watermarkC */
    187	REG_UPDATE(MCIF_WB_NB_PSTATE_CONTROL, NB_PSTATE_CHANGE_WATERMARK_MASK, 0x2);
    188	REG_UPDATE(MCIF_WB_NB_PSTATE_LATENCY_WATERMARK,
    189			NB_PSTATE_CHANGE_REFRESH_WATERMARK, params->pstate_watermark[2]);
    190	/* nbp_state_change_watermarkD */
    191	REG_UPDATE(MCIF_WB_NB_PSTATE_CONTROL, NB_PSTATE_CHANGE_WATERMARK_MASK, 0x3);
    192	REG_UPDATE(MCIF_WB_NB_PSTATE_LATENCY_WATERMARK,
    193			NB_PSTATE_CHANGE_REFRESH_WATERMARK, params->pstate_watermark[3]);
    194
    195	/* max_scaled_time */
    196	REG_UPDATE(MULTI_LEVEL_QOS_CTRL, MAX_SCALED_TIME_TO_URGENT, params->max_scaled_time);
    197
    198	/* slice_lines */
    199	REG_UPDATE(MCIF_WB_BUFMGR_VCE_CONTROL, MCIF_WB_BUFMGR_SLICE_SIZE, params->slice_lines-1);
    200
    201	/* Set arbitration unit for Luma/Chroma */
    202	/* arb_unit=2 should be chosen for more efficiency */
    203	/* Arbitration size, 0: 512 bytes 1: 1024 bytes 2: 2048 Bytes */
    204	REG_UPDATE(MCIF_WB_ARBITRATION_CONTROL, MCIF_WB_CLIENT_ARBITRATION_SLICE,  params->arbitration_slice);
    205}
    206
    207void mmhubbub2_config_mcif_irq(struct mcif_wb *mcif_wb,
    208		struct mcif_irq_params *params)
    209{
    210	struct dcn20_mmhubbub *mcif_wb20 = TO_DCN20_MMHUBBUB(mcif_wb);
    211
    212	/* Set interrupt mask */
    213	REG_UPDATE(MCIF_WB_BUFMGR_SW_CONTROL, MCIF_WB_BUFMGR_SW_INT_EN, params->sw_int_en);
    214	REG_UPDATE(MCIF_WB_BUFMGR_SW_CONTROL, MCIF_WB_BUFMGR_SW_SLICE_INT_EN, params->sw_slice_int_en);
    215	REG_UPDATE(MCIF_WB_BUFMGR_SW_CONTROL, MCIF_WB_BUFMGR_SW_OVERRUN_INT_EN,  params->sw_overrun_int_en);
    216
    217	REG_UPDATE(MCIF_WB_BUFMGR_VCE_CONTROL, MCIF_WB_BUFMGR_VCE_INT_EN,  params->vce_int_en);
    218	REG_UPDATE(MCIF_WB_BUFMGR_VCE_CONTROL, MCIF_WB_BUFMGR_VCE_SLICE_INT_EN,  params->vce_slice_int_en);
    219}
    220
    221void mmhubbub2_enable_mcif(struct mcif_wb *mcif_wb)
    222{
    223	struct dcn20_mmhubbub *mcif_wb20 = TO_DCN20_MMHUBBUB(mcif_wb);
    224
    225	/* Enable Mcifwb */
    226	REG_UPDATE(MCIF_WB_BUFMGR_SW_CONTROL, MCIF_WB_BUFMGR_ENABLE, 1);
    227}
    228
    229void mmhubbub2_disable_mcif(struct mcif_wb *mcif_wb)
    230{
    231	struct dcn20_mmhubbub *mcif_wb20 = TO_DCN20_MMHUBBUB(mcif_wb);
    232
    233	/* disable buffer manager */
    234	REG_UPDATE(MCIF_WB_BUFMGR_SW_CONTROL, MCIF_WB_BUFMGR_ENABLE, 0);
    235}
    236
    237/* set which group of pstate watermark to use and set wbif watermark change request */
    238/*
    239static void mmhubbub2_wbif_watermark_change_req(struct mcif_wb *mcif_wb, unsigned int wm_set)
    240{
    241	struct dcn20_mmhubbub *mcif_wb20 = TO_DCN20_MMHUBBUB(mcif_wb);
    242	uint32_t change_req;
    243
    244	REG_GET(SMU_WM_CONTROL, MCIF_WB0_WM_CHG_REQ, &change_req);
    245	change_req = (change_req == 0) ? 1 : 0;
    246	REG_UPDATE(SMU_WM_CONTROL, MCIF_WB0_WM_CHG_SEL, wm_set);
    247	REG_UPDATE(SMU_WM_CONTROL, MCIF_WB0_WM_CHG_REQ, change_req);
    248}
    249*/
    250/* Set watermark change interrupt disable bit */
    251/*
    252static void mmhubbub2_set_wbif_watermark_change_int_disable(struct mcif_wb *mcif_wb, unsigned int ack_int_dis)
    253{
    254	struct dcn20_mmhubbub *mcif_wb20 = TO_DCN20_MMHUBBUB(mcif_wb);
    255
    256	REG_UPDATE(SMU_WM_CONTROL, MCIF_WB0_WM_CHG_ACK_INT_DIS, ack_int_dis);
    257}
    258*/
    259/* Read watermark change interrupt status */
    260/*
    261unsigned int mmhubbub2_get_wbif_watermark_change_int_status(struct mcif_wb *mcif_wb)
    262{
    263	struct dcn20_mmhubbub *mcif_wb20 = TO_DCN20_MMHUBBUB(mcif_wb);
    264	uint32_t irq_status;
    265
    266	REG_GET(SMU_WM_CONTROL, MCIF_WB0_WM_CHG_ACK_INT_STATUS, &irq_status);
    267	return irq_status;
    268}
    269*/
    270
    271void mcifwb2_dump_frame(struct mcif_wb *mcif_wb,
    272		struct mcif_buf_params *mcif_params,
    273		enum dwb_scaler_mode out_format,
    274		unsigned int dest_width,
    275		unsigned int dest_height,
    276		struct mcif_wb_frame_dump_info *dump_info,
    277		unsigned char *luma_buffer,
    278		unsigned char *chroma_buffer,
    279		unsigned char *dest_luma_buffer,
    280		unsigned char *dest_chroma_buffer)
    281{
    282	struct dcn20_mmhubbub *mcif_wb20 = TO_DCN20_MMHUBBUB(mcif_wb);
    283
    284	REG_UPDATE(MCIF_WB_BUFMGR_SW_CONTROL, MCIF_WB_BUFMGR_SW_LOCK, 0xf);
    285
    286	memcpy(dest_luma_buffer,   luma_buffer,   mcif_params->luma_pitch * dest_height);
    287	memcpy(dest_chroma_buffer, chroma_buffer, mcif_params->chroma_pitch * dest_height / 2);
    288
    289	REG_UPDATE(MCIF_WB_BUFMGR_SW_CONTROL, MCIF_WB_BUFMGR_SW_LOCK, 0x0);
    290
    291	dump_info->format	= out_format;
    292	dump_info->width	= dest_width;
    293	dump_info->height	= dest_height;
    294	dump_info->luma_pitch	= mcif_params->luma_pitch;
    295	dump_info->chroma_pitch	= mcif_params->chroma_pitch;
    296	dump_info->size		= dest_height * (mcif_params->luma_pitch + mcif_params->chroma_pitch);
    297}
    298
    299const struct mcif_wb_funcs dcn20_mmhubbub_funcs = {
    300	.enable_mcif		= mmhubbub2_enable_mcif,
    301	.disable_mcif		= mmhubbub2_disable_mcif,
    302	.config_mcif_buf	= mmhubbub2_config_mcif_buf,
    303	.config_mcif_arb	= mmhubbub2_config_mcif_arb,
    304	.config_mcif_irq	= mmhubbub2_config_mcif_irq,
    305	.dump_frame		= mcifwb2_dump_frame,
    306};
    307
    308void dcn20_mmhubbub_construct(struct dcn20_mmhubbub *mcif_wb20,
    309		struct dc_context *ctx,
    310		const struct dcn20_mmhubbub_registers *mcif_wb_regs,
    311		const struct dcn20_mmhubbub_shift *mcif_wb_shift,
    312		const struct dcn20_mmhubbub_mask *mcif_wb_mask,
    313		int inst)
    314{
    315	mcif_wb20->base.ctx = ctx;
    316
    317	mcif_wb20->base.inst = inst;
    318	mcif_wb20->base.funcs = &dcn20_mmhubbub_funcs;
    319
    320	mcif_wb20->mcif_wb_regs = mcif_wb_regs;
    321	mcif_wb20->mcif_wb_shift = mcif_wb_shift;
    322	mcif_wb20->mcif_wb_mask = mcif_wb_mask;
    323}