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 gpio_result dal_irq_setup_hpd_filter( 415 struct gpio *irq, 416 struct gpio_hpd_config *config) 417 { 418 struct gpio_config_data config_data; 419 420 if (!config) 421 return GPIO_RESULT_INVALID_DATA; 422 423 config_data.type = GPIO_CONFIG_TYPE_HPD; 424 config_data.config.hpd = *config; 425 426 return dal_gpio_set_config(irq, &config_data); 427 } 428 429 /* 430 * @brief 431 * Creation and destruction 432 */ 433 434 struct gpio *dal_gpio_create_irq( 435 struct gpio_service *service, 436 enum gpio_id id, 437 uint32_t en) 438 { 439 struct gpio *irq; 440 441 switch (id) { 442 case GPIO_ID_HPD: 443 case GPIO_ID_GPIO_PAD: 444 break; 445 default: 446 ASSERT_CRITICAL(false); 447 return NULL; 448 } 449 450 irq = dal_gpio_create( 451 service, id, en, GPIO_PIN_OUTPUT_STATE_DEFAULT); 452 453 if (irq) 454 return irq; 455 456 ASSERT_CRITICAL(false); 457 return NULL; 458 } 459 460 void dal_gpio_destroy_irq( 461 struct gpio **irq) 462 { 463 if (!irq || !*irq) { 464 ASSERT_CRITICAL(false); 465 return; 466 } 467 468 dal_gpio_destroy(irq); 469 kfree(*irq); 470 471 *irq = NULL; 472 } 473 474 struct ddc *dal_gpio_create_ddc( 475 struct gpio_service *service, 476 uint32_t offset, 477 uint32_t mask, 478 struct gpio_ddc_hw_info *info) 479 { 480 enum gpio_id id; 481 uint32_t en; 482 struct ddc *ddc; 483 484 if (!service->translate.funcs->offset_to_id(offset, mask, &id, &en)) 485 return NULL; 486 487 ddc = kzalloc(sizeof(struct ddc), GFP_KERNEL); 488 489 if (!ddc) { 490 BREAK_TO_DEBUGGER(); 491 return NULL; 492 } 493 494 ddc->pin_data = dal_gpio_create( 495 service, GPIO_ID_DDC_DATA, en, GPIO_PIN_OUTPUT_STATE_DEFAULT); 496 497 if (!ddc->pin_data) { 498 BREAK_TO_DEBUGGER(); 499 goto failure_1; 500 } 501 502 ddc->pin_clock = dal_gpio_create( 503 service, GPIO_ID_DDC_CLOCK, en, GPIO_PIN_OUTPUT_STATE_DEFAULT); 504 505 if (!ddc->pin_clock) { 506 BREAK_TO_DEBUGGER(); 507 goto failure_2; 508 } 509 510 ddc->hw_info = *info; 511 512 ddc->ctx = service->ctx; 513 514 return ddc; 515 516 failure_2: 517 dal_gpio_destroy(&ddc->pin_data); 518 519 failure_1: 520 kfree(ddc); 521 522 return NULL; 523 } 524 525 void dal_gpio_destroy_ddc( 526 struct ddc **ddc) 527 { 528 if (!ddc || !*ddc) { 529 BREAK_TO_DEBUGGER(); 530 return; 531 } 532 533 dal_ddc_close(*ddc); 534 dal_gpio_destroy(&(*ddc)->pin_data); 535 dal_gpio_destroy(&(*ddc)->pin_clock); 536 kfree(*ddc); 537 538 *ddc = NULL; 539 } 540 541 enum gpio_result dal_ddc_open( 542 struct ddc *ddc, 543 enum gpio_mode mode, 544 enum gpio_ddc_config_type config_type) 545 { 546 enum gpio_result result; 547 548 struct gpio_config_data config_data; 549 struct hw_gpio *hw_data; 550 struct hw_gpio *hw_clock; 551 552 result = dal_gpio_open_ex(ddc->pin_data, mode); 553 554 if (result != GPIO_RESULT_OK) { 555 BREAK_TO_DEBUGGER(); 556 return result; 557 } 558 559 result = dal_gpio_open_ex(ddc->pin_clock, mode); 560 561 if (result != GPIO_RESULT_OK) { 562 BREAK_TO_DEBUGGER(); 563 goto failure; 564 } 565 566 /* DDC clock and data pins should belong 567 * to the same DDC block id, 568 * we use the data pin to set the pad mode. */ 569 570 if (mode == GPIO_MODE_INPUT) 571 /* this is from detect_sink_type, 572 * we need extra delay there */ 573 config_data.type = GPIO_CONFIG_TYPE_I2C_AUX_DUAL_MODE; 574 else 575 config_data.type = GPIO_CONFIG_TYPE_DDC; 576 577 config_data.config.ddc.type = config_type; 578 579 hw_data = FROM_HW_GPIO_PIN(ddc->pin_data->pin); 580 hw_clock = FROM_HW_GPIO_PIN(ddc->pin_clock->pin); 581 582 config_data.config.ddc.data_en_bit_present = hw_data->store.en != 0; 583 config_data.config.ddc.clock_en_bit_present = hw_clock->store.en != 0; 584 585 result = dal_gpio_set_config(ddc->pin_data, &config_data); 586 587 if (result == GPIO_RESULT_OK) 588 return result; 589 590 BREAK_TO_DEBUGGER(); 591 592 dal_gpio_close(ddc->pin_clock); 593 594 failure: 595 dal_gpio_close(ddc->pin_data); 596 597 return result; 598 } 599 600 enum gpio_result dal_ddc_change_mode( 601 struct ddc *ddc, 602 enum gpio_mode mode) 603 { 604 enum gpio_result result; 605 606 enum gpio_mode original_mode = 607 dal_gpio_get_mode(ddc->pin_data); 608 609 result = dal_gpio_change_mode(ddc->pin_data, mode); 610 611 /* [anaumov] DAL2 code returns GPIO_RESULT_NON_SPECIFIC_ERROR 612 * in case of failures; 613 * set_mode() is so that, in case of failure, 614 * we must explicitly set original mode */ 615 616 if (result != GPIO_RESULT_OK) 617 goto failure; 618 619 result = dal_gpio_change_mode(ddc->pin_clock, mode); 620 621 if (result == GPIO_RESULT_OK) 622 return result; 623 624 dal_gpio_change_mode(ddc->pin_clock, original_mode); 625 626 failure: 627 dal_gpio_change_mode(ddc->pin_data, original_mode); 628 629 return result; 630 } 631 632 enum gpio_ddc_line dal_ddc_get_line( 633 const struct ddc *ddc) 634 { 635 return (enum gpio_ddc_line)dal_gpio_get_enum(ddc->pin_data); 636 } 637 638 enum gpio_result dal_ddc_set_config( 639 struct ddc *ddc, 640 enum gpio_ddc_config_type config_type) 641 { 642 struct gpio_config_data config_data; 643 644 config_data.type = GPIO_CONFIG_TYPE_DDC; 645 646 config_data.config.ddc.type = config_type; 647 config_data.config.ddc.data_en_bit_present = false; 648 config_data.config.ddc.clock_en_bit_present = false; 649 650 return dal_gpio_set_config(ddc->pin_data, &config_data); 651 } 652 653 void dal_ddc_close( 654 struct ddc *ddc) 655 { 656 if (ddc != NULL) { 657 dal_gpio_close(ddc->pin_clock); 658 dal_gpio_close(ddc->pin_data); 659 } 660 } 661 662