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