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, 55 enum dce_environment dce_environment, 56 struct dc_context *ctx) 57 { 58 struct gpio_service *service; 59 int32_t index_of_id; 60 61 service = kzalloc(sizeof(struct gpio_service), GFP_KERNEL); 62 63 if (!service) { 64 BREAK_TO_DEBUGGER(); 65 return NULL; 66 } 67 68 if (!dal_hw_translate_init(&service->translate, dce_version, 69 dce_environment)) { 70 BREAK_TO_DEBUGGER(); 71 goto failure_1; 72 } 73 74 if (!dal_hw_factory_init(&service->factory, dce_version, 75 dce_environment)) { 76 BREAK_TO_DEBUGGER(); 77 goto failure_1; 78 } 79 80 /* allocate and initialize busyness storage */ 81 { 82 index_of_id = 0; 83 service->ctx = ctx; 84 85 do { 86 uint32_t number_of_bits = 87 service->factory.number_of_pins[index_of_id]; 88 uint32_t i = 0; 89 90 if (number_of_bits) { 91 service->busyness[index_of_id] = 92 kcalloc(number_of_bits, sizeof(char), 93 GFP_KERNEL); 94 95 if (!service->busyness[index_of_id]) { 96 BREAK_TO_DEBUGGER(); 97 goto failure_2; 98 } 99 100 do { 101 service->busyness[index_of_id][i] = 0; 102 ++i; 103 } while (i < number_of_bits); 104 } else { 105 service->busyness[index_of_id] = NULL; 106 } 107 108 ++index_of_id; 109 } while (index_of_id < GPIO_ID_COUNT); 110 } 111 112 return service; 113 114 failure_2: 115 while (index_of_id > 0) { 116 --index_of_id; 117 kfree(service->busyness[index_of_id]); 118 } 119 120 failure_1: 121 kfree(service); 122 123 return NULL; 124 } 125 126 struct gpio *dal_gpio_service_create_irq( 127 struct gpio_service *service, 128 uint32_t offset, 129 uint32_t mask) 130 { 131 enum gpio_id id = 0; 132 uint32_t en; 133 134 if (!service->translate.funcs->offset_to_id(offset, mask, &id, &en)) { 135 ASSERT_CRITICAL(false); 136 return NULL; 137 } 138 139 return dal_gpio_create_irq(service, id, en); 140 } 141 142 struct gpio *dal_gpio_service_create_generic_mux( 143 struct gpio_service *service, 144 uint32_t offset, 145 uint32_t mask) 146 { 147 enum gpio_id id = 0; 148 uint32_t en; 149 struct gpio *generic; 150 151 if (!service->translate.funcs->offset_to_id(offset, mask, &id, &en)) { 152 ASSERT_CRITICAL(false); 153 return NULL; 154 } 155 156 generic = dal_gpio_create( 157 service, id, en, GPIO_PIN_OUTPUT_STATE_DEFAULT); 158 159 return generic; 160 } 161 162 void dal_gpio_destroy_generic_mux( 163 struct gpio **mux) 164 { 165 if (!mux || !*mux) { 166 ASSERT_CRITICAL(false); 167 return; 168 } 169 170 dal_gpio_destroy(mux); 171 kfree(*mux); 172 173 *mux = NULL; 174 } 175 176 struct gpio_pin_info dal_gpio_get_generic_pin_info( 177 struct gpio_service *service, 178 enum gpio_id id, 179 uint32_t en) 180 { 181 struct gpio_pin_info pin = {0}; 182 183 if (service->translate.funcs->id_to_offset) { 184 service->translate.funcs->id_to_offset(id, en, &pin); 185 } else { 186 pin.mask = 0xFFFFFFFF; 187 pin.offset = 0xFFFFFFFF; 188 } 189 190 return pin; 191 } 192 193 void dal_gpio_service_destroy( 194 struct gpio_service **ptr) 195 { 196 if (!ptr || !*ptr) { 197 BREAK_TO_DEBUGGER(); 198 return; 199 } 200 201 /* free business storage */ 202 { 203 uint32_t index_of_id = 0; 204 205 do { 206 kfree((*ptr)->busyness[index_of_id]); 207 208 ++index_of_id; 209 } while (index_of_id < GPIO_ID_COUNT); 210 } 211 212 kfree(*ptr); 213 214 *ptr = NULL; 215 } 216 217 enum gpio_result dal_mux_setup_config( 218 struct gpio *mux, 219 struct gpio_generic_mux_config *config) 220 { 221 struct gpio_config_data config_data; 222 223 if (!config) 224 return GPIO_RESULT_INVALID_DATA; 225 226 config_data.config.generic_mux = *config; 227 config_data.type = GPIO_CONFIG_TYPE_GENERIC_MUX; 228 229 return dal_gpio_set_config(mux, &config_data); 230 } 231 232 /* 233 * @brief 234 * Private API. 235 */ 236 237 static bool is_pin_busy( 238 const struct gpio_service *service, 239 enum gpio_id id, 240 uint32_t en) 241 { 242 if (id == GPIO_ID_UNKNOWN) 243 return false; 244 245 return service->busyness[id][en]; 246 } 247 248 static void set_pin_busy( 249 struct gpio_service *service, 250 enum gpio_id id, 251 uint32_t en) 252 { 253 if (id == GPIO_ID_UNKNOWN) 254 return; 255 256 service->busyness[id][en] = true; 257 } 258 259 static void set_pin_free( 260 struct gpio_service *service, 261 enum gpio_id id, 262 uint32_t en) 263 { 264 if (id == GPIO_ID_UNKNOWN) 265 return; 266 267 service->busyness[id][en] = false; 268 } 269 270 enum gpio_result dal_gpio_service_lock( 271 struct gpio_service *service, 272 enum gpio_id id, 273 uint32_t en) 274 { 275 if (id != GPIO_ID_UNKNOWN && !service->busyness[id]) { 276 ASSERT_CRITICAL(false); 277 return GPIO_RESULT_OPEN_FAILED; 278 } 279 280 set_pin_busy(service, id, en); 281 return GPIO_RESULT_OK; 282 } 283 284 enum gpio_result dal_gpio_service_unlock( 285 struct gpio_service *service, 286 enum gpio_id id, 287 uint32_t en) 288 { 289 if (id != GPIO_ID_UNKNOWN && !service->busyness[id]) { 290 ASSERT_CRITICAL(false); 291 return GPIO_RESULT_OPEN_FAILED; 292 } 293 294 set_pin_free(service, id, en); 295 return GPIO_RESULT_OK; 296 } 297 298 enum gpio_result dal_gpio_service_open( 299 struct gpio *gpio) 300 { 301 struct gpio_service *service = gpio->service; 302 enum gpio_id id = gpio->id; 303 uint32_t en = gpio->en; 304 enum gpio_mode mode = gpio->mode; 305 306 struct hw_gpio_pin **pin = &gpio->pin; 307 308 309 if (!service->busyness[id]) { 310 ASSERT_CRITICAL(false); 311 return GPIO_RESULT_OPEN_FAILED; 312 } 313 314 if (is_pin_busy(service, id, en)) { 315 ASSERT_CRITICAL(false); 316 return GPIO_RESULT_DEVICE_BUSY; 317 } 318 319 switch (id) { 320 case GPIO_ID_DDC_DATA: 321 *pin = service->factory.funcs->get_ddc_pin(gpio); 322 service->factory.funcs->define_ddc_registers(*pin, en); 323 break; 324 case GPIO_ID_DDC_CLOCK: 325 *pin = service->factory.funcs->get_ddc_pin(gpio); 326 service->factory.funcs->define_ddc_registers(*pin, en); 327 break; 328 case GPIO_ID_GENERIC: 329 *pin = service->factory.funcs->get_generic_pin(gpio); 330 service->factory.funcs->define_generic_registers(*pin, en); 331 break; 332 case GPIO_ID_HPD: 333 *pin = service->factory.funcs->get_hpd_pin(gpio); 334 service->factory.funcs->define_hpd_registers(*pin, en); 335 break; 336 337 //TODO: gsl and sync support? create_sync and create_gsl are NULL 338 case GPIO_ID_SYNC: 339 case GPIO_ID_GSL: 340 break; 341 default: 342 ASSERT_CRITICAL(false); 343 return GPIO_RESULT_NON_SPECIFIC_ERROR; 344 } 345 346 if (!*pin) { 347 ASSERT_CRITICAL(false); 348 return GPIO_RESULT_NON_SPECIFIC_ERROR; 349 } 350 351 if (!(*pin)->funcs->open(*pin, mode)) { 352 ASSERT_CRITICAL(false); 353 dal_gpio_service_close(service, pin); 354 return GPIO_RESULT_OPEN_FAILED; 355 } 356 357 set_pin_busy(service, id, en); 358 return GPIO_RESULT_OK; 359 } 360 361 void dal_gpio_service_close( 362 struct gpio_service *service, 363 struct hw_gpio_pin **ptr) 364 { 365 struct hw_gpio_pin *pin; 366 367 if (!ptr) { 368 ASSERT_CRITICAL(false); 369 return; 370 } 371 372 pin = *ptr; 373 374 if (pin) { 375 set_pin_free(service, pin->id, pin->en); 376 377 pin->funcs->close(pin); 378 379 *ptr = NULL; 380 } 381 } 382 383 enum dc_irq_source dal_irq_get_source( 384 const struct gpio *irq) 385 { 386 enum gpio_id id = dal_gpio_get_id(irq); 387 388 switch (id) { 389 case GPIO_ID_HPD: 390 return (enum dc_irq_source)(DC_IRQ_SOURCE_HPD1 + 391 dal_gpio_get_enum(irq)); 392 case GPIO_ID_GPIO_PAD: 393 return (enum dc_irq_source)(DC_IRQ_SOURCE_GPIOPAD0 + 394 dal_gpio_get_enum(irq)); 395 default: 396 return DC_IRQ_SOURCE_INVALID; 397 } 398 } 399 400 enum dc_irq_source dal_irq_get_rx_source( 401 const struct gpio *irq) 402 { 403 enum gpio_id id = dal_gpio_get_id(irq); 404 405 switch (id) { 406 case GPIO_ID_HPD: 407 return (enum dc_irq_source)(DC_IRQ_SOURCE_HPD1RX + 408 dal_gpio_get_enum(irq)); 409 default: 410 return DC_IRQ_SOURCE_INVALID; 411 } 412 } 413 414 enum dc_irq_source dal_irq_get_read_request( 415 const struct gpio *irq) 416 { 417 enum gpio_id id = dal_gpio_get_id(irq); 418 419 switch (id) { 420 case GPIO_ID_HPD: 421 return (enum dc_irq_source)(DC_IRQ_SOURCE_DCI2C_RR_DDC1 + 422 dal_gpio_get_enum(irq)); 423 default: 424 return DC_IRQ_SOURCE_INVALID; 425 } 426 } 427 428 enum gpio_result dal_irq_setup_hpd_filter( 429 struct gpio *irq, 430 struct gpio_hpd_config *config) 431 { 432 struct gpio_config_data config_data; 433 434 if (!config) 435 return GPIO_RESULT_INVALID_DATA; 436 437 config_data.type = GPIO_CONFIG_TYPE_HPD; 438 config_data.config.hpd = *config; 439 440 return dal_gpio_set_config(irq, &config_data); 441 } 442 443 /* 444 * @brief 445 * Creation and destruction 446 */ 447 448 struct gpio *dal_gpio_create_irq( 449 struct gpio_service *service, 450 enum gpio_id id, 451 uint32_t en) 452 { 453 struct gpio *irq; 454 455 switch (id) { 456 case GPIO_ID_HPD: 457 case GPIO_ID_GPIO_PAD: 458 break; 459 default: 460 ASSERT_CRITICAL(false); 461 return NULL; 462 } 463 464 irq = dal_gpio_create( 465 service, id, en, GPIO_PIN_OUTPUT_STATE_DEFAULT); 466 467 if (irq) 468 return irq; 469 470 ASSERT_CRITICAL(false); 471 return NULL; 472 } 473 474 void dal_gpio_destroy_irq( 475 struct gpio **irq) 476 { 477 if (!irq || !*irq) { 478 ASSERT_CRITICAL(false); 479 return; 480 } 481 482 dal_gpio_destroy(irq); 483 kfree(*irq); 484 485 *irq = NULL; 486 } 487 488 struct ddc *dal_gpio_create_ddc( 489 struct gpio_service *service, 490 uint32_t offset, 491 uint32_t mask, 492 struct gpio_ddc_hw_info *info) 493 { 494 enum gpio_id id; 495 uint32_t en; 496 struct ddc *ddc; 497 498 if (!service->translate.funcs->offset_to_id(offset, mask, &id, &en)) 499 return NULL; 500 501 ddc = kzalloc(sizeof(struct ddc), GFP_KERNEL); 502 503 if (!ddc) { 504 BREAK_TO_DEBUGGER(); 505 return NULL; 506 } 507 508 ddc->pin_data = dal_gpio_create( 509 service, GPIO_ID_DDC_DATA, en, GPIO_PIN_OUTPUT_STATE_DEFAULT); 510 511 if (!ddc->pin_data) { 512 BREAK_TO_DEBUGGER(); 513 goto failure_1; 514 } 515 516 ddc->pin_clock = dal_gpio_create( 517 service, GPIO_ID_DDC_CLOCK, en, GPIO_PIN_OUTPUT_STATE_DEFAULT); 518 519 if (!ddc->pin_clock) { 520 BREAK_TO_DEBUGGER(); 521 goto failure_2; 522 } 523 524 ddc->hw_info = *info; 525 526 ddc->ctx = service->ctx; 527 528 return ddc; 529 530 failure_2: 531 dal_gpio_destroy(&ddc->pin_data); 532 533 failure_1: 534 kfree(ddc); 535 536 return NULL; 537 } 538 539 void dal_gpio_destroy_ddc( 540 struct ddc **ddc) 541 { 542 if (!ddc || !*ddc) { 543 BREAK_TO_DEBUGGER(); 544 return; 545 } 546 547 dal_ddc_close(*ddc); 548 dal_gpio_destroy(&(*ddc)->pin_data); 549 dal_gpio_destroy(&(*ddc)->pin_clock); 550 kfree(*ddc); 551 552 *ddc = NULL; 553 } 554 555 enum gpio_result dal_ddc_open( 556 struct ddc *ddc, 557 enum gpio_mode mode, 558 enum gpio_ddc_config_type config_type) 559 { 560 enum gpio_result result; 561 562 struct gpio_config_data config_data; 563 struct hw_gpio *hw_data; 564 struct hw_gpio *hw_clock; 565 566 result = dal_gpio_open_ex(ddc->pin_data, mode); 567 568 if (result != GPIO_RESULT_OK) { 569 BREAK_TO_DEBUGGER(); 570 return result; 571 } 572 573 result = dal_gpio_open_ex(ddc->pin_clock, mode); 574 575 if (result != GPIO_RESULT_OK) { 576 BREAK_TO_DEBUGGER(); 577 goto failure; 578 } 579 580 /* DDC clock and data pins should belong 581 * to the same DDC block id, 582 * we use the data pin to set the pad mode. */ 583 584 if (mode == GPIO_MODE_INPUT) 585 /* this is from detect_sink_type, 586 * we need extra delay there */ 587 config_data.type = GPIO_CONFIG_TYPE_I2C_AUX_DUAL_MODE; 588 else 589 config_data.type = GPIO_CONFIG_TYPE_DDC; 590 591 config_data.config.ddc.type = config_type; 592 593 hw_data = FROM_HW_GPIO_PIN(ddc->pin_data->pin); 594 hw_clock = FROM_HW_GPIO_PIN(ddc->pin_clock->pin); 595 596 config_data.config.ddc.data_en_bit_present = hw_data->store.en != 0; 597 config_data.config.ddc.clock_en_bit_present = hw_clock->store.en != 0; 598 599 result = dal_gpio_set_config(ddc->pin_data, &config_data); 600 601 if (result == GPIO_RESULT_OK) 602 return result; 603 604 BREAK_TO_DEBUGGER(); 605 606 dal_gpio_close(ddc->pin_clock); 607 608 failure: 609 dal_gpio_close(ddc->pin_data); 610 611 return result; 612 } 613 614 enum gpio_result dal_ddc_change_mode( 615 struct ddc *ddc, 616 enum gpio_mode mode) 617 { 618 enum gpio_result result; 619 620 enum gpio_mode original_mode = 621 dal_gpio_get_mode(ddc->pin_data); 622 623 result = dal_gpio_change_mode(ddc->pin_data, mode); 624 625 /* [anaumov] DAL2 code returns GPIO_RESULT_NON_SPECIFIC_ERROR 626 * in case of failures; 627 * set_mode() is so that, in case of failure, 628 * we must explicitly set original mode */ 629 630 if (result != GPIO_RESULT_OK) 631 goto failure; 632 633 result = dal_gpio_change_mode(ddc->pin_clock, mode); 634 635 if (result == GPIO_RESULT_OK) 636 return result; 637 638 dal_gpio_change_mode(ddc->pin_clock, original_mode); 639 640 failure: 641 dal_gpio_change_mode(ddc->pin_data, original_mode); 642 643 return result; 644 } 645 646 enum gpio_ddc_line dal_ddc_get_line( 647 const struct ddc *ddc) 648 { 649 return (enum gpio_ddc_line)dal_gpio_get_enum(ddc->pin_data); 650 } 651 652 enum gpio_result dal_ddc_set_config( 653 struct ddc *ddc, 654 enum gpio_ddc_config_type config_type) 655 { 656 struct gpio_config_data config_data; 657 658 config_data.type = GPIO_CONFIG_TYPE_DDC; 659 660 config_data.config.ddc.type = config_type; 661 config_data.config.ddc.data_en_bit_present = false; 662 config_data.config.ddc.clock_en_bit_present = false; 663 664 return dal_gpio_set_config(ddc->pin_data, &config_data); 665 } 666 667 void dal_ddc_close( 668 struct ddc *ddc) 669 { 670 if (ddc != NULL) { 671 dal_gpio_close(ddc->pin_clock); 672 dal_gpio_close(ddc->pin_data); 673 } 674 } 675 676