1bbeb64d0SHarry Wentland /* 2bbeb64d0SHarry Wentland * Copyright 2016 Advanced Micro Devices, Inc. 3bbeb64d0SHarry Wentland * 4bbeb64d0SHarry Wentland * Permission is hereby granted, free of charge, to any person obtaining a 5bbeb64d0SHarry Wentland * copy of this software and associated documentation files (the "Software"), 6bbeb64d0SHarry Wentland * to deal in the Software without restriction, including without limitation 7bbeb64d0SHarry Wentland * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8bbeb64d0SHarry Wentland * and/or sell copies of the Software, and to permit persons to whom the 9bbeb64d0SHarry Wentland * Software is furnished to do so, subject to the following conditions: 10bbeb64d0SHarry Wentland * 11bbeb64d0SHarry Wentland * The above copyright notice and this permission notice shall be included in 12bbeb64d0SHarry Wentland * all copies or substantial portions of the Software. 13bbeb64d0SHarry Wentland * 14bbeb64d0SHarry Wentland * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15bbeb64d0SHarry Wentland * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16bbeb64d0SHarry Wentland * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17bbeb64d0SHarry Wentland * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18bbeb64d0SHarry Wentland * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19bbeb64d0SHarry Wentland * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20bbeb64d0SHarry Wentland * OTHER DEALINGS IN THE SOFTWARE. 21bbeb64d0SHarry Wentland * 22bbeb64d0SHarry Wentland * Authors: AMD 23bbeb64d0SHarry Wentland * 24bbeb64d0SHarry Wentland */ 25bbeb64d0SHarry Wentland 26bbeb64d0SHarry Wentland 27bbeb64d0SHarry Wentland #include "dcn20_hubbub.h" 28bbeb64d0SHarry Wentland #include "reg_helper.h" 29057fc695SJun Lei #include "clk_mgr.h" 30bbeb64d0SHarry Wentland 31bbeb64d0SHarry Wentland #define REG(reg)\ 32bbeb64d0SHarry Wentland hubbub1->regs->reg 33bbeb64d0SHarry Wentland 34bbeb64d0SHarry Wentland #define CTX \ 35bbeb64d0SHarry Wentland hubbub1->base.ctx 36bbeb64d0SHarry Wentland 37bbeb64d0SHarry Wentland #undef FN 38bbeb64d0SHarry Wentland #define FN(reg_name, field_name) \ 39bbeb64d0SHarry Wentland hubbub1->shifts->field_name, hubbub1->masks->field_name 40bbeb64d0SHarry Wentland 41bbeb64d0SHarry Wentland #define REG(reg)\ 42bbeb64d0SHarry Wentland hubbub1->regs->reg 43bbeb64d0SHarry Wentland 44bbeb64d0SHarry Wentland #define CTX \ 45bbeb64d0SHarry Wentland hubbub1->base.ctx 46bbeb64d0SHarry Wentland 47bbeb64d0SHarry Wentland #undef FN 48bbeb64d0SHarry Wentland #define FN(reg_name, field_name) \ 49bbeb64d0SHarry Wentland hubbub1->shifts->field_name, hubbub1->masks->field_name 50bbeb64d0SHarry Wentland 51bda9afdaSDmytro Laktyushkin #ifdef NUM_VMID 52bda9afdaSDmytro Laktyushkin #undef NUM_VMID 53bda9afdaSDmytro Laktyushkin #endif 54bda9afdaSDmytro Laktyushkin #define NUM_VMID 16 55bda9afdaSDmytro Laktyushkin 56bbeb64d0SHarry Wentland bool hubbub2_dcc_support_swizzle( 57bbeb64d0SHarry Wentland enum swizzle_mode_values swizzle, 58bbeb64d0SHarry Wentland unsigned int bytes_per_element, 59bbeb64d0SHarry Wentland enum segment_order *segment_order_horz, 60bbeb64d0SHarry Wentland enum segment_order *segment_order_vert) 61bbeb64d0SHarry Wentland { 62bbeb64d0SHarry Wentland bool standard_swizzle = false; 63bbeb64d0SHarry Wentland bool display_swizzle = false; 64bbeb64d0SHarry Wentland bool render_swizzle = false; 65bbeb64d0SHarry Wentland 66bbeb64d0SHarry Wentland switch (swizzle) { 67bbeb64d0SHarry Wentland case DC_SW_4KB_S: 68bbeb64d0SHarry Wentland case DC_SW_64KB_S: 69bbeb64d0SHarry Wentland case DC_SW_VAR_S: 70bbeb64d0SHarry Wentland case DC_SW_4KB_S_X: 71bbeb64d0SHarry Wentland case DC_SW_64KB_S_X: 72bbeb64d0SHarry Wentland case DC_SW_VAR_S_X: 73bbeb64d0SHarry Wentland standard_swizzle = true; 74bbeb64d0SHarry Wentland break; 75bbeb64d0SHarry Wentland case DC_SW_64KB_R_X: 76bbeb64d0SHarry Wentland render_swizzle = true; 77bbeb64d0SHarry Wentland break; 78bbeb64d0SHarry Wentland case DC_SW_4KB_D: 79bbeb64d0SHarry Wentland case DC_SW_64KB_D: 80bbeb64d0SHarry Wentland case DC_SW_VAR_D: 81bbeb64d0SHarry Wentland case DC_SW_4KB_D_X: 82bbeb64d0SHarry Wentland case DC_SW_64KB_D_X: 83bbeb64d0SHarry Wentland case DC_SW_VAR_D_X: 84bbeb64d0SHarry Wentland display_swizzle = true; 85bbeb64d0SHarry Wentland break; 86bbeb64d0SHarry Wentland default: 87bbeb64d0SHarry Wentland break; 88bbeb64d0SHarry Wentland } 89bbeb64d0SHarry Wentland 90bbeb64d0SHarry Wentland if (standard_swizzle) { 91bbeb64d0SHarry Wentland if (bytes_per_element == 1) { 92bbeb64d0SHarry Wentland *segment_order_horz = segment_order__contiguous; 93bbeb64d0SHarry Wentland *segment_order_vert = segment_order__na; 94bbeb64d0SHarry Wentland return true; 95bbeb64d0SHarry Wentland } 96bbeb64d0SHarry Wentland if (bytes_per_element == 2) { 97bbeb64d0SHarry Wentland *segment_order_horz = segment_order__non_contiguous; 98bbeb64d0SHarry Wentland *segment_order_vert = segment_order__contiguous; 99bbeb64d0SHarry Wentland return true; 100bbeb64d0SHarry Wentland } 101bbeb64d0SHarry Wentland if (bytes_per_element == 4) { 102bbeb64d0SHarry Wentland *segment_order_horz = segment_order__non_contiguous; 103bbeb64d0SHarry Wentland *segment_order_vert = segment_order__contiguous; 104bbeb64d0SHarry Wentland return true; 105bbeb64d0SHarry Wentland } 106bbeb64d0SHarry Wentland if (bytes_per_element == 8) { 107bbeb64d0SHarry Wentland *segment_order_horz = segment_order__na; 108bbeb64d0SHarry Wentland *segment_order_vert = segment_order__contiguous; 109bbeb64d0SHarry Wentland return true; 110bbeb64d0SHarry Wentland } 111bbeb64d0SHarry Wentland } 112bbeb64d0SHarry Wentland if (render_swizzle) { 113bbeb64d0SHarry Wentland if (bytes_per_element == 2) { 114bbeb64d0SHarry Wentland *segment_order_horz = segment_order__contiguous; 115bbeb64d0SHarry Wentland *segment_order_vert = segment_order__contiguous; 116bbeb64d0SHarry Wentland return true; 117bbeb64d0SHarry Wentland } 118bbeb64d0SHarry Wentland if (bytes_per_element == 4) { 119bbeb64d0SHarry Wentland *segment_order_horz = segment_order__non_contiguous; 120bbeb64d0SHarry Wentland *segment_order_vert = segment_order__contiguous; 121bbeb64d0SHarry Wentland return true; 122bbeb64d0SHarry Wentland } 123bbeb64d0SHarry Wentland if (bytes_per_element == 8) { 124bbeb64d0SHarry Wentland *segment_order_horz = segment_order__contiguous; 125bbeb64d0SHarry Wentland *segment_order_vert = segment_order__non_contiguous; 126bbeb64d0SHarry Wentland return true; 127bbeb64d0SHarry Wentland } 128bbeb64d0SHarry Wentland } 129bbeb64d0SHarry Wentland if (display_swizzle && bytes_per_element == 8) { 130bbeb64d0SHarry Wentland *segment_order_horz = segment_order__contiguous; 131bbeb64d0SHarry Wentland *segment_order_vert = segment_order__non_contiguous; 132bbeb64d0SHarry Wentland return true; 133bbeb64d0SHarry Wentland } 134bbeb64d0SHarry Wentland 135bbeb64d0SHarry Wentland return false; 136bbeb64d0SHarry Wentland } 137bbeb64d0SHarry Wentland 138bbeb64d0SHarry Wentland bool hubbub2_dcc_support_pixel_format( 139bbeb64d0SHarry Wentland enum surface_pixel_format format, 140bbeb64d0SHarry Wentland unsigned int *bytes_per_element) 141bbeb64d0SHarry Wentland { 142bbeb64d0SHarry Wentland /* DML: get_bytes_per_element */ 143bbeb64d0SHarry Wentland switch (format) { 144bbeb64d0SHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555: 145bbeb64d0SHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_RGB565: 146bbeb64d0SHarry Wentland *bytes_per_element = 2; 147bbeb64d0SHarry Wentland return true; 148bbeb64d0SHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888: 149bbeb64d0SHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888: 150bbeb64d0SHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010: 151bbeb64d0SHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010: 152bbeb64d0SHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FIX: 153bbeb64d0SHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FIX: 154bbeb64d0SHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FLOAT: 155bbeb64d0SHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FLOAT: 156bbeb64d0SHarry Wentland *bytes_per_element = 4; 157bbeb64d0SHarry Wentland return true; 158bbeb64d0SHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616: 159bbeb64d0SHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F: 160bbeb64d0SHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F: 161bbeb64d0SHarry Wentland *bytes_per_element = 8; 162bbeb64d0SHarry Wentland return true; 163bbeb64d0SHarry Wentland default: 164bbeb64d0SHarry Wentland return false; 165bbeb64d0SHarry Wentland } 166bbeb64d0SHarry Wentland } 167bbeb64d0SHarry Wentland 168bbeb64d0SHarry Wentland static void hubbub2_get_blk256_size(unsigned int *blk256_width, unsigned int *blk256_height, 169bbeb64d0SHarry Wentland unsigned int bytes_per_element) 170bbeb64d0SHarry Wentland { 171bbeb64d0SHarry Wentland /* copied from DML. might want to refactor DML to leverage from DML */ 172bbeb64d0SHarry Wentland /* DML : get_blk256_size */ 173bbeb64d0SHarry Wentland if (bytes_per_element == 1) { 174bbeb64d0SHarry Wentland *blk256_width = 16; 175bbeb64d0SHarry Wentland *blk256_height = 16; 176bbeb64d0SHarry Wentland } else if (bytes_per_element == 2) { 177bbeb64d0SHarry Wentland *blk256_width = 16; 178bbeb64d0SHarry Wentland *blk256_height = 8; 179bbeb64d0SHarry Wentland } else if (bytes_per_element == 4) { 180bbeb64d0SHarry Wentland *blk256_width = 8; 181bbeb64d0SHarry Wentland *blk256_height = 8; 182bbeb64d0SHarry Wentland } else if (bytes_per_element == 8) { 183bbeb64d0SHarry Wentland *blk256_width = 8; 184bbeb64d0SHarry Wentland *blk256_height = 4; 185bbeb64d0SHarry Wentland } 186bbeb64d0SHarry Wentland } 187bbeb64d0SHarry Wentland 188bbeb64d0SHarry Wentland static void hubbub2_det_request_size( 189bbeb64d0SHarry Wentland unsigned int height, 190bbeb64d0SHarry Wentland unsigned int width, 191bbeb64d0SHarry Wentland unsigned int bpe, 192bbeb64d0SHarry Wentland bool *req128_horz_wc, 193bbeb64d0SHarry Wentland bool *req128_vert_wc) 194bbeb64d0SHarry Wentland { 195bbeb64d0SHarry Wentland unsigned int detile_buf_size = 164 * 1024; /* 164KB for DCN1.0 */ 196bbeb64d0SHarry Wentland 197bbeb64d0SHarry Wentland unsigned int blk256_height = 0; 198bbeb64d0SHarry Wentland unsigned int blk256_width = 0; 199bbeb64d0SHarry Wentland unsigned int swath_bytes_horz_wc, swath_bytes_vert_wc; 200bbeb64d0SHarry Wentland 201bbeb64d0SHarry Wentland hubbub2_get_blk256_size(&blk256_width, &blk256_height, bpe); 202bbeb64d0SHarry Wentland 2030cd32625SBob Yang swath_bytes_horz_wc = width * blk256_height * bpe; 2040cd32625SBob Yang swath_bytes_vert_wc = height * blk256_width * bpe; 205bbeb64d0SHarry Wentland 206bbeb64d0SHarry Wentland *req128_horz_wc = (2 * swath_bytes_horz_wc <= detile_buf_size) ? 207bbeb64d0SHarry Wentland false : /* full 256B request */ 208bbeb64d0SHarry Wentland true; /* half 128b request */ 209bbeb64d0SHarry Wentland 210bbeb64d0SHarry Wentland *req128_vert_wc = (2 * swath_bytes_vert_wc <= detile_buf_size) ? 211bbeb64d0SHarry Wentland false : /* full 256B request */ 212bbeb64d0SHarry Wentland true; /* half 128b request */ 213bbeb64d0SHarry Wentland } 214bbeb64d0SHarry Wentland 215bbeb64d0SHarry Wentland bool hubbub2_get_dcc_compression_cap(struct hubbub *hubbub, 216bbeb64d0SHarry Wentland const struct dc_dcc_surface_param *input, 217bbeb64d0SHarry Wentland struct dc_surface_dcc_cap *output) 218bbeb64d0SHarry Wentland { 219bbeb64d0SHarry Wentland struct dc *dc = hubbub->ctx->dc; 220bbeb64d0SHarry Wentland /* implement section 1.6.2.1 of DCN1_Programming_Guide.docx */ 221bbeb64d0SHarry Wentland enum dcc_control dcc_control; 222bbeb64d0SHarry Wentland unsigned int bpe; 223bbeb64d0SHarry Wentland enum segment_order segment_order_horz, segment_order_vert; 224bbeb64d0SHarry Wentland bool req128_horz_wc, req128_vert_wc; 225bbeb64d0SHarry Wentland 226bbeb64d0SHarry Wentland memset(output, 0, sizeof(*output)); 227bbeb64d0SHarry Wentland 228bbeb64d0SHarry Wentland if (dc->debug.disable_dcc == DCC_DISABLE) 229bbeb64d0SHarry Wentland return false; 230bbeb64d0SHarry Wentland 231bbeb64d0SHarry Wentland if (!hubbub->funcs->dcc_support_pixel_format(input->format, 232bbeb64d0SHarry Wentland &bpe)) 233bbeb64d0SHarry Wentland return false; 234bbeb64d0SHarry Wentland 235bbeb64d0SHarry Wentland if (!hubbub->funcs->dcc_support_swizzle(input->swizzle_mode, bpe, 236bbeb64d0SHarry Wentland &segment_order_horz, &segment_order_vert)) 237bbeb64d0SHarry Wentland return false; 238bbeb64d0SHarry Wentland 239bbeb64d0SHarry Wentland hubbub2_det_request_size(input->surface_size.height, input->surface_size.width, 240bbeb64d0SHarry Wentland bpe, &req128_horz_wc, &req128_vert_wc); 241bbeb64d0SHarry Wentland 242bbeb64d0SHarry Wentland if (!req128_horz_wc && !req128_vert_wc) { 243bbeb64d0SHarry Wentland dcc_control = dcc_control__256_256_xxx; 244bbeb64d0SHarry Wentland } else if (input->scan == SCAN_DIRECTION_HORIZONTAL) { 245bbeb64d0SHarry Wentland if (!req128_horz_wc) 246bbeb64d0SHarry Wentland dcc_control = dcc_control__256_256_xxx; 247bbeb64d0SHarry Wentland else if (segment_order_horz == segment_order__contiguous) 248bbeb64d0SHarry Wentland dcc_control = dcc_control__128_128_xxx; 249bbeb64d0SHarry Wentland else 250bbeb64d0SHarry Wentland dcc_control = dcc_control__256_64_64; 251bbeb64d0SHarry Wentland } else if (input->scan == SCAN_DIRECTION_VERTICAL) { 252bbeb64d0SHarry Wentland if (!req128_vert_wc) 253bbeb64d0SHarry Wentland dcc_control = dcc_control__256_256_xxx; 254bbeb64d0SHarry Wentland else if (segment_order_vert == segment_order__contiguous) 255bbeb64d0SHarry Wentland dcc_control = dcc_control__128_128_xxx; 256bbeb64d0SHarry Wentland else 257bbeb64d0SHarry Wentland dcc_control = dcc_control__256_64_64; 258bbeb64d0SHarry Wentland } else { 259bbeb64d0SHarry Wentland if ((req128_horz_wc && 260bbeb64d0SHarry Wentland segment_order_horz == segment_order__non_contiguous) || 261bbeb64d0SHarry Wentland (req128_vert_wc && 262bbeb64d0SHarry Wentland segment_order_vert == segment_order__non_contiguous)) 263bbeb64d0SHarry Wentland /* access_dir not known, must use most constraining */ 264bbeb64d0SHarry Wentland dcc_control = dcc_control__256_64_64; 265bbeb64d0SHarry Wentland else 266bbeb64d0SHarry Wentland /* reg128 is true for either horz and vert 267bbeb64d0SHarry Wentland * but segment_order is contiguous 268bbeb64d0SHarry Wentland */ 269bbeb64d0SHarry Wentland dcc_control = dcc_control__128_128_xxx; 270bbeb64d0SHarry Wentland } 271bbeb64d0SHarry Wentland 272bbeb64d0SHarry Wentland /* Exception for 64KB_R_X */ 273bbeb64d0SHarry Wentland if ((bpe == 2) && (input->swizzle_mode == DC_SW_64KB_R_X)) 274bbeb64d0SHarry Wentland dcc_control = dcc_control__128_128_xxx; 275bbeb64d0SHarry Wentland 276bbeb64d0SHarry Wentland if (dc->debug.disable_dcc == DCC_HALF_REQ_DISALBE && 277bbeb64d0SHarry Wentland dcc_control != dcc_control__256_256_xxx) 278bbeb64d0SHarry Wentland return false; 279bbeb64d0SHarry Wentland 280bbeb64d0SHarry Wentland switch (dcc_control) { 281bbeb64d0SHarry Wentland case dcc_control__256_256_xxx: 282bbeb64d0SHarry Wentland output->grph.rgb.max_uncompressed_blk_size = 256; 283bbeb64d0SHarry Wentland output->grph.rgb.max_compressed_blk_size = 256; 284bbeb64d0SHarry Wentland output->grph.rgb.independent_64b_blks = false; 285bbeb64d0SHarry Wentland break; 286bbeb64d0SHarry Wentland case dcc_control__128_128_xxx: 287bbeb64d0SHarry Wentland output->grph.rgb.max_uncompressed_blk_size = 128; 288bbeb64d0SHarry Wentland output->grph.rgb.max_compressed_blk_size = 128; 289bbeb64d0SHarry Wentland output->grph.rgb.independent_64b_blks = false; 290bbeb64d0SHarry Wentland break; 291bbeb64d0SHarry Wentland case dcc_control__256_64_64: 292bbeb64d0SHarry Wentland output->grph.rgb.max_uncompressed_blk_size = 256; 293bbeb64d0SHarry Wentland output->grph.rgb.max_compressed_blk_size = 64; 294bbeb64d0SHarry Wentland output->grph.rgb.independent_64b_blks = true; 295bbeb64d0SHarry Wentland break; 296bbeb64d0SHarry Wentland } 297bbeb64d0SHarry Wentland output->capable = true; 298bbeb64d0SHarry Wentland output->const_color_support = true; 299bbeb64d0SHarry Wentland 300bbeb64d0SHarry Wentland return true; 301bbeb64d0SHarry Wentland } 302bbeb64d0SHarry Wentland 3033979efceSJun Lei static enum dcn_hubbub_page_table_depth page_table_depth_to_hw(unsigned int page_table_depth) 3043979efceSJun Lei { 3053979efceSJun Lei enum dcn_hubbub_page_table_depth depth = 0; 3063979efceSJun Lei 3073979efceSJun Lei switch (page_table_depth) { 3083979efceSJun Lei case 1: 3093979efceSJun Lei depth = DCN_PAGE_TABLE_DEPTH_1_LEVEL; 3103979efceSJun Lei break; 3113979efceSJun Lei case 2: 3123979efceSJun Lei depth = DCN_PAGE_TABLE_DEPTH_2_LEVEL; 3133979efceSJun Lei break; 3143979efceSJun Lei case 3: 3153979efceSJun Lei depth = DCN_PAGE_TABLE_DEPTH_3_LEVEL; 3163979efceSJun Lei break; 3173979efceSJun Lei case 4: 3183979efceSJun Lei depth = DCN_PAGE_TABLE_DEPTH_4_LEVEL; 3193979efceSJun Lei break; 3203979efceSJun Lei default: 3213979efceSJun Lei ASSERT(false); 3223979efceSJun Lei break; 3233979efceSJun Lei } 3243979efceSJun Lei 3253979efceSJun Lei return depth; 3263979efceSJun Lei } 3273979efceSJun Lei 3283979efceSJun Lei static enum dcn_hubbub_page_table_block_size page_table_block_size_to_hw(unsigned int page_table_block_size) 3293979efceSJun Lei { 3303979efceSJun Lei enum dcn_hubbub_page_table_block_size block_size = 0; 3313979efceSJun Lei 3323979efceSJun Lei switch (page_table_block_size) { 3333979efceSJun Lei case 4096: 3343979efceSJun Lei block_size = DCN_PAGE_TABLE_BLOCK_SIZE_4KB; 3353979efceSJun Lei break; 3363979efceSJun Lei case 65536: 3373979efceSJun Lei block_size = DCN_PAGE_TABLE_BLOCK_SIZE_64KB; 3383979efceSJun Lei break; 3393979efceSJun Lei default: 3403979efceSJun Lei ASSERT(false); 341a6f30079SDmytro Laktyushkin block_size = page_table_block_size; 3423979efceSJun Lei break; 3433979efceSJun Lei } 3443979efceSJun Lei 3453979efceSJun Lei return block_size; 3463979efceSJun Lei } 347bbeb64d0SHarry Wentland 348bda9afdaSDmytro Laktyushkin void hubbub2_init_vm_ctx(struct hubbub *hubbub, 349bda9afdaSDmytro Laktyushkin struct dcn_hubbub_virt_addr_config *va_config, 350bda9afdaSDmytro Laktyushkin int vmid) 351bbeb64d0SHarry Wentland { 352bbeb64d0SHarry Wentland struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); 353bbeb64d0SHarry Wentland struct dcn_vmid_page_table_config virt_config; 354bbeb64d0SHarry Wentland 355bda9afdaSDmytro Laktyushkin virt_config.page_table_start_addr = va_config->page_table_start_addr >> 12; 356bda9afdaSDmytro Laktyushkin virt_config.page_table_end_addr = va_config->page_table_end_addr >> 12; 357bda9afdaSDmytro Laktyushkin virt_config.depth = page_table_depth_to_hw(va_config->page_table_depth); 358bda9afdaSDmytro Laktyushkin virt_config.block_size = page_table_block_size_to_hw(va_config->page_table_block_size); 359bda9afdaSDmytro Laktyushkin virt_config.page_table_base_addr = va_config->page_table_base_addr; 360bbeb64d0SHarry Wentland 361bda9afdaSDmytro Laktyushkin dcn20_vmid_setup(&hubbub1->vmid[vmid], &virt_config); 362bda9afdaSDmytro Laktyushkin } 363bda9afdaSDmytro Laktyushkin 364bda9afdaSDmytro Laktyushkin int hubbub2_init_dchub_sys_ctx(struct hubbub *hubbub, 365bda9afdaSDmytro Laktyushkin struct dcn_hubbub_phys_addr_config *pa_config) 366bda9afdaSDmytro Laktyushkin { 367bda9afdaSDmytro Laktyushkin struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); 368bda9afdaSDmytro Laktyushkin struct dcn_vmid_page_table_config phys_config; 369bda9afdaSDmytro Laktyushkin 370bda9afdaSDmytro Laktyushkin REG_SET(DCN_VM_FB_LOCATION_BASE, 0, 371b48935b3SJun Lei FB_BASE, pa_config->system_aperture.fb_base >> 24); 372bda9afdaSDmytro Laktyushkin REG_SET(DCN_VM_FB_LOCATION_TOP, 0, 373b48935b3SJun Lei FB_TOP, pa_config->system_aperture.fb_top >> 24); 374bda9afdaSDmytro Laktyushkin REG_SET(DCN_VM_FB_OFFSET, 0, 375b48935b3SJun Lei FB_OFFSET, pa_config->system_aperture.fb_offset >> 24); 376bda9afdaSDmytro Laktyushkin REG_SET(DCN_VM_AGP_BOT, 0, 377b48935b3SJun Lei AGP_BOT, pa_config->system_aperture.agp_bot >> 24); 378bda9afdaSDmytro Laktyushkin REG_SET(DCN_VM_AGP_TOP, 0, 379b48935b3SJun Lei AGP_TOP, pa_config->system_aperture.agp_top >> 24); 380bda9afdaSDmytro Laktyushkin REG_SET(DCN_VM_AGP_BASE, 0, 381b48935b3SJun Lei AGP_BASE, pa_config->system_aperture.agp_base >> 24); 382bda9afdaSDmytro Laktyushkin 383bda9afdaSDmytro Laktyushkin if (pa_config->gart_config.page_table_start_addr != pa_config->gart_config.page_table_end_addr) { 384bda9afdaSDmytro Laktyushkin phys_config.page_table_start_addr = pa_config->gart_config.page_table_start_addr >> 12; 385bda9afdaSDmytro Laktyushkin phys_config.page_table_end_addr = pa_config->gart_config.page_table_end_addr >> 12; 386bda9afdaSDmytro Laktyushkin phys_config.page_table_base_addr = pa_config->gart_config.page_table_base_addr; 387b48935b3SJun Lei phys_config.depth = 0; 388b48935b3SJun Lei phys_config.block_size = 0; 389bbeb64d0SHarry Wentland // Init VMID 0 based on PA config 390bbeb64d0SHarry Wentland dcn20_vmid_setup(&hubbub1->vmid[0], &phys_config); 3913979efceSJun Lei } 392bbeb64d0SHarry Wentland 393bda9afdaSDmytro Laktyushkin return NUM_VMID; 3943979efceSJun Lei } 395bbeb64d0SHarry Wentland 396bbeb64d0SHarry Wentland void hubbub2_update_dchub(struct hubbub *hubbub, 397bbeb64d0SHarry Wentland struct dchub_init_data *dh_data) 398bbeb64d0SHarry Wentland { 399bbeb64d0SHarry Wentland struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); 400bbeb64d0SHarry Wentland 401bbeb64d0SHarry Wentland if (REG(DCHUBBUB_SDPIF_FB_TOP) == 0) { 402bbeb64d0SHarry Wentland ASSERT(false); 403bbeb64d0SHarry Wentland /*should not come here*/ 404bbeb64d0SHarry Wentland return; 405bbeb64d0SHarry Wentland } 406bbeb64d0SHarry Wentland /* TODO: port code from dal2 */ 407bbeb64d0SHarry Wentland switch (dh_data->fb_mode) { 408bbeb64d0SHarry Wentland case FRAME_BUFFER_MODE_ZFB_ONLY: 409bbeb64d0SHarry Wentland /*For ZFB case need to put DCHUB FB BASE and TOP upside down to indicate ZFB mode*/ 410bbeb64d0SHarry Wentland REG_UPDATE(DCHUBBUB_SDPIF_FB_TOP, 411bbeb64d0SHarry Wentland SDPIF_FB_TOP, 0); 412bbeb64d0SHarry Wentland 413bbeb64d0SHarry Wentland REG_UPDATE(DCHUBBUB_SDPIF_FB_BASE, 414bbeb64d0SHarry Wentland SDPIF_FB_BASE, 0x0FFFF); 415bbeb64d0SHarry Wentland 416bbeb64d0SHarry Wentland REG_UPDATE(DCHUBBUB_SDPIF_AGP_BASE, 417bbeb64d0SHarry Wentland SDPIF_AGP_BASE, dh_data->zfb_phys_addr_base >> 22); 418bbeb64d0SHarry Wentland 419bbeb64d0SHarry Wentland REG_UPDATE(DCHUBBUB_SDPIF_AGP_BOT, 420bbeb64d0SHarry Wentland SDPIF_AGP_BOT, dh_data->zfb_mc_base_addr >> 22); 421bbeb64d0SHarry Wentland 422bbeb64d0SHarry Wentland REG_UPDATE(DCHUBBUB_SDPIF_AGP_TOP, 423bbeb64d0SHarry Wentland SDPIF_AGP_TOP, (dh_data->zfb_mc_base_addr + 424bbeb64d0SHarry Wentland dh_data->zfb_size_in_byte - 1) >> 22); 425bbeb64d0SHarry Wentland break; 426bbeb64d0SHarry Wentland case FRAME_BUFFER_MODE_MIXED_ZFB_AND_LOCAL: 427bbeb64d0SHarry Wentland /*Should not touch FB LOCATION (done by VBIOS on AsicInit table)*/ 428bbeb64d0SHarry Wentland 429bbeb64d0SHarry Wentland REG_UPDATE(DCHUBBUB_SDPIF_AGP_BASE, 430bbeb64d0SHarry Wentland SDPIF_AGP_BASE, dh_data->zfb_phys_addr_base >> 22); 431bbeb64d0SHarry Wentland 432bbeb64d0SHarry Wentland REG_UPDATE(DCHUBBUB_SDPIF_AGP_BOT, 433bbeb64d0SHarry Wentland SDPIF_AGP_BOT, dh_data->zfb_mc_base_addr >> 22); 434bbeb64d0SHarry Wentland 435bbeb64d0SHarry Wentland REG_UPDATE(DCHUBBUB_SDPIF_AGP_TOP, 436bbeb64d0SHarry Wentland SDPIF_AGP_TOP, (dh_data->zfb_mc_base_addr + 437bbeb64d0SHarry Wentland dh_data->zfb_size_in_byte - 1) >> 22); 438bbeb64d0SHarry Wentland break; 439bbeb64d0SHarry Wentland case FRAME_BUFFER_MODE_LOCAL_ONLY: 440bbeb64d0SHarry Wentland /*Should not touch FB LOCATION (done by VBIOS on AsicInit table)*/ 441bbeb64d0SHarry Wentland REG_UPDATE(DCHUBBUB_SDPIF_AGP_BASE, 442bbeb64d0SHarry Wentland SDPIF_AGP_BASE, 0); 443bbeb64d0SHarry Wentland 444bbeb64d0SHarry Wentland REG_UPDATE(DCHUBBUB_SDPIF_AGP_BOT, 445bbeb64d0SHarry Wentland SDPIF_AGP_BOT, 0X03FFFF); 446bbeb64d0SHarry Wentland 447bbeb64d0SHarry Wentland REG_UPDATE(DCHUBBUB_SDPIF_AGP_TOP, 448bbeb64d0SHarry Wentland SDPIF_AGP_TOP, 0); 449bbeb64d0SHarry Wentland break; 450bbeb64d0SHarry Wentland default: 451bbeb64d0SHarry Wentland break; 452bbeb64d0SHarry Wentland } 453bbeb64d0SHarry Wentland 454bbeb64d0SHarry Wentland dh_data->dchub_initialzied = true; 455bbeb64d0SHarry Wentland dh_data->dchub_info_valid = false; 456bbeb64d0SHarry Wentland } 457bbeb64d0SHarry Wentland 458bbeb64d0SHarry Wentland void hubbub2_wm_read_state(struct hubbub *hubbub, 459bbeb64d0SHarry Wentland struct dcn_hubbub_wm *wm) 460bbeb64d0SHarry Wentland { 461bbeb64d0SHarry Wentland struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); 462bbeb64d0SHarry Wentland 463bbeb64d0SHarry Wentland struct dcn_hubbub_wm_set *s; 464bbeb64d0SHarry Wentland 465bbeb64d0SHarry Wentland memset(wm, 0, sizeof(struct dcn_hubbub_wm)); 466bbeb64d0SHarry Wentland 467bbeb64d0SHarry Wentland s = &wm->sets[0]; 468bbeb64d0SHarry Wentland s->wm_set = 0; 469bbeb64d0SHarry Wentland s->data_urgent = REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A); 470bbeb64d0SHarry Wentland if (REG(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A)) 471bbeb64d0SHarry Wentland s->pte_meta_urgent = REG_READ(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A); 472bbeb64d0SHarry Wentland if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A)) { 473bbeb64d0SHarry Wentland s->sr_enter = REG_READ(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A); 474bbeb64d0SHarry Wentland s->sr_exit = REG_READ(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A); 475bbeb64d0SHarry Wentland } 476bbeb64d0SHarry Wentland s->dram_clk_chanage = REG_READ(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A); 477bbeb64d0SHarry Wentland 478bbeb64d0SHarry Wentland s = &wm->sets[1]; 479bbeb64d0SHarry Wentland s->wm_set = 1; 480bbeb64d0SHarry Wentland s->data_urgent = REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B); 481bbeb64d0SHarry Wentland if (REG(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B)) 482bbeb64d0SHarry Wentland s->pte_meta_urgent = REG_READ(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B); 483bbeb64d0SHarry Wentland if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B)) { 484bbeb64d0SHarry Wentland s->sr_enter = REG_READ(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B); 485bbeb64d0SHarry Wentland s->sr_exit = REG_READ(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B); 486bbeb64d0SHarry Wentland } 487bbeb64d0SHarry Wentland s->dram_clk_chanage = REG_READ(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B); 488bbeb64d0SHarry Wentland 489bbeb64d0SHarry Wentland s = &wm->sets[2]; 490bbeb64d0SHarry Wentland s->wm_set = 2; 491bbeb64d0SHarry Wentland s->data_urgent = REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C); 492bbeb64d0SHarry Wentland if (REG(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C)) 493bbeb64d0SHarry Wentland s->pte_meta_urgent = REG_READ(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C); 494bbeb64d0SHarry Wentland if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C)) { 495bbeb64d0SHarry Wentland s->sr_enter = REG_READ(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C); 496bbeb64d0SHarry Wentland s->sr_exit = REG_READ(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C); 497bbeb64d0SHarry Wentland } 498bbeb64d0SHarry Wentland s->dram_clk_chanage = REG_READ(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C); 499bbeb64d0SHarry Wentland 500bbeb64d0SHarry Wentland s = &wm->sets[3]; 501bbeb64d0SHarry Wentland s->wm_set = 3; 502bbeb64d0SHarry Wentland s->data_urgent = REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D); 503bbeb64d0SHarry Wentland if (REG(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D)) 504bbeb64d0SHarry Wentland s->pte_meta_urgent = REG_READ(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D); 505bbeb64d0SHarry Wentland if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D)) { 506bbeb64d0SHarry Wentland s->sr_enter = REG_READ(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D); 507bbeb64d0SHarry Wentland s->sr_exit = REG_READ(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D); 508bbeb64d0SHarry Wentland } 509bbeb64d0SHarry Wentland s->dram_clk_chanage = REG_READ(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D); 510bbeb64d0SHarry Wentland } 511bbeb64d0SHarry Wentland 512bbeb64d0SHarry Wentland void hubbub2_get_dchub_ref_freq(struct hubbub *hubbub, 513bbeb64d0SHarry Wentland unsigned int dccg_ref_freq_inKhz, 514bbeb64d0SHarry Wentland unsigned int *dchub_ref_freq_inKhz) 515bbeb64d0SHarry Wentland { 516bbeb64d0SHarry Wentland struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); 517bbeb64d0SHarry Wentland uint32_t ref_div = 0; 518bbeb64d0SHarry Wentland uint32_t ref_en = 0; 519bbeb64d0SHarry Wentland 520bbeb64d0SHarry Wentland REG_GET_2(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, &ref_div, 521bbeb64d0SHarry Wentland DCHUBBUB_GLOBAL_TIMER_ENABLE, &ref_en); 522bbeb64d0SHarry Wentland 523bbeb64d0SHarry Wentland if (ref_en) { 524bbeb64d0SHarry Wentland if (ref_div == 2) 525bbeb64d0SHarry Wentland *dchub_ref_freq_inKhz = dccg_ref_freq_inKhz / 2; 526bbeb64d0SHarry Wentland else 527bbeb64d0SHarry Wentland *dchub_ref_freq_inKhz = dccg_ref_freq_inKhz; 528bbeb64d0SHarry Wentland 529bbeb64d0SHarry Wentland // DC hub reference frequency must be around 50Mhz, otherwise there may be 530bbeb64d0SHarry Wentland // overflow/underflow issues when doing HUBBUB programming 531bbeb64d0SHarry Wentland if (*dchub_ref_freq_inKhz < 40000 || *dchub_ref_freq_inKhz > 60000) 532bbeb64d0SHarry Wentland ASSERT_CRITICAL(false); 533bbeb64d0SHarry Wentland 534bbeb64d0SHarry Wentland return; 535bbeb64d0SHarry Wentland } else { 536bbeb64d0SHarry Wentland *dchub_ref_freq_inKhz = dccg_ref_freq_inKhz; 537bbeb64d0SHarry Wentland 538bbeb64d0SHarry Wentland // HUBBUB global timer must be enabled. 539bbeb64d0SHarry Wentland ASSERT_CRITICAL(false); 540bbeb64d0SHarry Wentland return; 541bbeb64d0SHarry Wentland } 542bbeb64d0SHarry Wentland } 543bbeb64d0SHarry Wentland 544040a4d63SYongqiang Sun static void hubbub2_program_watermarks( 545040a4d63SYongqiang Sun struct hubbub *hubbub, 546040a4d63SYongqiang Sun struct dcn_watermark_set *watermarks, 547040a4d63SYongqiang Sun unsigned int refclk_mhz, 548040a4d63SYongqiang Sun bool safe_to_lower) 549040a4d63SYongqiang Sun { 550040a4d63SYongqiang Sun struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); 551040a4d63SYongqiang Sun /* 552040a4d63SYongqiang Sun * Need to clamp to max of the register values (i.e. no wrap) 553040a4d63SYongqiang Sun * for dcn1, all wm registers are 21-bit wide 554040a4d63SYongqiang Sun */ 555040a4d63SYongqiang Sun hubbub1_program_urgent_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower); 556040a4d63SYongqiang Sun hubbub1_program_stutter_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower); 557057fc695SJun Lei 558057fc695SJun Lei /* 559057fc695SJun Lei * There's a special case when going from p-state support to p-state unsupported 560057fc695SJun Lei * here we are going to LOWER watermarks to go to dummy p-state only, but this has 561057fc695SJun Lei * to be done prepare_bandwidth, not optimize 562057fc695SJun Lei */ 563057fc695SJun Lei if (hubbub1->base.ctx->dc->clk_mgr->clks.prev_p_state_change_support == true && 564057fc695SJun Lei hubbub1->base.ctx->dc->clk_mgr->clks.p_state_change_support == false) 565057fc695SJun Lei safe_to_lower = true; 566057fc695SJun Lei 567040a4d63SYongqiang Sun hubbub1_program_pstate_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower); 568040a4d63SYongqiang Sun 569040a4d63SYongqiang Sun REG_SET(DCHUBBUB_ARB_SAT_LEVEL, 0, 570040a4d63SYongqiang Sun DCHUBBUB_ARB_SAT_LEVEL, 60 * refclk_mhz); 571040a4d63SYongqiang Sun REG_UPDATE(DCHUBBUB_ARB_DF_REQ_OUTSTAND, DCHUBBUB_ARB_MIN_REQ_OUTSTAND, 180); 572040a4d63SYongqiang Sun 573040a4d63SYongqiang Sun hubbub1_allow_self_refresh_control(hubbub, !hubbub->ctx->dc->debug.disable_stutter); 574040a4d63SYongqiang Sun } 575040a4d63SYongqiang Sun 576bbeb64d0SHarry Wentland static const struct hubbub_funcs hubbub2_funcs = { 577bbeb64d0SHarry Wentland .update_dchub = hubbub2_update_dchub, 578bda9afdaSDmytro Laktyushkin .init_dchub_sys_ctx = hubbub2_init_dchub_sys_ctx, 579bda9afdaSDmytro Laktyushkin .init_vm_ctx = hubbub2_init_vm_ctx, 580bbeb64d0SHarry Wentland .dcc_support_swizzle = hubbub2_dcc_support_swizzle, 581bbeb64d0SHarry Wentland .dcc_support_pixel_format = hubbub2_dcc_support_pixel_format, 582bbeb64d0SHarry Wentland .get_dcc_compression_cap = hubbub2_get_dcc_compression_cap, 583bbeb64d0SHarry Wentland .wm_read_state = hubbub2_wm_read_state, 584bbeb64d0SHarry Wentland .get_dchub_ref_freq = hubbub2_get_dchub_ref_freq, 585040a4d63SYongqiang Sun .program_watermarks = hubbub2_program_watermarks, 586bbeb64d0SHarry Wentland }; 587bbeb64d0SHarry Wentland 588bbeb64d0SHarry Wentland void hubbub2_construct(struct dcn20_hubbub *hubbub, 589bbeb64d0SHarry Wentland struct dc_context *ctx, 590bbeb64d0SHarry Wentland const struct dcn_hubbub_registers *hubbub_regs, 591bbeb64d0SHarry Wentland const struct dcn_hubbub_shift *hubbub_shift, 592bbeb64d0SHarry Wentland const struct dcn_hubbub_mask *hubbub_mask) 593bbeb64d0SHarry Wentland { 594bbeb64d0SHarry Wentland hubbub->base.ctx = ctx; 595bbeb64d0SHarry Wentland 596bbeb64d0SHarry Wentland hubbub->base.funcs = &hubbub2_funcs; 597bbeb64d0SHarry Wentland 598bbeb64d0SHarry Wentland hubbub->regs = hubbub_regs; 599bbeb64d0SHarry Wentland hubbub->shifts = hubbub_shift; 600bbeb64d0SHarry Wentland hubbub->masks = hubbub_mask; 601bbeb64d0SHarry Wentland 602bbeb64d0SHarry Wentland hubbub->debug_test_index_pstate = 0xB; 603bbeb64d0SHarry Wentland } 604