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