Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amd/display: Hook up calls to do stereo mux and dig programming to stereo control interface

[Why]
Implementation of stereo mux register is complete, but unused. Need to
call functions to write relevant configs.

[How]
Add function to write stereo config for enable/disable case and call in
stereo control interface.

Signed-off-by: Murton Liu <murton.liu@amd.com>
Reviewed-by: Aric Cyr <Aric.Cyr@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Murton Liu and committed by
Alex Deucher
c2cd9d04 692626fc

+186 -3
+47
drivers/gpu/drm/amd/display/dc/core/dc.c
··· 1236 1236 kref_put(&context->refcount, dc_state_free); 1237 1237 } 1238 1238 1239 + bool dc_set_generic_gpio_for_stereo(bool enable, 1240 + struct gpio_service *gpio_service) 1241 + { 1242 + enum gpio_result gpio_result = GPIO_RESULT_NON_SPECIFIC_ERROR; 1243 + struct gpio_pin_info pin_info; 1244 + struct gpio *generic; 1245 + struct gpio_generic_mux_config *config = kzalloc(sizeof(struct gpio_generic_mux_config), 1246 + GFP_KERNEL); 1247 + 1248 + pin_info = dal_gpio_get_generic_pin_info(gpio_service, GPIO_ID_GENERIC, 0); 1249 + 1250 + if (pin_info.mask == 0xFFFFFFFF || pin_info.offset == 0xFFFFFFFF) { 1251 + kfree(config); 1252 + return false; 1253 + } else { 1254 + generic = dal_gpio_service_create_generic_mux( 1255 + gpio_service, 1256 + pin_info.offset, 1257 + pin_info.mask); 1258 + } 1259 + 1260 + if (!generic) { 1261 + kfree(config); 1262 + return false; 1263 + } 1264 + 1265 + gpio_result = dal_gpio_open(generic, GPIO_MODE_OUTPUT); 1266 + 1267 + config->enable_output_from_mux = enable; 1268 + config->mux_select = GPIO_SIGNAL_SOURCE_PASS_THROUGH_STEREO_SYNC; 1269 + 1270 + if (gpio_result == GPIO_RESULT_OK) 1271 + gpio_result = dal_mux_setup_config(generic, config); 1272 + 1273 + if (gpio_result == GPIO_RESULT_OK) { 1274 + dal_gpio_close(generic); 1275 + dal_gpio_destroy_generic_mux(&generic); 1276 + kfree(config); 1277 + return true; 1278 + } else { 1279 + dal_gpio_close(generic); 1280 + dal_gpio_destroy_generic_mux(&generic); 1281 + kfree(config); 1282 + return false; 1283 + } 1284 + } 1285 + 1239 1286 static bool is_surface_in_context( 1240 1287 const struct dc_state *context, 1241 1288 const struct dc_plane_state *plane_state)
+3
drivers/gpu/drm/amd/display/dc/dc.h
··· 852 852 853 853 void get_clock_requirements_for_state(struct dc_state *state, struct AsicStateEx *info); 854 854 855 + bool dc_set_generic_gpio_for_stereo(bool enable, 856 + struct gpio_service *gpio_service); 857 + 855 858 /* 856 859 * fast_validate: we return after determining if we can support the new state, 857 860 * but before we populate the programming info
+7
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
··· 2692 2692 2693 2693 dcn10_config_stereo_parameters(stream, &flags); 2694 2694 2695 + if (stream->timing.timing_3d_format == TIMING_3D_FORMAT_SIDEBAND_FA) { 2696 + if (!dc_set_generic_gpio_for_stereo(true, dc->ctx->gpio_service)) 2697 + dc_set_generic_gpio_for_stereo(false, dc->ctx->gpio_service); 2698 + } else { 2699 + dc_set_generic_gpio_for_stereo(false, dc->ctx->gpio_service); 2700 + } 2701 + 2695 2702 pipe_ctx->stream_res.opp->funcs->opp_program_stereo( 2696 2703 pipe_ctx->stream_res.opp, 2697 2704 flags.PROGRAM_STEREO == 1 ? true:false,
+40 -2
drivers/gpu/drm/amd/display/dc/gpio/dcn10/hw_factory_dcn10.c
··· 31 31 #include "../hw_gpio.h" 32 32 #include "../hw_ddc.h" 33 33 #include "../hw_hpd.h" 34 + #include "../hw_generic.h" 34 35 35 36 #include "hw_factory_dcn10.h" 36 37 ··· 122 121 DDC_MASK_SH_LIST(_MASK) 123 122 }; 124 123 124 + #include "../generic_regs.h" 125 + 126 + /* set field name */ 127 + #define SF_GENERIC(reg_name, field_name, post_fix)\ 128 + .field_name = reg_name ## __ ## field_name ## post_fix 129 + 130 + #define generic_regs(id) \ 131 + {\ 132 + GENERIC_REG_LIST(id)\ 133 + } 134 + 135 + static const struct generic_registers generic_regs[] = { 136 + generic_regs(A), 137 + generic_regs(B), 138 + }; 139 + 140 + static const struct generic_sh_mask generic_shift[] = { 141 + GENERIC_MASK_SH_LIST(__SHIFT, A), 142 + GENERIC_MASK_SH_LIST(__SHIFT, B), 143 + }; 144 + 145 + static const struct generic_sh_mask generic_mask[] = { 146 + GENERIC_MASK_SH_LIST(_MASK, A), 147 + GENERIC_MASK_SH_LIST(_MASK, B), 148 + }; 149 + 150 + static void define_generic_registers(struct hw_gpio_pin *pin, uint32_t en) 151 + { 152 + struct hw_generic *generic = HW_GENERIC_FROM_BASE(pin); 153 + 154 + generic->regs = &generic_regs[en]; 155 + generic->shifts = &generic_shift[en]; 156 + generic->masks = &generic_mask[en]; 157 + generic->base.regs = &generic_regs[en].gpio; 158 + } 159 + 125 160 static void define_ddc_registers( 126 161 struct hw_gpio_pin *pin, 127 162 uint32_t en) ··· 198 161 static const struct hw_factory_funcs funcs = { 199 162 .create_ddc_data = dal_hw_ddc_create, 200 163 .create_ddc_clock = dal_hw_ddc_create, 201 - .create_generic = NULL, 164 + .create_generic = dal_hw_generic_create, 202 165 .create_hpd = dal_hw_hpd_create, 203 166 .create_sync = NULL, 204 167 .create_gsl = NULL, 205 168 .define_hpd_registers = define_hpd_registers, 206 - .define_ddc_registers = define_ddc_registers 169 + .define_ddc_registers = define_ddc_registers, 170 + .define_generic_registers = define_generic_registers 207 171 }; 208 172 /* 209 173 * dal_hw_factory_dcn10_init
+72
drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c
··· 141 141 return dal_gpio_create_irq(service, id, en); 142 142 } 143 143 144 + struct gpio *dal_gpio_service_create_generic_mux( 145 + struct gpio_service *service, 146 + uint32_t offset, 147 + uint32_t mask) 148 + { 149 + enum gpio_id id; 150 + uint32_t en; 151 + struct gpio *generic; 152 + 153 + if (mask == 1) 154 + en = GPIO_GENERIC_A; 155 + else if (mask == 0x00000100L) 156 + en = GPIO_GENERIC_B; 157 + else 158 + return NULL; 159 + 160 + id = GPIO_ID_GENERIC; 161 + 162 + generic = dal_gpio_create( 163 + service, id, en, GPIO_PIN_OUTPUT_STATE_DEFAULT); 164 + 165 + return generic; 166 + } 167 + 168 + void dal_gpio_destroy_generic_mux( 169 + struct gpio **mux) 170 + { 171 + if (!mux || !*mux) { 172 + ASSERT_CRITICAL(false); 173 + return; 174 + } 175 + 176 + dal_gpio_close(*mux); 177 + dal_gpio_destroy(mux); 178 + kfree(*mux); 179 + 180 + *mux = NULL; 181 + } 182 + 183 + struct gpio_pin_info dal_gpio_get_generic_pin_info( 184 + struct gpio_service *service, 185 + enum gpio_id id, 186 + uint32_t en) 187 + { 188 + struct gpio_pin_info pin; 189 + 190 + if (service->translate.funcs->id_to_offset) { 191 + service->translate.funcs->id_to_offset(id, en, &pin); 192 + } else { 193 + pin.mask = 0xFFFFFFFF; 194 + pin.offset = 0xFFFFFFFF; 195 + } 196 + 197 + return pin; 198 + } 199 + 144 200 void dal_gpio_service_destroy( 145 201 struct gpio_service **ptr) 146 202 { ··· 219 163 kfree(*ptr); 220 164 221 165 *ptr = NULL; 166 + } 167 + 168 + enum gpio_result dal_mux_setup_config( 169 + struct gpio *mux, 170 + struct gpio_generic_mux_config *config) 171 + { 172 + struct gpio_config_data config_data; 173 + 174 + if (!config) 175 + return GPIO_RESULT_INVALID_DATA; 176 + 177 + config_data.config.generic_mux = *config; 178 + config_data.type = GPIO_CONFIG_TYPE_GENERIC_MUX; 179 + 180 + return dal_gpio_set_config(mux, &config_data); 222 181 } 223 182 224 183 /* ··· 326 255 case GPIO_ID_GENERIC: 327 256 pin = service->factory.funcs->create_generic( 328 257 service->ctx, id, en); 258 + service->factory.funcs->define_generic_registers(pin, en); 329 259 break; 330 260 case GPIO_ID_HPD: 331 261 pin = service->factory.funcs->create_hpd(
+17 -1
drivers/gpu/drm/amd/display/include/gpio_service_interface.h
··· 51 51 uint32_t offset, 52 52 uint32_t mask); 53 53 54 + struct gpio *dal_gpio_service_create_generic_mux( 55 + struct gpio_service *service, 56 + uint32_t offset, 57 + uint32_t mask); 58 + 59 + void dal_gpio_destroy_generic_mux( 60 + struct gpio **mux); 61 + 62 + enum gpio_result dal_mux_setup_config( 63 + struct gpio *mux, 64 + struct gpio_generic_mux_config *config); 65 + 66 + struct gpio_pin_info dal_gpio_get_generic_pin_info( 67 + struct gpio_service *service, 68 + enum gpio_id id, 69 + uint32_t en); 70 + 54 71 struct ddc *dal_gpio_create_ddc( 55 72 struct gpio_service *service, 56 73 uint32_t offset, 57 74 uint32_t mask, 58 75 struct gpio_ddc_hw_info *info); 59 - 60 76 61 77 void dal_gpio_destroy_ddc( 62 78 struct ddc **ddc);