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