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