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 static uint32_t convert_and_clamp( 536f451b60SBhawanpreet Lakha uint32_t wm_ns, 546f451b60SBhawanpreet Lakha uint32_t refclk_mhz, 556f451b60SBhawanpreet Lakha uint32_t clamp_value) 566f451b60SBhawanpreet Lakha { 576f451b60SBhawanpreet Lakha uint32_t ret_val = 0; 586f451b60SBhawanpreet Lakha ret_val = wm_ns * refclk_mhz; 596f451b60SBhawanpreet Lakha ret_val /= 1000; 606f451b60SBhawanpreet Lakha 616f451b60SBhawanpreet Lakha if (ret_val > clamp_value) 626f451b60SBhawanpreet Lakha ret_val = clamp_value; 636f451b60SBhawanpreet Lakha 646f451b60SBhawanpreet Lakha return ret_val; 656f451b60SBhawanpreet Lakha } 666f451b60SBhawanpreet Lakha 676f451b60SBhawanpreet Lakha void dcn21_dchvm_init(struct hubbub *hubbub) 686f451b60SBhawanpreet Lakha { 696f451b60SBhawanpreet Lakha struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); 7048d92e8eSDmytro Laktyushkin uint32_t riommu_active; 7148d92e8eSDmytro Laktyushkin int i; 726f451b60SBhawanpreet Lakha 736f451b60SBhawanpreet Lakha //Init DCHVM block 746f451b60SBhawanpreet Lakha REG_UPDATE(DCHVM_CTRL0, HOSTVM_INIT_REQ, 1); 756f451b60SBhawanpreet Lakha 766f451b60SBhawanpreet Lakha //Poll until RIOMMU_ACTIVE = 1 7748d92e8eSDmytro Laktyushkin for (i = 0; i < 100; i++) { 7848d92e8eSDmytro Laktyushkin REG_GET(DCHVM_RIOMMU_STAT0, RIOMMU_ACTIVE, &riommu_active); 796f451b60SBhawanpreet Lakha 8048d92e8eSDmytro Laktyushkin if (riommu_active) 8148d92e8eSDmytro Laktyushkin break; 8248d92e8eSDmytro Laktyushkin else 8348d92e8eSDmytro Laktyushkin udelay(5); 8448d92e8eSDmytro Laktyushkin } 8548d92e8eSDmytro Laktyushkin 8648d92e8eSDmytro Laktyushkin if (riommu_active) { 876f451b60SBhawanpreet Lakha //Reflect the power status of DCHUBBUB 886f451b60SBhawanpreet Lakha REG_UPDATE(DCHVM_RIOMMU_CTRL0, HOSTVM_POWERSTATUS, 1); 896f451b60SBhawanpreet Lakha 906f451b60SBhawanpreet Lakha //Start rIOMMU prefetching 916f451b60SBhawanpreet Lakha REG_UPDATE(DCHVM_RIOMMU_CTRL0, HOSTVM_PREFETCH_REQ, 1); 926f451b60SBhawanpreet Lakha 936f451b60SBhawanpreet Lakha // Enable dynamic clock gating 946f451b60SBhawanpreet Lakha REG_UPDATE_4(DCHVM_CLK_CTRL, 956f451b60SBhawanpreet Lakha HVM_DISPCLK_R_GATE_DIS, 0, 966f451b60SBhawanpreet Lakha HVM_DISPCLK_G_GATE_DIS, 0, 976f451b60SBhawanpreet Lakha HVM_DCFCLK_R_GATE_DIS, 0, 986f451b60SBhawanpreet Lakha HVM_DCFCLK_G_GATE_DIS, 0); 996f451b60SBhawanpreet Lakha 1006f451b60SBhawanpreet Lakha //Poll until HOSTVM_PREFETCH_DONE = 1 1016f451b60SBhawanpreet Lakha REG_WAIT(DCHVM_RIOMMU_STAT0, HOSTVM_PREFETCH_DONE, 1, 5, 100); 10282df77aeSSung Lee 10382df77aeSSung Lee hubbub->riommu_active = true; 1046f451b60SBhawanpreet Lakha } 10548d92e8eSDmytro Laktyushkin } 1066f451b60SBhawanpreet Lakha 1074de094eeSBhawanpreet Lakha int hubbub21_init_dchub(struct hubbub *hubbub, 1086f451b60SBhawanpreet Lakha struct dcn_hubbub_phys_addr_config *pa_config) 1096f451b60SBhawanpreet Lakha { 1106f451b60SBhawanpreet Lakha struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); 111d4516d3eSBhawanpreet Lakha struct dcn_vmid_page_table_config phys_config; 1126f451b60SBhawanpreet Lakha 1136f451b60SBhawanpreet Lakha REG_SET(DCN_VM_FB_LOCATION_BASE, 0, 114d4516d3eSBhawanpreet Lakha FB_BASE, pa_config->system_aperture.fb_base >> 24); 1156f451b60SBhawanpreet Lakha REG_SET(DCN_VM_FB_LOCATION_TOP, 0, 116d4516d3eSBhawanpreet Lakha FB_TOP, pa_config->system_aperture.fb_top >> 24); 1176f451b60SBhawanpreet Lakha REG_SET(DCN_VM_FB_OFFSET, 0, 118d4516d3eSBhawanpreet Lakha FB_OFFSET, pa_config->system_aperture.fb_offset >> 24); 1196f451b60SBhawanpreet Lakha REG_SET(DCN_VM_AGP_BOT, 0, 120d4516d3eSBhawanpreet Lakha AGP_BOT, pa_config->system_aperture.agp_bot >> 24); 1216f451b60SBhawanpreet Lakha REG_SET(DCN_VM_AGP_TOP, 0, 122d4516d3eSBhawanpreet Lakha AGP_TOP, pa_config->system_aperture.agp_top >> 24); 1236f451b60SBhawanpreet Lakha REG_SET(DCN_VM_AGP_BASE, 0, 124d4516d3eSBhawanpreet Lakha AGP_BASE, pa_config->system_aperture.agp_base >> 24); 125d4516d3eSBhawanpreet Lakha 126d4516d3eSBhawanpreet Lakha if (pa_config->gart_config.page_table_start_addr != pa_config->gart_config.page_table_end_addr) { 127d4516d3eSBhawanpreet Lakha phys_config.page_table_start_addr = pa_config->gart_config.page_table_start_addr >> 12; 128d4516d3eSBhawanpreet Lakha phys_config.page_table_end_addr = pa_config->gart_config.page_table_end_addr >> 12; 129d4516d3eSBhawanpreet Lakha phys_config.page_table_base_addr = pa_config->gart_config.page_table_base_addr | 1; //Note: hack 130d4516d3eSBhawanpreet Lakha phys_config.depth = 0; 131d4516d3eSBhawanpreet Lakha phys_config.block_size = 0; 132d4516d3eSBhawanpreet Lakha // Init VMID 0 based on PA config 133d4516d3eSBhawanpreet Lakha dcn20_vmid_setup(&hubbub1->vmid[0], &phys_config); 134d4516d3eSBhawanpreet Lakha } 1356f451b60SBhawanpreet Lakha 1366f451b60SBhawanpreet Lakha dcn21_dchvm_init(hubbub); 1376f451b60SBhawanpreet Lakha 138fdcf62fbSDmytro Laktyushkin return hubbub1->num_vmid; 1396f451b60SBhawanpreet Lakha } 1406f451b60SBhawanpreet Lakha 14189e94bc5SYongqiang Sun bool hubbub21_program_urgent_watermarks( 1426f451b60SBhawanpreet Lakha struct hubbub *hubbub, 1436f451b60SBhawanpreet Lakha struct dcn_watermark_set *watermarks, 1446f451b60SBhawanpreet Lakha unsigned int refclk_mhz, 1456f451b60SBhawanpreet Lakha bool safe_to_lower) 1466f451b60SBhawanpreet Lakha { 1476f451b60SBhawanpreet Lakha struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); 1486f451b60SBhawanpreet Lakha uint32_t prog_wm_value; 14989e94bc5SYongqiang Sun bool wm_pending = false; 1506f451b60SBhawanpreet Lakha 1516f451b60SBhawanpreet Lakha /* Repeat for water mark set A, B, C and D. */ 1526f451b60SBhawanpreet Lakha /* clock state A */ 1536f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->a.urgent_ns > hubbub1->watermarks.a.urgent_ns) { 1546f451b60SBhawanpreet Lakha hubbub1->watermarks.a.urgent_ns = watermarks->a.urgent_ns; 1556f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp(watermarks->a.urgent_ns, 1566f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 1576f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, 0, 1586f451b60SBhawanpreet Lakha DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, prog_wm_value, 1596f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_URGENCY_WATERMARK_A, prog_wm_value); 1606f451b60SBhawanpreet Lakha 1616f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_A calculated =%d\n" 1626f451b60SBhawanpreet Lakha "HW register value = 0x%x\n", 1636f451b60SBhawanpreet Lakha watermarks->a.urgent_ns, prog_wm_value); 16489e94bc5SYongqiang Sun } else if (watermarks->a.urgent_ns < hubbub1->watermarks.a.urgent_ns) 16589e94bc5SYongqiang Sun wm_pending = true; 1666f451b60SBhawanpreet Lakha 1676f451b60SBhawanpreet Lakha /* determine the transfer time for a quantity of data for a particular requestor.*/ 1686f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->a.frac_urg_bw_flip 1696f451b60SBhawanpreet Lakha > hubbub1->watermarks.a.frac_urg_bw_flip) { 1706f451b60SBhawanpreet Lakha hubbub1->watermarks.a.frac_urg_bw_flip = watermarks->a.frac_urg_bw_flip; 1716f451b60SBhawanpreet Lakha 1726f451b60SBhawanpreet Lakha REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_A, 0, 1736f451b60SBhawanpreet Lakha DCHUBBUB_ARB_FRAC_URG_BW_FLIP_A, watermarks->a.frac_urg_bw_flip); 17489e94bc5SYongqiang Sun } else if (watermarks->a.frac_urg_bw_flip 17589e94bc5SYongqiang Sun < hubbub1->watermarks.a.frac_urg_bw_flip) 17689e94bc5SYongqiang Sun wm_pending = true; 1776f451b60SBhawanpreet Lakha 1786f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->a.frac_urg_bw_nom 1796f451b60SBhawanpreet Lakha > hubbub1->watermarks.a.frac_urg_bw_nom) { 1806f451b60SBhawanpreet Lakha hubbub1->watermarks.a.frac_urg_bw_nom = watermarks->a.frac_urg_bw_nom; 1816f451b60SBhawanpreet Lakha 1826f451b60SBhawanpreet Lakha REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_A, 0, 1836f451b60SBhawanpreet Lakha DCHUBBUB_ARB_FRAC_URG_BW_NOM_A, watermarks->a.frac_urg_bw_nom); 18489e94bc5SYongqiang Sun } else if (watermarks->a.frac_urg_bw_nom 18589e94bc5SYongqiang Sun < hubbub1->watermarks.a.frac_urg_bw_nom) 18689e94bc5SYongqiang Sun wm_pending = true; 18789e94bc5SYongqiang Sun 1884de094eeSBhawanpreet Lakha if (safe_to_lower || watermarks->a.urgent_latency_ns > hubbub1->watermarks.a.urgent_latency_ns) { 1894de094eeSBhawanpreet Lakha hubbub1->watermarks.a.urgent_latency_ns = watermarks->a.urgent_latency_ns; 1904de094eeSBhawanpreet Lakha prog_wm_value = convert_and_clamp(watermarks->a.urgent_latency_ns, 1914de094eeSBhawanpreet Lakha refclk_mhz, 0x1fffff); 1924de094eeSBhawanpreet Lakha REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A, 0, 1934de094eeSBhawanpreet Lakha DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A, prog_wm_value); 19489e94bc5SYongqiang Sun } else if (watermarks->a.urgent_latency_ns < hubbub1->watermarks.a.urgent_latency_ns) 19589e94bc5SYongqiang Sun wm_pending = true; 1966f451b60SBhawanpreet Lakha 1976f451b60SBhawanpreet Lakha /* clock state B */ 1986f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->b.urgent_ns > hubbub1->watermarks.b.urgent_ns) { 1996f451b60SBhawanpreet Lakha hubbub1->watermarks.b.urgent_ns = watermarks->b.urgent_ns; 2006f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp(watermarks->b.urgent_ns, 2016f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 2026f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, 0, 2036f451b60SBhawanpreet Lakha DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, prog_wm_value, 2046f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_URGENCY_WATERMARK_B, prog_wm_value); 2056f451b60SBhawanpreet Lakha 2066f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_B calculated =%d\n" 2076f451b60SBhawanpreet Lakha "HW register value = 0x%x\n", 2086f451b60SBhawanpreet Lakha watermarks->b.urgent_ns, prog_wm_value); 20989e94bc5SYongqiang Sun } else if (watermarks->b.urgent_ns < hubbub1->watermarks.b.urgent_ns) 21089e94bc5SYongqiang Sun wm_pending = true; 2116f451b60SBhawanpreet Lakha 2126f451b60SBhawanpreet Lakha /* determine the transfer time for a quantity of data for a particular requestor.*/ 2136f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->a.frac_urg_bw_flip 2146f451b60SBhawanpreet Lakha > hubbub1->watermarks.a.frac_urg_bw_flip) { 2156f451b60SBhawanpreet Lakha hubbub1->watermarks.a.frac_urg_bw_flip = watermarks->a.frac_urg_bw_flip; 2166f451b60SBhawanpreet Lakha 2176f451b60SBhawanpreet Lakha REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_B, 0, 2186f451b60SBhawanpreet Lakha DCHUBBUB_ARB_FRAC_URG_BW_FLIP_B, watermarks->a.frac_urg_bw_flip); 21989e94bc5SYongqiang Sun } else if (watermarks->a.frac_urg_bw_flip 22089e94bc5SYongqiang Sun < hubbub1->watermarks.a.frac_urg_bw_flip) 22189e94bc5SYongqiang Sun wm_pending = true; 2226f451b60SBhawanpreet Lakha 2236f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->a.frac_urg_bw_nom 2246f451b60SBhawanpreet Lakha > hubbub1->watermarks.a.frac_urg_bw_nom) { 2256f451b60SBhawanpreet Lakha hubbub1->watermarks.a.frac_urg_bw_nom = watermarks->a.frac_urg_bw_nom; 2266f451b60SBhawanpreet Lakha 2276f451b60SBhawanpreet Lakha REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_B, 0, 2286f451b60SBhawanpreet Lakha DCHUBBUB_ARB_FRAC_URG_BW_NOM_B, watermarks->a.frac_urg_bw_nom); 22989e94bc5SYongqiang Sun } else if (watermarks->a.frac_urg_bw_nom 23089e94bc5SYongqiang Sun < hubbub1->watermarks.a.frac_urg_bw_nom) 23189e94bc5SYongqiang Sun wm_pending = true; 2326f451b60SBhawanpreet Lakha 2334de094eeSBhawanpreet Lakha if (safe_to_lower || watermarks->b.urgent_latency_ns > hubbub1->watermarks.b.urgent_latency_ns) { 2344de094eeSBhawanpreet Lakha hubbub1->watermarks.b.urgent_latency_ns = watermarks->b.urgent_latency_ns; 2354de094eeSBhawanpreet Lakha prog_wm_value = convert_and_clamp(watermarks->b.urgent_latency_ns, 2364de094eeSBhawanpreet Lakha refclk_mhz, 0x1fffff); 2374de094eeSBhawanpreet Lakha REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B, 0, 2384de094eeSBhawanpreet Lakha DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B, prog_wm_value); 23989e94bc5SYongqiang Sun } else if (watermarks->b.urgent_latency_ns < hubbub1->watermarks.b.urgent_latency_ns) 24089e94bc5SYongqiang Sun wm_pending = true; 2414de094eeSBhawanpreet Lakha 2426f451b60SBhawanpreet Lakha /* clock state C */ 2436f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->c.urgent_ns > hubbub1->watermarks.c.urgent_ns) { 2446f451b60SBhawanpreet Lakha hubbub1->watermarks.c.urgent_ns = watermarks->c.urgent_ns; 2456f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp(watermarks->c.urgent_ns, 2466f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 2476f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, 0, 2486f451b60SBhawanpreet Lakha DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, prog_wm_value, 2496f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_URGENCY_WATERMARK_C, prog_wm_value); 2506f451b60SBhawanpreet Lakha 2516f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_C calculated =%d\n" 2526f451b60SBhawanpreet Lakha "HW register value = 0x%x\n", 2536f451b60SBhawanpreet Lakha watermarks->c.urgent_ns, prog_wm_value); 25489e94bc5SYongqiang Sun } else if (watermarks->c.urgent_ns < hubbub1->watermarks.c.urgent_ns) 25589e94bc5SYongqiang Sun wm_pending = true; 2566f451b60SBhawanpreet Lakha 2576f451b60SBhawanpreet Lakha /* determine the transfer time for a quantity of data for a particular requestor.*/ 2586f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->a.frac_urg_bw_flip 2596f451b60SBhawanpreet Lakha > hubbub1->watermarks.a.frac_urg_bw_flip) { 2606f451b60SBhawanpreet Lakha hubbub1->watermarks.a.frac_urg_bw_flip = watermarks->a.frac_urg_bw_flip; 2616f451b60SBhawanpreet Lakha 2626f451b60SBhawanpreet Lakha REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_C, 0, 2636f451b60SBhawanpreet Lakha DCHUBBUB_ARB_FRAC_URG_BW_FLIP_C, watermarks->a.frac_urg_bw_flip); 26489e94bc5SYongqiang Sun } else if (watermarks->a.frac_urg_bw_flip 26589e94bc5SYongqiang Sun < hubbub1->watermarks.a.frac_urg_bw_flip) 26689e94bc5SYongqiang Sun wm_pending = true; 2676f451b60SBhawanpreet Lakha 2686f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->a.frac_urg_bw_nom 2696f451b60SBhawanpreet Lakha > hubbub1->watermarks.a.frac_urg_bw_nom) { 2706f451b60SBhawanpreet Lakha hubbub1->watermarks.a.frac_urg_bw_nom = watermarks->a.frac_urg_bw_nom; 2716f451b60SBhawanpreet Lakha 2726f451b60SBhawanpreet Lakha REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_C, 0, 2736f451b60SBhawanpreet Lakha DCHUBBUB_ARB_FRAC_URG_BW_NOM_C, watermarks->a.frac_urg_bw_nom); 27489e94bc5SYongqiang Sun } else if (watermarks->a.frac_urg_bw_nom 27589e94bc5SYongqiang Sun < hubbub1->watermarks.a.frac_urg_bw_nom) 27689e94bc5SYongqiang Sun wm_pending = true; 2776f451b60SBhawanpreet Lakha 2784de094eeSBhawanpreet Lakha if (safe_to_lower || watermarks->c.urgent_latency_ns > hubbub1->watermarks.c.urgent_latency_ns) { 2794de094eeSBhawanpreet Lakha hubbub1->watermarks.c.urgent_latency_ns = watermarks->c.urgent_latency_ns; 2804de094eeSBhawanpreet Lakha prog_wm_value = convert_and_clamp(watermarks->c.urgent_latency_ns, 2814de094eeSBhawanpreet Lakha refclk_mhz, 0x1fffff); 2824de094eeSBhawanpreet Lakha REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C, 0, 2834de094eeSBhawanpreet Lakha DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C, prog_wm_value); 28489e94bc5SYongqiang Sun } else if (watermarks->c.urgent_latency_ns < hubbub1->watermarks.c.urgent_latency_ns) 28589e94bc5SYongqiang Sun wm_pending = true; 2864de094eeSBhawanpreet Lakha 2876f451b60SBhawanpreet Lakha /* clock state D */ 2886f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->d.urgent_ns > hubbub1->watermarks.d.urgent_ns) { 2896f451b60SBhawanpreet Lakha hubbub1->watermarks.d.urgent_ns = watermarks->d.urgent_ns; 2906f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp(watermarks->d.urgent_ns, 2916f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 2926f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, 0, 2936f451b60SBhawanpreet Lakha DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, prog_wm_value, 2946f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_URGENCY_WATERMARK_D, prog_wm_value); 2956f451b60SBhawanpreet Lakha 2966f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_D calculated =%d\n" 2976f451b60SBhawanpreet Lakha "HW register value = 0x%x\n", 2986f451b60SBhawanpreet Lakha watermarks->d.urgent_ns, prog_wm_value); 29989e94bc5SYongqiang Sun } else if (watermarks->d.urgent_ns < hubbub1->watermarks.d.urgent_ns) 30089e94bc5SYongqiang Sun wm_pending = true; 3016f451b60SBhawanpreet Lakha 3026f451b60SBhawanpreet Lakha /* determine the transfer time for a quantity of data for a particular requestor.*/ 3036f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->a.frac_urg_bw_flip 3046f451b60SBhawanpreet Lakha > hubbub1->watermarks.a.frac_urg_bw_flip) { 3056f451b60SBhawanpreet Lakha hubbub1->watermarks.a.frac_urg_bw_flip = watermarks->a.frac_urg_bw_flip; 3066f451b60SBhawanpreet Lakha 3076f451b60SBhawanpreet Lakha REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_D, 0, 3086f451b60SBhawanpreet Lakha DCHUBBUB_ARB_FRAC_URG_BW_FLIP_D, watermarks->a.frac_urg_bw_flip); 30989e94bc5SYongqiang Sun } else if (watermarks->a.frac_urg_bw_flip 31089e94bc5SYongqiang Sun < hubbub1->watermarks.a.frac_urg_bw_flip) 31189e94bc5SYongqiang Sun wm_pending = true; 3126f451b60SBhawanpreet Lakha 3136f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->a.frac_urg_bw_nom 3146f451b60SBhawanpreet Lakha > hubbub1->watermarks.a.frac_urg_bw_nom) { 3156f451b60SBhawanpreet Lakha hubbub1->watermarks.a.frac_urg_bw_nom = watermarks->a.frac_urg_bw_nom; 3166f451b60SBhawanpreet Lakha 3176f451b60SBhawanpreet Lakha REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_D, 0, 3186f451b60SBhawanpreet Lakha DCHUBBUB_ARB_FRAC_URG_BW_NOM_D, watermarks->a.frac_urg_bw_nom); 31989e94bc5SYongqiang Sun } else if (watermarks->a.frac_urg_bw_nom 32089e94bc5SYongqiang Sun < hubbub1->watermarks.a.frac_urg_bw_nom) 32189e94bc5SYongqiang Sun wm_pending = true; 3224de094eeSBhawanpreet Lakha 3234de094eeSBhawanpreet Lakha if (safe_to_lower || watermarks->d.urgent_latency_ns > hubbub1->watermarks.d.urgent_latency_ns) { 3244de094eeSBhawanpreet Lakha hubbub1->watermarks.d.urgent_latency_ns = watermarks->d.urgent_latency_ns; 3254de094eeSBhawanpreet Lakha prog_wm_value = convert_and_clamp(watermarks->d.urgent_latency_ns, 3264de094eeSBhawanpreet Lakha refclk_mhz, 0x1fffff); 3274de094eeSBhawanpreet Lakha REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, 0, 3284de094eeSBhawanpreet Lakha DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, prog_wm_value); 32989e94bc5SYongqiang Sun } else if (watermarks->d.urgent_latency_ns < hubbub1->watermarks.d.urgent_latency_ns) 33089e94bc5SYongqiang Sun wm_pending = true; 33189e94bc5SYongqiang Sun 33289e94bc5SYongqiang Sun return wm_pending; 3336f451b60SBhawanpreet Lakha } 3346f451b60SBhawanpreet Lakha 33589e94bc5SYongqiang Sun bool hubbub21_program_stutter_watermarks( 3366f451b60SBhawanpreet Lakha struct hubbub *hubbub, 3376f451b60SBhawanpreet Lakha struct dcn_watermark_set *watermarks, 3386f451b60SBhawanpreet Lakha unsigned int refclk_mhz, 3396f451b60SBhawanpreet Lakha bool safe_to_lower) 3406f451b60SBhawanpreet Lakha { 3416f451b60SBhawanpreet Lakha struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); 3426f451b60SBhawanpreet Lakha uint32_t prog_wm_value; 34389e94bc5SYongqiang Sun bool wm_pending = false; 3446f451b60SBhawanpreet Lakha 3456f451b60SBhawanpreet Lakha /* clock state A */ 3466f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns 3476f451b60SBhawanpreet Lakha > hubbub1->watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns) { 3486f451b60SBhawanpreet Lakha hubbub1->watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns = 3496f451b60SBhawanpreet Lakha watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns; 3506f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp( 3516f451b60SBhawanpreet Lakha watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, 3526f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 3536f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, 0, 3546f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value, 3556f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value); 3566f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_A calculated =%d\n" 3576f451b60SBhawanpreet Lakha "HW register value = 0x%x\n", 3586f451b60SBhawanpreet Lakha watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); 35989e94bc5SYongqiang Sun } else if (watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns 36089e94bc5SYongqiang Sun < hubbub1->watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns) 36189e94bc5SYongqiang Sun wm_pending = true; 3626f451b60SBhawanpreet Lakha 3636f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->a.cstate_pstate.cstate_exit_ns 3646f451b60SBhawanpreet Lakha > hubbub1->watermarks.a.cstate_pstate.cstate_exit_ns) { 3656f451b60SBhawanpreet Lakha hubbub1->watermarks.a.cstate_pstate.cstate_exit_ns = 3666f451b60SBhawanpreet Lakha watermarks->a.cstate_pstate.cstate_exit_ns; 3676f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp( 3686f451b60SBhawanpreet Lakha watermarks->a.cstate_pstate.cstate_exit_ns, 3696f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 3706f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, 0, 3716f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value, 3726f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value); 3736f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_A calculated =%d\n" 3746f451b60SBhawanpreet Lakha "HW register value = 0x%x\n", 3756f451b60SBhawanpreet Lakha watermarks->a.cstate_pstate.cstate_exit_ns, prog_wm_value); 37689e94bc5SYongqiang Sun } else if (watermarks->a.cstate_pstate.cstate_exit_ns 37789e94bc5SYongqiang Sun < hubbub1->watermarks.a.cstate_pstate.cstate_exit_ns) 37889e94bc5SYongqiang Sun wm_pending = true; 3796f451b60SBhawanpreet Lakha 3806f451b60SBhawanpreet Lakha /* clock state B */ 3816f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns 3826f451b60SBhawanpreet Lakha > hubbub1->watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns) { 3836f451b60SBhawanpreet Lakha hubbub1->watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns = 3846f451b60SBhawanpreet Lakha watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns; 3856f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp( 3866f451b60SBhawanpreet Lakha watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, 3876f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 3886f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, 0, 3896f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value, 3906f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value); 3916f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_B calculated =%d\n" 3926f451b60SBhawanpreet Lakha "HW register value = 0x%x\n", 3936f451b60SBhawanpreet Lakha watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); 39489e94bc5SYongqiang Sun } else if (watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns 39589e94bc5SYongqiang Sun < hubbub1->watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns) 39689e94bc5SYongqiang Sun wm_pending = true; 3976f451b60SBhawanpreet Lakha 3986f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->b.cstate_pstate.cstate_exit_ns 3996f451b60SBhawanpreet Lakha > hubbub1->watermarks.b.cstate_pstate.cstate_exit_ns) { 4006f451b60SBhawanpreet Lakha hubbub1->watermarks.b.cstate_pstate.cstate_exit_ns = 4016f451b60SBhawanpreet Lakha watermarks->b.cstate_pstate.cstate_exit_ns; 4026f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp( 4036f451b60SBhawanpreet Lakha watermarks->b.cstate_pstate.cstate_exit_ns, 4046f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 4056f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, 0, 4066f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, prog_wm_value, 4076f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value); 4086f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_B calculated =%d\n" 4096f451b60SBhawanpreet Lakha "HW register value = 0x%x\n", 4106f451b60SBhawanpreet Lakha watermarks->b.cstate_pstate.cstate_exit_ns, prog_wm_value); 41189e94bc5SYongqiang Sun } else if (watermarks->b.cstate_pstate.cstate_exit_ns 41289e94bc5SYongqiang Sun < hubbub1->watermarks.b.cstate_pstate.cstate_exit_ns) 41389e94bc5SYongqiang Sun wm_pending = true; 4146f451b60SBhawanpreet Lakha 4156f451b60SBhawanpreet Lakha /* clock state C */ 4166f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns 4176f451b60SBhawanpreet Lakha > hubbub1->watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns) { 4186f451b60SBhawanpreet Lakha hubbub1->watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns = 4196f451b60SBhawanpreet Lakha watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns; 4206f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp( 4216f451b60SBhawanpreet Lakha watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, 4226f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 4236f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, 0, 4246f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value, 4256f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value); 4266f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_C calculated =%d\n" 4276f451b60SBhawanpreet Lakha "HW register value = 0x%x\n", 4286f451b60SBhawanpreet Lakha watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); 42989e94bc5SYongqiang Sun } else if (watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns 43089e94bc5SYongqiang Sun < hubbub1->watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns) 43189e94bc5SYongqiang Sun wm_pending = true; 4326f451b60SBhawanpreet Lakha 4336f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->c.cstate_pstate.cstate_exit_ns 4346f451b60SBhawanpreet Lakha > hubbub1->watermarks.c.cstate_pstate.cstate_exit_ns) { 4356f451b60SBhawanpreet Lakha hubbub1->watermarks.c.cstate_pstate.cstate_exit_ns = 4366f451b60SBhawanpreet Lakha watermarks->c.cstate_pstate.cstate_exit_ns; 4376f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp( 4386f451b60SBhawanpreet Lakha watermarks->c.cstate_pstate.cstate_exit_ns, 4396f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 4406f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, 0, 4416f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, prog_wm_value, 4426f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value); 4436f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_C calculated =%d\n" 4446f451b60SBhawanpreet Lakha "HW register value = 0x%x\n", 4456f451b60SBhawanpreet Lakha watermarks->c.cstate_pstate.cstate_exit_ns, prog_wm_value); 44689e94bc5SYongqiang Sun } else if (watermarks->c.cstate_pstate.cstate_exit_ns 44789e94bc5SYongqiang Sun < hubbub1->watermarks.c.cstate_pstate.cstate_exit_ns) 44889e94bc5SYongqiang Sun wm_pending = true; 4496f451b60SBhawanpreet Lakha 4506f451b60SBhawanpreet Lakha /* clock state D */ 4516f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns 4526f451b60SBhawanpreet Lakha > hubbub1->watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns) { 4536f451b60SBhawanpreet Lakha hubbub1->watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns = 4546f451b60SBhawanpreet Lakha watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns; 4556f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp( 4566f451b60SBhawanpreet Lakha watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, 4576f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 4586f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, 0, 4596f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value, 4606f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value); 4616f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_D calculated =%d\n" 4626f451b60SBhawanpreet Lakha "HW register value = 0x%x\n", 4636f451b60SBhawanpreet Lakha watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); 46489e94bc5SYongqiang Sun } else if (watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns 46589e94bc5SYongqiang Sun < hubbub1->watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns) 46689e94bc5SYongqiang Sun wm_pending = true; 4676f451b60SBhawanpreet Lakha 4686f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->d.cstate_pstate.cstate_exit_ns 4696f451b60SBhawanpreet Lakha > hubbub1->watermarks.d.cstate_pstate.cstate_exit_ns) { 4706f451b60SBhawanpreet Lakha hubbub1->watermarks.d.cstate_pstate.cstate_exit_ns = 4716f451b60SBhawanpreet Lakha watermarks->d.cstate_pstate.cstate_exit_ns; 4726f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp( 4736f451b60SBhawanpreet Lakha watermarks->d.cstate_pstate.cstate_exit_ns, 4746f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 4756f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, 0, 4766f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, prog_wm_value, 4776f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value); 4786f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_D calculated =%d\n" 4796f451b60SBhawanpreet Lakha "HW register value = 0x%x\n", 4806f451b60SBhawanpreet Lakha watermarks->d.cstate_pstate.cstate_exit_ns, prog_wm_value); 48189e94bc5SYongqiang Sun } else if (watermarks->d.cstate_pstate.cstate_exit_ns 48289e94bc5SYongqiang Sun < hubbub1->watermarks.d.cstate_pstate.cstate_exit_ns) 48389e94bc5SYongqiang Sun wm_pending = true; 48489e94bc5SYongqiang Sun 48589e94bc5SYongqiang Sun return wm_pending; 4866f451b60SBhawanpreet Lakha } 4876f451b60SBhawanpreet Lakha 48889e94bc5SYongqiang Sun bool hubbub21_program_pstate_watermarks( 4896f451b60SBhawanpreet Lakha struct hubbub *hubbub, 4906f451b60SBhawanpreet Lakha struct dcn_watermark_set *watermarks, 4916f451b60SBhawanpreet Lakha unsigned int refclk_mhz, 4926f451b60SBhawanpreet Lakha bool safe_to_lower) 4936f451b60SBhawanpreet Lakha { 4946f451b60SBhawanpreet Lakha struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); 4956f451b60SBhawanpreet Lakha uint32_t prog_wm_value; 4966f451b60SBhawanpreet Lakha 49789e94bc5SYongqiang Sun bool wm_pending = false; 49889e94bc5SYongqiang Sun 4996f451b60SBhawanpreet Lakha /* clock state A */ 5006f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->a.cstate_pstate.pstate_change_ns 5016f451b60SBhawanpreet Lakha > hubbub1->watermarks.a.cstate_pstate.pstate_change_ns) { 5026f451b60SBhawanpreet Lakha hubbub1->watermarks.a.cstate_pstate.pstate_change_ns = 5036f451b60SBhawanpreet Lakha watermarks->a.cstate_pstate.pstate_change_ns; 5046f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp( 5056f451b60SBhawanpreet Lakha watermarks->a.cstate_pstate.pstate_change_ns, 5066f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 5076f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, 0, 5086f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, prog_wm_value, 5096f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, prog_wm_value); 5106f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_A calculated =%d\n" 5116f451b60SBhawanpreet Lakha "HW register value = 0x%x\n\n", 5126f451b60SBhawanpreet Lakha watermarks->a.cstate_pstate.pstate_change_ns, prog_wm_value); 51389e94bc5SYongqiang Sun } else if (watermarks->a.cstate_pstate.pstate_change_ns 51489e94bc5SYongqiang Sun < hubbub1->watermarks.a.cstate_pstate.pstate_change_ns) 51589e94bc5SYongqiang Sun wm_pending = true; 5166f451b60SBhawanpreet Lakha 5176f451b60SBhawanpreet Lakha /* clock state B */ 5186f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->b.cstate_pstate.pstate_change_ns 5196f451b60SBhawanpreet Lakha > hubbub1->watermarks.b.cstate_pstate.pstate_change_ns) { 5206f451b60SBhawanpreet Lakha hubbub1->watermarks.b.cstate_pstate.pstate_change_ns = 5216f451b60SBhawanpreet Lakha watermarks->b.cstate_pstate.pstate_change_ns; 5226f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp( 5236f451b60SBhawanpreet Lakha watermarks->b.cstate_pstate.pstate_change_ns, 5246f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 5256f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, 0, 5266f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, prog_wm_value, 5276f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, prog_wm_value); 5286f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_B calculated =%d\n" 5296f451b60SBhawanpreet Lakha "HW register value = 0x%x\n\n", 5306f451b60SBhawanpreet Lakha watermarks->b.cstate_pstate.pstate_change_ns, prog_wm_value); 53189e94bc5SYongqiang Sun } else if (watermarks->b.cstate_pstate.pstate_change_ns 53289e94bc5SYongqiang Sun < hubbub1->watermarks.b.cstate_pstate.pstate_change_ns) 53389e94bc5SYongqiang Sun wm_pending = false; 5346f451b60SBhawanpreet Lakha 5356f451b60SBhawanpreet Lakha /* clock state C */ 5366f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->c.cstate_pstate.pstate_change_ns 5376f451b60SBhawanpreet Lakha > hubbub1->watermarks.c.cstate_pstate.pstate_change_ns) { 5386f451b60SBhawanpreet Lakha hubbub1->watermarks.c.cstate_pstate.pstate_change_ns = 5396f451b60SBhawanpreet Lakha watermarks->c.cstate_pstate.pstate_change_ns; 5406f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp( 5416f451b60SBhawanpreet Lakha watermarks->c.cstate_pstate.pstate_change_ns, 5426f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 5436f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, 0, 5446f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, prog_wm_value, 5456f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, prog_wm_value); 5466f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_C calculated =%d\n" 5476f451b60SBhawanpreet Lakha "HW register value = 0x%x\n\n", 5486f451b60SBhawanpreet Lakha watermarks->c.cstate_pstate.pstate_change_ns, prog_wm_value); 54989e94bc5SYongqiang Sun } else if (watermarks->c.cstate_pstate.pstate_change_ns 55089e94bc5SYongqiang Sun < hubbub1->watermarks.c.cstate_pstate.pstate_change_ns) 55189e94bc5SYongqiang Sun wm_pending = true; 5526f451b60SBhawanpreet Lakha 5536f451b60SBhawanpreet Lakha /* clock state D */ 5546f451b60SBhawanpreet Lakha if (safe_to_lower || watermarks->d.cstate_pstate.pstate_change_ns 5556f451b60SBhawanpreet Lakha > hubbub1->watermarks.d.cstate_pstate.pstate_change_ns) { 5566f451b60SBhawanpreet Lakha hubbub1->watermarks.d.cstate_pstate.pstate_change_ns = 5576f451b60SBhawanpreet Lakha watermarks->d.cstate_pstate.pstate_change_ns; 5586f451b60SBhawanpreet Lakha prog_wm_value = convert_and_clamp( 5596f451b60SBhawanpreet Lakha watermarks->d.cstate_pstate.pstate_change_ns, 5606f451b60SBhawanpreet Lakha refclk_mhz, 0x1fffff); 5616f451b60SBhawanpreet Lakha REG_SET_2(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, 0, 5626f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, prog_wm_value, 5636f451b60SBhawanpreet Lakha DCHUBBUB_ARB_VM_ROW_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, prog_wm_value); 5646f451b60SBhawanpreet Lakha DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_D calculated =%d\n" 5656f451b60SBhawanpreet Lakha "HW register value = 0x%x\n\n", 5666f451b60SBhawanpreet Lakha watermarks->d.cstate_pstate.pstate_change_ns, prog_wm_value); 56789e94bc5SYongqiang Sun } else if (watermarks->d.cstate_pstate.pstate_change_ns 56889e94bc5SYongqiang Sun < hubbub1->watermarks.d.cstate_pstate.pstate_change_ns) 56989e94bc5SYongqiang Sun wm_pending = true; 57089e94bc5SYongqiang Sun 57189e94bc5SYongqiang Sun return wm_pending; 5726f451b60SBhawanpreet Lakha } 5736f451b60SBhawanpreet Lakha 57489e94bc5SYongqiang Sun bool hubbub21_program_watermarks( 5756f451b60SBhawanpreet Lakha struct hubbub *hubbub, 5766f451b60SBhawanpreet Lakha struct dcn_watermark_set *watermarks, 5776f451b60SBhawanpreet Lakha unsigned int refclk_mhz, 5786f451b60SBhawanpreet Lakha bool safe_to_lower) 5796f451b60SBhawanpreet Lakha { 5806f451b60SBhawanpreet Lakha struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); 58189e94bc5SYongqiang Sun bool wm_pending = false; 5826f451b60SBhawanpreet Lakha 58389e94bc5SYongqiang Sun if (hubbub21_program_urgent_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower)) 58489e94bc5SYongqiang Sun wm_pending = true; 58589e94bc5SYongqiang Sun 58689e94bc5SYongqiang Sun if (hubbub21_program_stutter_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower)) 58789e94bc5SYongqiang Sun wm_pending = true; 58889e94bc5SYongqiang Sun 58989e94bc5SYongqiang Sun if (hubbub21_program_pstate_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower)) 59089e94bc5SYongqiang Sun wm_pending = true; 5916f451b60SBhawanpreet Lakha 5926f451b60SBhawanpreet Lakha /* 5936f451b60SBhawanpreet Lakha * The DCHub arbiter has a mechanism to dynamically rate limit the DCHub request stream to the fabric. 5946f451b60SBhawanpreet Lakha * If the memory controller is fully utilized and the DCHub requestors are 5956f451b60SBhawanpreet Lakha * well ahead of their amortized schedule, then it is safe to prevent the next winner 5966f451b60SBhawanpreet Lakha * from being committed and sent to the fabric. 5976f451b60SBhawanpreet Lakha * The utilization of the memory controller is approximated by ensuring that 5986f451b60SBhawanpreet Lakha * the number of outstanding requests is greater than a threshold specified 5996f451b60SBhawanpreet Lakha * by the ARB_MIN_REQ_OUTSTANDING. To determine that the DCHub requestors are well ahead of the amortized schedule, 6006f451b60SBhawanpreet Lakha * the slack of the next winner is compared with the ARB_SAT_LEVEL in DLG RefClk cycles. 6016f451b60SBhawanpreet Lakha * 6026f451b60SBhawanpreet Lakha * TODO: Revisit request limit after figure out right number. request limit for Renoir isn't decided yet, set maximum value (0x1FF) 6036f451b60SBhawanpreet Lakha * to turn off it for now. 6046f451b60SBhawanpreet Lakha */ 6056f451b60SBhawanpreet Lakha REG_SET(DCHUBBUB_ARB_SAT_LEVEL, 0, 6066f451b60SBhawanpreet Lakha DCHUBBUB_ARB_SAT_LEVEL, 60 * refclk_mhz); 6076f451b60SBhawanpreet Lakha REG_UPDATE_2(DCHUBBUB_ARB_DF_REQ_OUTSTAND, 6086f451b60SBhawanpreet Lakha DCHUBBUB_ARB_MIN_REQ_OUTSTAND, 0x1FF, 6096f451b60SBhawanpreet Lakha DCHUBBUB_ARB_MIN_REQ_OUTSTAND_COMMIT_THRESHOLD, 0xA); 6106f451b60SBhawanpreet Lakha REG_UPDATE(DCHUBBUB_ARB_HOSTVM_CNTL, 6116f451b60SBhawanpreet Lakha DCHUBBUB_ARB_MAX_QOS_COMMIT_THRESHOLD, 0xF); 6126f451b60SBhawanpreet Lakha 6136f451b60SBhawanpreet Lakha hubbub1_allow_self_refresh_control(hubbub, !hubbub->ctx->dc->debug.disable_stutter); 61489e94bc5SYongqiang Sun 61589e94bc5SYongqiang Sun return wm_pending; 6166f451b60SBhawanpreet Lakha } 6176f451b60SBhawanpreet Lakha 6186f451b60SBhawanpreet Lakha void hubbub21_wm_read_state(struct hubbub *hubbub, 6196f451b60SBhawanpreet Lakha struct dcn_hubbub_wm *wm) 6206f451b60SBhawanpreet Lakha { 6216f451b60SBhawanpreet Lakha struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); 6226f451b60SBhawanpreet Lakha struct dcn_hubbub_wm_set *s; 6236f451b60SBhawanpreet Lakha 6246f451b60SBhawanpreet Lakha memset(wm, 0, sizeof(struct dcn_hubbub_wm)); 6256f451b60SBhawanpreet Lakha 6266f451b60SBhawanpreet Lakha s = &wm->sets[0]; 6276f451b60SBhawanpreet Lakha s->wm_set = 0; 6286f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, 6296f451b60SBhawanpreet Lakha DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, &s->data_urgent); 6306f451b60SBhawanpreet Lakha 6316f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, 6326f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, &s->sr_enter); 6336f451b60SBhawanpreet Lakha 6346f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, 6356f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, &s->sr_exit); 6366f451b60SBhawanpreet Lakha 6376f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, 6386f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, &s->dram_clk_chanage); 6396f451b60SBhawanpreet Lakha 6406f451b60SBhawanpreet Lakha s = &wm->sets[1]; 6416f451b60SBhawanpreet Lakha s->wm_set = 1; 6426f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, 6436f451b60SBhawanpreet Lakha DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, &s->data_urgent); 6446f451b60SBhawanpreet Lakha 6456f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, 6466f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, &s->sr_enter); 6476f451b60SBhawanpreet Lakha 6486f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, 6496f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, &s->sr_exit); 6506f451b60SBhawanpreet Lakha 6516f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, 6526f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, &s->dram_clk_chanage); 6536f451b60SBhawanpreet Lakha 6546f451b60SBhawanpreet Lakha s = &wm->sets[2]; 6556f451b60SBhawanpreet Lakha s->wm_set = 2; 6566f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, 6576f451b60SBhawanpreet Lakha DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, &s->data_urgent); 6586f451b60SBhawanpreet Lakha 6596f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, 6606f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, &s->sr_enter); 6616f451b60SBhawanpreet Lakha 6626f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, 6636f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, &s->sr_exit); 6646f451b60SBhawanpreet Lakha 6656f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, 6666f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, &s->dram_clk_chanage); 6676f451b60SBhawanpreet Lakha 6686f451b60SBhawanpreet Lakha s = &wm->sets[3]; 6696f451b60SBhawanpreet Lakha s->wm_set = 3; 6706f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, 6716f451b60SBhawanpreet Lakha DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, &s->data_urgent); 6726f451b60SBhawanpreet Lakha 6736f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, 6746f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, &s->sr_enter); 6756f451b60SBhawanpreet Lakha 6766f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, 6776f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, &s->sr_exit); 6786f451b60SBhawanpreet Lakha 6796f451b60SBhawanpreet Lakha REG_GET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, 6806f451b60SBhawanpreet Lakha DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, &s->dram_clk_chanage); 6816f451b60SBhawanpreet Lakha } 6826f451b60SBhawanpreet Lakha 683*240e6d25SIsabella Basso static void hubbub21_apply_DEDCN21_147_wa(struct hubbub *hubbub) 684f93e29f0SLewis Huang { 685f93e29f0SLewis Huang struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); 686f93e29f0SLewis Huang uint32_t prog_wm_value; 687f93e29f0SLewis Huang 688f93e29f0SLewis Huang prog_wm_value = REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A); 689f93e29f0SLewis Huang REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, prog_wm_value); 690f93e29f0SLewis Huang } 6916f451b60SBhawanpreet Lakha 6926f451b60SBhawanpreet Lakha static const struct hubbub_funcs hubbub21_funcs = { 6936f451b60SBhawanpreet Lakha .update_dchub = hubbub2_update_dchub, 6946f451b60SBhawanpreet Lakha .init_dchub_sys_ctx = hubbub21_init_dchub, 6956ba3712dSDmytro Laktyushkin .init_vm_ctx = hubbub2_init_vm_ctx, 6966f451b60SBhawanpreet Lakha .dcc_support_swizzle = hubbub2_dcc_support_swizzle, 6976f451b60SBhawanpreet Lakha .dcc_support_pixel_format = hubbub2_dcc_support_pixel_format, 6986f451b60SBhawanpreet Lakha .get_dcc_compression_cap = hubbub2_get_dcc_compression_cap, 6996f451b60SBhawanpreet Lakha .wm_read_state = hubbub21_wm_read_state, 7006f451b60SBhawanpreet Lakha .get_dchub_ref_freq = hubbub2_get_dchub_ref_freq, 7016f451b60SBhawanpreet Lakha .program_watermarks = hubbub21_program_watermarks, 702d9758768SGeorge Shen .allow_self_refresh_control = hubbub1_allow_self_refresh_control, 703f93e29f0SLewis Huang .apply_DEDCN21_147_wa = hubbub21_apply_DEDCN21_147_wa, 70498e95e4fSJosip Pavic .hubbub_read_state = hubbub2_read_state, 7056f451b60SBhawanpreet Lakha }; 7066f451b60SBhawanpreet Lakha 7076f451b60SBhawanpreet Lakha void hubbub21_construct(struct dcn20_hubbub *hubbub, 7086f451b60SBhawanpreet Lakha struct dc_context *ctx, 7096f451b60SBhawanpreet Lakha const struct dcn_hubbub_registers *hubbub_regs, 7106f451b60SBhawanpreet Lakha const struct dcn_hubbub_shift *hubbub_shift, 7116f451b60SBhawanpreet Lakha const struct dcn_hubbub_mask *hubbub_mask) 7126f451b60SBhawanpreet Lakha { 7136f451b60SBhawanpreet Lakha hubbub->base.ctx = ctx; 7146f451b60SBhawanpreet Lakha 7156f451b60SBhawanpreet Lakha hubbub->base.funcs = &hubbub21_funcs; 7166f451b60SBhawanpreet Lakha 7176f451b60SBhawanpreet Lakha hubbub->regs = hubbub_regs; 7186f451b60SBhawanpreet Lakha hubbub->shifts = hubbub_shift; 7196f451b60SBhawanpreet Lakha hubbub->masks = hubbub_mask; 7206f451b60SBhawanpreet Lakha 7216f451b60SBhawanpreet Lakha hubbub->debug_test_index_pstate = 0xB; 722df1fba07SBhawanpreet Lakha hubbub->detile_buf_size = 164 * 1024; /* 164KB for DCN2.0 */ 7236f451b60SBhawanpreet Lakha } 724