116012806SWyatt Wood /* 216012806SWyatt Wood * Copyright 2019 Advanced Micro Devices, Inc. 316012806SWyatt Wood * 416012806SWyatt Wood * Permission is hereby granted, free of charge, to any person obtaining a 516012806SWyatt Wood * copy of this software and associated documentation files (the "Software"), 616012806SWyatt Wood * to deal in the Software without restriction, including without limitation 716012806SWyatt Wood * the rights to use, copy, modify, merge, publish, distribute, sublicense, 816012806SWyatt Wood * and/or sell copies of the Software, and to permit persons to whom the 916012806SWyatt Wood * Software is furnished to do so, subject to the following conditions: 1016012806SWyatt Wood * 1116012806SWyatt Wood * The above copyright notice and this permission notice shall be included in 1216012806SWyatt Wood * all copies or substantial portions of the Software. 1316012806SWyatt Wood * 1416012806SWyatt Wood * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1516012806SWyatt Wood * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1616012806SWyatt Wood * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1716012806SWyatt Wood * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 1816012806SWyatt Wood * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 1916012806SWyatt Wood * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 2016012806SWyatt Wood * OTHER DEALINGS IN THE SOFTWARE. 2116012806SWyatt Wood * 2216012806SWyatt Wood * Authors: AMD 2316012806SWyatt Wood * 2416012806SWyatt Wood */ 2516012806SWyatt Wood 2616012806SWyatt Wood #include "dmub_abm.h" 27*b8fe5637SLeon Huang #include "dmub_abm_lcd.h" 2816012806SWyatt Wood #include "dc.h" 2916012806SWyatt Wood #include "core_types.h" 3016012806SWyatt Wood 3116012806SWyatt Wood #define TO_DMUB_ABM(abm)\ 3216012806SWyatt Wood container_of(abm, struct dce_abm, base) 3316012806SWyatt Wood 34*b8fe5637SLeon Huang #define ABM_FEATURE_NO_SUPPORT 0 35*b8fe5637SLeon Huang #define ABM_LCD_SUPPORT 1 3616012806SWyatt Wood 37*b8fe5637SLeon Huang static unsigned int abm_feature_support(struct abm *abm, unsigned int panel_inst) 38dd5a94ceSWyatt Wood { 3916012806SWyatt Wood struct dc_context *dc = abm->ctx; 4063de4f04SJake Wang struct dc_link *edp_links[MAX_NUM_EDP]; 4163de4f04SJake Wang int i; 4263de4f04SJake Wang int edp_num; 43*b8fe5637SLeon Huang unsigned int ret = ABM_FEATURE_NO_SUPPORT; 4463de4f04SJake Wang 457ae1dbe6SWenjing Liu dc_get_edp_links(dc->dc, edp_links, &edp_num); 4663de4f04SJake Wang 4763de4f04SJake Wang for (i = 0; i < edp_num; i++) { 48*b8fe5637SLeon Huang if (panel_inst == i) 49*b8fe5637SLeon Huang break; 5063de4f04SJake Wang } 5116012806SWyatt Wood 52*b8fe5637SLeon Huang if (i < edp_num) { 53*b8fe5637SLeon Huang ret = ABM_LCD_SUPPORT; 5416012806SWyatt Wood } 5516012806SWyatt Wood 56*b8fe5637SLeon Huang return ret; 57*b8fe5637SLeon Huang } 58*b8fe5637SLeon Huang 59*b8fe5637SLeon Huang static void dmub_abm_init_ex(struct abm *abm, uint32_t backlight) 60*b8fe5637SLeon Huang { 61*b8fe5637SLeon Huang dmub_abm_init(abm, backlight); 62*b8fe5637SLeon Huang } 63*b8fe5637SLeon Huang 64*b8fe5637SLeon Huang static unsigned int dmub_abm_get_current_backlight_ex(struct abm *abm) 65*b8fe5637SLeon Huang { 66*b8fe5637SLeon Huang return dmub_abm_get_current_backlight(abm); 67*b8fe5637SLeon Huang } 68*b8fe5637SLeon Huang 69*b8fe5637SLeon Huang static unsigned int dmub_abm_get_target_backlight_ex(struct abm *abm) 70*b8fe5637SLeon Huang { 71*b8fe5637SLeon Huang return dmub_abm_get_target_backlight(abm); 72*b8fe5637SLeon Huang } 73*b8fe5637SLeon Huang 74*b8fe5637SLeon Huang static bool dmub_abm_set_level_ex(struct abm *abm, uint32_t level) 75*b8fe5637SLeon Huang { 76*b8fe5637SLeon Huang bool ret = false; 77*b8fe5637SLeon Huang unsigned int feature_support, i; 78*b8fe5637SLeon Huang uint8_t panel_mask0 = 0; 79*b8fe5637SLeon Huang 80*b8fe5637SLeon Huang for (i = 0; i < MAX_NUM_EDP; i++) { 81*b8fe5637SLeon Huang feature_support = abm_feature_support(abm, i); 82*b8fe5637SLeon Huang 83*b8fe5637SLeon Huang if (feature_support == ABM_LCD_SUPPORT) 84*b8fe5637SLeon Huang panel_mask0 |= (0x01 << i); 85*b8fe5637SLeon Huang } 86*b8fe5637SLeon Huang 87*b8fe5637SLeon Huang if (panel_mask0) 88*b8fe5637SLeon Huang ret = dmub_abm_set_level(abm, level, panel_mask0); 89*b8fe5637SLeon Huang 90*b8fe5637SLeon Huang return ret; 91*b8fe5637SLeon Huang } 92*b8fe5637SLeon Huang 93*b8fe5637SLeon Huang static bool dmub_abm_init_config_ex(struct abm *abm, 9416012806SWyatt Wood const char *src, 956e568e43SJake Wang unsigned int bytes, 966e568e43SJake Wang unsigned int inst) 9716012806SWyatt Wood { 98*b8fe5637SLeon Huang unsigned int feature_support; 99c5d5b0ecSWyatt Wood 100*b8fe5637SLeon Huang feature_support = abm_feature_support(abm, inst); 101c5d5b0ecSWyatt Wood 102*b8fe5637SLeon Huang if (feature_support == ABM_LCD_SUPPORT) 103*b8fe5637SLeon Huang dmub_abm_init_config(abm, src, bytes, inst); 104c5d5b0ecSWyatt Wood 10516012806SWyatt Wood return true; 10616012806SWyatt Wood } 10716012806SWyatt Wood 108*b8fe5637SLeon Huang static bool dmub_abm_set_pause_ex(struct abm *abm, bool pause, unsigned int panel_inst, unsigned int stream_inst) 109b629a824SEric Yang { 110*b8fe5637SLeon Huang bool ret = false; 111*b8fe5637SLeon Huang unsigned int feature_support; 112b629a824SEric Yang 113*b8fe5637SLeon Huang feature_support = abm_feature_support(abm, panel_inst); 114b629a824SEric Yang 115*b8fe5637SLeon Huang if (feature_support == ABM_LCD_SUPPORT) 116*b8fe5637SLeon Huang ret = dmub_abm_set_pause(abm, pause, panel_inst, stream_inst); 117b629a824SEric Yang 118*b8fe5637SLeon Huang return ret; 119*b8fe5637SLeon Huang } 120*b8fe5637SLeon Huang 121*b8fe5637SLeon Huang static bool dmub_abm_set_pipe_ex(struct abm *abm, uint32_t otg_inst, uint32_t option, uint32_t panel_inst) 122*b8fe5637SLeon Huang { 123*b8fe5637SLeon Huang bool ret = false; 124*b8fe5637SLeon Huang unsigned int feature_support; 125*b8fe5637SLeon Huang 126*b8fe5637SLeon Huang feature_support = abm_feature_support(abm, panel_inst); 127*b8fe5637SLeon Huang 128*b8fe5637SLeon Huang if (feature_support == ABM_LCD_SUPPORT) 129*b8fe5637SLeon Huang ret = dmub_abm_set_pipe(abm, otg_inst, option, panel_inst); 130*b8fe5637SLeon Huang 131*b8fe5637SLeon Huang return ret; 132*b8fe5637SLeon Huang } 133*b8fe5637SLeon Huang 134*b8fe5637SLeon Huang static bool dmub_abm_set_event_ex(struct abm *abm, unsigned int full_screen, unsigned int video_mode, 135*b8fe5637SLeon Huang unsigned int hdr_mode, unsigned int panel_inst) 136*b8fe5637SLeon Huang { 137*b8fe5637SLeon Huang bool ret = false; 138*b8fe5637SLeon Huang unsigned int feature_support; 139*b8fe5637SLeon Huang 140*b8fe5637SLeon Huang feature_support = abm_feature_support(abm, panel_inst); 141*b8fe5637SLeon Huang 142*b8fe5637SLeon Huang return ret; 143*b8fe5637SLeon Huang } 144*b8fe5637SLeon Huang 145*b8fe5637SLeon Huang static bool dmub_abm_set_backlight_level_pwm_ex(struct abm *abm, 146*b8fe5637SLeon Huang unsigned int backlight_pwm_u16_16, 147*b8fe5637SLeon Huang unsigned int frame_ramp, 148*b8fe5637SLeon Huang unsigned int controller_id, 149*b8fe5637SLeon Huang unsigned int panel_inst) 150*b8fe5637SLeon Huang { 151*b8fe5637SLeon Huang bool ret = false; 152*b8fe5637SLeon Huang unsigned int feature_support; 153*b8fe5637SLeon Huang 154*b8fe5637SLeon Huang feature_support = abm_feature_support(abm, panel_inst); 155*b8fe5637SLeon Huang 156*b8fe5637SLeon Huang if (feature_support == ABM_LCD_SUPPORT) 157*b8fe5637SLeon Huang ret = dmub_abm_set_backlight_level(abm, backlight_pwm_u16_16, frame_ramp, panel_inst); 158*b8fe5637SLeon Huang 159*b8fe5637SLeon Huang return ret; 160b629a824SEric Yang } 161b629a824SEric Yang 16216012806SWyatt Wood static const struct abm_funcs abm_funcs = { 163*b8fe5637SLeon Huang .abm_init = dmub_abm_init_ex, 164*b8fe5637SLeon Huang .set_abm_level = dmub_abm_set_level_ex, 165*b8fe5637SLeon Huang .get_current_backlight = dmub_abm_get_current_backlight_ex, 166*b8fe5637SLeon Huang .get_target_backlight = dmub_abm_get_target_backlight_ex, 167*b8fe5637SLeon Huang .init_abm_config = dmub_abm_init_config_ex, 168*b8fe5637SLeon Huang .set_abm_pause = dmub_abm_set_pause_ex, 169*b8fe5637SLeon Huang .set_pipe_ex = dmub_abm_set_pipe_ex, 170*b8fe5637SLeon Huang .set_abm_event = dmub_abm_set_event_ex, 171*b8fe5637SLeon Huang .set_backlight_level_pwm = dmub_abm_set_backlight_level_pwm_ex, 17216012806SWyatt Wood }; 17316012806SWyatt Wood 17416012806SWyatt Wood static void dmub_abm_construct( 17516012806SWyatt Wood struct dce_abm *abm_dce, 17616012806SWyatt Wood struct dc_context *ctx, 17716012806SWyatt Wood const struct dce_abm_registers *regs, 17816012806SWyatt Wood const struct dce_abm_shift *abm_shift, 17916012806SWyatt Wood const struct dce_abm_mask *abm_mask) 18016012806SWyatt Wood { 18116012806SWyatt Wood struct abm *base = &abm_dce->base; 18216012806SWyatt Wood 18316012806SWyatt Wood base->ctx = ctx; 18416012806SWyatt Wood base->funcs = &abm_funcs; 18516012806SWyatt Wood base->dmcu_is_running = false; 18616012806SWyatt Wood 18716012806SWyatt Wood abm_dce->regs = regs; 18816012806SWyatt Wood abm_dce->abm_shift = abm_shift; 18916012806SWyatt Wood abm_dce->abm_mask = abm_mask; 19016012806SWyatt Wood } 19116012806SWyatt Wood 19216012806SWyatt Wood struct abm *dmub_abm_create( 19316012806SWyatt Wood struct dc_context *ctx, 19416012806SWyatt Wood const struct dce_abm_registers *regs, 19516012806SWyatt Wood const struct dce_abm_shift *abm_shift, 19616012806SWyatt Wood const struct dce_abm_mask *abm_mask) 19716012806SWyatt Wood { 198*b8fe5637SLeon Huang if (ctx->dc->caps.dmcub_support) { 19916012806SWyatt Wood struct dce_abm *abm_dce = kzalloc(sizeof(*abm_dce), GFP_KERNEL); 20016012806SWyatt Wood 20116012806SWyatt Wood if (abm_dce == NULL) { 20216012806SWyatt Wood BREAK_TO_DEBUGGER(); 20316012806SWyatt Wood return NULL; 20416012806SWyatt Wood } 20516012806SWyatt Wood 20616012806SWyatt Wood dmub_abm_construct(abm_dce, ctx, regs, abm_shift, abm_mask); 20716012806SWyatt Wood 20816012806SWyatt Wood return &abm_dce->base; 20916012806SWyatt Wood } 210*b8fe5637SLeon Huang return NULL; 211*b8fe5637SLeon Huang } 21216012806SWyatt Wood 21316012806SWyatt Wood void dmub_abm_destroy(struct abm **abm) 21416012806SWyatt Wood { 21516012806SWyatt Wood struct dce_abm *abm_dce = TO_DMUB_ABM(*abm); 21616012806SWyatt Wood 21716012806SWyatt Wood kfree(abm_dce); 21816012806SWyatt Wood *abm = NULL; 21916012806SWyatt Wood } 220