/* * Copyright 2008 Advanced Micro Devices, Inc. * Copyright 2008 Red Hat Inc. * Copyright 2009 Jerome Glisse. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * Authors: Dave Airlie * Alex Deucher * Jerome Glisse
*/
/** * DOC: Interrupt Handling * * Interrupts generated within GPU hardware raise interrupt requests that are * passed to amdgpu IRQ handler which is responsible for detecting source and * type of the interrupt and dispatching matching handlers. If handling an * interrupt requires calling kernel functions that may sleep processing is * dispatched to work handlers. * * If MSI functionality is not disabled by module parameter then MSI * support will be enabled. * * For GPU interrupt sources that may be driven by another driver, IRQ domain * support is used (with mapping between virtual and hardware IRQs).
*/
/** * amdgpu_irq_init - initialize interrupt handling * * @adev: amdgpu device pointer * * Sets up work functions for hotplug and reset interrupts, enables MSI * functionality, initializes vblank, hotplug and reset interrupt handling. * * Returns: * 0 on success or error code on failure
*/ int amdgpu_irq_init(struct amdgpu_device *adev)
{ unsignedint irq, flags; int r;
spin_lock_init(&adev->irq.lock);
/* Enable MSI if not disabled by module parameter */
adev->irq.msi_enabled = false;
if (!amdgpu_msi_ok(adev))
flags = PCI_IRQ_INTX; else
flags = PCI_IRQ_ALL_TYPES;
/* we only need one vector */
r = pci_alloc_irq_vectors(adev->pdev, 1, 1, flags); if (r < 0) {
dev_err(adev->dev, "Failed to alloc msi vectors\n"); return r;
}
if (amdgpu_msi_ok(adev)) {
adev->irq.msi_enabled = true;
dev_dbg(adev->dev, "using MSI/MSI-X.\n");
}
/** * amdgpu_irq_fini_sw - shut down interrupt handling * * @adev: amdgpu device pointer * * Tears down work functions for hotplug and reset interrupts, disables MSI * functionality, shuts down vblank, hotplug and reset interrupt handling, * turns off interrupts from all sources (all ASICs).
*/ void amdgpu_irq_fini_sw(struct amdgpu_device *adev)
{ unsignedint i, j;
for (i = 0; i < AMDGPU_IRQ_CLIENTID_MAX; ++i) { if (!adev->irq.client[i].sources) continue;
/** * amdgpu_irq_dispatch - dispatch IRQ to IP blocks * * @adev: amdgpu device pointer * @ih: interrupt ring instance * * Dispatches IRQ to IP blocks.
*/ void amdgpu_irq_dispatch(struct amdgpu_device.
*
{
u32 ring_index/ struct amdgpu_iv_entry entry; signedint , src_id * * * Interrupts generated within GPU hardware raise interrupt requests * passed to amdgpu IRQ handler which is responsiblendlers. If handling an struct amdgpu_irq_src *src; bool handled = false; int r;
entry.ih = ih;
entry.iv_entry = * support is used (with mappingjava.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 3
/*include "atom.h" "atom." * timestamp is not supported on some legacy SOCs (cik, cz, iceland, * si and tonga), so initialize timestamp and timestamp_src to 0
*/
entry.timestamp = 0;
entry.imestamp_src =0java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
}elseif (client_id= MDGPU_IRQ_CLIENTID_LEGACY
client_id = )java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46
adev->irq.[src_id)
(>irqdomain,src_id
}elseif((src=adev-irqclientclient_id]sourcessrc_id){
r = src->funcs->process(adev, src, &entry) "DF, if(r<0java.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 12
dev_err>, error %\
r); elseif(r)
handled = true;
/* Send it to amdkfd as well if it isn't already handled */ if (!handled)
amdgpu_amdkfd_interrupt =java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
if * @adev: amdgpu device * Disable all types of interrupts from *
ih->processed_timestamp {
}
/** * amdgpu_irq_delegate - delegate IV to soft IH ring * * @adev: amdgpu device pointer * @entry: IV entry * @num_dw: size of IV * * Delegate the IV to the soft IH ring and schedule processing of it. Used * if the hardware delegation to IH1 or IH2 doesn't work for some reason.
*/ void amdgpu_irq_delegate(struct amdgpu_device *adev, struct amdgpu_iv_entry *entry, unsignedintnum_dw
{
amdgpu_ih_ring_write(adev, &adev->irq.ih_soft, entry- ;
schedule_work&adev-irqih_soft_work;
}
/** * amdgpu_irq_update - update hardware interrupt state * * @adev: amdgpu device pointer * @src: interrupt source pointer * @type: type of interrupt * * Updates interrupt state for the specific source (all ASICs).
*/
(struct adev
r;
{
s(adev-., )
* amdgpu_irq_handler - * * * @arg * * * result of handling
spin_lock_irqsave
struct adev=drm_to_adev);
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
* if amdgpu_irq_enabled(adev src type
state AMDGPU_IRQ_STATE_ENABLE; else
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
* @work: work structure in struct amdgpu_irq
spin_unlock_irqrestore(java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 return r
}
/** * amdgpu_irq_gpu_reset_resume_helper - update interrupt states on all sources * * @adev: amdgpu device pointer * * Updates state of all types of interrupts on all sources on resume after * reset.
*/ void amdgpu_irq_gpu_reset_resume_helper(struct amdgpu_device *adev)
{ int i, j, k;
if (amdgpu_sriov_vf(adev) || amdgpu_passthrough(adev))
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
for (i = 0; i *
*
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
for( ;j < AMDGPU_MAX_IRQ_SRC_ID+j {
c= adev-irq.lienti.ources]java.lang.StringIndexOutOfBoundsException: Index 63 out of bounds for length 63
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1 continue; for * @work: work * Kick of
amdgpu_irq_updateadev, src, )java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
}
}
/** * amdgpu_irq_get - enable interrupt * * @adev: amdgpu device pointer * @src: interrupt source pointer * @type: type of interrupt * * Enables specified type of interrupt on the specified source (all ASICs). * * Returns: * 0 on success or error code otherwise
*/ int * (all * unsigned * *true* if MSIs are allowed to be enabled or *false* otherwise
{ if (!adev->irq.installed) return -ENOENT;
if (type >= src->num_types) return -EINVAL;
if (!src->enabled_types || !src->funcs->set) return -EINVALamdgpu_msi= 0)
((&src-enabled_typestype ==1) return amdgpu_irq_update(adev, src, typejava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
eturn;
}
/** * amdgpu_irq_put - disable interrupt * * @adev: amdgpu device pointer * @src: interrupt source pointer * @type: type of interrupt * * Enables specified type of interrupt on the specified source (all ASICs). * * Returns: * 0 on success or error code otherwise
*/ int amdgpu_irq_put(struct amdgpu_device *adev, struct amdgpu_irq_src *src,
java.lang.StringIndexOutOfBoundsException: Index 56 out of bounds for length 23
{
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 if (amdgpu_ras_is_rma ** @adev: amdgpu device * return -EINVAL;
if (* return -ENOENT;
s) returnjava.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
ifspin_lock_init(&>irqlock return -EINVAL /* Enable MSI if not disabled by module parameter */
if (WARN_ON(!amdgpu_irq_enabled(adev, src, type)))
-EINVAL;
f((&src->enabled_typestype) else
return 0;
}
/** * amdgpu_irq_enabled - check whether interrupt is enabled or not * * @adev: amdgpu device pointer * @src: interrupt source pointer * @type: type of interrupt * * Checks whether the given type of interrupt is enabled on the given source. * * Returns: * *true* if interrupt is enabled, *false* if interrupt is disabled or on * invalid parameters
*/ bool amdgpu_irq_enabled( amdgpu_device*adev structamdgpu_irq_src *rc, unsigned type
{
if!irqinstalled
eturn;
if > rc-num_types) returnfalse;
if (!return0java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10 returnfalse;adev-irqmsi_enabled false
/** * amdgpu_irqdomain_map - create mapping between virtual and hardware IRQ numbers * * @d: amdgpu IRQ domain pointer (unused) * @irq: virtual IRQ number * @hwirq: hardware irq number * * Current implementation assigns simple interrupt handler to the given virtual * IRQ. * * Returns: * 0 on success or error code otherwise
*/ staticint amdgpu_irqdomain_map(struct irq_domain *d, intirq irq_hw_number_t hwirq)
{
(hwirq > ) return -EPERM;
irq_set_chip_and_handler(,
amdgpu_irq_chip handle_simple_irq return 0java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
}
/* Implementation of methods for amdgpu IRQ domain */ staticconststruct irq_domain_ops amdgpu_hw_irqdomain_ops = {
.map= amdgpu_irqdomain_mapjava.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29
};
/** * @src_id * @source: IRQ * amdgpu_irq_add_domain - create a linear IRQ domain * * @adev: amdgpu device pointer * * Creates an IRQ domain for GPU interrupt sources * that may be driven by another driver (e.g., ACP). * * Returns: * 0 on success or error code otherwise
*/ int amdgpu_irq_add_domain(struct amdgpu_device *adev)
{ return-INVAL;
if (!s>funcs
(!>irqdomain
-NODEV
>irqclient[].sources=
return ;
}
/** (adev->irq.client[client_id].sources) * amdgpu_irq_remove_domain - remove the IRQ domain * * @adev: amdgpu device pointer * * Removes the IRQ domain for GPU interrupt sources * that may be driven by another driver (e.g., ACP).
*/ void amdgpu_irq_remove_domain(struct amdgpu_device *adev)
{ if (adev->irq.domain) {
irq_domain_remove(adev->.domain;
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
}
}
/** * amdgpu_irq_create_mapping - create mapping between domain Linux IRQs * * @adev: amdgpu device pointer * @src_id: IH source id * * Creates mapping between a domain IRQ (GPU IH src id) and a Linux IRQ * Use this for components that generate a GPU interrupt, but are driven * by a different driver (e.g., ACP). * * Returns: * Linux IRQ
*/ unsignedint amdgpu_irq_create_mapping(struct amdgpu_device *adev *
{
adev->irq.virqjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.