16f451b60SBhawanpreet Lakha /* 26f451b60SBhawanpreet Lakha * Copyright 2018 Advanced Micro Devices, Inc. 36f451b60SBhawanpreet Lakha * 46f451b60SBhawanpreet Lakha * Permission is hereby granted, free of charge, to any person obtaining a 56f451b60SBhawanpreet Lakha * copy of this software and associated documentation files (the "Software"), 66f451b60SBhawanpreet Lakha * to deal in the Software without restriction, including without limitation 76f451b60SBhawanpreet Lakha * the rights to use, copy, modify, merge, publish, distribute, sublicense, 86f451b60SBhawanpreet Lakha * and/or sell copies of the Software, and to permit persons to whom the 96f451b60SBhawanpreet Lakha * Software is furnished to do so, subject to the following conditions: 106f451b60SBhawanpreet Lakha * 116f451b60SBhawanpreet Lakha * The above copyright notice and this permission notice shall be included in 126f451b60SBhawanpreet Lakha * all copies or substantial portions of the Software. 136f451b60SBhawanpreet Lakha * 146f451b60SBhawanpreet Lakha * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 156f451b60SBhawanpreet Lakha * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 166f451b60SBhawanpreet Lakha * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 176f451b60SBhawanpreet Lakha * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 186f451b60SBhawanpreet Lakha * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 196f451b60SBhawanpreet Lakha * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 206f451b60SBhawanpreet Lakha * OTHER DEALINGS IN THE SOFTWARE. 216f451b60SBhawanpreet Lakha * 226f451b60SBhawanpreet Lakha * Authors: AMD 236f451b60SBhawanpreet Lakha * 246f451b60SBhawanpreet Lakha */ 2548d92e8eSDmytro Laktyushkin #include <linux/delay.h> 266f451b60SBhawanpreet Lakha #include "dm_services.h" 276f451b60SBhawanpreet Lakha #include "dcn20/dcn20_hubbub.h" 286f451b60SBhawanpreet Lakha #include "dcn21_hubbub.h" 296f451b60SBhawanpreet Lakha #include "reg_helper.h" 306f451b60SBhawanpreet Lakha 316f451b60SBhawanpreet Lakha #define REG(reg)\ 326f451b60SBhawanpreet Lakha hubbub1->regs->reg 336f451b60SBhawanpreet Lakha #define DC_LOGGER \ 346f451b60SBhawanpreet Lakha hubbub1->base.ctx->logger 356f451b60SBhawanpreet Lakha #define CTX \ 366f451b60SBhawanpreet Lakha hubbub1->base.ctx 376f451b60SBhawanpreet Lakha 386f451b60SBhawanpreet Lakha #undef FN 396f451b60SBhawanpreet Lakha #define FN(reg_name, field_name) \ 406f451b60SBhawanpreet Lakha hubbub1->shifts->field_name, hubbub1->masks->field_name 416f451b60SBhawanpreet Lakha 426f451b60SBhawanpreet Lakha #define REG(reg)\ 436f451b60SBhawanpreet Lakha hubbub1->regs->reg 446f451b60SBhawanpreet Lakha 456f451b60SBhawanpreet Lakha #define CTX \ 466f451b60SBhawanpreet Lakha hubbub1->base.ctx 476f451b60SBhawanpreet Lakha 486f451b60SBhawanpreet Lakha #undef FN 496f451b60SBhawanpreet Lakha #define FN(reg_name, field_name) \ 506f451b60SBhawanpreet Lakha hubbub1->shifts->field_name, hubbub1->masks->field_name 516f451b60SBhawanpreet Lakha 526f451b60SBhawanpreet Lakha #ifdef NUM_VMID 536f451b60SBhawanpreet Lakha #undef NUM_VMID 546f451b60SBhawanpreet Lakha #endif 556f451b60SBhawanpreet Lakha #define NUM_VMID 1 566f451b60SBhawanpreet Lakha 576f451b60SBhawanpreet Lakha static uint32_t convert_and_clamp( 586f451b60SBhawanpreet Lakha uint32_t wm_ns, 596f451b60SBhawanpreet Lakha uint32_t refclk_mhz, 606f451b60SBhawanpreet Lakha uint32_t clamp_value) 616f451b60SBhawanpreet Lakha { 626f451b60SBhawanpreet Lakha uint32_t ret_val = 0; 636f451b60SBhawanpreet Lakha ret_val = wm_ns * refclk_mhz; 646f451b60SBhawanpreet Lakha ret_val /= 1000; 656f451b60SBhawanpreet Lakha 666f451b60SBhawanpreet Lakha if (ret_val > clamp_value) 676f451b60SBhawanpreet Lakha ret_val = clamp_value; 686f451b60SBhawanpreet Lakha 696f451b60SBhawanpreet Lakha return ret_val; 706f451b60SBhawanpreet Lakha } 716f451b60SBhawanpreet Lakha 726f451b60SBhawanpreet Lakha void dcn21_dchvm_init(struct hubbub *hubbub) 736f451b60SBhawanpreet Lakha { 746f451b60SBhawanpreet Lakha struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); 7548d92e8eSDmytro Laktyushkin uint32_t riommu_active; 7648d92e8eSDmytro Laktyushkin int i; 776f451b60SBhawanpreet Lakha 786f451b60SBhawanpreet Lakha //Init DCHVM block 796f451b60SBhawanpreet Lakha REG_UPDATE(DCHVM_CTRL0, HOSTVM_INIT_REQ, 1); 806f451b60SBhawanpreet Lakha 816f451b60SBhawanpreet Lakha //Poll until RIOMMU_ACTIVE = 1 8248d92e8eSDmytro Laktyushkin for (i = 0; i < 100; i++) { 8348d92e8eSDmytro Laktyushkin REG_GET(DCHVM_RIOMMU_STAT0, RIOMMU_ACTIVE, &riommu_active); 846f451b60SBhawanpreet Lakha 8548d92e8eSDmytro Laktyushkin if (riommu_active) 8648d92e8eSDmytro Laktyushkin break; 8748d92e8eSDmytro Laktyushkin else 8848d92e8eSDmytro Laktyushkin udelay(5); 8948d92e8eSDmytro Laktyushkin } 9048d92e8eSDmytro Laktyushkin 9148d92e8eSDmytro Laktyushkin if (riommu_active) { 926f451b60SBhawanpreet Lakha //Reflect the power status of DCHUBBUB 936f451b60SBhawanpreet Lakha REG_UPDATE(DCHVM_RIOMMU_CTRL0, HOSTVM_POWERSTATUS, 1); 946f451b60SBhawanpreet Lakha 956f451b60SBhawanpreet Lakha //Start rIOMMU prefetching 966f451b60SBhawanpreet Lakha REG_UPDATE(DCHVM_RIOMMU_CTRL0, HOSTVM_PREFETCH_REQ, 1); 976f451b60SBhawanpreet Lakha 986f451b60SBhawanpreet Lakha // Enable dynamic clock gating 996f451b60SBhawanpreet Lakha REG_UPDATE_4(DCHVM_CLK_CTRL, 1006f451b60SBhawanpreet Lakha HVM_DISPCLK_R_GATE_DIS, 0, 1016f451b60SBhawanpreet Lakha HVM_DISPCLK_G_GATE_DIS, 0, 1026f451b60SBhawanpreet Lakha HVM_DCFCLK_R_GATE_DIS, 0, 1036f451b60SBhawanpreet Lakha HVM_DCFCLK_G_GATE_DIS, 0); 1046f451b60SBhawanpreet Lakha 1056f451b60SBhawanpreet Lakha //Poll until HOSTVM_PREFETCH_DONE = 1 1066f451b60SBhawanpreet Lakha REG_WAIT(DCHVM_RIOMMU_STAT0, HOSTVM_PREFETCH_DONE, 1, 5, 100); 1076f451b60SBhawanpreet Lakha } 10848d92e8eSDmytro Laktyushkin } 1096f451b60SBhawanpreet Lakha 1104de094eeSBhawanpreet Lakha int hubbub21_init_dchub(struct hubbub *hubbub, 1116f451b60SBhawanpreet Lakha struct dcn_hubbub_phys_addr_config *pa_config) 1126f451b60SBhawanpreet Lakha { 1136f451b60SBhawanpreet Lakha struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); 114d4516d3eSBhawanpreet Lakha struct dcn_vmid_page_table_config phys_config; 1156f451b60SBhawanpreet Lakha 1166f451b60SBhawanpreet Lakha REG_SET(DCN_VM_FB_LOCATION_BASE, 0, 117d4516d3eSBhawanpreet Lakha FB_BASE, pa_config->system_aperture.fb_base >> 24); 1186f451b60SBhawanpreet Lakha REG_SET(DCN_VM_FB_LOCATION_TOP, 0, 119d4516d3eSBhawanpreet Lakha FB_TOP, pa_config->system_aperture.fb_top >> 24); 1206f451b60SBhawanpreet Lakha REG_SET(DCN_VM_FB_OFFSET, 0, 121d4516d3eSBhawanpreet Lakha FB_OFFSET, pa_config->system_aperture.fb_offset >> 24); 1226f451b60SBhawanpreet Lakha REG_SET(DCN_VM_AGP_BOT, 0, 123d4516d3eSBhawanpreet Lakha AGP_BOT, pa_config->system_aperture.agp_bot >> 24); 1246f451b60SBhawanpreet Lakha REG_SET(DCN_VM_AGP_TOP, 0, 125d4516d3eSBhawanpreet Lakha AGP_TOP, pa_config->system_aperture.agp_top >> 24); 1266f451b60SBhawanpreet Lakha REG_SET(DCN_VM_AGP_BASE, 0, 127d4516d3eSBhawanpreet Lakha AGP_BASE, pa_config->system_aperture.agp_base >> 24); 128d4516d3eSBhawanpreet Lakha 129d4516d3eSBhawanpreet Lakha if (pa_config->gart_config.page_table_start_addr != pa_config->gart_config.page_table_end_addr) { 130d4516d3eSBhawanpreet Lakha phys_config.page_table_start_addr = pa_config->gart_config.page_table_start_addr >> 12; 131d4516d3eSBhawanpreet Lakha phys_config.page_table_end_addr = pa_config->gart_config.page_table_end_addr >> 12; 132d4516d3eSBhawanpreet Lakha phys_config.page_table_base_addr = pa_config->gart_config.page_table_base_addr | 1; //Note: hack 133d4516d3eSBhawanpreet Lakha phys_config.depth = 0; 134d4516d3eSBhawanpreet Lakha phys_config.block_size = 0; 135d4516d3eSBhawanpreet Lakha // Init VMID 0 based on PA config 136d4516d3eSBhawanpreet Lakha dcn20_vmid_setup(&hubbub1->vmid[0], &phys_config); 137d4516d3eSBhawanpreet Lakha } 1386f451b60SBhawanpreet Lakha 1396f451b60SBhawanpreet Lakha dcn21_dchvm_init(hubbub); 1406f451b60SBhawanpreet Lakha 1416f451b60SBhawanpreet Lakha return NUM_VMID; 1426f451b60SBhawanpreet Lakha } 1436f451b60SBhawanpreet Lakha 1444de094eeSBhawanpreet Lakha void hubbub21_program_urgent_watermarks( 1456f451b60SBhawanpreet Lakha struct hubbub *hubbub, 1466f451b60SBhawanpreet Lakha struct dcn_watermark_set *watermarks, 1476f451b60SBhawanpreet Lakha unsigned int refclk_mhz, 1486f451b60SBhawanpreet Lakha bool safe_to_lower) 1496f451b60SBhawanpreet Lakha { 1506f451b60SBhawanpreet Lakha struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); 1516f451b60SBhawanpreet Lakha uint32_t prog_wm_value; 1526f451b60SBhawanpreet Lakha 1536f451b60SBhawanpreet Lakha /* Repeat for water mark set A, B, C and D. */ 1546f451b60SBhawanpreet Lakha /* clock state A */ 1556f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->a.urgent_ns > hubbub1->watermarks.a.urgent_ns) { 1566f451b60SBhawanpreet Lakha hubbub1->watermarks.a.urgent_ns = watermarks->a.urgent_ns; 1576f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp(watermarks->a.urgent_ns, 1586f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 1596f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, 0, 1606f451b60SBhawanpreet Lakha DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, prog_wm_value, 1616f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_URGENCY_WATERMARK_A, prog_wm_value); 1626f451b60SBhawanpreet Lakha 1636f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_A calculated =%d\n" 1646f451b60SBhawanpreet Lakha "HW register value = 0x%x\n", 1656f451b60SBhawanpreet Lakha watermarks->a.urgent_ns, prog_wm_value); 1666f451b60SBhawanpreet Lakha } 1676f451b60SBhawanpreet Lakha 1686f451b60SBhawanpreet Lakha /* determine the transfer time for a quantity of data for a particular requestor.*/ 1696f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->a.frac_urg_bw_flip 1706f451b60SBhawanpreet Lakha > hubbub1->watermarks.a.frac_urg_bw_flip) { 1716f451b60SBhawanpreet Lakha hubbub1->watermarks.a.frac_urg_bw_flip = watermarks->a.frac_urg_bw_flip; 1726f451b60SBhawanpreet Lakha 1736f451b60SBhawanpreet Lakha REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_A, 0, 1746f451b60SBhawanpreet Lakha DCHUBBUB_ARB_FRAC_URG_BW_FLIP_A, watermarks->a.frac_urg_bw_flip); 1756f451b60SBhawanpreet Lakha } 1766f451b60SBhawanpreet Lakha 1776f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->a.frac_urg_bw_nom 1786f451b60SBhawanpreet Lakha > hubbub1->watermarks.a.frac_urg_bw_nom) { 1796f451b60SBhawanpreet Lakha hubbub1->watermarks.a.frac_urg_bw_nom = watermarks->a.frac_urg_bw_nom; 1806f451b60SBhawanpreet Lakha 1816f451b60SBhawanpreet Lakha REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_A, 0, 1826f451b60SBhawanpreet Lakha DCHUBBUB_ARB_FRAC_URG_BW_NOM_A, watermarks->a.frac_urg_bw_nom); 1836f451b60SBhawanpreet Lakha } 1844de094eeSBhawanpreet Lakha if (safe_to_lower || watermarks->a.urgent_latency_ns > hubbub1->watermarks.a.urgent_latency_ns) { 1854de094eeSBhawanpreet Lakha hubbub1->watermarks.a.urgent_latency_ns = watermarks->a.urgent_latency_ns; 1864de094eeSBhawanpreet Lakha prog_wm_value = convert_and_clamp(watermarks->a.urgent_latency_ns, 1874de094eeSBhawanpreet Lakha refclk_mhz, 0x1fffff); 1884de094eeSBhawanpreet Lakha REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A, 0, 1894de094eeSBhawanpreet Lakha DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A, prog_wm_value); 1904de094eeSBhawanpreet Lakha } 1916f451b60SBhawanpreet Lakha 1926f451b60SBhawanpreet Lakha /* clock state B */ 1936f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->b.urgent_ns > hubbub1->watermarks.b.urgent_ns) { 1946f451b60SBhawanpreet Lakha hubbub1->watermarks.b.urgent_ns = watermarks->b.urgent_ns; 1956f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp(watermarks->b.urgent_ns, 1966f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 1976f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, 0, 1986f451b60SBhawanpreet Lakha DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, prog_wm_value, 1996f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_URGENCY_WATERMARK_B, prog_wm_value); 2006f451b60SBhawanpreet Lakha 2016f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_B calculated =%d\n" 2026f451b60SBhawanpreet Lakha "HW register value = 0x%x\n", 2036f451b60SBhawanpreet Lakha watermarks->b.urgent_ns, prog_wm_value); 2046f451b60SBhawanpreet Lakha } 2056f451b60SBhawanpreet Lakha 2066f451b60SBhawanpreet Lakha /* determine the transfer time for a quantity of data for a particular requestor.*/ 2076f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->a.frac_urg_bw_flip 2086f451b60SBhawanpreet Lakha > hubbub1->watermarks.a.frac_urg_bw_flip) { 2096f451b60SBhawanpreet Lakha hubbub1->watermarks.a.frac_urg_bw_flip = watermarks->a.frac_urg_bw_flip; 2106f451b60SBhawanpreet Lakha 2116f451b60SBhawanpreet Lakha REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_B, 0, 2126f451b60SBhawanpreet Lakha DCHUBBUB_ARB_FRAC_URG_BW_FLIP_B, watermarks->a.frac_urg_bw_flip); 2136f451b60SBhawanpreet Lakha } 2146f451b60SBhawanpreet Lakha 2156f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->a.frac_urg_bw_nom 2166f451b60SBhawanpreet Lakha > hubbub1->watermarks.a.frac_urg_bw_nom) { 2176f451b60SBhawanpreet Lakha hubbub1->watermarks.a.frac_urg_bw_nom = watermarks->a.frac_urg_bw_nom; 2186f451b60SBhawanpreet Lakha 2196f451b60SBhawanpreet Lakha REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_B, 0, 2206f451b60SBhawanpreet Lakha DCHUBBUB_ARB_FRAC_URG_BW_NOM_B, watermarks->a.frac_urg_bw_nom); 2216f451b60SBhawanpreet Lakha } 2226f451b60SBhawanpreet Lakha 2234de094eeSBhawanpreet Lakha if (safe_to_lower || watermarks->b.urgent_latency_ns > hubbub1->watermarks.b.urgent_latency_ns) { 2244de094eeSBhawanpreet Lakha hubbub1->watermarks.b.urgent_latency_ns = watermarks->b.urgent_latency_ns; 2254de094eeSBhawanpreet Lakha prog_wm_value = convert_and_clamp(watermarks->b.urgent_latency_ns, 2264de094eeSBhawanpreet Lakha refclk_mhz, 0x1fffff); 2274de094eeSBhawanpreet Lakha REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B, 0, 2284de094eeSBhawanpreet Lakha DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B, prog_wm_value); 2294de094eeSBhawanpreet Lakha } 2304de094eeSBhawanpreet Lakha 2316f451b60SBhawanpreet Lakha /* clock state C */ 2326f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->c.urgent_ns > hubbub1->watermarks.c.urgent_ns) { 2336f451b60SBhawanpreet Lakha hubbub1->watermarks.c.urgent_ns = watermarks->c.urgent_ns; 2346f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp(watermarks->c.urgent_ns, 2356f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 2366f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, 0, 2376f451b60SBhawanpreet Lakha DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, prog_wm_value, 2386f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_URGENCY_WATERMARK_C, prog_wm_value); 2396f451b60SBhawanpreet Lakha 2406f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_C calculated =%d\n" 2416f451b60SBhawanpreet Lakha "HW register value = 0x%x\n", 2426f451b60SBhawanpreet Lakha watermarks->c.urgent_ns, prog_wm_value); 2436f451b60SBhawanpreet Lakha } 2446f451b60SBhawanpreet Lakha 2456f451b60SBhawanpreet Lakha /* determine the transfer time for a quantity of data for a particular requestor.*/ 2466f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->a.frac_urg_bw_flip 2476f451b60SBhawanpreet Lakha > hubbub1->watermarks.a.frac_urg_bw_flip) { 2486f451b60SBhawanpreet Lakha hubbub1->watermarks.a.frac_urg_bw_flip = watermarks->a.frac_urg_bw_flip; 2496f451b60SBhawanpreet Lakha 2506f451b60SBhawanpreet Lakha REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_C, 0, 2516f451b60SBhawanpreet Lakha DCHUBBUB_ARB_FRAC_URG_BW_FLIP_C, watermarks->a.frac_urg_bw_flip); 2526f451b60SBhawanpreet Lakha } 2536f451b60SBhawanpreet Lakha 2546f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->a.frac_urg_bw_nom 2556f451b60SBhawanpreet Lakha > hubbub1->watermarks.a.frac_urg_bw_nom) { 2566f451b60SBhawanpreet Lakha hubbub1->watermarks.a.frac_urg_bw_nom = watermarks->a.frac_urg_bw_nom; 2576f451b60SBhawanpreet Lakha 2586f451b60SBhawanpreet Lakha REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_C, 0, 2596f451b60SBhawanpreet Lakha DCHUBBUB_ARB_FRAC_URG_BW_NOM_C, watermarks->a.frac_urg_bw_nom); 2606f451b60SBhawanpreet Lakha } 2616f451b60SBhawanpreet Lakha 2624de094eeSBhawanpreet Lakha if (safe_to_lower || watermarks->c.urgent_latency_ns > hubbub1->watermarks.c.urgent_latency_ns) { 2634de094eeSBhawanpreet Lakha hubbub1->watermarks.c.urgent_latency_ns = watermarks->c.urgent_latency_ns; 2644de094eeSBhawanpreet Lakha prog_wm_value = convert_and_clamp(watermarks->c.urgent_latency_ns, 2654de094eeSBhawanpreet Lakha refclk_mhz, 0x1fffff); 2664de094eeSBhawanpreet Lakha REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C, 0, 2674de094eeSBhawanpreet Lakha DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C, prog_wm_value); 2684de094eeSBhawanpreet Lakha } 2694de094eeSBhawanpreet Lakha 2706f451b60SBhawanpreet Lakha /* clock state D */ 2716f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->d.urgent_ns > hubbub1->watermarks.d.urgent_ns) { 2726f451b60SBhawanpreet Lakha hubbub1->watermarks.d.urgent_ns = watermarks->d.urgent_ns; 2736f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp(watermarks->d.urgent_ns, 2746f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 2756f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, 0, 2766f451b60SBhawanpreet Lakha DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, prog_wm_value, 2776f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_URGENCY_WATERMARK_D, prog_wm_value); 2786f451b60SBhawanpreet Lakha 2796f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_D calculated =%d\n" 2806f451b60SBhawanpreet Lakha "HW register value = 0x%x\n", 2816f451b60SBhawanpreet Lakha watermarks->d.urgent_ns, prog_wm_value); 2826f451b60SBhawanpreet Lakha } 2836f451b60SBhawanpreet Lakha 2846f451b60SBhawanpreet Lakha /* determine the transfer time for a quantity of data for a particular requestor.*/ 2856f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->a.frac_urg_bw_flip 2866f451b60SBhawanpreet Lakha > hubbub1->watermarks.a.frac_urg_bw_flip) { 2876f451b60SBhawanpreet Lakha hubbub1->watermarks.a.frac_urg_bw_flip = watermarks->a.frac_urg_bw_flip; 2886f451b60SBhawanpreet Lakha 2896f451b60SBhawanpreet Lakha REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_D, 0, 2906f451b60SBhawanpreet Lakha DCHUBBUB_ARB_FRAC_URG_BW_FLIP_D, watermarks->a.frac_urg_bw_flip); 2916f451b60SBhawanpreet Lakha } 2926f451b60SBhawanpreet Lakha 2936f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->a.frac_urg_bw_nom 2946f451b60SBhawanpreet Lakha > hubbub1->watermarks.a.frac_urg_bw_nom) { 2956f451b60SBhawanpreet Lakha hubbub1->watermarks.a.frac_urg_bw_nom = watermarks->a.frac_urg_bw_nom; 2966f451b60SBhawanpreet Lakha 2976f451b60SBhawanpreet Lakha REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_D, 0, 2986f451b60SBhawanpreet Lakha DCHUBBUB_ARB_FRAC_URG_BW_NOM_D, watermarks->a.frac_urg_bw_nom); 2996f451b60SBhawanpreet Lakha } 3004de094eeSBhawanpreet Lakha 3014de094eeSBhawanpreet Lakha if (safe_to_lower || watermarks->d.urgent_latency_ns > hubbub1->watermarks.d.urgent_latency_ns) { 3024de094eeSBhawanpreet Lakha hubbub1->watermarks.d.urgent_latency_ns = watermarks->d.urgent_latency_ns; 3034de094eeSBhawanpreet Lakha prog_wm_value = convert_and_clamp(watermarks->d.urgent_latency_ns, 3044de094eeSBhawanpreet Lakha refclk_mhz, 0x1fffff); 3054de094eeSBhawanpreet Lakha REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, 0, 3064de094eeSBhawanpreet Lakha DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, prog_wm_value); 3074de094eeSBhawanpreet Lakha } 3086f451b60SBhawanpreet Lakha } 3096f451b60SBhawanpreet Lakha 3104de094eeSBhawanpreet Lakha void hubbub21_program_stutter_watermarks( 3116f451b60SBhawanpreet Lakha struct hubbub *hubbub, 3126f451b60SBhawanpreet Lakha struct dcn_watermark_set *watermarks, 3136f451b60SBhawanpreet Lakha unsigned int refclk_mhz, 3146f451b60SBhawanpreet Lakha bool safe_to_lower) 3156f451b60SBhawanpreet Lakha { 3166f451b60SBhawanpreet Lakha struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); 3176f451b60SBhawanpreet Lakha uint32_t prog_wm_value; 3186f451b60SBhawanpreet Lakha 3196f451b60SBhawanpreet Lakha /* clock state A */ 3206f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns 3216f451b60SBhawanpreet Lakha > hubbub1->watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns) { 3226f451b60SBhawanpreet Lakha hubbub1->watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns = 3236f451b60SBhawanpreet Lakha watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns; 3246f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp( 3256f451b60SBhawanpreet Lakha watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, 3266f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 3276f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, 0, 3286f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value, 3296f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value); 3306f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_A calculated =%d\n" 3316f451b60SBhawanpreet Lakha "HW register value = 0x%x\n", 3326f451b60SBhawanpreet Lakha watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); 3336f451b60SBhawanpreet Lakha } 3346f451b60SBhawanpreet Lakha 3356f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->a.cstate_pstate.cstate_exit_ns 3366f451b60SBhawanpreet Lakha > hubbub1->watermarks.a.cstate_pstate.cstate_exit_ns) { 3376f451b60SBhawanpreet Lakha hubbub1->watermarks.a.cstate_pstate.cstate_exit_ns = 3386f451b60SBhawanpreet Lakha watermarks->a.cstate_pstate.cstate_exit_ns; 3396f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp( 3406f451b60SBhawanpreet Lakha watermarks->a.cstate_pstate.cstate_exit_ns, 3416f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 3426f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, 0, 3436f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value, 3446f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value); 3456f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_A calculated =%d\n" 3466f451b60SBhawanpreet Lakha "HW register value = 0x%x\n", 3476f451b60SBhawanpreet Lakha watermarks->a.cstate_pstate.cstate_exit_ns, prog_wm_value); 3486f451b60SBhawanpreet Lakha } 3496f451b60SBhawanpreet Lakha 3506f451b60SBhawanpreet Lakha /* clock state B */ 3516f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns 3526f451b60SBhawanpreet Lakha > hubbub1->watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns) { 3536f451b60SBhawanpreet Lakha hubbub1->watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns = 3546f451b60SBhawanpreet Lakha watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns; 3556f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp( 3566f451b60SBhawanpreet Lakha watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, 3576f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 3586f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, 0, 3596f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value, 3606f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value); 3616f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_B calculated =%d\n" 3626f451b60SBhawanpreet Lakha "HW register value = 0x%x\n", 3636f451b60SBhawanpreet Lakha watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); 3646f451b60SBhawanpreet Lakha } 3656f451b60SBhawanpreet Lakha 3666f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->b.cstate_pstate.cstate_exit_ns 3676f451b60SBhawanpreet Lakha > hubbub1->watermarks.b.cstate_pstate.cstate_exit_ns) { 3686f451b60SBhawanpreet Lakha hubbub1->watermarks.b.cstate_pstate.cstate_exit_ns = 3696f451b60SBhawanpreet Lakha watermarks->b.cstate_pstate.cstate_exit_ns; 3706f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp( 3716f451b60SBhawanpreet Lakha watermarks->b.cstate_pstate.cstate_exit_ns, 3726f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 3736f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, 0, 3746f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, prog_wm_value, 3756f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value); 3766f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_B calculated =%d\n" 3776f451b60SBhawanpreet Lakha "HW register value = 0x%x\n", 3786f451b60SBhawanpreet Lakha watermarks->b.cstate_pstate.cstate_exit_ns, prog_wm_value); 3796f451b60SBhawanpreet Lakha } 3806f451b60SBhawanpreet Lakha 3816f451b60SBhawanpreet Lakha /* clock state C */ 3826f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns 3836f451b60SBhawanpreet Lakha > hubbub1->watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns) { 3846f451b60SBhawanpreet Lakha hubbub1->watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns = 3856f451b60SBhawanpreet Lakha watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns; 3866f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp( 3876f451b60SBhawanpreet Lakha watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, 3886f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 3896f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, 0, 3906f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value, 3916f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value); 3926f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_C calculated =%d\n" 3936f451b60SBhawanpreet Lakha "HW register value = 0x%x\n", 3946f451b60SBhawanpreet Lakha watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); 3956f451b60SBhawanpreet Lakha } 3966f451b60SBhawanpreet Lakha 3976f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->c.cstate_pstate.cstate_exit_ns 3986f451b60SBhawanpreet Lakha > hubbub1->watermarks.c.cstate_pstate.cstate_exit_ns) { 3996f451b60SBhawanpreet Lakha hubbub1->watermarks.c.cstate_pstate.cstate_exit_ns = 4006f451b60SBhawanpreet Lakha watermarks->c.cstate_pstate.cstate_exit_ns; 4016f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp( 4026f451b60SBhawanpreet Lakha watermarks->c.cstate_pstate.cstate_exit_ns, 4036f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 4046f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, 0, 4056f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, prog_wm_value, 4066f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value); 4076f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_C calculated =%d\n" 4086f451b60SBhawanpreet Lakha "HW register value = 0x%x\n", 4096f451b60SBhawanpreet Lakha watermarks->c.cstate_pstate.cstate_exit_ns, prog_wm_value); 4106f451b60SBhawanpreet Lakha } 4116f451b60SBhawanpreet Lakha 4126f451b60SBhawanpreet Lakha /* clock state D */ 4136f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns 4146f451b60SBhawanpreet Lakha > hubbub1->watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns) { 4156f451b60SBhawanpreet Lakha hubbub1->watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns = 4166f451b60SBhawanpreet Lakha watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns; 4176f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp( 4186f451b60SBhawanpreet Lakha watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, 4196f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 4206f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, 0, 4216f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value, 4226f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value); 4236f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_D calculated =%d\n" 4246f451b60SBhawanpreet Lakha "HW register value = 0x%x\n", 4256f451b60SBhawanpreet Lakha watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); 4266f451b60SBhawanpreet Lakha } 4276f451b60SBhawanpreet Lakha 4286f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->d.cstate_pstate.cstate_exit_ns 4296f451b60SBhawanpreet Lakha > hubbub1->watermarks.d.cstate_pstate.cstate_exit_ns) { 4306f451b60SBhawanpreet Lakha hubbub1->watermarks.d.cstate_pstate.cstate_exit_ns = 4316f451b60SBhawanpreet Lakha watermarks->d.cstate_pstate.cstate_exit_ns; 4326f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp( 4336f451b60SBhawanpreet Lakha watermarks->d.cstate_pstate.cstate_exit_ns, 4346f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 4356f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, 0, 4366f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, prog_wm_value, 4376f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value); 4386f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_D calculated =%d\n" 4396f451b60SBhawanpreet Lakha "HW register value = 0x%x\n", 4406f451b60SBhawanpreet Lakha watermarks->d.cstate_pstate.cstate_exit_ns, prog_wm_value); 4416f451b60SBhawanpreet Lakha } 4426f451b60SBhawanpreet Lakha } 4436f451b60SBhawanpreet Lakha 4444de094eeSBhawanpreet Lakha void hubbub21_program_pstate_watermarks( 4456f451b60SBhawanpreet Lakha struct hubbub *hubbub, 4466f451b60SBhawanpreet Lakha struct dcn_watermark_set *watermarks, 4476f451b60SBhawanpreet Lakha unsigned int refclk_mhz, 4486f451b60SBhawanpreet Lakha bool safe_to_lower) 4496f451b60SBhawanpreet Lakha { 4506f451b60SBhawanpreet Lakha struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); 4516f451b60SBhawanpreet Lakha uint32_t prog_wm_value; 4526f451b60SBhawanpreet Lakha 4536f451b60SBhawanpreet Lakha /* clock state A */ 4546f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->a.cstate_pstate.pstate_change_ns 4556f451b60SBhawanpreet Lakha > hubbub1->watermarks.a.cstate_pstate.pstate_change_ns) { 4566f451b60SBhawanpreet Lakha hubbub1->watermarks.a.cstate_pstate.pstate_change_ns = 4576f451b60SBhawanpreet Lakha watermarks->a.cstate_pstate.pstate_change_ns; 4586f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp( 4596f451b60SBhawanpreet Lakha watermarks->a.cstate_pstate.pstate_change_ns, 4606f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 4616f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, 0, 4626f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, prog_wm_value, 4636f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, prog_wm_value); 4646f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_A calculated =%d\n" 4656f451b60SBhawanpreet Lakha "HW register value = 0x%x\n\n", 4666f451b60SBhawanpreet Lakha watermarks->a.cstate_pstate.pstate_change_ns, prog_wm_value); 4676f451b60SBhawanpreet Lakha } 4686f451b60SBhawanpreet Lakha 4696f451b60SBhawanpreet Lakha /* clock state B */ 4706f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->b.cstate_pstate.pstate_change_ns 4716f451b60SBhawanpreet Lakha > hubbub1->watermarks.b.cstate_pstate.pstate_change_ns) { 4726f451b60SBhawanpreet Lakha hubbub1->watermarks.b.cstate_pstate.pstate_change_ns = 4736f451b60SBhawanpreet Lakha watermarks->b.cstate_pstate.pstate_change_ns; 4746f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp( 4756f451b60SBhawanpreet Lakha watermarks->b.cstate_pstate.pstate_change_ns, 4766f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 4776f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, 0, 4786f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, prog_wm_value, 4796f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, prog_wm_value); 4806f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_B calculated =%d\n" 4816f451b60SBhawanpreet Lakha "HW register value = 0x%x\n\n", 4826f451b60SBhawanpreet Lakha watermarks->b.cstate_pstate.pstate_change_ns, prog_wm_value); 4836f451b60SBhawanpreet Lakha } 4846f451b60SBhawanpreet Lakha 4856f451b60SBhawanpreet Lakha /* clock state C */ 4866f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->c.cstate_pstate.pstate_change_ns 4876f451b60SBhawanpreet Lakha > hubbub1->watermarks.c.cstate_pstate.pstate_change_ns) { 4886f451b60SBhawanpreet Lakha hubbub1->watermarks.c.cstate_pstate.pstate_change_ns = 4896f451b60SBhawanpreet Lakha watermarks->c.cstate_pstate.pstate_change_ns; 4906f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp( 4916f451b60SBhawanpreet Lakha watermarks->c.cstate_pstate.pstate_change_ns, 4926f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 4936f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, 0, 4946f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, prog_wm_value, 4956f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, prog_wm_value); 4966f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_C calculated =%d\n" 4976f451b60SBhawanpreet Lakha "HW register value = 0x%x\n\n", 4986f451b60SBhawanpreet Lakha watermarks->c.cstate_pstate.pstate_change_ns, prog_wm_value); 4996f451b60SBhawanpreet Lakha } 5006f451b60SBhawanpreet Lakha 5016f451b60SBhawanpreet Lakha /* clock state D */ 5026f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->d.cstate_pstate.pstate_change_ns 5036f451b60SBhawanpreet Lakha > hubbub1->watermarks.d.cstate_pstate.pstate_change_ns) { 5046f451b60SBhawanpreet Lakha hubbub1->watermarks.d.cstate_pstate.pstate_change_ns = 5056f451b60SBhawanpreet Lakha watermarks->d.cstate_pstate.pstate_change_ns; 5066f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp( 5076f451b60SBhawanpreet Lakha watermarks->d.cstate_pstate.pstate_change_ns, 5086f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 5096f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, 0, 5106f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, prog_wm_value, 5116f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, prog_wm_value); 5126f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_D calculated =%d\n" 5136f451b60SBhawanpreet Lakha "HW register value = 0x%x\n\n", 5146f451b60SBhawanpreet Lakha watermarks->d.cstate_pstate.pstate_change_ns, prog_wm_value); 5156f451b60SBhawanpreet Lakha } 5166f451b60SBhawanpreet Lakha } 5176f451b60SBhawanpreet Lakha 5186f451b60SBhawanpreet Lakha void hubbub21_program_watermarks( 5196f451b60SBhawanpreet Lakha struct hubbub *hubbub, 5206f451b60SBhawanpreet Lakha struct dcn_watermark_set *watermarks, 5216f451b60SBhawanpreet Lakha unsigned int refclk_mhz, 5226f451b60SBhawanpreet Lakha bool safe_to_lower) 5236f451b60SBhawanpreet Lakha { 5246f451b60SBhawanpreet Lakha struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); 5256f451b60SBhawanpreet Lakha 5266f451b60SBhawanpreet Lakha hubbub21_program_urgent_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower); 5276f451b60SBhawanpreet Lakha hubbub21_program_stutter_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower); 5286f451b60SBhawanpreet Lakha hubbub21_program_pstate_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower); 5296f451b60SBhawanpreet Lakha 5306f451b60SBhawanpreet Lakha /* 5316f451b60SBhawanpreet Lakha * The DCHub arbiter has a mechanism to dynamically rate limit the DCHub request stream to the fabric. 5326f451b60SBhawanpreet Lakha * If the memory controller is fully utilized and the DCHub requestors are 5336f451b60SBhawanpreet Lakha * well ahead of their amortized schedule, then it is safe to prevent the next winner 5346f451b60SBhawanpreet Lakha * from being committed and sent to the fabric. 5356f451b60SBhawanpreet Lakha * The utilization of the memory controller is approximated by ensuring that 5366f451b60SBhawanpreet Lakha * the number of outstanding requests is greater than a threshold specified 5376f451b60SBhawanpreet Lakha * by the ARB_MIN_REQ_OUTSTANDING. To determine that the DCHub requestors are well ahead of the amortized schedule, 5386f451b60SBhawanpreet Lakha * the slack of the next winner is compared with the ARB_SAT_LEVEL in DLG RefClk cycles. 5396f451b60SBhawanpreet Lakha * 5406f451b60SBhawanpreet Lakha * TODO: Revisit request limit after figure out right number. request limit for Renoir isn't decided yet, set maximum value (0x1FF) 5416f451b60SBhawanpreet Lakha * to turn off it for now. 5426f451b60SBhawanpreet Lakha */ 5436f451b60SBhawanpreet Lakha REG_SET(DCHUBBUB_ARB_SAT_LEVEL, 0, 5446f451b60SBhawanpreet Lakha DCHUBBUB_ARB_SAT_LEVEL, 60 * refclk_mhz); 5456f451b60SBhawanpreet Lakha REG_UPDATE_2(DCHUBBUB_ARB_DF_REQ_OUTSTAND, 5466f451b60SBhawanpreet Lakha DCHUBBUB_ARB_MIN_REQ_OUTSTAND, 0x1FF, 5476f451b60SBhawanpreet Lakha DCHUBBUB_ARB_MIN_REQ_OUTSTAND_COMMIT_THRESHOLD, 0xA); 5486f451b60SBhawanpreet Lakha REG_UPDATE(DCHUBBUB_ARB_HOSTVM_CNTL, 5496f451b60SBhawanpreet Lakha DCHUBBUB_ARB_MAX_QOS_COMMIT_THRESHOLD, 0xF); 5506f451b60SBhawanpreet Lakha 5516f451b60SBhawanpreet Lakha hubbub1_allow_self_refresh_control(hubbub, !hubbub->ctx->dc->debug.disable_stutter); 5526f451b60SBhawanpreet Lakha } 5536f451b60SBhawanpreet Lakha 5546f451b60SBhawanpreet Lakha void hubbub21_wm_read_state(struct hubbub *hubbub, 5556f451b60SBhawanpreet Lakha struct dcn_hubbub_wm *wm) 5566f451b60SBhawanpreet Lakha { 5576f451b60SBhawanpreet Lakha struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); 5586f451b60SBhawanpreet Lakha struct dcn_hubbub_wm_set *s; 5596f451b60SBhawanpreet Lakha 5606f451b60SBhawanpreet Lakha memset(wm, 0, sizeof(struct dcn_hubbub_wm)); 5616f451b60SBhawanpreet Lakha 5626f451b60SBhawanpreet Lakha s = &wm->sets[0]; 5636f451b60SBhawanpreet Lakha s->wm_set = 0; 5646f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, 5656f451b60SBhawanpreet Lakha DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, &s->data_urgent); 5666f451b60SBhawanpreet Lakha 5676f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, 5686f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, &s->sr_enter); 5696f451b60SBhawanpreet Lakha 5706f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, 5716f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, &s->sr_exit); 5726f451b60SBhawanpreet Lakha 5736f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, 5746f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, &s->dram_clk_chanage); 5756f451b60SBhawanpreet Lakha 5766f451b60SBhawanpreet Lakha s = &wm->sets[1]; 5776f451b60SBhawanpreet Lakha s->wm_set = 1; 5786f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, 5796f451b60SBhawanpreet Lakha DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, &s->data_urgent); 5806f451b60SBhawanpreet Lakha 5816f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, 5826f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, &s->sr_enter); 5836f451b60SBhawanpreet Lakha 5846f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, 5856f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, &s->sr_exit); 5866f451b60SBhawanpreet Lakha 5876f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, 5886f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, &s->dram_clk_chanage); 5896f451b60SBhawanpreet Lakha 5906f451b60SBhawanpreet Lakha s = &wm->sets[2]; 5916f451b60SBhawanpreet Lakha s->wm_set = 2; 5926f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, 5936f451b60SBhawanpreet Lakha DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, &s->data_urgent); 5946f451b60SBhawanpreet Lakha 5956f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, 5966f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, &s->sr_enter); 5976f451b60SBhawanpreet Lakha 5986f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, 5996f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, &s->sr_exit); 6006f451b60SBhawanpreet Lakha 6016f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, 6026f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, &s->dram_clk_chanage); 6036f451b60SBhawanpreet Lakha 6046f451b60SBhawanpreet Lakha s = &wm->sets[3]; 6056f451b60SBhawanpreet Lakha s->wm_set = 3; 6066f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, 6076f451b60SBhawanpreet Lakha DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, &s->data_urgent); 6086f451b60SBhawanpreet Lakha 6096f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, 6106f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, &s->sr_enter); 6116f451b60SBhawanpreet Lakha 6126f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, 6136f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, &s->sr_exit); 6146f451b60SBhawanpreet Lakha 6156f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, 6166f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, &s->dram_clk_chanage); 6176f451b60SBhawanpreet Lakha } 6186f451b60SBhawanpreet Lakha 619f93e29f0SLewis Huang void hubbub21_apply_DEDCN21_147_wa(struct hubbub *hubbub) 620f93e29f0SLewis Huang { 621f93e29f0SLewis Huang struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); 622f93e29f0SLewis Huang uint32_t prog_wm_value; 623f93e29f0SLewis Huang 624f93e29f0SLewis Huang prog_wm_value = REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A); 625f93e29f0SLewis Huang REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, prog_wm_value); 626f93e29f0SLewis Huang } 6276f451b60SBhawanpreet Lakha 6286f451b60SBhawanpreet Lakha static const struct hubbub_funcs hubbub21_funcs = { 6296f451b60SBhawanpreet Lakha .update_dchub = hubbub2_update_dchub, 6306f451b60SBhawanpreet Lakha .init_dchub_sys_ctx = hubbub21_init_dchub, 6316ba3712dSDmytro Laktyushkin .init_vm_ctx = hubbub2_init_vm_ctx, 6326f451b60SBhawanpreet Lakha .dcc_support_swizzle = hubbub2_dcc_support_swizzle, 6336f451b60SBhawanpreet Lakha .dcc_support_pixel_format = hubbub2_dcc_support_pixel_format, 6346f451b60SBhawanpreet Lakha .get_dcc_compression_cap = hubbub2_get_dcc_compression_cap, 6356f451b60SBhawanpreet Lakha .wm_read_state = hubbub21_wm_read_state, 6366f451b60SBhawanpreet Lakha .get_dchub_ref_freq = hubbub2_get_dchub_ref_freq, 6376f451b60SBhawanpreet Lakha .program_watermarks = hubbub21_program_watermarks, 638f93e29f0SLewis Huang .apply_DEDCN21_147_wa = hubbub21_apply_DEDCN21_147_wa, 6396f451b60SBhawanpreet Lakha }; 6406f451b60SBhawanpreet Lakha 6416f451b60SBhawanpreet Lakha void hubbub21_construct(struct dcn20_hubbub *hubbub, 6426f451b60SBhawanpreet Lakha struct dc_context *ctx, 6436f451b60SBhawanpreet Lakha const struct dcn_hubbub_registers *hubbub_regs, 6446f451b60SBhawanpreet Lakha const struct dcn_hubbub_shift *hubbub_shift, 6456f451b60SBhawanpreet Lakha const struct dcn_hubbub_mask *hubbub_mask) 6466f451b60SBhawanpreet Lakha { 6476f451b60SBhawanpreet Lakha hubbub->base.ctx = ctx; 6486f451b60SBhawanpreet Lakha 6496f451b60SBhawanpreet Lakha hubbub->base.funcs = &hubbub21_funcs; 6506f451b60SBhawanpreet Lakha 6516f451b60SBhawanpreet Lakha hubbub->regs = hubbub_regs; 6526f451b60SBhawanpreet Lakha hubbub->shifts = hubbub_shift; 6536f451b60SBhawanpreet Lakha hubbub->masks = hubbub_mask; 6546f451b60SBhawanpreet Lakha 6556f451b60SBhawanpreet Lakha hubbub->debug_test_index_pstate = 0xB; 6566f451b60SBhawanpreet Lakha } 657