Linux-libre 5.3.12-gnu
[librecmc/linux-libre.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 <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