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); 1146f451b60SBhawanpreet Lakha 1156f451b60SBhawanpreet Lakha REG_SET(DCN_VM_FB_LOCATION_BASE, 0, 1166f451b60SBhawanpreet Lakha FB_BASE, pa_config->system_aperture.fb_base); 1176f451b60SBhawanpreet Lakha REG_SET(DCN_VM_FB_LOCATION_TOP, 0, 1186f451b60SBhawanpreet Lakha FB_TOP, pa_config->system_aperture.fb_top); 1196f451b60SBhawanpreet Lakha REG_SET(DCN_VM_FB_OFFSET, 0, 1206f451b60SBhawanpreet Lakha FB_OFFSET, pa_config->system_aperture.fb_offset); 1216f451b60SBhawanpreet Lakha REG_SET(DCN_VM_AGP_BOT, 0, 1226f451b60SBhawanpreet Lakha AGP_BOT, pa_config->system_aperture.agp_bot); 1236f451b60SBhawanpreet Lakha REG_SET(DCN_VM_AGP_TOP, 0, 1246f451b60SBhawanpreet Lakha AGP_TOP, pa_config->system_aperture.agp_top); 1256f451b60SBhawanpreet Lakha REG_SET(DCN_VM_AGP_BASE, 0, 1266f451b60SBhawanpreet Lakha AGP_BASE, pa_config->system_aperture.agp_base); 1276f451b60SBhawanpreet Lakha 1286f451b60SBhawanpreet Lakha dcn21_dchvm_init(hubbub); 1296f451b60SBhawanpreet Lakha 1306f451b60SBhawanpreet Lakha return NUM_VMID; 1316f451b60SBhawanpreet Lakha } 1326f451b60SBhawanpreet Lakha 1334de094eeSBhawanpreet Lakha void hubbub21_program_urgent_watermarks( 1346f451b60SBhawanpreet Lakha struct hubbub *hubbub, 1356f451b60SBhawanpreet Lakha struct dcn_watermark_set *watermarks, 1366f451b60SBhawanpreet Lakha unsigned int refclk_mhz, 1376f451b60SBhawanpreet Lakha bool safe_to_lower) 1386f451b60SBhawanpreet Lakha { 1396f451b60SBhawanpreet Lakha struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); 1406f451b60SBhawanpreet Lakha uint32_t prog_wm_value; 1416f451b60SBhawanpreet Lakha 1426f451b60SBhawanpreet Lakha /* Repeat for water mark set A, B, C and D. */ 1436f451b60SBhawanpreet Lakha /* clock state A */ 1446f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->a.urgent_ns > hubbub1->watermarks.a.urgent_ns) { 1456f451b60SBhawanpreet Lakha hubbub1->watermarks.a.urgent_ns = watermarks->a.urgent_ns; 1466f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp(watermarks->a.urgent_ns, 1476f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 1486f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, 0, 1496f451b60SBhawanpreet Lakha DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, prog_wm_value, 1506f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_URGENCY_WATERMARK_A, prog_wm_value); 1516f451b60SBhawanpreet Lakha 1526f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_A calculated =%d\n" 1536f451b60SBhawanpreet Lakha "HW register value = 0x%x\n", 1546f451b60SBhawanpreet Lakha watermarks->a.urgent_ns, prog_wm_value); 1556f451b60SBhawanpreet Lakha } 1566f451b60SBhawanpreet Lakha 1576f451b60SBhawanpreet Lakha /* determine the transfer time for a quantity of data for a particular requestor.*/ 1586f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->a.frac_urg_bw_flip 1596f451b60SBhawanpreet Lakha > hubbub1->watermarks.a.frac_urg_bw_flip) { 1606f451b60SBhawanpreet Lakha hubbub1->watermarks.a.frac_urg_bw_flip = watermarks->a.frac_urg_bw_flip; 1616f451b60SBhawanpreet Lakha 1626f451b60SBhawanpreet Lakha REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_A, 0, 1636f451b60SBhawanpreet Lakha DCHUBBUB_ARB_FRAC_URG_BW_FLIP_A, watermarks->a.frac_urg_bw_flip); 1646f451b60SBhawanpreet Lakha } 1656f451b60SBhawanpreet Lakha 1666f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->a.frac_urg_bw_nom 1676f451b60SBhawanpreet Lakha > hubbub1->watermarks.a.frac_urg_bw_nom) { 1686f451b60SBhawanpreet Lakha hubbub1->watermarks.a.frac_urg_bw_nom = watermarks->a.frac_urg_bw_nom; 1696f451b60SBhawanpreet Lakha 1706f451b60SBhawanpreet Lakha REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_A, 0, 1716f451b60SBhawanpreet Lakha DCHUBBUB_ARB_FRAC_URG_BW_NOM_A, watermarks->a.frac_urg_bw_nom); 1726f451b60SBhawanpreet Lakha } 1734de094eeSBhawanpreet Lakha if (safe_to_lower || watermarks->a.urgent_latency_ns > hubbub1->watermarks.a.urgent_latency_ns) { 1744de094eeSBhawanpreet Lakha hubbub1->watermarks.a.urgent_latency_ns = watermarks->a.urgent_latency_ns; 1754de094eeSBhawanpreet Lakha prog_wm_value = convert_and_clamp(watermarks->a.urgent_latency_ns, 1764de094eeSBhawanpreet Lakha refclk_mhz, 0x1fffff); 1774de094eeSBhawanpreet Lakha REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A, 0, 1784de094eeSBhawanpreet Lakha DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A, prog_wm_value); 1794de094eeSBhawanpreet Lakha } 1806f451b60SBhawanpreet Lakha 1816f451b60SBhawanpreet Lakha /* clock state B */ 1826f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->b.urgent_ns > hubbub1->watermarks.b.urgent_ns) { 1836f451b60SBhawanpreet Lakha hubbub1->watermarks.b.urgent_ns = watermarks->b.urgent_ns; 1846f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp(watermarks->b.urgent_ns, 1856f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 1866f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, 0, 1876f451b60SBhawanpreet Lakha DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, prog_wm_value, 1886f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_URGENCY_WATERMARK_B, prog_wm_value); 1896f451b60SBhawanpreet Lakha 1906f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_B calculated =%d\n" 1916f451b60SBhawanpreet Lakha "HW register value = 0x%x\n", 1926f451b60SBhawanpreet Lakha watermarks->b.urgent_ns, prog_wm_value); 1936f451b60SBhawanpreet Lakha } 1946f451b60SBhawanpreet Lakha 1956f451b60SBhawanpreet Lakha /* determine the transfer time for a quantity of data for a particular requestor.*/ 1966f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->a.frac_urg_bw_flip 1976f451b60SBhawanpreet Lakha > hubbub1->watermarks.a.frac_urg_bw_flip) { 1986f451b60SBhawanpreet Lakha hubbub1->watermarks.a.frac_urg_bw_flip = watermarks->a.frac_urg_bw_flip; 1996f451b60SBhawanpreet Lakha 2006f451b60SBhawanpreet Lakha REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_B, 0, 2016f451b60SBhawanpreet Lakha DCHUBBUB_ARB_FRAC_URG_BW_FLIP_B, watermarks->a.frac_urg_bw_flip); 2026f451b60SBhawanpreet Lakha } 2036f451b60SBhawanpreet Lakha 2046f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->a.frac_urg_bw_nom 2056f451b60SBhawanpreet Lakha > hubbub1->watermarks.a.frac_urg_bw_nom) { 2066f451b60SBhawanpreet Lakha hubbub1->watermarks.a.frac_urg_bw_nom = watermarks->a.frac_urg_bw_nom; 2076f451b60SBhawanpreet Lakha 2086f451b60SBhawanpreet Lakha REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_B, 0, 2096f451b60SBhawanpreet Lakha DCHUBBUB_ARB_FRAC_URG_BW_NOM_B, watermarks->a.frac_urg_bw_nom); 2106f451b60SBhawanpreet Lakha } 2116f451b60SBhawanpreet Lakha 2124de094eeSBhawanpreet Lakha if (safe_to_lower || watermarks->b.urgent_latency_ns > hubbub1->watermarks.b.urgent_latency_ns) { 2134de094eeSBhawanpreet Lakha hubbub1->watermarks.b.urgent_latency_ns = watermarks->b.urgent_latency_ns; 2144de094eeSBhawanpreet Lakha prog_wm_value = convert_and_clamp(watermarks->b.urgent_latency_ns, 2154de094eeSBhawanpreet Lakha refclk_mhz, 0x1fffff); 2164de094eeSBhawanpreet Lakha REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B, 0, 2174de094eeSBhawanpreet Lakha DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B, prog_wm_value); 2184de094eeSBhawanpreet Lakha } 2194de094eeSBhawanpreet Lakha 2206f451b60SBhawanpreet Lakha /* clock state C */ 2216f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->c.urgent_ns > hubbub1->watermarks.c.urgent_ns) { 2226f451b60SBhawanpreet Lakha hubbub1->watermarks.c.urgent_ns = watermarks->c.urgent_ns; 2236f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp(watermarks->c.urgent_ns, 2246f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 2256f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, 0, 2266f451b60SBhawanpreet Lakha DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, prog_wm_value, 2276f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_URGENCY_WATERMARK_C, prog_wm_value); 2286f451b60SBhawanpreet Lakha 2296f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_C calculated =%d\n" 2306f451b60SBhawanpreet Lakha "HW register value = 0x%x\n", 2316f451b60SBhawanpreet Lakha watermarks->c.urgent_ns, prog_wm_value); 2326f451b60SBhawanpreet Lakha } 2336f451b60SBhawanpreet Lakha 2346f451b60SBhawanpreet Lakha /* determine the transfer time for a quantity of data for a particular requestor.*/ 2356f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->a.frac_urg_bw_flip 2366f451b60SBhawanpreet Lakha > hubbub1->watermarks.a.frac_urg_bw_flip) { 2376f451b60SBhawanpreet Lakha hubbub1->watermarks.a.frac_urg_bw_flip = watermarks->a.frac_urg_bw_flip; 2386f451b60SBhawanpreet Lakha 2396f451b60SBhawanpreet Lakha REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_C, 0, 2406f451b60SBhawanpreet Lakha DCHUBBUB_ARB_FRAC_URG_BW_FLIP_C, watermarks->a.frac_urg_bw_flip); 2416f451b60SBhawanpreet Lakha } 2426f451b60SBhawanpreet Lakha 2436f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->a.frac_urg_bw_nom 2446f451b60SBhawanpreet Lakha > hubbub1->watermarks.a.frac_urg_bw_nom) { 2456f451b60SBhawanpreet Lakha hubbub1->watermarks.a.frac_urg_bw_nom = watermarks->a.frac_urg_bw_nom; 2466f451b60SBhawanpreet Lakha 2476f451b60SBhawanpreet Lakha REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_C, 0, 2486f451b60SBhawanpreet Lakha DCHUBBUB_ARB_FRAC_URG_BW_NOM_C, watermarks->a.frac_urg_bw_nom); 2496f451b60SBhawanpreet Lakha } 2506f451b60SBhawanpreet Lakha 2514de094eeSBhawanpreet Lakha if (safe_to_lower || watermarks->c.urgent_latency_ns > hubbub1->watermarks.c.urgent_latency_ns) { 2524de094eeSBhawanpreet Lakha hubbub1->watermarks.c.urgent_latency_ns = watermarks->c.urgent_latency_ns; 2534de094eeSBhawanpreet Lakha prog_wm_value = convert_and_clamp(watermarks->c.urgent_latency_ns, 2544de094eeSBhawanpreet Lakha refclk_mhz, 0x1fffff); 2554de094eeSBhawanpreet Lakha REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C, 0, 2564de094eeSBhawanpreet Lakha DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C, prog_wm_value); 2574de094eeSBhawanpreet Lakha } 2584de094eeSBhawanpreet Lakha 2596f451b60SBhawanpreet Lakha /* clock state D */ 2606f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->d.urgent_ns > hubbub1->watermarks.d.urgent_ns) { 2616f451b60SBhawanpreet Lakha hubbub1->watermarks.d.urgent_ns = watermarks->d.urgent_ns; 2626f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp(watermarks->d.urgent_ns, 2636f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 2646f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, 0, 2656f451b60SBhawanpreet Lakha DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, prog_wm_value, 2666f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_URGENCY_WATERMARK_D, prog_wm_value); 2676f451b60SBhawanpreet Lakha 2686f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_D calculated =%d\n" 2696f451b60SBhawanpreet Lakha "HW register value = 0x%x\n", 2706f451b60SBhawanpreet Lakha watermarks->d.urgent_ns, prog_wm_value); 2716f451b60SBhawanpreet Lakha } 2726f451b60SBhawanpreet Lakha 2736f451b60SBhawanpreet Lakha /* determine the transfer time for a quantity of data for a particular requestor.*/ 2746f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->a.frac_urg_bw_flip 2756f451b60SBhawanpreet Lakha > hubbub1->watermarks.a.frac_urg_bw_flip) { 2766f451b60SBhawanpreet Lakha hubbub1->watermarks.a.frac_urg_bw_flip = watermarks->a.frac_urg_bw_flip; 2776f451b60SBhawanpreet Lakha 2786f451b60SBhawanpreet Lakha REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_D, 0, 2796f451b60SBhawanpreet Lakha DCHUBBUB_ARB_FRAC_URG_BW_FLIP_D, watermarks->a.frac_urg_bw_flip); 2806f451b60SBhawanpreet Lakha } 2816f451b60SBhawanpreet Lakha 2826f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->a.frac_urg_bw_nom 2836f451b60SBhawanpreet Lakha > hubbub1->watermarks.a.frac_urg_bw_nom) { 2846f451b60SBhawanpreet Lakha hubbub1->watermarks.a.frac_urg_bw_nom = watermarks->a.frac_urg_bw_nom; 2856f451b60SBhawanpreet Lakha 2866f451b60SBhawanpreet Lakha REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_D, 0, 2876f451b60SBhawanpreet Lakha DCHUBBUB_ARB_FRAC_URG_BW_NOM_D, watermarks->a.frac_urg_bw_nom); 2886f451b60SBhawanpreet Lakha } 2894de094eeSBhawanpreet Lakha 2904de094eeSBhawanpreet Lakha if (safe_to_lower || watermarks->d.urgent_latency_ns > hubbub1->watermarks.d.urgent_latency_ns) { 2914de094eeSBhawanpreet Lakha hubbub1->watermarks.d.urgent_latency_ns = watermarks->d.urgent_latency_ns; 2924de094eeSBhawanpreet Lakha prog_wm_value = convert_and_clamp(watermarks->d.urgent_latency_ns, 2934de094eeSBhawanpreet Lakha refclk_mhz, 0x1fffff); 2944de094eeSBhawanpreet Lakha REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, 0, 2954de094eeSBhawanpreet Lakha DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, prog_wm_value); 2964de094eeSBhawanpreet Lakha } 2976f451b60SBhawanpreet Lakha } 2986f451b60SBhawanpreet Lakha 2994de094eeSBhawanpreet Lakha void hubbub21_program_stutter_watermarks( 3006f451b60SBhawanpreet Lakha struct hubbub *hubbub, 3016f451b60SBhawanpreet Lakha struct dcn_watermark_set *watermarks, 3026f451b60SBhawanpreet Lakha unsigned int refclk_mhz, 3036f451b60SBhawanpreet Lakha bool safe_to_lower) 3046f451b60SBhawanpreet Lakha { 3056f451b60SBhawanpreet Lakha struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); 3066f451b60SBhawanpreet Lakha uint32_t prog_wm_value; 3076f451b60SBhawanpreet Lakha 3086f451b60SBhawanpreet Lakha /* clock state A */ 3096f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns 3106f451b60SBhawanpreet Lakha > hubbub1->watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns) { 3116f451b60SBhawanpreet Lakha hubbub1->watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns = 3126f451b60SBhawanpreet Lakha watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns; 3136f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp( 3146f451b60SBhawanpreet Lakha watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, 3156f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 3166f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, 0, 3176f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value, 3186f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value); 3196f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_A calculated =%d\n" 3206f451b60SBhawanpreet Lakha "HW register value = 0x%x\n", 3216f451b60SBhawanpreet Lakha watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); 3226f451b60SBhawanpreet Lakha } 3236f451b60SBhawanpreet Lakha 3246f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->a.cstate_pstate.cstate_exit_ns 3256f451b60SBhawanpreet Lakha > hubbub1->watermarks.a.cstate_pstate.cstate_exit_ns) { 3266f451b60SBhawanpreet Lakha hubbub1->watermarks.a.cstate_pstate.cstate_exit_ns = 3276f451b60SBhawanpreet Lakha watermarks->a.cstate_pstate.cstate_exit_ns; 3286f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp( 3296f451b60SBhawanpreet Lakha watermarks->a.cstate_pstate.cstate_exit_ns, 3306f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 3316f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, 0, 3326f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value, 3336f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value); 3346f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_A calculated =%d\n" 3356f451b60SBhawanpreet Lakha "HW register value = 0x%x\n", 3366f451b60SBhawanpreet Lakha watermarks->a.cstate_pstate.cstate_exit_ns, prog_wm_value); 3376f451b60SBhawanpreet Lakha } 3386f451b60SBhawanpreet Lakha 3396f451b60SBhawanpreet Lakha /* clock state B */ 3406f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns 3416f451b60SBhawanpreet Lakha > hubbub1->watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns) { 3426f451b60SBhawanpreet Lakha hubbub1->watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns = 3436f451b60SBhawanpreet Lakha watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns; 3446f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp( 3456f451b60SBhawanpreet Lakha watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, 3466f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 3476f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, 0, 3486f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value, 3496f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value); 3506f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_B calculated =%d\n" 3516f451b60SBhawanpreet Lakha "HW register value = 0x%x\n", 3526f451b60SBhawanpreet Lakha watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); 3536f451b60SBhawanpreet Lakha } 3546f451b60SBhawanpreet Lakha 3556f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->b.cstate_pstate.cstate_exit_ns 3566f451b60SBhawanpreet Lakha > hubbub1->watermarks.b.cstate_pstate.cstate_exit_ns) { 3576f451b60SBhawanpreet Lakha hubbub1->watermarks.b.cstate_pstate.cstate_exit_ns = 3586f451b60SBhawanpreet Lakha watermarks->b.cstate_pstate.cstate_exit_ns; 3596f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp( 3606f451b60SBhawanpreet Lakha watermarks->b.cstate_pstate.cstate_exit_ns, 3616f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 3626f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, 0, 3636f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, prog_wm_value, 3646f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value); 3656f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_B calculated =%d\n" 3666f451b60SBhawanpreet Lakha "HW register value = 0x%x\n", 3676f451b60SBhawanpreet Lakha watermarks->b.cstate_pstate.cstate_exit_ns, prog_wm_value); 3686f451b60SBhawanpreet Lakha } 3696f451b60SBhawanpreet Lakha 3706f451b60SBhawanpreet Lakha /* clock state C */ 3716f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns 3726f451b60SBhawanpreet Lakha > hubbub1->watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns) { 3736f451b60SBhawanpreet Lakha hubbub1->watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns = 3746f451b60SBhawanpreet Lakha watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns; 3756f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp( 3766f451b60SBhawanpreet Lakha watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, 3776f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 3786f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, 0, 3796f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value, 3806f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value); 3816f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_C calculated =%d\n" 3826f451b60SBhawanpreet Lakha "HW register value = 0x%x\n", 3836f451b60SBhawanpreet Lakha watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); 3846f451b60SBhawanpreet Lakha } 3856f451b60SBhawanpreet Lakha 3866f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->c.cstate_pstate.cstate_exit_ns 3876f451b60SBhawanpreet Lakha > hubbub1->watermarks.c.cstate_pstate.cstate_exit_ns) { 3886f451b60SBhawanpreet Lakha hubbub1->watermarks.c.cstate_pstate.cstate_exit_ns = 3896f451b60SBhawanpreet Lakha watermarks->c.cstate_pstate.cstate_exit_ns; 3906f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp( 3916f451b60SBhawanpreet Lakha watermarks->c.cstate_pstate.cstate_exit_ns, 3926f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 3936f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, 0, 3946f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, prog_wm_value, 3956f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value); 3966f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_C calculated =%d\n" 3976f451b60SBhawanpreet Lakha "HW register value = 0x%x\n", 3986f451b60SBhawanpreet Lakha watermarks->c.cstate_pstate.cstate_exit_ns, prog_wm_value); 3996f451b60SBhawanpreet Lakha } 4006f451b60SBhawanpreet Lakha 4016f451b60SBhawanpreet Lakha /* clock state D */ 4026f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns 4036f451b60SBhawanpreet Lakha > hubbub1->watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns) { 4046f451b60SBhawanpreet Lakha hubbub1->watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns = 4056f451b60SBhawanpreet Lakha watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns; 4066f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp( 4076f451b60SBhawanpreet Lakha watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, 4086f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 4096f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, 0, 4106f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value, 4116f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value); 4126f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_D calculated =%d\n" 4136f451b60SBhawanpreet Lakha "HW register value = 0x%x\n", 4146f451b60SBhawanpreet Lakha watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); 4156f451b60SBhawanpreet Lakha } 4166f451b60SBhawanpreet Lakha 4176f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->d.cstate_pstate.cstate_exit_ns 4186f451b60SBhawanpreet Lakha > hubbub1->watermarks.d.cstate_pstate.cstate_exit_ns) { 4196f451b60SBhawanpreet Lakha hubbub1->watermarks.d.cstate_pstate.cstate_exit_ns = 4206f451b60SBhawanpreet Lakha watermarks->d.cstate_pstate.cstate_exit_ns; 4216f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp( 4226f451b60SBhawanpreet Lakha watermarks->d.cstate_pstate.cstate_exit_ns, 4236f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 4246f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, 0, 4256f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, prog_wm_value, 4266f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value); 4276f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_D calculated =%d\n" 4286f451b60SBhawanpreet Lakha "HW register value = 0x%x\n", 4296f451b60SBhawanpreet Lakha watermarks->d.cstate_pstate.cstate_exit_ns, prog_wm_value); 4306f451b60SBhawanpreet Lakha } 4316f451b60SBhawanpreet Lakha } 4326f451b60SBhawanpreet Lakha 4334de094eeSBhawanpreet Lakha void hubbub21_program_pstate_watermarks( 4346f451b60SBhawanpreet Lakha struct hubbub *hubbub, 4356f451b60SBhawanpreet Lakha struct dcn_watermark_set *watermarks, 4366f451b60SBhawanpreet Lakha unsigned int refclk_mhz, 4376f451b60SBhawanpreet Lakha bool safe_to_lower) 4386f451b60SBhawanpreet Lakha { 4396f451b60SBhawanpreet Lakha struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); 4406f451b60SBhawanpreet Lakha uint32_t prog_wm_value; 4416f451b60SBhawanpreet Lakha 4426f451b60SBhawanpreet Lakha /* clock state A */ 4436f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->a.cstate_pstate.pstate_change_ns 4446f451b60SBhawanpreet Lakha > hubbub1->watermarks.a.cstate_pstate.pstate_change_ns) { 4456f451b60SBhawanpreet Lakha hubbub1->watermarks.a.cstate_pstate.pstate_change_ns = 4466f451b60SBhawanpreet Lakha watermarks->a.cstate_pstate.pstate_change_ns; 4476f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp( 4486f451b60SBhawanpreet Lakha watermarks->a.cstate_pstate.pstate_change_ns, 4496f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 4506f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, 0, 4516f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, prog_wm_value, 4526f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, prog_wm_value); 4536f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_A calculated =%d\n" 4546f451b60SBhawanpreet Lakha "HW register value = 0x%x\n\n", 4556f451b60SBhawanpreet Lakha watermarks->a.cstate_pstate.pstate_change_ns, prog_wm_value); 4566f451b60SBhawanpreet Lakha } 4576f451b60SBhawanpreet Lakha 4586f451b60SBhawanpreet Lakha /* clock state B */ 4596f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->b.cstate_pstate.pstate_change_ns 4606f451b60SBhawanpreet Lakha > hubbub1->watermarks.b.cstate_pstate.pstate_change_ns) { 4616f451b60SBhawanpreet Lakha hubbub1->watermarks.b.cstate_pstate.pstate_change_ns = 4626f451b60SBhawanpreet Lakha watermarks->b.cstate_pstate.pstate_change_ns; 4636f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp( 4646f451b60SBhawanpreet Lakha watermarks->b.cstate_pstate.pstate_change_ns, 4656f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 4666f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, 0, 4676f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, prog_wm_value, 4686f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, prog_wm_value); 4696f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_B calculated =%d\n" 4706f451b60SBhawanpreet Lakha "HW register value = 0x%x\n\n", 4716f451b60SBhawanpreet Lakha watermarks->b.cstate_pstate.pstate_change_ns, prog_wm_value); 4726f451b60SBhawanpreet Lakha } 4736f451b60SBhawanpreet Lakha 4746f451b60SBhawanpreet Lakha /* clock state C */ 4756f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->c.cstate_pstate.pstate_change_ns 4766f451b60SBhawanpreet Lakha > hubbub1->watermarks.c.cstate_pstate.pstate_change_ns) { 4776f451b60SBhawanpreet Lakha hubbub1->watermarks.c.cstate_pstate.pstate_change_ns = 4786f451b60SBhawanpreet Lakha watermarks->c.cstate_pstate.pstate_change_ns; 4796f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp( 4806f451b60SBhawanpreet Lakha watermarks->c.cstate_pstate.pstate_change_ns, 4816f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 4826f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, 0, 4836f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, prog_wm_value, 4846f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, prog_wm_value); 4856f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_C calculated =%d\n" 4866f451b60SBhawanpreet Lakha "HW register value = 0x%x\n\n", 4876f451b60SBhawanpreet Lakha watermarks->c.cstate_pstate.pstate_change_ns, prog_wm_value); 4886f451b60SBhawanpreet Lakha } 4896f451b60SBhawanpreet Lakha 4906f451b60SBhawanpreet Lakha /* clock state D */ 4916f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->d.cstate_pstate.pstate_change_ns 4926f451b60SBhawanpreet Lakha > hubbub1->watermarks.d.cstate_pstate.pstate_change_ns) { 4936f451b60SBhawanpreet Lakha hubbub1->watermarks.d.cstate_pstate.pstate_change_ns = 4946f451b60SBhawanpreet Lakha watermarks->d.cstate_pstate.pstate_change_ns; 4956f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp( 4966f451b60SBhawanpreet Lakha watermarks->d.cstate_pstate.pstate_change_ns, 4976f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 4986f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, 0, 4996f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, prog_wm_value, 5006f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, prog_wm_value); 5016f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_D calculated =%d\n" 5026f451b60SBhawanpreet Lakha "HW register value = 0x%x\n\n", 5036f451b60SBhawanpreet Lakha watermarks->d.cstate_pstate.pstate_change_ns, prog_wm_value); 5046f451b60SBhawanpreet Lakha } 5056f451b60SBhawanpreet Lakha } 5066f451b60SBhawanpreet Lakha 5076f451b60SBhawanpreet Lakha void hubbub21_program_watermarks( 5086f451b60SBhawanpreet Lakha struct hubbub *hubbub, 5096f451b60SBhawanpreet Lakha struct dcn_watermark_set *watermarks, 5106f451b60SBhawanpreet Lakha unsigned int refclk_mhz, 5116f451b60SBhawanpreet Lakha bool safe_to_lower) 5126f451b60SBhawanpreet Lakha { 5136f451b60SBhawanpreet Lakha struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); 5146f451b60SBhawanpreet Lakha 5156f451b60SBhawanpreet Lakha hubbub21_program_urgent_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower); 5166f451b60SBhawanpreet Lakha hubbub21_program_stutter_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower); 5176f451b60SBhawanpreet Lakha hubbub21_program_pstate_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower); 5186f451b60SBhawanpreet Lakha 5196f451b60SBhawanpreet Lakha /* 5206f451b60SBhawanpreet Lakha * The DCHub arbiter has a mechanism to dynamically rate limit the DCHub request stream to the fabric. 5216f451b60SBhawanpreet Lakha * If the memory controller is fully utilized and the DCHub requestors are 5226f451b60SBhawanpreet Lakha * well ahead of their amortized schedule, then it is safe to prevent the next winner 5236f451b60SBhawanpreet Lakha * from being committed and sent to the fabric. 5246f451b60SBhawanpreet Lakha * The utilization of the memory controller is approximated by ensuring that 5256f451b60SBhawanpreet Lakha * the number of outstanding requests is greater than a threshold specified 5266f451b60SBhawanpreet Lakha * by the ARB_MIN_REQ_OUTSTANDING. To determine that the DCHub requestors are well ahead of the amortized schedule, 5276f451b60SBhawanpreet Lakha * the slack of the next winner is compared with the ARB_SAT_LEVEL in DLG RefClk cycles. 5286f451b60SBhawanpreet Lakha * 5296f451b60SBhawanpreet Lakha * TODO: Revisit request limit after figure out right number. request limit for Renoir isn't decided yet, set maximum value (0x1FF) 5306f451b60SBhawanpreet Lakha * to turn off it for now. 5316f451b60SBhawanpreet Lakha */ 5326f451b60SBhawanpreet Lakha REG_SET(DCHUBBUB_ARB_SAT_LEVEL, 0, 5336f451b60SBhawanpreet Lakha DCHUBBUB_ARB_SAT_LEVEL, 60 * refclk_mhz); 5346f451b60SBhawanpreet Lakha REG_UPDATE_2(DCHUBBUB_ARB_DF_REQ_OUTSTAND, 5356f451b60SBhawanpreet Lakha DCHUBBUB_ARB_MIN_REQ_OUTSTAND, 0x1FF, 5366f451b60SBhawanpreet Lakha DCHUBBUB_ARB_MIN_REQ_OUTSTAND_COMMIT_THRESHOLD, 0xA); 5376f451b60SBhawanpreet Lakha REG_UPDATE(DCHUBBUB_ARB_HOSTVM_CNTL, 5386f451b60SBhawanpreet Lakha DCHUBBUB_ARB_MAX_QOS_COMMIT_THRESHOLD, 0xF); 5396f451b60SBhawanpreet Lakha 5406f451b60SBhawanpreet Lakha hubbub1_allow_self_refresh_control(hubbub, !hubbub->ctx->dc->debug.disable_stutter); 5416f451b60SBhawanpreet Lakha } 5426f451b60SBhawanpreet Lakha 5436f451b60SBhawanpreet Lakha void hubbub21_wm_read_state(struct hubbub *hubbub, 5446f451b60SBhawanpreet Lakha struct dcn_hubbub_wm *wm) 5456f451b60SBhawanpreet Lakha { 5466f451b60SBhawanpreet Lakha struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); 5476f451b60SBhawanpreet Lakha struct dcn_hubbub_wm_set *s; 5486f451b60SBhawanpreet Lakha 5496f451b60SBhawanpreet Lakha memset(wm, 0, sizeof(struct dcn_hubbub_wm)); 5506f451b60SBhawanpreet Lakha 5516f451b60SBhawanpreet Lakha s = &wm->sets[0]; 5526f451b60SBhawanpreet Lakha s->wm_set = 0; 5536f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, 5546f451b60SBhawanpreet Lakha DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, &s->data_urgent); 5556f451b60SBhawanpreet Lakha 5566f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, 5576f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, &s->sr_enter); 5586f451b60SBhawanpreet Lakha 5596f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, 5606f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, &s->sr_exit); 5616f451b60SBhawanpreet Lakha 5626f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, 5636f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, &s->dram_clk_chanage); 5646f451b60SBhawanpreet Lakha 5656f451b60SBhawanpreet Lakha s = &wm->sets[1]; 5666f451b60SBhawanpreet Lakha s->wm_set = 1; 5676f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, 5686f451b60SBhawanpreet Lakha DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, &s->data_urgent); 5696f451b60SBhawanpreet Lakha 5706f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, 5716f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, &s->sr_enter); 5726f451b60SBhawanpreet Lakha 5736f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, 5746f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, &s->sr_exit); 5756f451b60SBhawanpreet Lakha 5766f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, 5776f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, &s->dram_clk_chanage); 5786f451b60SBhawanpreet Lakha 5796f451b60SBhawanpreet Lakha s = &wm->sets[2]; 5806f451b60SBhawanpreet Lakha s->wm_set = 2; 5816f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, 5826f451b60SBhawanpreet Lakha DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, &s->data_urgent); 5836f451b60SBhawanpreet Lakha 5846f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, 5856f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, &s->sr_enter); 5866f451b60SBhawanpreet Lakha 5876f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, 5886f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, &s->sr_exit); 5896f451b60SBhawanpreet Lakha 5906f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, 5916f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, &s->dram_clk_chanage); 5926f451b60SBhawanpreet Lakha 5936f451b60SBhawanpreet Lakha s = &wm->sets[3]; 5946f451b60SBhawanpreet Lakha s->wm_set = 3; 5956f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, 5966f451b60SBhawanpreet Lakha DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, &s->data_urgent); 5976f451b60SBhawanpreet Lakha 5986f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, 5996f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, &s->sr_enter); 6006f451b60SBhawanpreet Lakha 6016f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, 6026f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, &s->sr_exit); 6036f451b60SBhawanpreet Lakha 6046f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, 6056f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, &s->dram_clk_chanage); 6066f451b60SBhawanpreet Lakha } 6076f451b60SBhawanpreet Lakha 6086f451b60SBhawanpreet Lakha 6096f451b60SBhawanpreet Lakha static const struct hubbub_funcs hubbub21_funcs = { 6106f451b60SBhawanpreet Lakha .update_dchub = hubbub2_update_dchub, 6116f451b60SBhawanpreet Lakha .init_dchub_sys_ctx = hubbub21_init_dchub, 6126f451b60SBhawanpreet Lakha .init_vm_ctx = NULL, 6136f451b60SBhawanpreet Lakha .dcc_support_swizzle = hubbub2_dcc_support_swizzle, 6146f451b60SBhawanpreet Lakha .dcc_support_pixel_format = hubbub2_dcc_support_pixel_format, 6156f451b60SBhawanpreet Lakha .get_dcc_compression_cap = hubbub2_get_dcc_compression_cap, 6166f451b60SBhawanpreet Lakha .wm_read_state = hubbub21_wm_read_state, 6176f451b60SBhawanpreet Lakha .get_dchub_ref_freq = hubbub2_get_dchub_ref_freq, 6186f451b60SBhawanpreet Lakha .program_watermarks = hubbub21_program_watermarks, 6196f451b60SBhawanpreet Lakha }; 6206f451b60SBhawanpreet Lakha 6216f451b60SBhawanpreet Lakha void hubbub21_construct(struct dcn20_hubbub *hubbub, 6226f451b60SBhawanpreet Lakha struct dc_context *ctx, 6236f451b60SBhawanpreet Lakha const struct dcn_hubbub_registers *hubbub_regs, 6246f451b60SBhawanpreet Lakha const struct dcn_hubbub_shift *hubbub_shift, 6256f451b60SBhawanpreet Lakha const struct dcn_hubbub_mask *hubbub_mask) 6266f451b60SBhawanpreet Lakha { 6276f451b60SBhawanpreet Lakha hubbub->base.ctx = ctx; 6286f451b60SBhawanpreet Lakha 6296f451b60SBhawanpreet Lakha hubbub->base.funcs = &hubbub21_funcs; 6306f451b60SBhawanpreet Lakha 6316f451b60SBhawanpreet Lakha hubbub->regs = hubbub_regs; 6326f451b60SBhawanpreet Lakha hubbub->shifts = hubbub_shift; 6336f451b60SBhawanpreet Lakha hubbub->masks = hubbub_mask; 6346f451b60SBhawanpreet Lakha 6356f451b60SBhawanpreet Lakha hubbub->debug_test_index_pstate = 0xB; 6366f451b60SBhawanpreet Lakha } 637