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