GNU Linux-libre 4.19.245-gnu1
[releases.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,
55         enum dce_environment dce_environment,
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,
70                         dce_environment)) {
71                 BREAK_TO_DEBUGGER();
72                 goto failure_1;
73         }
74
75         if (!dal_hw_factory_init(&service->factory, dce_version,
76                         dce_environment)) {
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                 id = GPIO_ID_HPD;
379                 ASSERT_CRITICAL(false);
380                 return NULL;
381         }
382
383         irq = dal_gpio_create(
384                 service, id, en, GPIO_PIN_OUTPUT_STATE_DEFAULT);
385
386         if (irq)
387                 return irq;
388
389         ASSERT_CRITICAL(false);
390         return NULL;
391 }
392
393 void dal_gpio_destroy_irq(
394         struct gpio **irq)
395 {
396         if (!irq || !*irq) {
397                 ASSERT_CRITICAL(false);
398                 return;
399         }
400
401         dal_gpio_close(*irq);
402         dal_gpio_destroy(irq);
403         kfree(*irq);
404
405         *irq = NULL;
406 }
407
408 struct ddc *dal_gpio_create_ddc(
409         struct gpio_service *service,
410         uint32_t offset,
411         uint32_t mask,
412         struct gpio_ddc_hw_info *info)
413 {
414         enum gpio_id id;
415         uint32_t en;
416         struct ddc *ddc;
417
418         if (!service->translate.funcs->offset_to_id(offset, mask, &id, &en))
419                 return NULL;
420
421         ddc = kzalloc(sizeof(struct ddc), GFP_KERNEL);
422
423         if (!ddc) {
424                 BREAK_TO_DEBUGGER();
425                 return NULL;
426         }
427
428         ddc->pin_data = dal_gpio_create(
429                 service, GPIO_ID_DDC_DATA, en, GPIO_PIN_OUTPUT_STATE_DEFAULT);
430
431         if (!ddc->pin_data) {
432                 BREAK_TO_DEBUGGER();
433                 goto failure_1;
434         }
435
436         ddc->pin_clock = dal_gpio_create(
437                 service, GPIO_ID_DDC_CLOCK, en, GPIO_PIN_OUTPUT_STATE_DEFAULT);
438
439         if (!ddc->pin_clock) {
440                 BREAK_TO_DEBUGGER();
441                 goto failure_2;
442         }
443
444         ddc->hw_info = *info;
445
446         ddc->ctx = service->ctx;
447
448         return ddc;
449
450 failure_2:
451         dal_gpio_destroy(&ddc->pin_data);
452
453 failure_1:
454         kfree(ddc);
455
456         return NULL;
457 }
458
459 void dal_gpio_destroy_ddc(
460         struct ddc **ddc)
461 {
462         if (!ddc || !*ddc) {
463                 BREAK_TO_DEBUGGER();
464                 return;
465         }
466
467         dal_ddc_close(*ddc);
468         dal_gpio_destroy(&(*ddc)->pin_data);
469         dal_gpio_destroy(&(*ddc)->pin_clock);
470         kfree(*ddc);
471
472         *ddc = NULL;
473 }
474
475 enum gpio_result dal_ddc_open(
476         struct ddc *ddc,
477         enum gpio_mode mode,
478         enum gpio_ddc_config_type config_type)
479 {
480         enum gpio_result result;
481
482         struct gpio_config_data config_data;
483         struct hw_gpio *hw_data;
484         struct hw_gpio *hw_clock;
485
486         result = dal_gpio_open_ex(ddc->pin_data, mode);
487
488         if (result != GPIO_RESULT_OK) {
489                 BREAK_TO_DEBUGGER();
490                 return result;
491         }
492
493         result = dal_gpio_open_ex(ddc->pin_clock, mode);
494
495         if (result != GPIO_RESULT_OK) {
496                 BREAK_TO_DEBUGGER();
497                 goto failure;
498         }
499
500         /* DDC clock and data pins should belong
501          * to the same DDC block id,
502          * we use the data pin to set the pad mode. */
503
504         if (mode == GPIO_MODE_INPUT)
505                 /* this is from detect_sink_type,
506                  * we need extra delay there */
507                 config_data.type = GPIO_CONFIG_TYPE_I2C_AUX_DUAL_MODE;
508         else
509                 config_data.type = GPIO_CONFIG_TYPE_DDC;
510
511         config_data.config.ddc.type = config_type;
512
513         hw_data = FROM_HW_GPIO_PIN(ddc->pin_data->pin);
514         hw_clock = FROM_HW_GPIO_PIN(ddc->pin_clock->pin);
515
516         config_data.config.ddc.data_en_bit_present = hw_data->store.en != 0;
517         config_data.config.ddc.clock_en_bit_present = hw_clock->store.en != 0;
518
519         result = dal_gpio_set_config(ddc->pin_data, &config_data);
520
521         if (result == GPIO_RESULT_OK)
522                 return result;
523
524         BREAK_TO_DEBUGGER();
525
526         dal_gpio_close(ddc->pin_clock);
527
528 failure:
529         dal_gpio_close(ddc->pin_data);
530
531         return result;
532 }
533
534 enum gpio_result dal_ddc_change_mode(
535         struct ddc *ddc,
536         enum gpio_mode mode)
537 {
538         enum gpio_result result;
539
540         enum gpio_mode original_mode =
541                 dal_gpio_get_mode(ddc->pin_data);
542
543         result = dal_gpio_change_mode(ddc->pin_data, mode);
544
545         /* [anaumov] DAL2 code returns GPIO_RESULT_NON_SPECIFIC_ERROR
546          * in case of failures;
547          * set_mode() is so that, in case of failure,
548          * we must explicitly set original mode */
549
550         if (result != GPIO_RESULT_OK)
551                 goto failure;
552
553         result = dal_gpio_change_mode(ddc->pin_clock, mode);
554
555         if (result == GPIO_RESULT_OK)
556                 return result;
557
558         dal_gpio_change_mode(ddc->pin_clock, original_mode);
559
560 failure:
561         dal_gpio_change_mode(ddc->pin_data, original_mode);
562
563         return result;
564 }
565
566 enum gpio_ddc_line dal_ddc_get_line(
567         const struct ddc *ddc)
568 {
569         return (enum gpio_ddc_line)dal_gpio_get_enum(ddc->pin_data);
570 }
571
572 enum gpio_result dal_ddc_set_config(
573         struct ddc *ddc,
574         enum gpio_ddc_config_type config_type)
575 {
576         struct gpio_config_data config_data;
577
578         config_data.type = GPIO_CONFIG_TYPE_DDC;
579
580         config_data.config.ddc.type = config_type;
581         config_data.config.ddc.data_en_bit_present = false;
582         config_data.config.ddc.clock_en_bit_present = false;
583
584         return dal_gpio_set_config(ddc->pin_data, &config_data);
585 }
586
587 void dal_ddc_close(
588         struct ddc *ddc)
589 {
590         dal_gpio_close(ddc->pin_clock);
591         dal_gpio_close(ddc->pin_data);
592 }
593