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