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