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 		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 
594