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 (!service->translate.funcs->offset_to_id(offset, mask, &id, &en)) { 154 ASSERT_CRITICAL(false); 155 return NULL; 156 } 157 158 generic = dal_gpio_create( 159 service, id, en, GPIO_PIN_OUTPUT_STATE_DEFAULT); 160 161 return generic; 162 } 163 164 void dal_gpio_destroy_generic_mux( 165 struct gpio **mux) 166 { 167 if (!mux || !*mux) { 168 ASSERT_CRITICAL(false); 169 return; 170 } 171 172 dal_gpio_close(*mux); 173 dal_gpio_destroy(mux); 174 kfree(*mux); 175 176 *mux = NULL; 177 } 178 179 struct gpio_pin_info dal_gpio_get_generic_pin_info( 180 struct gpio_service *service, 181 enum gpio_id id, 182 uint32_t en) 183 { 184 struct gpio_pin_info pin; 185 186 if (service->translate.funcs->id_to_offset) { 187 service->translate.funcs->id_to_offset(id, en, &pin); 188 } else { 189 pin.mask = 0xFFFFFFFF; 190 pin.offset = 0xFFFFFFFF; 191 } 192 193 return pin; 194 } 195 196 void dal_gpio_service_destroy( 197 struct gpio_service **ptr) 198 { 199 if (!ptr || !*ptr) { 200 BREAK_TO_DEBUGGER(); 201 return; 202 } 203 204 /* free business storage */ 205 { 206 uint32_t index_of_id = 0; 207 208 do { 209 kfree((*ptr)->busyness[index_of_id]); 210 211 ++index_of_id; 212 } while (index_of_id < GPIO_ID_COUNT); 213 } 214 215 kfree(*ptr); 216 217 *ptr = NULL; 218 } 219 220 enum gpio_result dal_mux_setup_config( 221 struct gpio *mux, 222 struct gpio_generic_mux_config *config) 223 { 224 struct gpio_config_data config_data; 225 226 if (!config) 227 return GPIO_RESULT_INVALID_DATA; 228 229 config_data.config.generic_mux = *config; 230 config_data.type = GPIO_CONFIG_TYPE_GENERIC_MUX; 231 232 return dal_gpio_set_config(mux, &config_data); 233 } 234 235 /* 236 * @brief 237 * Private API. 238 */ 239 240 static bool is_pin_busy( 241 const struct gpio_service *service, 242 enum gpio_id id, 243 uint32_t en) 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 service->busyness[id][en] = true; 254 } 255 256 static void set_pin_free( 257 struct gpio_service *service, 258 enum gpio_id id, 259 uint32_t en) 260 { 261 service->busyness[id][en] = false; 262 } 263 264 enum gpio_result dal_gpio_service_lock( 265 struct gpio_service *service, 266 enum gpio_id id, 267 uint32_t en) 268 { 269 if (!service->busyness[id]) { 270 ASSERT_CRITICAL(false); 271 return GPIO_RESULT_OPEN_FAILED; 272 } 273 274 set_pin_busy(service, id, en); 275 return GPIO_RESULT_OK; 276 } 277 278 enum gpio_result dal_gpio_service_unlock( 279 struct gpio_service *service, 280 enum gpio_id id, 281 uint32_t en) 282 { 283 if (!service->busyness[id]) { 284 ASSERT_CRITICAL(false); 285 return GPIO_RESULT_OPEN_FAILED; 286 } 287 288 set_pin_free(service, id, en); 289 return GPIO_RESULT_OK; 290 } 291 292 enum gpio_result dal_gpio_service_open( 293 struct gpio_service *service, 294 enum gpio_id id, 295 uint32_t en, 296 enum gpio_mode mode, 297 struct hw_gpio_pin **ptr) 298 { 299 struct hw_gpio_pin *pin; 300 301 if (!service->busyness[id]) { 302 ASSERT_CRITICAL(false); 303 return GPIO_RESULT_OPEN_FAILED; 304 } 305 306 if (is_pin_busy(service, id, en)) { 307 ASSERT_CRITICAL(false); 308 return GPIO_RESULT_DEVICE_BUSY; 309 } 310 311 switch (id) { 312 case GPIO_ID_DDC_DATA: 313 pin = service->factory.funcs->create_ddc_data( 314 service->ctx, id, en); 315 service->factory.funcs->define_ddc_registers(pin, en); 316 break; 317 case GPIO_ID_DDC_CLOCK: 318 pin = service->factory.funcs->create_ddc_clock( 319 service->ctx, id, en); 320 service->factory.funcs->define_ddc_registers(pin, en); 321 break; 322 case GPIO_ID_GENERIC: 323 pin = service->factory.funcs->create_generic( 324 service->ctx, id, en); 325 service->factory.funcs->define_generic_registers(pin, en); 326 break; 327 case GPIO_ID_HPD: 328 pin = service->factory.funcs->create_hpd( 329 service->ctx, id, en); 330 service->factory.funcs->define_hpd_registers(pin, en); 331 break; 332 case GPIO_ID_SYNC: 333 pin = service->factory.funcs->create_sync( 334 service->ctx, id, en); 335 break; 336 case GPIO_ID_GSL: 337 pin = service->factory.funcs->create_gsl( 338 service->ctx, id, en); 339 break; 340 default: 341 ASSERT_CRITICAL(false); 342 return GPIO_RESULT_NON_SPECIFIC_ERROR; 343 } 344 345 if (!pin) { 346 ASSERT_CRITICAL(false); 347 return GPIO_RESULT_NON_SPECIFIC_ERROR; 348 } 349 350 if (!pin->funcs->open(pin, mode)) { 351 ASSERT_CRITICAL(false); 352 dal_gpio_service_close(service, &pin); 353 return GPIO_RESULT_OPEN_FAILED; 354 } 355 356 set_pin_busy(service, id, en); 357 *ptr = pin; 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 pin->funcs->destroy(ptr); 380 } 381 } 382 383 384 enum dc_irq_source dal_irq_get_source( 385 const struct gpio *irq) 386 { 387 enum gpio_id id = dal_gpio_get_id(irq); 388 389 switch (id) { 390 case GPIO_ID_HPD: 391 return (enum dc_irq_source)(DC_IRQ_SOURCE_HPD1 + 392 dal_gpio_get_enum(irq)); 393 case GPIO_ID_GPIO_PAD: 394 return (enum dc_irq_source)(DC_IRQ_SOURCE_GPIOPAD0 + 395 dal_gpio_get_enum(irq)); 396 default: 397 return DC_IRQ_SOURCE_INVALID; 398 } 399 } 400 401 enum dc_irq_source dal_irq_get_rx_source( 402 const struct gpio *irq) 403 { 404 enum gpio_id id = dal_gpio_get_id(irq); 405 406 switch (id) { 407 case GPIO_ID_HPD: 408 return (enum dc_irq_source)(DC_IRQ_SOURCE_HPD1RX + 409 dal_gpio_get_enum(irq)); 410 default: 411 return DC_IRQ_SOURCE_INVALID; 412 } 413 } 414 415 enum gpio_result dal_irq_setup_hpd_filter( 416 struct gpio *irq, 417 struct gpio_hpd_config *config) 418 { 419 struct gpio_config_data config_data; 420 421 if (!config) 422 return GPIO_RESULT_INVALID_DATA; 423 424 config_data.type = GPIO_CONFIG_TYPE_HPD; 425 config_data.config.hpd = *config; 426 427 return dal_gpio_set_config(irq, &config_data); 428 } 429 430 /* 431 * @brief 432 * Creation and destruction 433 */ 434 435 struct gpio *dal_gpio_create_irq( 436 struct gpio_service *service, 437 enum gpio_id id, 438 uint32_t en) 439 { 440 struct gpio *irq; 441 442 switch (id) { 443 case GPIO_ID_HPD: 444 case GPIO_ID_GPIO_PAD: 445 break; 446 default: 447 id = GPIO_ID_HPD; 448 ASSERT_CRITICAL(false); 449 return NULL; 450 } 451 452 irq = dal_gpio_create( 453 service, id, en, GPIO_PIN_OUTPUT_STATE_DEFAULT); 454 455 if (irq) 456 return irq; 457 458 ASSERT_CRITICAL(false); 459 return NULL; 460 } 461 462 void dal_gpio_destroy_irq( 463 struct gpio **irq) 464 { 465 if (!irq || !*irq) { 466 ASSERT_CRITICAL(false); 467 return; 468 } 469 470 dal_gpio_close(*irq); 471 dal_gpio_destroy(irq); 472 kfree(*irq); 473 474 *irq = NULL; 475 } 476 477 struct ddc *dal_gpio_create_ddc( 478 struct gpio_service *service, 479 uint32_t offset, 480 uint32_t mask, 481 struct gpio_ddc_hw_info *info) 482 { 483 enum gpio_id id; 484 uint32_t en; 485 struct ddc *ddc; 486 487 if (!service->translate.funcs->offset_to_id(offset, mask, &id, &en)) 488 return NULL; 489 490 ddc = kzalloc(sizeof(struct ddc), GFP_KERNEL); 491 492 if (!ddc) { 493 BREAK_TO_DEBUGGER(); 494 return NULL; 495 } 496 497 ddc->pin_data = dal_gpio_create( 498 service, GPIO_ID_DDC_DATA, en, GPIO_PIN_OUTPUT_STATE_DEFAULT); 499 500 if (!ddc->pin_data) { 501 BREAK_TO_DEBUGGER(); 502 goto failure_1; 503 } 504 505 ddc->pin_clock = dal_gpio_create( 506 service, GPIO_ID_DDC_CLOCK, en, GPIO_PIN_OUTPUT_STATE_DEFAULT); 507 508 if (!ddc->pin_clock) { 509 BREAK_TO_DEBUGGER(); 510 goto failure_2; 511 } 512 513 ddc->hw_info = *info; 514 515 ddc->ctx = service->ctx; 516 517 return ddc; 518 519 failure_2: 520 dal_gpio_destroy(&ddc->pin_data); 521 522 failure_1: 523 kfree(ddc); 524 525 return NULL; 526 } 527 528 void dal_gpio_destroy_ddc( 529 struct ddc **ddc) 530 { 531 if (!ddc || !*ddc) { 532 BREAK_TO_DEBUGGER(); 533 return; 534 } 535 536 dal_ddc_close(*ddc); 537 dal_gpio_destroy(&(*ddc)->pin_data); 538 dal_gpio_destroy(&(*ddc)->pin_clock); 539 kfree(*ddc); 540 541 *ddc = NULL; 542 } 543 544 enum gpio_result dal_ddc_open( 545 struct ddc *ddc, 546 enum gpio_mode mode, 547 enum gpio_ddc_config_type config_type) 548 { 549 enum gpio_result result; 550 551 struct gpio_config_data config_data; 552 struct hw_gpio *hw_data; 553 struct hw_gpio *hw_clock; 554 555 result = dal_gpio_open_ex(ddc->pin_data, mode); 556 557 if (result != GPIO_RESULT_OK) { 558 BREAK_TO_DEBUGGER(); 559 return result; 560 } 561 562 result = dal_gpio_open_ex(ddc->pin_clock, mode); 563 564 if (result != GPIO_RESULT_OK) { 565 BREAK_TO_DEBUGGER(); 566 goto failure; 567 } 568 569 /* DDC clock and data pins should belong 570 * to the same DDC block id, 571 * we use the data pin to set the pad mode. */ 572 573 if (mode == GPIO_MODE_INPUT) 574 /* this is from detect_sink_type, 575 * we need extra delay there */ 576 config_data.type = GPIO_CONFIG_TYPE_I2C_AUX_DUAL_MODE; 577 else 578 config_data.type = GPIO_CONFIG_TYPE_DDC; 579 580 config_data.config.ddc.type = config_type; 581 582 hw_data = FROM_HW_GPIO_PIN(ddc->pin_data->pin); 583 hw_clock = FROM_HW_GPIO_PIN(ddc->pin_clock->pin); 584 585 config_data.config.ddc.data_en_bit_present = hw_data->store.en != 0; 586 config_data.config.ddc.clock_en_bit_present = hw_clock->store.en != 0; 587 588 result = dal_gpio_set_config(ddc->pin_data, &config_data); 589 590 if (result == GPIO_RESULT_OK) 591 return result; 592 593 BREAK_TO_DEBUGGER(); 594 595 dal_gpio_close(ddc->pin_clock); 596 597 failure: 598 dal_gpio_close(ddc->pin_data); 599 600 return result; 601 } 602 603 enum gpio_result dal_ddc_change_mode( 604 struct ddc *ddc, 605 enum gpio_mode mode) 606 { 607 enum gpio_result result; 608 609 enum gpio_mode original_mode = 610 dal_gpio_get_mode(ddc->pin_data); 611 612 result = dal_gpio_change_mode(ddc->pin_data, mode); 613 614 /* [anaumov] DAL2 code returns GPIO_RESULT_NON_SPECIFIC_ERROR 615 * in case of failures; 616 * set_mode() is so that, in case of failure, 617 * we must explicitly set original mode */ 618 619 if (result != GPIO_RESULT_OK) 620 goto failure; 621 622 result = dal_gpio_change_mode(ddc->pin_clock, mode); 623 624 if (result == GPIO_RESULT_OK) 625 return result; 626 627 dal_gpio_change_mode(ddc->pin_clock, original_mode); 628 629 failure: 630 dal_gpio_change_mode(ddc->pin_data, original_mode); 631 632 return result; 633 } 634 635 enum gpio_ddc_line dal_ddc_get_line( 636 const struct ddc *ddc) 637 { 638 return (enum gpio_ddc_line)dal_gpio_get_enum(ddc->pin_data); 639 } 640 641 enum gpio_result dal_ddc_set_config( 642 struct ddc *ddc, 643 enum gpio_ddc_config_type config_type) 644 { 645 struct gpio_config_data config_data; 646 647 config_data.type = GPIO_CONFIG_TYPE_DDC; 648 649 config_data.config.ddc.type = config_type; 650 config_data.config.ddc.data_en_bit_present = false; 651 config_data.config.ddc.clock_en_bit_present = false; 652 653 return dal_gpio_set_config(ddc->pin_data, &config_data); 654 } 655 656 void dal_ddc_close( 657 struct ddc *ddc) 658 { 659 dal_gpio_close(ddc->pin_clock); 660 dal_gpio_close(ddc->pin_data); 661 } 662 663