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