1 /* 2 * Copyright 2012-15 Advanced Micro Devices, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * Authors: AMD 23 * 24 */ 25 26 /* 27 * Pre-requisites: headers required by header of this unit 28 */ 29 30 #include "dm_services.h" 31 #include "include/gpio_interface.h" 32 #include "include/gpio_service_interface.h" 33 #include "hw_translate.h" 34 #include "hw_factory.h" 35 36 /* 37 * Header of this unit 38 */ 39 40 #include "gpio_service.h" 41 42 /* 43 * Post-requisites: headers required by this unit 44 */ 45 46 #include "hw_gpio.h" 47 48 /* 49 * @brief 50 * Public API. 51 */ 52 53 struct gpio_service *dal_gpio_service_create( 54 enum dce_version dce_version_major, 55 enum dce_version dce_version_minor, 56 struct dc_context *ctx) 57 { 58 struct gpio_service *service; 59 60 uint32_t index_of_id; 61 62 service = kzalloc(sizeof(struct gpio_service), GFP_KERNEL); 63 64 if (!service) { 65 BREAK_TO_DEBUGGER(); 66 return NULL; 67 } 68 69 if (!dal_hw_translate_init(&service->translate, dce_version_major, 70 dce_version_minor)) { 71 BREAK_TO_DEBUGGER(); 72 goto failure_1; 73 } 74 75 if (!dal_hw_factory_init(&service->factory, dce_version_major, 76 dce_version_minor)) { 77 BREAK_TO_DEBUGGER(); 78 goto failure_1; 79 } 80 81 /* allocate and initialize business storage */ 82 { 83 const uint32_t bits_per_uint = sizeof(uint32_t) << 3; 84 85 index_of_id = 0; 86 service->ctx = ctx; 87 88 do { 89 uint32_t number_of_bits = 90 service->factory.number_of_pins[index_of_id]; 91 92 uint32_t number_of_uints = 93 (number_of_bits + bits_per_uint - 1) / 94 bits_per_uint; 95 96 uint32_t *slot; 97 98 if (number_of_bits) { 99 uint32_t index_of_uint = 0; 100 101 slot = kcalloc(number_of_uints, 102 sizeof(uint32_t), 103 GFP_KERNEL); 104 105 if (!slot) { 106 BREAK_TO_DEBUGGER(); 107 goto failure_2; 108 } 109 110 do { 111 slot[index_of_uint] = 0; 112 113 ++index_of_uint; 114 } while (index_of_uint < number_of_uints); 115 } else 116 slot = NULL; 117 118 service->busyness[index_of_id] = slot; 119 120 ++index_of_id; 121 } while (index_of_id < GPIO_ID_COUNT); 122 } 123 124 return service; 125 126 failure_2: 127 while (index_of_id) { 128 uint32_t *slot; 129 130 --index_of_id; 131 132 slot = service->busyness[index_of_id]; 133 134 kfree(slot); 135 } 136 137 failure_1: 138 kfree(service); 139 140 return NULL; 141 } 142 143 struct gpio *dal_gpio_service_create_irq( 144 struct gpio_service *service, 145 uint32_t offset, 146 uint32_t mask) 147 { 148 enum gpio_id id; 149 uint32_t en; 150 151 if (!service->translate.funcs->offset_to_id(offset, mask, &id, &en)) { 152 ASSERT_CRITICAL(false); 153 return NULL; 154 } 155 156 return dal_gpio_create_irq(service, id, en); 157 } 158 159 void dal_gpio_service_destroy( 160 struct gpio_service **ptr) 161 { 162 if (!ptr || !*ptr) { 163 BREAK_TO_DEBUGGER(); 164 return; 165 } 166 167 /* free business storage */ 168 { 169 uint32_t index_of_id = 0; 170 171 do { 172 uint32_t *slot = (*ptr)->busyness[index_of_id]; 173 174 kfree(slot); 175 176 ++index_of_id; 177 } while (index_of_id < GPIO_ID_COUNT); 178 } 179 180 kfree(*ptr); 181 182 *ptr = NULL; 183 } 184 185 /* 186 * @brief 187 * Private API. 188 */ 189 190 static bool is_pin_busy( 191 const struct gpio_service *service, 192 enum gpio_id id, 193 uint32_t en) 194 { 195 const uint32_t bits_per_uint = sizeof(uint32_t) << 3; 196 197 const uint32_t *slot = service->busyness[id] + (en / bits_per_uint); 198 199 return 0 != (*slot & (1 << (en % bits_per_uint))); 200 } 201 202 static void set_pin_busy( 203 struct gpio_service *service, 204 enum gpio_id id, 205 uint32_t en) 206 { 207 const uint32_t bits_per_uint = sizeof(uint32_t) << 3; 208 209 service->busyness[id][en / bits_per_uint] |= 210 (1 << (en % bits_per_uint)); 211 } 212 213 static void set_pin_free( 214 struct gpio_service *service, 215 enum gpio_id id, 216 uint32_t en) 217 { 218 const uint32_t bits_per_uint = sizeof(uint32_t) << 3; 219 220 service->busyness[id][en / bits_per_uint] &= 221 ~(1 << (en % bits_per_uint)); 222 } 223 224 enum gpio_result dal_gpio_service_open( 225 struct gpio_service *service, 226 enum gpio_id id, 227 uint32_t en, 228 enum gpio_mode mode, 229 struct hw_gpio_pin **ptr) 230 { 231 struct hw_gpio_pin *pin; 232 233 if (!service->busyness[id]) { 234 ASSERT_CRITICAL(false); 235 return GPIO_RESULT_OPEN_FAILED; 236 } 237 238 if (is_pin_busy(service, id, en)) { 239 ASSERT_CRITICAL(false); 240 return GPIO_RESULT_DEVICE_BUSY; 241 } 242 243 switch (id) { 244 case GPIO_ID_DDC_DATA: 245 pin = service->factory.funcs->create_ddc_data( 246 service->ctx, id, en); 247 service->factory.funcs->define_ddc_registers(pin, en); 248 break; 249 case GPIO_ID_DDC_CLOCK: 250 pin = service->factory.funcs->create_ddc_clock( 251 service->ctx, id, en); 252 service->factory.funcs->define_ddc_registers(pin, en); 253 break; 254 case GPIO_ID_GENERIC: 255 pin = service->factory.funcs->create_generic( 256 service->ctx, id, en); 257 break; 258 case GPIO_ID_HPD: 259 pin = service->factory.funcs->create_hpd( 260 service->ctx, id, en); 261 service->factory.funcs->define_hpd_registers(pin, en); 262 break; 263 case GPIO_ID_SYNC: 264 pin = service->factory.funcs->create_sync( 265 service->ctx, id, en); 266 break; 267 case GPIO_ID_GSL: 268 pin = service->factory.funcs->create_gsl( 269 service->ctx, id, en); 270 break; 271 default: 272 ASSERT_CRITICAL(false); 273 return GPIO_RESULT_NON_SPECIFIC_ERROR; 274 } 275 276 if (!pin) { 277 ASSERT_CRITICAL(false); 278 return GPIO_RESULT_NON_SPECIFIC_ERROR; 279 } 280 281 if (!pin->funcs->open(pin, mode)) { 282 ASSERT_CRITICAL(false); 283 dal_gpio_service_close(service, &pin); 284 return GPIO_RESULT_OPEN_FAILED; 285 } 286 287 set_pin_busy(service, id, en); 288 *ptr = pin; 289 return GPIO_RESULT_OK; 290 } 291 292 void dal_gpio_service_close( 293 struct gpio_service *service, 294 struct hw_gpio_pin **ptr) 295 { 296 struct hw_gpio_pin *pin; 297 298 if (!ptr) { 299 ASSERT_CRITICAL(false); 300 return; 301 } 302 303 pin = *ptr; 304 305 if (pin) { 306 set_pin_free(service, pin->id, pin->en); 307 308 pin->funcs->close(pin); 309 310 pin->funcs->destroy(ptr); 311 } 312 } 313 314 315 enum dc_irq_source dal_irq_get_source( 316 const struct gpio *irq) 317 { 318 enum gpio_id id = dal_gpio_get_id(irq); 319 320 switch (id) { 321 case GPIO_ID_HPD: 322 return (enum dc_irq_source)(DC_IRQ_SOURCE_HPD1 + 323 dal_gpio_get_enum(irq)); 324 case GPIO_ID_GPIO_PAD: 325 return (enum dc_irq_source)(DC_IRQ_SOURCE_GPIOPAD0 + 326 dal_gpio_get_enum(irq)); 327 default: 328 return DC_IRQ_SOURCE_INVALID; 329 } 330 } 331 332 enum dc_irq_source dal_irq_get_rx_source( 333 const struct gpio *irq) 334 { 335 enum gpio_id id = dal_gpio_get_id(irq); 336 337 switch (id) { 338 case GPIO_ID_HPD: 339 return (enum dc_irq_source)(DC_IRQ_SOURCE_HPD1RX + 340 dal_gpio_get_enum(irq)); 341 default: 342 return DC_IRQ_SOURCE_INVALID; 343 } 344 } 345 346 enum gpio_result dal_irq_setup_hpd_filter( 347 struct gpio *irq, 348 struct gpio_hpd_config *config) 349 { 350 struct gpio_config_data config_data; 351 352 if (!config) 353 return GPIO_RESULT_INVALID_DATA; 354 355 config_data.type = GPIO_CONFIG_TYPE_HPD; 356 config_data.config.hpd = *config; 357 358 return dal_gpio_set_config(irq, &config_data); 359 } 360 361 /* 362 * @brief 363 * Creation and destruction 364 */ 365 366 struct gpio *dal_gpio_create_irq( 367 struct gpio_service *service, 368 enum gpio_id id, 369 uint32_t en) 370 { 371 struct gpio *irq; 372 373 switch (id) { 374 case GPIO_ID_HPD: 375 case GPIO_ID_GPIO_PAD: 376 break; 377 default: 378 ASSERT_CRITICAL(false); 379 return NULL; 380 } 381 382 irq = dal_gpio_create( 383 service, id, en, GPIO_PIN_OUTPUT_STATE_DEFAULT); 384 385 if (irq) 386 return irq; 387 388 ASSERT_CRITICAL(false); 389 return NULL; 390 } 391 392 void dal_gpio_destroy_irq( 393 struct gpio **irq) 394 { 395 if (!irq || !*irq) { 396 ASSERT_CRITICAL(false); 397 return; 398 } 399 400 dal_gpio_close(*irq); 401 dal_gpio_destroy(irq); 402 kfree(*irq); 403 404 *irq = NULL; 405 } 406 407 struct ddc *dal_gpio_create_ddc( 408 struct gpio_service *service, 409 uint32_t offset, 410 uint32_t mask, 411 struct gpio_ddc_hw_info *info) 412 { 413 enum gpio_id id; 414 uint32_t en; 415 struct ddc *ddc; 416 417 if (!service->translate.funcs->offset_to_id(offset, mask, &id, &en)) 418 return NULL; 419 420 ddc = kzalloc(sizeof(struct ddc), GFP_KERNEL); 421 422 if (!ddc) { 423 BREAK_TO_DEBUGGER(); 424 return NULL; 425 } 426 427 ddc->pin_data = dal_gpio_create( 428 service, GPIO_ID_DDC_DATA, en, GPIO_PIN_OUTPUT_STATE_DEFAULT); 429 430 if (!ddc->pin_data) { 431 BREAK_TO_DEBUGGER(); 432 goto failure_1; 433 } 434 435 ddc->pin_clock = dal_gpio_create( 436 service, GPIO_ID_DDC_CLOCK, en, GPIO_PIN_OUTPUT_STATE_DEFAULT); 437 438 if (!ddc->pin_clock) { 439 BREAK_TO_DEBUGGER(); 440 goto failure_2; 441 } 442 443 ddc->hw_info = *info; 444 445 ddc->ctx = service->ctx; 446 447 return ddc; 448 449 failure_2: 450 dal_gpio_destroy(&ddc->pin_data); 451 452 failure_1: 453 kfree(ddc); 454 455 return NULL; 456 } 457 458 void dal_gpio_destroy_ddc( 459 struct ddc **ddc) 460 { 461 if (!ddc || !*ddc) { 462 BREAK_TO_DEBUGGER(); 463 return; 464 } 465 466 dal_ddc_close(*ddc); 467 dal_gpio_destroy(&(*ddc)->pin_data); 468 dal_gpio_destroy(&(*ddc)->pin_clock); 469 kfree(*ddc); 470 471 *ddc = NULL; 472 } 473 474 enum gpio_result dal_ddc_open( 475 struct ddc *ddc, 476 enum gpio_mode mode, 477 enum gpio_ddc_config_type config_type) 478 { 479 enum gpio_result result; 480 481 struct gpio_config_data config_data; 482 struct hw_gpio *hw_data; 483 struct hw_gpio *hw_clock; 484 485 result = dal_gpio_open_ex(ddc->pin_data, mode); 486 487 if (result != GPIO_RESULT_OK) { 488 BREAK_TO_DEBUGGER(); 489 return result; 490 } 491 492 result = dal_gpio_open_ex(ddc->pin_clock, mode); 493 494 if (result != GPIO_RESULT_OK) { 495 BREAK_TO_DEBUGGER(); 496 goto failure; 497 } 498 499 /* DDC clock and data pins should belong 500 * to the same DDC block id, 501 * we use the data pin to set the pad mode. */ 502 503 if (mode == GPIO_MODE_INPUT) 504 /* this is from detect_sink_type, 505 * we need extra delay there */ 506 config_data.type = GPIO_CONFIG_TYPE_I2C_AUX_DUAL_MODE; 507 else 508 config_data.type = GPIO_CONFIG_TYPE_DDC; 509 510 config_data.config.ddc.type = config_type; 511 512 hw_data = FROM_HW_GPIO_PIN(ddc->pin_data->pin); 513 hw_clock = FROM_HW_GPIO_PIN(ddc->pin_clock->pin); 514 515 config_data.config.ddc.data_en_bit_present = hw_data->store.en != 0; 516 config_data.config.ddc.clock_en_bit_present = hw_clock->store.en != 0; 517 518 result = dal_gpio_set_config(ddc->pin_data, &config_data); 519 520 if (result == GPIO_RESULT_OK) 521 return result; 522 523 BREAK_TO_DEBUGGER(); 524 525 dal_gpio_close(ddc->pin_clock); 526 527 failure: 528 dal_gpio_close(ddc->pin_data); 529 530 return result; 531 } 532 533 enum gpio_result dal_ddc_change_mode( 534 struct ddc *ddc, 535 enum gpio_mode mode) 536 { 537 enum gpio_result result; 538 539 enum gpio_mode original_mode = 540 dal_gpio_get_mode(ddc->pin_data); 541 542 result = dal_gpio_change_mode(ddc->pin_data, mode); 543 544 /* [anaumov] DAL2 code returns GPIO_RESULT_NON_SPECIFIC_ERROR 545 * in case of failures; 546 * set_mode() is so that, in case of failure, 547 * we must explicitly set original mode */ 548 549 if (result != GPIO_RESULT_OK) 550 goto failure; 551 552 result = dal_gpio_change_mode(ddc->pin_clock, mode); 553 554 if (result == GPIO_RESULT_OK) 555 return result; 556 557 dal_gpio_change_mode(ddc->pin_clock, original_mode); 558 559 failure: 560 dal_gpio_change_mode(ddc->pin_data, original_mode); 561 562 return result; 563 } 564 565 enum gpio_ddc_line dal_ddc_get_line( 566 const struct ddc *ddc) 567 { 568 return (enum gpio_ddc_line)dal_gpio_get_enum(ddc->pin_data); 569 } 570 571 enum gpio_result dal_ddc_set_config( 572 struct ddc *ddc, 573 enum gpio_ddc_config_type config_type) 574 { 575 struct gpio_config_data config_data; 576 577 config_data.type = GPIO_CONFIG_TYPE_DDC; 578 579 config_data.config.ddc.type = config_type; 580 config_data.config.ddc.data_en_bit_present = false; 581 config_data.config.ddc.clock_en_bit_present = false; 582 583 return dal_gpio_set_config(ddc->pin_data, &config_data); 584 } 585 586 void dal_ddc_close( 587 struct ddc *ddc) 588 { 589 dal_gpio_close(ddc->pin_clock); 590 dal_gpio_close(ddc->pin_data); 591 } 592 593