brintos

brintos / linux-shallow public Read only

0
0
Text · 4.3 KiB · eca3d7e Raw
180 lines · c
1/*2 * Copyright 2012-15 Advanced Micro Devices, Inc.3 *4 * Permission is hereby granted, free of charge, to any person obtaining a5 * copy of this software and associated documentation files (the "Software"),6 * to deal in the Software without restriction, including without limitation7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,8 * and/or sell copies of the Software, and to permit persons to whom the9 * Software is furnished to do so, subject to the following conditions:10 *11 * The above copyright notice and this permission notice shall be included in12 * all copies or substantial portions of the Software.13 *14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR18 * 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 OR20 * OTHER DEALINGS IN THE SOFTWARE.21 *22 * Authors: AMD23 *24 */25 26#include "dm_services.h"27 28#include "include/irq_service_interface.h"29#include "include/logger_interface.h"30 31#include "dce110/irq_service_dce110.h"32 33#if defined(CONFIG_DRM_AMD_DC_SI)34#include "dce60/irq_service_dce60.h"35#endif36 37#include "dce80/irq_service_dce80.h"38#include "dce120/irq_service_dce120.h"39#include "dcn10/irq_service_dcn10.h"40 41#include "reg_helper.h"42#include "irq_service.h"43 44 45 46#define CTX \47		irq_service->ctx48#define DC_LOGGER \49	irq_service->ctx->logger50 51void dal_irq_service_construct(52	struct irq_service *irq_service,53	struct irq_service_init_data *init_data)54{55	if (!init_data || !init_data->ctx) {56		BREAK_TO_DEBUGGER();57		return;58	}59 60	irq_service->ctx = init_data->ctx;61}62 63void dal_irq_service_destroy(struct irq_service **irq_service)64{65	if (!irq_service || !*irq_service) {66		BREAK_TO_DEBUGGER();67		return;68	}69 70	kfree(*irq_service);71 72	*irq_service = NULL;73}74 75static const struct irq_source_info *find_irq_source_info(76	struct irq_service *irq_service,77	enum dc_irq_source source)78{79	if (source >= DAL_IRQ_SOURCES_NUMBER)80		return NULL;81 82	return &irq_service->info[source];83}84 85void dal_irq_service_set_generic(86	struct irq_service *irq_service,87	const struct irq_source_info *info,88	bool enable)89{90	uint32_t addr = info->enable_reg;91	uint32_t value = dm_read_reg(irq_service->ctx, addr);92 93	value = (value & ~info->enable_mask) |94		(info->enable_value[enable ? 0 : 1] & info->enable_mask);95	dm_write_reg(irq_service->ctx, addr, value);96}97 98bool dal_irq_service_set(99	struct irq_service *irq_service,100	enum dc_irq_source source,101	bool enable)102{103	const struct irq_source_info *info =104		find_irq_source_info(irq_service, source);105 106	if (!info) {107		DC_LOG_ERROR("%s: cannot find irq info table entry for %d\n",108			__func__,109			source);110		return false;111	}112 113	dal_irq_service_ack(irq_service, source);114 115	if (info->funcs && info->funcs->set) {116		if (info->funcs->set == dal_irq_service_dummy_set) {117			DC_LOG_WARNING("%s: src: %d, st: %d\n", __func__,118				       source, enable);119			ASSERT(0);120		}121 122		return info->funcs->set(irq_service, info, enable);123	}124 125	dal_irq_service_set_generic(irq_service, info, enable);126 127	return true;128}129 130void dal_irq_service_ack_generic(131	struct irq_service *irq_service,132	const struct irq_source_info *info)133{134	uint32_t addr = info->ack_reg;135	uint32_t value = dm_read_reg(irq_service->ctx, addr);136 137	value = (value & ~info->ack_mask) |138		(info->ack_value & info->ack_mask);139	dm_write_reg(irq_service->ctx, addr, value);140}141 142bool dal_irq_service_ack(143	struct irq_service *irq_service,144	enum dc_irq_source source)145{146	const struct irq_source_info *info =147		find_irq_source_info(irq_service, source);148 149	if (!info) {150		DC_LOG_ERROR("%s: cannot find irq info table entry for %d\n",151			__func__,152			source);153		return false;154	}155 156	if (info->funcs && info->funcs->ack) {157		if (info->funcs->ack == dal_irq_service_dummy_ack) {158			DC_LOG_WARNING("%s: src: %d\n", __func__, source);159			ASSERT(0);160		}161 162		return info->funcs->ack(irq_service, info);163	}164 165	dal_irq_service_ack_generic(irq_service, info);166 167	return true;168}169 170enum dc_irq_source dal_irq_service_to_irq_source(171		struct irq_service *irq_service,172		uint32_t src_id,173		uint32_t ext_id)174{175	return irq_service->funcs->to_dal_irq_source(176		irq_service,177		src_id,178		ext_id);179}180