2014-07-16 21:08:55 +03:00
/*
* Copyright 2014 Advanced Micro Devices , Inc .
*
* 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 .
*/
# include <linux/amd-iommu.h>
# include <linux/bsearch.h>
# include <linux/pci.h>
# include <linux/slab.h>
# include "kfd_priv.h"
static const struct kfd_device_info kaveri_device_info = {
. max_pasid_bits = 16 ,
} ;
struct kfd_deviceid {
unsigned short did ;
const struct kfd_device_info * device_info ;
} ;
/* Please keep this sorted by increasing device id. */
static const struct kfd_deviceid supported_devices [ ] = {
{ 0x1304 , & kaveri_device_info } , /* Kaveri */
{ 0x1305 , & kaveri_device_info } , /* Kaveri */
{ 0x1306 , & kaveri_device_info } , /* Kaveri */
{ 0x1307 , & kaveri_device_info } , /* Kaveri */
{ 0x1309 , & kaveri_device_info } , /* Kaveri */
{ 0x130A , & kaveri_device_info } , /* Kaveri */
{ 0x130B , & kaveri_device_info } , /* Kaveri */
{ 0x130C , & kaveri_device_info } , /* Kaveri */
{ 0x130D , & kaveri_device_info } , /* Kaveri */
{ 0x130E , & kaveri_device_info } , /* Kaveri */
{ 0x130F , & kaveri_device_info } , /* Kaveri */
{ 0x1310 , & kaveri_device_info } , /* Kaveri */
{ 0x1311 , & kaveri_device_info } , /* Kaveri */
{ 0x1312 , & kaveri_device_info } , /* Kaveri */
{ 0x1313 , & kaveri_device_info } , /* Kaveri */
{ 0x1315 , & kaveri_device_info } , /* Kaveri */
{ 0x1316 , & kaveri_device_info } , /* Kaveri */
{ 0x1317 , & kaveri_device_info } , /* Kaveri */
{ 0x1318 , & kaveri_device_info } , /* Kaveri */
{ 0x131B , & kaveri_device_info } , /* Kaveri */
{ 0x131C , & kaveri_device_info } , /* Kaveri */
{ 0x131D , & kaveri_device_info } , /* Kaveri */
} ;
static const struct kfd_device_info * lookup_device_info ( unsigned short did )
{
size_t i ;
for ( i = 0 ; i < ARRAY_SIZE ( supported_devices ) ; i + + ) {
if ( supported_devices [ i ] . did = = did ) {
BUG_ON ( supported_devices [ i ] . device_info = = NULL ) ;
return supported_devices [ i ] . device_info ;
}
}
return NULL ;
}
struct kfd_dev * kgd2kfd_probe ( struct kgd_dev * kgd , struct pci_dev * pdev )
{
struct kfd_dev * kfd ;
const struct kfd_device_info * device_info =
lookup_device_info ( pdev - > device ) ;
if ( ! device_info )
return NULL ;
kfd = kzalloc ( sizeof ( * kfd ) , GFP_KERNEL ) ;
if ( ! kfd )
return NULL ;
kfd - > kgd = kgd ;
kfd - > device_info = device_info ;
kfd - > pdev = pdev ;
return kfd ;
}
bool kgd2kfd_device_init ( struct kfd_dev * kfd ,
const struct kgd2kfd_shared_resources * gpu_resources )
{
kfd - > shared_resources = * gpu_resources ;
2014-07-16 21:22:32 +03:00
if ( kfd_topology_add_device ( kfd ) ! = 0 )
return false ;
2014-07-16 21:08:55 +03:00
kfd - > init_complete = true ;
dev_info ( kfd_device , " added device (%x:%x) \n " , kfd - > pdev - > vendor ,
kfd - > pdev - > device ) ;
return true ;
}
void kgd2kfd_device_exit ( struct kfd_dev * kfd )
{
2014-07-16 21:22:32 +03:00
int err = kfd_topology_remove_device ( kfd ) ;
BUG_ON ( err ! = 0 ) ;
2014-07-16 21:08:55 +03:00
kfree ( kfd ) ;
}
void kgd2kfd_suspend ( struct kfd_dev * kfd )
{
BUG_ON ( kfd = = NULL ) ;
}
int kgd2kfd_resume ( struct kfd_dev * kfd )
{
BUG_ON ( kfd = = NULL ) ;
return 0 ;
}
void kgd2kfd_interrupt ( struct kfd_dev * dev , const void * ih_ring_entry )
{
}