├── pci_ids ├── vmwgfx_pci_ids.h ├── i810_pci_ids.h ├── i915_pci_ids.h ├── r200_pci_ids.h ├── radeon_pci_ids.h ├── i965_pci_ids.h ├── pci_id_driver_map.h ├── r300_pci_ids.h └── r600_pci_ids.h ├── gralloc_drm_handle.h ├── radeon ├── radeon.h └── radeon_chipinfo_gen.h ├── gralloc_drm_priv.h ├── Android.mk ├── gralloc_drm.h ├── dri └── intel_chipset.h ├── gralloc.c ├── gralloc_drm.c ├── gralloc_drm_nouveau.c ├── gralloc_drm_radeon.c ├── gralloc_drm_pipe.c ├── gralloc_drm_kms.c └── gralloc_drm_intel.c /pci_ids/vmwgfx_pci_ids.h: -------------------------------------------------------------------------------- 1 | CHIPSET(0x0405, SVGAII, SVGAII) 2 | -------------------------------------------------------------------------------- /pci_ids/i810_pci_ids.h: -------------------------------------------------------------------------------- 1 | CHIPSET(0x7121, I810, i8xx) 2 | CHIPSET(0x7123, I810_DC100, i8xx) 3 | CHIPSET(0x7125, I810_E, i8xx) 4 | CHIPSET(0x1132, I815, i8xx) 5 | -------------------------------------------------------------------------------- /pci_ids/i915_pci_ids.h: -------------------------------------------------------------------------------- 1 | CHIPSET(0x3577, I830_M, i8xx) 2 | CHIPSET(0x2562, 845_G, i8xx) 3 | CHIPSET(0x3582, I855_GM, i8xx) 4 | CHIPSET(0x2572, I865_G, i8xx) 5 | CHIPSET(0x2582, I915_G, i915) 6 | CHIPSET(0x258A, E7221_G, i915) 7 | CHIPSET(0x2592, I915_GM, i915) 8 | CHIPSET(0x2772, I945_G, i945) 9 | CHIPSET(0x27A2, I945_GM, i945) 10 | CHIPSET(0x27AE, I945_GME, i945) 11 | CHIPSET(0x29B2, Q35_G, i945) 12 | CHIPSET(0x29C2, G33_G, i945) 13 | CHIPSET(0x29D2, Q33_G, i945) 14 | CHIPSET(0xA011, IGD_GM, i945) 15 | CHIPSET(0xA001, IGD_G, i945) 16 | -------------------------------------------------------------------------------- /pci_ids/r200_pci_ids.h: -------------------------------------------------------------------------------- 1 | CHIPSET(0x5148, R200_QH, R200) 2 | CHIPSET(0x514C, R200_QL, R200) 3 | CHIPSET(0x514D, R200_QM, R200) 4 | CHIPSET(0x4242, R200_BB, R200) 5 | 6 | CHIPSET(0x4966, RV250_If, RV250) 7 | CHIPSET(0x4967, RV250_Ig, RV250) 8 | CHIPSET(0x4C64, RV250_Ld, RV250) 9 | CHIPSET(0x4C66, RV250_Lf, RV250) 10 | CHIPSET(0x4C67, RV250_Lg, RV250) 11 | 12 | CHIPSET(0x5960, RV280_5960, RV280) 13 | CHIPSET(0x5961, RV280_5961, RV280) 14 | CHIPSET(0x5962, RV280_5962, RV280) 15 | CHIPSET(0x5964, RV280_5964, RV280) 16 | CHIPSET(0x5965, RV280_5965, RV280) 17 | CHIPSET(0x5C61, RV280_5C61, RV280) 18 | CHIPSET(0x5C63, RV280_5C63, RV280) 19 | CHIPSET(0x5834, RS300_5834, RS300) 20 | CHIPSET(0x5835, RS300_5835, RS300) 21 | CHIPSET(0x7834, RS350_7834, RS300) 22 | CHIPSET(0x7835, RS350_7835, RS300) 23 | -------------------------------------------------------------------------------- /pci_ids/radeon_pci_ids.h: -------------------------------------------------------------------------------- 1 | CHIPSET(0x4C57, RADEON_LW, RV200) 2 | CHIPSET(0x4C58, RADEON_LX, RV200) 3 | CHIPSET(0x4C59, RADEON_LY, RV100) 4 | CHIPSET(0x4C5A, RADEON_LZ, RV100) 5 | CHIPSET(0x5144, RADEON_QD, R100) 6 | CHIPSET(0x5145, RADEON_QE, R100) 7 | CHIPSET(0x5146, RADEON_QF, R100) 8 | CHIPSET(0x5147, RADEON_QG, R100) 9 | CHIPSET(0x5159, RADEON_QY, RV100) 10 | CHIPSET(0x515A, RADEON_QZ, RV100) 11 | 12 | CHIPSET(0x5157, RV200_QW, RV200) 13 | CHIPSET(0x5158, RV200_QX, RV200) 14 | 15 | CHIPSET(0x515E, RN50_515E, UNKNOWN) 16 | CHIPSET(0x5969, RN50_5969, UNKNOWN) 17 | 18 | CHIPSET(0x4136, RS100_4136, RS100) 19 | CHIPSET(0x4336, RS100_4336, RS100) 20 | CHIPSET(0x4137, RS200_4137, RS200) 21 | CHIPSET(0x4337, RS200_4337, RS200) 22 | CHIPSET(0x4237, RS250_4237, RS200) 23 | CHIPSET(0x4437, RS250_4437, RS200) 24 | -------------------------------------------------------------------------------- /pci_ids/i965_pci_ids.h: -------------------------------------------------------------------------------- 1 | CHIPSET(0x29A2, I965_G, i965) 2 | CHIPSET(0x2992, I965_Q, i965) 3 | CHIPSET(0x2982, I965_G_1, i965) 4 | CHIPSET(0x2972, I946_GZ, i965) 5 | CHIPSET(0x2A02, I965_GM, i965) 6 | CHIPSET(0x2A12, I965_GME, i965) 7 | CHIPSET(0x2A42, GM45_GM, g4x) 8 | CHIPSET(0x2E02, IGD_E_G, g4x) 9 | CHIPSET(0x2E12, Q45_G, g4x) 10 | CHIPSET(0x2E22, G45_G, g4x) 11 | CHIPSET(0x2E32, G41_G, g4x) 12 | CHIPSET(0x2E42, B43_G, g4x) 13 | CHIPSET(0x2E92, B43_G1, g4x) 14 | CHIPSET(0x0042, ILD_G, ilk) 15 | CHIPSET(0x0046, ILM_G, ilk) 16 | CHIPSET(0x0102, SANDYBRIDGE_GT1, snb_gt1) 17 | CHIPSET(0x0112, SANDYBRIDGE_GT2, snb_gt2) 18 | CHIPSET(0x0122, SANDYBRIDGE_GT2_PLUS, snb_gt2) 19 | CHIPSET(0x0106, SANDYBRIDGE_M_GT1, snb_gt1) 20 | CHIPSET(0x0116, SANDYBRIDGE_M_GT2, snb_gt2) 21 | CHIPSET(0x0126, SANDYBRIDGE_M_GT2_PLUS, snb_gt2) 22 | CHIPSET(0x010A, SANDYBRIDGE_S, snb_gt1) 23 | CHIPSET(0x0152, IVYBRIDGE_GT1, ivb_gt1) 24 | CHIPSET(0x0162, IVYBRIDGE_GT2, ivb_gt2) 25 | CHIPSET(0x0156, IVYBRIDGE_M_GT1, ivb_gt1) 26 | CHIPSET(0x0166, IVYBRIDGE_M_GT2, ivb_gt2) 27 | CHIPSET(0x015a, IVYBRIDGE_S_GT1, ivb_gt1) 28 | -------------------------------------------------------------------------------- /gralloc_drm_handle.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2011 Chia-I Wu 3 | * Copyright (C) 2010-2011 LunarG Inc. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a 6 | * copy of this software and associated documentation files (the "Software"), 7 | * to deal in the Software without restriction, including without limitation 8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 | * and/or sell copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included 13 | * in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 | * DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | #ifndef _GRALLOC_DRM_HANDLE_H_ 25 | #define _GRALLOC_DRM_HANDLE_H_ 26 | 27 | #include 28 | 29 | struct gralloc_drm_handle_t { 30 | native_handle_t base; 31 | 32 | #define GRALLOC_DRM_HANDLE_MAGIC 0x12345678 33 | #define GRALLOC_DRM_HANDLE_NUM_INTS 9 34 | #define GRALLOC_DRM_HANDLE_NUM_FDS 0 35 | int magic; 36 | 37 | int width; 38 | int height; 39 | int format; 40 | int usage; 41 | 42 | int name; /* the name of the bo */ 43 | int stride; /* the stride in bytes */ 44 | 45 | int data_owner; /* owner of data (for validation) */ 46 | int data; /* pointer to struct gralloc_drm_bo_t */ 47 | }; 48 | 49 | static inline struct gralloc_drm_handle_t *gralloc_drm_handle(buffer_handle_t _handle) 50 | { 51 | struct gralloc_drm_handle_t *handle = 52 | (struct gralloc_drm_handle_t *) _handle; 53 | 54 | if (handle && (handle->base.version != sizeof(handle->base) || 55 | handle->base.numInts != GRALLOC_DRM_HANDLE_NUM_INTS || 56 | handle->base.numFds != GRALLOC_DRM_HANDLE_NUM_FDS || 57 | handle->magic != GRALLOC_DRM_HANDLE_MAGIC)) 58 | handle = NULL; 59 | 60 | return handle; 61 | } 62 | 63 | #endif /* _GRALLOC_DRM_HANDLE_H_ */ 64 | -------------------------------------------------------------------------------- /pci_ids/pci_id_driver_map.h: -------------------------------------------------------------------------------- 1 | #ifndef _PCI_ID_DRIVER_MAP_H_ 2 | #define _PCI_ID_DRIVER_MAP_H_ 3 | 4 | #include 5 | 6 | #ifndef ARRAY_SIZE 7 | #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) 8 | #endif 9 | 10 | #if !defined(DRIVER_MAP_DRI2_ONLY) && !defined(DRIVER_MAP_GALLIUM_ONLY) 11 | static const int i810_chip_ids[] = { 12 | #define CHIPSET(chip, desc, misc) chip, 13 | #include "pci_ids/i810_pci_ids.h" 14 | #undef CHIPSET 15 | }; 16 | #endif 17 | 18 | static const int i915_chip_ids[] = { 19 | #define CHIPSET(chip, desc, misc) chip, 20 | #include "pci_ids/i915_pci_ids.h" 21 | #undef CHIPSET 22 | }; 23 | 24 | static const int i965_chip_ids[] = { 25 | #define CHIPSET(chip, desc, misc) chip, 26 | #include "pci_ids/i965_pci_ids.h" 27 | #undef CHIPSET 28 | }; 29 | 30 | #ifndef DRIVER_MAP_GALLIUM_ONLY 31 | static const int r100_chip_ids[] = { 32 | #define CHIPSET(chip, name, family) chip, 33 | #include "pci_ids/radeon_pci_ids.h" 34 | #undef CHIPSET 35 | }; 36 | 37 | static const int r200_chip_ids[] = { 38 | #define CHIPSET(chip, name, family) chip, 39 | #include "pci_ids/r200_pci_ids.h" 40 | #undef CHIPSET 41 | }; 42 | #endif 43 | 44 | static const int r300_chip_ids[] = { 45 | #define CHIPSET(chip, name, family) chip, 46 | #include "pci_ids/r300_pci_ids.h" 47 | #undef CHIPSET 48 | }; 49 | 50 | static const int r600_chip_ids[] = { 51 | #define CHIPSET(chip, name, family) chip, 52 | #include "pci_ids/r600_pci_ids.h" 53 | #undef CHIPSET 54 | }; 55 | 56 | static const int vmwgfx_chip_ids[] = { 57 | #define CHIPSET(chip, name, family) chip, 58 | #include "pci_ids/vmwgfx_pci_ids.h" 59 | #undef CHIPSET 60 | }; 61 | 62 | static const struct { 63 | int vendor_id; 64 | const char *driver; 65 | const int *chip_ids; 66 | int num_chips_ids; 67 | } driver_map[] = { 68 | #if !defined(DRIVER_MAP_DRI2_ONLY) && !defined(DRIVER_MAP_GALLIUM_ONLY) 69 | { 0x8086, "i810", i810_chip_ids, ARRAY_SIZE(i810_chip_ids) }, 70 | #endif 71 | { 0x8086, "i915", i915_chip_ids, ARRAY_SIZE(i915_chip_ids) }, 72 | { 0x8086, "i965", i965_chip_ids, ARRAY_SIZE(i965_chip_ids) }, 73 | #ifndef DRIVER_MAP_GALLIUM_ONLY 74 | { 0x1002, "radeon", r100_chip_ids, ARRAY_SIZE(r100_chip_ids) }, 75 | { 0x1002, "r200", r200_chip_ids, ARRAY_SIZE(r200_chip_ids) }, 76 | #endif 77 | { 0x1002, "r300", r300_chip_ids, ARRAY_SIZE(r300_chip_ids) }, 78 | { 0x1002, "r600", r600_chip_ids, ARRAY_SIZE(r600_chip_ids) }, 79 | { 0x10de, "nouveau", NULL, -1 }, 80 | { 0x15ad, "vmwgfx", vmwgfx_chip_ids, ARRAY_SIZE(vmwgfx_chip_ids) }, 81 | { 0x0000, NULL, NULL, 0 }, 82 | }; 83 | 84 | #endif /* _PCI_ID_DRIVER_MAP_H_ */ 85 | -------------------------------------------------------------------------------- /radeon/radeon.h: -------------------------------------------------------------------------------- 1 | /* A subset of radeon.h from xf86-video-ati */ 2 | 3 | /* 4 | * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and 5 | * VA Linux Systems Inc., Fremont, California. 6 | * 7 | * All Rights Reserved. 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining 10 | * a copy of this software and associated documentation files (the 11 | * "Software"), to deal in the Software without restriction, including 12 | * without limitation on the rights to use, copy, modify, merge, 13 | * publish, distribute, sublicense, and/or sell copies of the Software, 14 | * and to permit persons to whom the Software is furnished to do so, 15 | * subject to the following conditions: 16 | * 17 | * The above copyright notice and this permission notice (including the 18 | * next paragraph) shall be included in all copies or substantial 19 | * portions of the Software. 20 | * 21 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 24 | * NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR 25 | * THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 26 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 28 | * DEALINGS IN THE SOFTWARE. 29 | */ 30 | 31 | /* 32 | * Authors: 33 | * Kevin E. Martin 34 | * Rickard E. Faith 35 | * Alan Hourihane 36 | * 37 | */ 38 | 39 | #ifndef _RADEON_H_ 40 | #define _RADEON_H_ 41 | 42 | typedef enum { 43 | CHIP_FAMILY_UNKNOW, 44 | CHIP_FAMILY_LEGACY, 45 | CHIP_FAMILY_RADEON, 46 | CHIP_FAMILY_RV100, 47 | CHIP_FAMILY_RS100, /* U1 (IGP320M) or A3 (IGP320)*/ 48 | CHIP_FAMILY_RV200, 49 | CHIP_FAMILY_RS200, /* U2 (IGP330M/340M/350M) or A4 (IGP330/340/345/350), RS250 (IGP 7000) */ 50 | CHIP_FAMILY_R200, 51 | CHIP_FAMILY_RV250, 52 | CHIP_FAMILY_RS300, /* RS300/RS350 */ 53 | CHIP_FAMILY_RV280, 54 | CHIP_FAMILY_R300, 55 | CHIP_FAMILY_R350, 56 | CHIP_FAMILY_RV350, 57 | CHIP_FAMILY_RV380, /* RV370/RV380/M22/M24 */ 58 | CHIP_FAMILY_R420, /* R420/R423/M18 */ 59 | CHIP_FAMILY_RV410, /* RV410, M26 */ 60 | CHIP_FAMILY_RS400, /* xpress 200, 200m (RS400) Intel */ 61 | CHIP_FAMILY_RS480, /* xpress 200, 200m (RS410/480/482/485) AMD */ 62 | CHIP_FAMILY_RV515, /* rv515 */ 63 | CHIP_FAMILY_R520, /* r520 */ 64 | CHIP_FAMILY_RV530, /* rv530 */ 65 | CHIP_FAMILY_R580, /* r580 */ 66 | CHIP_FAMILY_RV560, /* rv560 */ 67 | CHIP_FAMILY_RV570, /* rv570 */ 68 | CHIP_FAMILY_RS600, 69 | CHIP_FAMILY_RS690, 70 | CHIP_FAMILY_RS740, 71 | CHIP_FAMILY_R600, /* r600 */ 72 | CHIP_FAMILY_RV610, 73 | CHIP_FAMILY_RV630, 74 | CHIP_FAMILY_RV670, 75 | CHIP_FAMILY_RV620, 76 | CHIP_FAMILY_RV635, 77 | CHIP_FAMILY_RS780, 78 | CHIP_FAMILY_RS880, 79 | CHIP_FAMILY_RV770, /* r700 */ 80 | CHIP_FAMILY_RV730, 81 | CHIP_FAMILY_RV710, 82 | CHIP_FAMILY_RV740, 83 | CHIP_FAMILY_CEDAR, /* evergreen */ 84 | CHIP_FAMILY_REDWOOD, 85 | CHIP_FAMILY_JUNIPER, 86 | CHIP_FAMILY_CYPRESS, 87 | CHIP_FAMILY_HEMLOCK, 88 | CHIP_FAMILY_PALM, 89 | CHIP_FAMILY_SUMO, 90 | CHIP_FAMILY_SUMO2, 91 | CHIP_FAMILY_BARTS, 92 | CHIP_FAMILY_TURKS, 93 | CHIP_FAMILY_CAICOS, 94 | CHIP_FAMILY_CAYMAN, 95 | CHIP_FAMILY_LAST 96 | } RADEONChipFamily; 97 | 98 | typedef struct { 99 | uint32_t pci_device_id; 100 | RADEONChipFamily chip_family; 101 | int mobility; 102 | int igp; 103 | int nocrtc2; 104 | int nointtvout; 105 | int singledac; 106 | } RADEONCardInfo; 107 | 108 | #endif /* _RADEON_H_ */ 109 | -------------------------------------------------------------------------------- /gralloc_drm_priv.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2011 Chia-I Wu 3 | * Copyright (C) 2010-2011 LunarG Inc. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a 6 | * copy of this software and associated documentation files (the "Software"), 7 | * to deal in the Software without restriction, including without limitation 8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 | * and/or sell copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included 13 | * in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 | * DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | #ifndef _GRALLOC_DRM_PRIV_H_ 25 | #define _GRALLOC_DRM_PRIV_H_ 26 | 27 | #include 28 | #include 29 | 30 | #include "gralloc_drm_handle.h" 31 | 32 | /* how a bo is posted */ 33 | enum drm_swap_mode { 34 | DRM_SWAP_NOOP, 35 | DRM_SWAP_FLIP, 36 | DRM_SWAP_COPY, 37 | DRM_SWAP_SETCRTC, 38 | }; 39 | 40 | struct gralloc_drm_t { 41 | /* initialized by gralloc_drm_create */ 42 | int fd; 43 | struct gralloc_drm_drv_t *drv; 44 | 45 | /* initialized by gralloc_drm_init_kms */ 46 | drmModeResPtr resources; 47 | uint32_t crtc_id; 48 | uint32_t connector_id; 49 | drmModeModeInfo mode; 50 | int xdpi, ydpi; 51 | #ifdef DRM_MODE_FEATURE_DIRTYFB 52 | drmModeClip clip; 53 | #endif 54 | 55 | /* initialized by drv->init_kms_features */ 56 | int fb_format; 57 | enum drm_swap_mode swap_mode; 58 | int swap_interval; 59 | int mode_quirk_vmwgfx; 60 | int mode_sync_flip; /* page flip should block */ 61 | int vblank_secondary; 62 | 63 | drmEventContext evctx; 64 | 65 | int first_post; 66 | struct gralloc_drm_bo_t *current_front, *next_front; 67 | int waiting_flip; 68 | unsigned int last_swap; 69 | }; 70 | 71 | struct gralloc_drm_drv_t { 72 | /* destroy the driver */ 73 | void (*destroy)(struct gralloc_drm_drv_t *drv); 74 | 75 | /* initialize KMS features */ 76 | void (*init_kms_features)(struct gralloc_drm_drv_t *drv, 77 | struct gralloc_drm_t *drm); 78 | 79 | /* allocate or import a bo */ 80 | struct gralloc_drm_bo_t *(*alloc)(struct gralloc_drm_drv_t *drv, 81 | struct gralloc_drm_handle_t *handle); 82 | 83 | /* free a bo */ 84 | void (*free)(struct gralloc_drm_drv_t *drv, 85 | struct gralloc_drm_bo_t *bo); 86 | 87 | /* map a bo for CPU access */ 88 | int (*map)(struct gralloc_drm_drv_t *drv, 89 | struct gralloc_drm_bo_t *bo, 90 | int x, int y, int w, int h, int enable_write, void **addr); 91 | 92 | /* unmap a bo */ 93 | void (*unmap)(struct gralloc_drm_drv_t *drv, 94 | struct gralloc_drm_bo_t *bo); 95 | 96 | /* copy between two bo's, used for DRM_SWAP_COPY */ 97 | void (*copy)(struct gralloc_drm_drv_t *drv, 98 | struct gralloc_drm_bo_t *dst, 99 | struct gralloc_drm_bo_t *src, 100 | short x1, short y1, short x2, short y2); 101 | }; 102 | 103 | struct gralloc_drm_bo_t { 104 | struct gralloc_drm_t *drm; 105 | struct gralloc_drm_handle_t *handle; 106 | 107 | int imported; /* the handle is from a remote proces when true */ 108 | int fb_handle; /* the GEM handle of the bo */ 109 | int fb_id; /* the fb id */ 110 | 111 | int lock_count; 112 | int locked_for; 113 | }; 114 | 115 | struct gralloc_drm_drv_t *gralloc_drm_drv_create_for_pipe(int fd, const char *name); 116 | struct gralloc_drm_drv_t *gralloc_drm_drv_create_for_intel(int fd); 117 | struct gralloc_drm_drv_t *gralloc_drm_drv_create_for_radeon(int fd); 118 | struct gralloc_drm_drv_t *gralloc_drm_drv_create_for_nouveau(int fd); 119 | 120 | #endif /* _GRALLOC_DRM_PRIV_H_ */ 121 | -------------------------------------------------------------------------------- /Android.mk: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010 Chia-I Wu 2 | # Copyright (C) 2010-2011 LunarG 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 12 | # in 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | # DEALINGS IN THE SOFTWARE. 21 | 22 | # Android.mk for drm_gralloc 23 | 24 | DRM_GPU_DRIVERS := $(strip $(filter-out swrast, $(BOARD_GPU_DRIVERS))) 25 | 26 | intel_drivers := i915 i965 i915g 27 | radeon_drivers := r300g r600g 28 | nouveau_drivers := nouveau 29 | vmwgfx_drivers := vmwgfx 30 | 31 | valid_drivers := \ 32 | $(intel_drivers) \ 33 | $(radeon_drivers) \ 34 | $(nouveau_drivers) \ 35 | $(vmwgfx_drivers) 36 | 37 | # warn about invalid drivers 38 | invalid_drivers := $(filter-out $(valid_drivers), $(DRM_GPU_DRIVERS)) 39 | ifneq ($(invalid_drivers),) 40 | $(warning invalid GPU drivers: $(invalid_drivers)) 41 | # tidy up 42 | DRM_GPU_DRIVERS := $(filter-out $(invalid_drivers), $(DRM_GPU_DRIVERS)) 43 | endif 44 | 45 | ifneq ($(filter $(vmwgfx_drivers), $(DRM_GPU_DRIVERS)),) 46 | DRM_USES_PIPE := true 47 | else 48 | DRM_USES_PIPE := false 49 | endif 50 | 51 | ifneq ($(strip $(DRM_GPU_DRIVERS)),) 52 | 53 | LOCAL_PATH := $(call my-dir) 54 | 55 | include $(CLEAR_VARS) 56 | 57 | LOCAL_SRC_FILES := \ 58 | gralloc.c \ 59 | gralloc_drm.c \ 60 | gralloc_drm_kms.c 61 | 62 | LOCAL_C_INCLUDES := \ 63 | external/drm \ 64 | external/drm/include/drm 65 | 66 | LOCAL_SHARED_LIBRARIES := \ 67 | libdrm \ 68 | liblog \ 69 | libcutils \ 70 | 71 | # for glFlush/glFinish 72 | LOCAL_SHARED_LIBRARIES += \ 73 | libGLESv1_CM 74 | 75 | ifneq ($(filter $(intel_drivers), $(DRM_GPU_DRIVERS)),) 76 | LOCAL_SRC_FILES += gralloc_drm_intel.c 77 | LOCAL_C_INCLUDES += external/drm/intel 78 | LOCAL_CFLAGS += -DENABLE_INTEL 79 | LOCAL_SHARED_LIBRARIES += libdrm_intel 80 | endif 81 | 82 | ifneq ($(filter $(radeon_drivers), $(DRM_GPU_DRIVERS)),) 83 | LOCAL_SRC_FILES += gralloc_drm_radeon.c 84 | LOCAL_C_INCLUDES += external/drm/radeon 85 | LOCAL_CFLAGS += -DENABLE_RADEON 86 | LOCAL_SHARED_LIBRARIES += libdrm_radeon 87 | endif 88 | 89 | ifneq ($(filter $(nouveau_drivers), $(DRM_GPU_DRIVERS)),) 90 | LOCAL_SRC_FILES += gralloc_drm_nouveau.c 91 | LOCAL_C_INCLUDES += external/drm/nouveau 92 | LOCAL_CFLAGS += -DENABLE_NOUVEAU 93 | LOCAL_SHARED_LIBRARIES += libdrm_nouveau 94 | endif 95 | 96 | ifeq ($(strip $(DRM_USES_PIPE)),true) 97 | LOCAL_SRC_FILES += gralloc_drm_pipe.c 98 | LOCAL_CFLAGS += -DENABLE_PIPE 99 | LOCAL_C_INCLUDES += \ 100 | external/mesa/src/gallium/include \ 101 | external/mesa/src/gallium/winsys \ 102 | external/mesa/src/gallium/drivers \ 103 | external/mesa/src/gallium/auxiliary 104 | 105 | ifneq ($(filter r600g, $(DRM_GPU_DRIVERS)),) 106 | LOCAL_CFLAGS += -DENABLE_PIPE_R600 107 | LOCAL_STATIC_LIBRARIES += \ 108 | libmesa_pipe_r600 \ 109 | libmesa_winsys_r600 110 | endif 111 | ifneq ($(filter vmwgfx, $(DRM_GPU_DRIVERS)),) 112 | LOCAL_CFLAGS += -DENABLE_PIPE_VMWGFX 113 | LOCAL_STATIC_LIBRARIES += \ 114 | libmesa_pipe_svga \ 115 | libmesa_winsys_svga 116 | LOCAL_C_INCLUDES += \ 117 | external/mesa/src/gallium/drivers/svga/include 118 | endif 119 | 120 | LOCAL_STATIC_LIBRARIES += \ 121 | libmesa_gallium 122 | LOCAL_SHARED_LIBRARIES += libdl 123 | endif # DRM_USES_PIPE 124 | 125 | LOCAL_MODULE := gralloc.$(TARGET_PRODUCT) 126 | LOCAL_MODULE_TAGS := optional 127 | LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw 128 | 129 | include $(BUILD_SHARED_LIBRARY) 130 | 131 | endif # DRM_GPU_DRIVERS 132 | -------------------------------------------------------------------------------- /gralloc_drm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2011 Chia-I Wu 3 | * Copyright (C) 2010-2011 LunarG Inc. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a 6 | * copy of this software and associated documentation files (the "Software"), 7 | * to deal in the Software without restriction, including without limitation 8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 | * and/or sell copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included 13 | * in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 | * DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | #ifndef _GRALLOC_DRM_H_ 25 | #define _GRALLOC_DRM_H_ 26 | 27 | #include 28 | 29 | struct gralloc_drm_t; 30 | struct gralloc_drm_bo_t; 31 | 32 | struct gralloc_drm_t *gralloc_drm_create(void); 33 | void gralloc_drm_destroy(struct gralloc_drm_t *drm); 34 | 35 | int gralloc_drm_get_fd(struct gralloc_drm_t *drm); 36 | int gralloc_drm_get_magic(struct gralloc_drm_t *drm, int32_t *magic); 37 | int gralloc_drm_auth_magic(struct gralloc_drm_t *drm, int32_t magic); 38 | int gralloc_drm_set_master(struct gralloc_drm_t *drm); 39 | void gralloc_drm_drop_master(struct gralloc_drm_t *drm); 40 | 41 | int gralloc_drm_init_kms(struct gralloc_drm_t *drm); 42 | void gralloc_drm_fini_kms(struct gralloc_drm_t *drm); 43 | int gralloc_drm_is_kms_initialized(struct gralloc_drm_t *drm); 44 | 45 | void gralloc_drm_get_kms_info(struct gralloc_drm_t *drm, struct framebuffer_device_t *fb); 46 | int gralloc_drm_is_kms_pipelined(struct gralloc_drm_t *drm); 47 | 48 | static inline int gralloc_drm_get_bpp(int format) 49 | { 50 | int bpp; 51 | 52 | switch (format) { 53 | case HAL_PIXEL_FORMAT_RGBA_8888: 54 | case HAL_PIXEL_FORMAT_RGBX_8888: 55 | case HAL_PIXEL_FORMAT_BGRA_8888: 56 | bpp = 4; 57 | break; 58 | case HAL_PIXEL_FORMAT_RGB_888: 59 | bpp = 3; 60 | break; 61 | case HAL_PIXEL_FORMAT_RGB_565: 62 | case HAL_PIXEL_FORMAT_RGBA_5551: 63 | case HAL_PIXEL_FORMAT_RGBA_4444: 64 | case HAL_PIXEL_FORMAT_YCbCr_422_I: 65 | bpp = 2; 66 | break; 67 | /* planar; only Y is considered */ 68 | case HAL_PIXEL_FORMAT_YV12: 69 | case HAL_PIXEL_FORMAT_YCbCr_422_SP: 70 | case HAL_PIXEL_FORMAT_YCrCb_420_SP: 71 | bpp = 1; 72 | break; 73 | default: 74 | bpp = 0; 75 | break; 76 | } 77 | 78 | return bpp; 79 | } 80 | 81 | static inline void gralloc_drm_align_geometry(int format, int *width, int *height) 82 | { 83 | int align_w = 1, align_h = 1, extra_height_div = 0; 84 | 85 | switch (format) { 86 | case HAL_PIXEL_FORMAT_YV12: 87 | align_w = 32; 88 | align_h = 2; 89 | extra_height_div = 2; 90 | break; 91 | case HAL_PIXEL_FORMAT_YCbCr_422_SP: 92 | align_w = 2; 93 | extra_height_div = 1; 94 | break; 95 | case HAL_PIXEL_FORMAT_YCrCb_420_SP: 96 | align_w = 2; 97 | align_h = 2; 98 | extra_height_div = 2; 99 | break; 100 | case HAL_PIXEL_FORMAT_YCbCr_422_I: 101 | align_w = 2; 102 | break; 103 | } 104 | 105 | *width = (*width + align_w - 1) & ~(align_w - 1); 106 | *height = (*height + align_h - 1) & ~(align_h - 1); 107 | 108 | if (extra_height_div) 109 | *height += *height / extra_height_div; 110 | } 111 | 112 | int gralloc_drm_handle_register(buffer_handle_t handle, struct gralloc_drm_t *drm); 113 | int gralloc_drm_handle_unregister(buffer_handle_t handle); 114 | 115 | struct gralloc_drm_bo_t *gralloc_drm_bo_create(struct gralloc_drm_t *drm, int width, int height, int format, int usage); 116 | void gralloc_drm_bo_destroy(struct gralloc_drm_bo_t *bo); 117 | 118 | struct gralloc_drm_bo_t *gralloc_drm_bo_from_handle(buffer_handle_t handle); 119 | buffer_handle_t gralloc_drm_bo_get_handle(struct gralloc_drm_bo_t *bo, int *stride); 120 | 121 | int gralloc_drm_bo_lock(struct gralloc_drm_bo_t *bo, int x, int y, int w, int h, int enable_write, void **addr); 122 | void gralloc_drm_bo_unlock(struct gralloc_drm_bo_t *bo); 123 | 124 | int gralloc_drm_bo_need_fb(const struct gralloc_drm_bo_t *bo); 125 | int gralloc_drm_bo_add_fb(struct gralloc_drm_bo_t *bo); 126 | void gralloc_drm_bo_rm_fb(struct gralloc_drm_bo_t *bo); 127 | int gralloc_drm_bo_post(struct gralloc_drm_bo_t *bo); 128 | 129 | #endif /* _GRALLOC_DRM_H_ */ 130 | -------------------------------------------------------------------------------- /dri/intel_chipset.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2007 Intel Corporation 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 (including the next 12 | * paragraph) shall be included in all copies or substantial portions of the 13 | * Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | * IN THE SOFTWARE. 22 | * 23 | * Authors: 24 | * Eric Anholt 25 | * 26 | */ 27 | 28 | #define PCI_CHIP_I810 0x7121 29 | #define PCI_CHIP_I810_DC100 0x7123 30 | #define PCI_CHIP_I810_E 0x7125 31 | #define PCI_CHIP_I815 0x1132 32 | 33 | #define PCI_CHIP_I830_M 0x3577 34 | #define PCI_CHIP_845_G 0x2562 35 | #define PCI_CHIP_I855_GM 0x3582 36 | #define PCI_CHIP_I865_G 0x2572 37 | 38 | #define PCI_CHIP_I915_G 0x2582 39 | #define PCI_CHIP_E7221_G 0x258A 40 | #define PCI_CHIP_I915_GM 0x2592 41 | #define PCI_CHIP_I945_G 0x2772 42 | #define PCI_CHIP_I945_GM 0x27A2 43 | #define PCI_CHIP_I945_GME 0x27AE 44 | 45 | #define PCI_CHIP_Q35_G 0x29B2 46 | #define PCI_CHIP_G33_G 0x29C2 47 | #define PCI_CHIP_Q33_G 0x29D2 48 | 49 | #define PCI_CHIP_IGD_GM 0xA011 50 | #define PCI_CHIP_IGD_G 0xA001 51 | 52 | #define IS_IGDGM(devid) (devid == PCI_CHIP_IGD_GM) 53 | #define IS_IGDG(devid) (devid == PCI_CHIP_IGD_G) 54 | #define IS_IGD(devid) (IS_IGDG(devid) || IS_IGDGM(devid)) 55 | 56 | #define PCI_CHIP_I965_G 0x29A2 57 | #define PCI_CHIP_I965_Q 0x2992 58 | #define PCI_CHIP_I965_G_1 0x2982 59 | #define PCI_CHIP_I946_GZ 0x2972 60 | #define PCI_CHIP_I965_GM 0x2A02 61 | #define PCI_CHIP_I965_GME 0x2A12 62 | 63 | #define PCI_CHIP_GM45_GM 0x2A42 64 | 65 | #define PCI_CHIP_IGD_E_G 0x2E02 66 | #define PCI_CHIP_Q45_G 0x2E12 67 | #define PCI_CHIP_G45_G 0x2E22 68 | #define PCI_CHIP_G41_G 0x2E32 69 | #define PCI_CHIP_B43_G 0x2E42 70 | #define PCI_CHIP_B43_G1 0x2E92 71 | 72 | #define PCI_CHIP_ILD_G 0x0042 73 | #define PCI_CHIP_ILM_G 0x0046 74 | 75 | #define PCI_CHIP_SANDYBRIDGE_GT1 0x0102 /* Desktop */ 76 | #define PCI_CHIP_SANDYBRIDGE_GT2 0x0112 77 | #define PCI_CHIP_SANDYBRIDGE_GT2_PLUS 0x0122 78 | #define PCI_CHIP_SANDYBRIDGE_M_GT1 0x0106 /* Mobile */ 79 | #define PCI_CHIP_SANDYBRIDGE_M_GT2 0x0116 80 | #define PCI_CHIP_SANDYBRIDGE_M_GT2_PLUS 0x0126 81 | #define PCI_CHIP_SANDYBRIDGE_S 0x010A /* Server */ 82 | 83 | #define PCI_CHIP_IVYBRIDGE_GT1 0x0152 /* Desktop */ 84 | #define PCI_CHIP_IVYBRIDGE_GT2 0x0162 85 | #define PCI_CHIP_IVYBRIDGE_M_GT1 0x0156 /* Mobile */ 86 | #define PCI_CHIP_IVYBRIDGE_M_GT2 0x0166 87 | #define PCI_CHIP_IVYBRIDGE_S_GT1 0x015a /* Server */ 88 | 89 | #define IS_MOBILE(devid) (devid == PCI_CHIP_I855_GM || \ 90 | devid == PCI_CHIP_I915_GM || \ 91 | devid == PCI_CHIP_I945_GM || \ 92 | devid == PCI_CHIP_I945_GME || \ 93 | devid == PCI_CHIP_I965_GM || \ 94 | devid == PCI_CHIP_I965_GME || \ 95 | devid == PCI_CHIP_GM45_GM || \ 96 | IS_IGD(devid) || \ 97 | devid == PCI_CHIP_ILM_G) 98 | 99 | #define IS_G45(devid) (devid == PCI_CHIP_IGD_E_G || \ 100 | devid == PCI_CHIP_Q45_G || \ 101 | devid == PCI_CHIP_G45_G || \ 102 | devid == PCI_CHIP_G41_G || \ 103 | devid == PCI_CHIP_B43_G || \ 104 | devid == PCI_CHIP_B43_G1) 105 | #define IS_GM45(devid) (devid == PCI_CHIP_GM45_GM) 106 | #define IS_G4X(devid) (IS_G45(devid) || IS_GM45(devid)) 107 | 108 | #define IS_ILD(devid) (devid == PCI_CHIP_ILD_G) 109 | #define IS_ILM(devid) (devid == PCI_CHIP_ILM_G) 110 | #define IS_GEN5(devid) (IS_ILD(devid) || IS_ILM(devid)) 111 | 112 | #define IS_915(devid) (devid == PCI_CHIP_I915_G || \ 113 | devid == PCI_CHIP_E7221_G || \ 114 | devid == PCI_CHIP_I915_GM) 115 | 116 | #define IS_945(devid) (devid == PCI_CHIP_I945_G || \ 117 | devid == PCI_CHIP_I945_GM || \ 118 | devid == PCI_CHIP_I945_GME || \ 119 | devid == PCI_CHIP_G33_G || \ 120 | devid == PCI_CHIP_Q33_G || \ 121 | devid == PCI_CHIP_Q35_G || IS_IGD(devid)) 122 | 123 | #define IS_GEN4(devid) (devid == PCI_CHIP_I965_G || \ 124 | devid == PCI_CHIP_I965_Q || \ 125 | devid == PCI_CHIP_I965_G_1 || \ 126 | devid == PCI_CHIP_I965_GM || \ 127 | devid == PCI_CHIP_I965_GME || \ 128 | devid == PCI_CHIP_I946_GZ || \ 129 | IS_G4X(devid)) 130 | 131 | /* Compat macro for intel_decode.c */ 132 | #define IS_IRONLAKE(devid) IS_GEN5(devid) 133 | 134 | #define IS_SNB_GT1(devid) (devid == PCI_CHIP_SANDYBRIDGE_GT1 || \ 135 | devid == PCI_CHIP_SANDYBRIDGE_M_GT1 || \ 136 | devid == PCI_CHIP_SANDYBRIDGE_S) 137 | 138 | #define IS_SNB_GT2(devid) (devid == PCI_CHIP_SANDYBRIDGE_GT2 || \ 139 | devid == PCI_CHIP_SANDYBRIDGE_GT2_PLUS || \ 140 | devid == PCI_CHIP_SANDYBRIDGE_M_GT2 || \ 141 | devid == PCI_CHIP_SANDYBRIDGE_M_GT2_PLUS) 142 | 143 | #define IS_GEN6(devid) (IS_SNB_GT1(devid) || IS_SNB_GT2(devid)) 144 | 145 | #define IS_IVB_GT1(devid) (devid == PCI_CHIP_IVYBRIDGE_GT1 || \ 146 | devid == PCI_CHIP_IVYBRIDGE_M_GT1 || \ 147 | devid == PCI_CHIP_IVYBRIDGE_S_GT1) 148 | 149 | #define IS_IVB_GT2(devid) (devid == PCI_CHIP_IVYBRIDGE_GT2 || \ 150 | devid == PCI_CHIP_IVYBRIDGE_M_GT2) 151 | 152 | #define IS_IVYBRIDGE(devid) (IS_IVB_GT1(devid) || IS_IVB_GT2(devid)) 153 | 154 | #define IS_GEN7(devid) IS_IVYBRIDGE(devid) 155 | 156 | #define IS_965(devid) (IS_GEN4(devid) || \ 157 | IS_G4X(devid) || \ 158 | IS_GEN5(devid) || \ 159 | IS_GEN6(devid) || \ 160 | IS_GEN7(devid)) 161 | 162 | #define IS_9XX(devid) (IS_915(devid) || \ 163 | IS_945(devid) || \ 164 | IS_965(devid)) 165 | 166 | #define IS_GEN3(devid) (IS_915(devid) || \ 167 | IS_945(devid)) 168 | 169 | #define IS_GEN2(devid) (devid == PCI_CHIP_I830_M || \ 170 | devid == PCI_CHIP_845_G || \ 171 | devid == PCI_CHIP_I855_GM || \ 172 | devid == PCI_CHIP_I865_G) 173 | -------------------------------------------------------------------------------- /pci_ids/r300_pci_ids.h: -------------------------------------------------------------------------------- 1 | CHIPSET(0x4144, R300_AD, R300) 2 | CHIPSET(0x4145, R300_AE, R300) 3 | CHIPSET(0x4146, R300_AF, R300) 4 | CHIPSET(0x4147, R300_AG, R300) 5 | CHIPSET(0x4E44, R300_ND, R300) 6 | CHIPSET(0x4E45, R300_NE, R300) 7 | CHIPSET(0x4E46, R300_NF, R300) 8 | CHIPSET(0x4E47, R300_NG, R300) 9 | 10 | CHIPSET(0x4E48, R350_NH, R350) 11 | CHIPSET(0x4E49, R350_NI, R350) 12 | CHIPSET(0x4E4B, R350_NK, R350) 13 | CHIPSET(0x4148, R350_AH, R350) 14 | CHIPSET(0x4149, R350_AI, R350) 15 | CHIPSET(0x414A, R350_AJ, R350) 16 | CHIPSET(0x414B, R350_AK, R350) 17 | CHIPSET(0x4E4A, R360_NJ, R350) 18 | 19 | CHIPSET(0x4150, RV350_AP, RV350) 20 | CHIPSET(0x4151, RV350_AQ, RV350) 21 | CHIPSET(0x4152, RV350_AR, RV350) 22 | CHIPSET(0x4153, RV350_AS, RV350) 23 | CHIPSET(0x4154, RV350_AT, RV350) 24 | CHIPSET(0x4155, RV350_AU, RV350) 25 | CHIPSET(0x4156, RV350_AV, RV350) 26 | CHIPSET(0x4E50, RV350_NP, RV350) 27 | CHIPSET(0x4E51, RV350_NQ, RV350) 28 | CHIPSET(0x4E52, RV350_NR, RV350) 29 | CHIPSET(0x4E53, RV350_NS, RV350) 30 | CHIPSET(0x4E54, RV350_NT, RV350) 31 | CHIPSET(0x4E56, RV350_NV, RV350) 32 | 33 | CHIPSET(0x5460, RV370_5460, RV370) 34 | CHIPSET(0x5462, RV370_5462, RV370) 35 | CHIPSET(0x5464, RV370_5464, RV370) 36 | CHIPSET(0x5B60, RV370_5B60, RV370) 37 | CHIPSET(0x5B62, RV370_5B62, RV370) 38 | CHIPSET(0x5B63, RV370_5B63, RV370) 39 | CHIPSET(0x5B64, RV370_5B64, RV370) 40 | CHIPSET(0x5B65, RV370_5B65, RV370) 41 | 42 | CHIPSET(0x3150, RV380_3150, RV380) 43 | CHIPSET(0x3152, RV380_3152, RV380) 44 | CHIPSET(0x3154, RV380_3154, RV380) 45 | CHIPSET(0x3155, RV380_3155, RV380) 46 | CHIPSET(0x3E50, RV380_3E50, RV380) 47 | CHIPSET(0x3E54, RV380_3E54, RV380) 48 | 49 | CHIPSET(0x4A48, R420_JH, R420) 50 | CHIPSET(0x4A49, R420_JI, R420) 51 | CHIPSET(0x4A4A, R420_JJ, R420) 52 | CHIPSET(0x4A4B, R420_JK, R420) 53 | CHIPSET(0x4A4C, R420_JL, R420) 54 | CHIPSET(0x4A4D, R420_JM, R420) 55 | CHIPSET(0x4A4E, R420_JN, R420) 56 | CHIPSET(0x4A4F, R420_JO, R420) 57 | CHIPSET(0x4A50, R420_JP, R420) 58 | CHIPSET(0x4A54, R420_JT, R420) 59 | 60 | CHIPSET(0x5548, R423_UH, R423) 61 | CHIPSET(0x5549, R423_UI, R423) 62 | CHIPSET(0x554A, R423_UJ, R423) 63 | CHIPSET(0x554B, R423_UK, R423) 64 | CHIPSET(0x5550, R423_5550, R423) 65 | CHIPSET(0x5551, R423_UQ, R423) 66 | CHIPSET(0x5552, R423_UR, R423) 67 | CHIPSET(0x5554, R423_UT, R423) 68 | CHIPSET(0x5D57, R423_5D57, R423) 69 | 70 | CHIPSET(0x554C, R430_554C, R430) 71 | CHIPSET(0x554D, R430_554D, R430) 72 | CHIPSET(0x554E, R430_554E, R430) 73 | CHIPSET(0x554F, R430_554F, R430) 74 | CHIPSET(0x5D48, R430_5D48, R430) 75 | CHIPSET(0x5D49, R430_5D49, R430) 76 | CHIPSET(0x5D4A, R430_5D4A, R430) 77 | 78 | CHIPSET(0x5D4C, R480_5D4C, R480) 79 | CHIPSET(0x5D4D, R480_5D4D, R480) 80 | CHIPSET(0x5D4E, R480_5D4E, R480) 81 | CHIPSET(0x5D4F, R480_5D4F, R480) 82 | CHIPSET(0x5D50, R480_5D50, R480) 83 | CHIPSET(0x5D52, R480_5D52, R480) 84 | 85 | CHIPSET(0x4B48, R481_4B48, R481) 86 | CHIPSET(0x4B49, R481_4B49, R481) 87 | CHIPSET(0x4B4A, R481_4B4A, R481) 88 | CHIPSET(0x4B4B, R481_4B4B, R481) 89 | CHIPSET(0x4B4C, R481_4B4C, R481) 90 | 91 | CHIPSET(0x564A, RV410_564A, RV410) 92 | CHIPSET(0x564B, RV410_564B, RV410) 93 | CHIPSET(0x564F, RV410_564F, RV410) 94 | CHIPSET(0x5652, RV410_5652, RV410) 95 | CHIPSET(0x5653, RV410_5653, RV410) 96 | CHIPSET(0x5657, RV410_5657, RV410) 97 | CHIPSET(0x5E48, RV410_5E48, RV410) 98 | CHIPSET(0x5E4A, RV410_5E4A, RV410) 99 | CHIPSET(0x5E4B, RV410_5E4B, RV410) 100 | CHIPSET(0x5E4C, RV410_5E4C, RV410) 101 | CHIPSET(0x5E4D, RV410_5E4D, RV410) 102 | CHIPSET(0x5E4F, RV410_5E4F, RV410) 103 | 104 | CHIPSET(0x5A41, RS400_5A41, RS400) 105 | CHIPSET(0x5A42, RS400_5A42, RS400) 106 | 107 | CHIPSET(0x5A61, RC410_5A61, RC410) 108 | CHIPSET(0x5A62, RC410_5A62, RC410) 109 | 110 | CHIPSET(0x5954, RS480_5954, RS480) 111 | CHIPSET(0x5955, RS480_5955, RS480) 112 | CHIPSET(0x5974, RS482_5974, RS480) 113 | CHIPSET(0x5975, RS482_5975, RS480) 114 | 115 | CHIPSET(0x7100, R520_7100, R520) 116 | CHIPSET(0x7101, R520_7101, R520) 117 | CHIPSET(0x7102, R520_7102, R520) 118 | CHIPSET(0x7103, R520_7103, R520) 119 | CHIPSET(0x7104, R520_7104, R520) 120 | CHIPSET(0x7105, R520_7105, R520) 121 | CHIPSET(0x7106, R520_7106, R520) 122 | CHIPSET(0x7108, R520_7108, R520) 123 | CHIPSET(0x7109, R520_7109, R520) 124 | CHIPSET(0x710A, R520_710A, R520) 125 | CHIPSET(0x710B, R520_710B, R520) 126 | CHIPSET(0x710C, R520_710C, R520) 127 | CHIPSET(0x710E, R520_710E, R520) 128 | CHIPSET(0x710F, R520_710F, R520) 129 | 130 | CHIPSET(0x7140, RV515_7140, RV515) 131 | CHIPSET(0x7141, RV515_7141, RV515) 132 | CHIPSET(0x7142, RV515_7142, RV515) 133 | CHIPSET(0x7143, RV515_7143, RV515) 134 | CHIPSET(0x7144, RV515_7144, RV515) 135 | CHIPSET(0x7145, RV515_7145, RV515) 136 | CHIPSET(0x7146, RV515_7146, RV515) 137 | CHIPSET(0x7147, RV515_7147, RV515) 138 | CHIPSET(0x7149, RV515_7149, RV515) 139 | CHIPSET(0x714A, RV515_714A, RV515) 140 | CHIPSET(0x714B, RV515_714B, RV515) 141 | CHIPSET(0x714C, RV515_714C, RV515) 142 | CHIPSET(0x714D, RV515_714D, RV515) 143 | CHIPSET(0x714E, RV515_714E, RV515) 144 | CHIPSET(0x714F, RV515_714F, RV515) 145 | CHIPSET(0x7151, RV515_7151, RV515) 146 | CHIPSET(0x7152, RV515_7152, RV515) 147 | CHIPSET(0x7153, RV515_7153, RV515) 148 | CHIPSET(0x715E, RV515_715E, RV515) 149 | CHIPSET(0x715F, RV515_715F, RV515) 150 | CHIPSET(0x7180, RV515_7180, RV515) 151 | CHIPSET(0x7181, RV515_7181, RV515) 152 | CHIPSET(0x7183, RV515_7183, RV515) 153 | CHIPSET(0x7186, RV515_7186, RV515) 154 | CHIPSET(0x7187, RV515_7187, RV515) 155 | CHIPSET(0x7188, RV515_7188, RV515) 156 | CHIPSET(0x718A, RV515_718A, RV515) 157 | CHIPSET(0x718B, RV515_718B, RV515) 158 | CHIPSET(0x718C, RV515_718C, RV515) 159 | CHIPSET(0x718D, RV515_718D, RV515) 160 | CHIPSET(0x718F, RV515_718F, RV515) 161 | CHIPSET(0x7193, RV515_7193, RV515) 162 | CHIPSET(0x7196, RV515_7196, RV515) 163 | CHIPSET(0x719B, RV515_719B, RV515) 164 | CHIPSET(0x719F, RV515_719F, RV515) 165 | CHIPSET(0x7200, RV515_7200, RV515) 166 | CHIPSET(0x7210, RV515_7210, RV515) 167 | CHIPSET(0x7211, RV515_7211, RV515) 168 | 169 | CHIPSET(0x71C0, RV530_71C0, RV530) 170 | CHIPSET(0x71C1, RV530_71C1, RV530) 171 | CHIPSET(0x71C2, RV530_71C2, RV530) 172 | CHIPSET(0x71C3, RV530_71C3, RV530) 173 | CHIPSET(0x71C4, RV530_71C4, RV530) 174 | CHIPSET(0x71C5, RV530_71C5, RV530) 175 | CHIPSET(0x71C6, RV530_71C6, RV530) 176 | CHIPSET(0x71C7, RV530_71C7, RV530) 177 | CHIPSET(0x71CD, RV530_71CD, RV530) 178 | CHIPSET(0x71CE, RV530_71CE, RV530) 179 | CHIPSET(0x71D2, RV530_71D2, RV530) 180 | CHIPSET(0x71D4, RV530_71D4, RV530) 181 | CHIPSET(0x71D5, RV530_71D5, RV530) 182 | CHIPSET(0x71D6, RV530_71D6, RV530) 183 | CHIPSET(0x71DA, RV530_71DA, RV530) 184 | CHIPSET(0x71DE, RV530_71DE, RV530) 185 | 186 | CHIPSET(0x7281, RV560_7281, RV560) 187 | CHIPSET(0x7283, RV560_7283, RV560) 188 | CHIPSET(0x7287, RV560_7287, RV560) 189 | CHIPSET(0x7290, RV560_7290, RV560) 190 | CHIPSET(0x7291, RV560_7291, RV560) 191 | CHIPSET(0x7293, RV560_7293, RV560) 192 | CHIPSET(0x7297, RV560_7297, RV560) 193 | 194 | CHIPSET(0x7280, RV570_7280, RV570) 195 | CHIPSET(0x7288, RV570_7288, RV570) 196 | CHIPSET(0x7289, RV570_7289, RV570) 197 | CHIPSET(0x728B, RV570_728B, RV570) 198 | CHIPSET(0x728C, RV570_728C, RV570) 199 | 200 | CHIPSET(0x7240, R580_7240, R580) 201 | CHIPSET(0x7243, R580_7243, R580) 202 | CHIPSET(0x7244, R580_7244, R580) 203 | CHIPSET(0x7245, R580_7245, R580) 204 | CHIPSET(0x7246, R580_7246, R580) 205 | CHIPSET(0x7247, R580_7247, R580) 206 | CHIPSET(0x7248, R580_7248, R580) 207 | CHIPSET(0x7249, R580_7249, R580) 208 | CHIPSET(0x724A, R580_724A, R580) 209 | CHIPSET(0x724B, R580_724B, R580) 210 | CHIPSET(0x724C, R580_724C, R580) 211 | CHIPSET(0x724D, R580_724D, R580) 212 | CHIPSET(0x724E, R580_724E, R580) 213 | CHIPSET(0x724F, R580_724F, R580) 214 | CHIPSET(0x7284, R580_7284, R580) 215 | 216 | CHIPSET(0x793F, RS600_793F, RS600) 217 | CHIPSET(0x7941, RS600_7941, RS600) 218 | CHIPSET(0x7942, RS600_7942, RS600) 219 | 220 | CHIPSET(0x791E, RS690_791E, RS690) 221 | CHIPSET(0x791F, RS690_791F, RS690) 222 | 223 | CHIPSET(0x796C, RS740_796C, RS740) 224 | CHIPSET(0x796D, RS740_796D, RS740) 225 | CHIPSET(0x796E, RS740_796E, RS740) 226 | CHIPSET(0x796F, RS740_796F, RS740) 227 | -------------------------------------------------------------------------------- /pci_ids/r600_pci_ids.h: -------------------------------------------------------------------------------- 1 | CHIPSET(0x9400, R600_9400, R600) 2 | CHIPSET(0x9401, R600_9401, R600) 3 | CHIPSET(0x9402, R600_9402, R600) 4 | CHIPSET(0x9403, R600_9403, R600) 5 | CHIPSET(0x9405, R600_9405, R600) 6 | CHIPSET(0x940A, R600_940A, R600) 7 | CHIPSET(0x940B, R600_940B, R600) 8 | CHIPSET(0x940F, R600_940F, R600) 9 | 10 | CHIPSET(0x94C0, RV610_94C0, RV610) 11 | CHIPSET(0x94C1, RV610_94C1, RV610) 12 | CHIPSET(0x94C3, RV610_94C3, RV610) 13 | CHIPSET(0x94C4, RV610_94C4, RV610) 14 | CHIPSET(0x94C5, RV610_94C5, RV610) 15 | CHIPSET(0x94C6, RV610_94C6, RV610) 16 | CHIPSET(0x94C7, RV610_94C7, RV610) 17 | CHIPSET(0x94C8, RV610_94C8, RV610) 18 | CHIPSET(0x94C9, RV610_94C9, RV610) 19 | CHIPSET(0x94CB, RV610_94CB, RV610) 20 | CHIPSET(0x94CC, RV610_94CC, RV610) 21 | CHIPSET(0x94CD, RV610_94CD, RV610) 22 | 23 | CHIPSET(0x9580, RV630_9580, RV630) 24 | CHIPSET(0x9581, RV630_9581, RV630) 25 | CHIPSET(0x9583, RV630_9583, RV630) 26 | CHIPSET(0x9586, RV630_9586, RV630) 27 | CHIPSET(0x9587, RV630_9587, RV630) 28 | CHIPSET(0x9588, RV630_9588, RV630) 29 | CHIPSET(0x9589, RV630_9589, RV630) 30 | CHIPSET(0x958A, RV630_958A, RV630) 31 | CHIPSET(0x958B, RV630_958B, RV630) 32 | CHIPSET(0x958C, RV630_958C, RV630) 33 | CHIPSET(0x958D, RV630_958D, RV630) 34 | CHIPSET(0x958E, RV630_958E, RV630) 35 | CHIPSET(0x958F, RV630_958F, RV630) 36 | 37 | CHIPSET(0x9500, RV670_9500, RV670) 38 | CHIPSET(0x9501, RV670_9501, RV670) 39 | CHIPSET(0x9504, RV670_9504, RV670) 40 | CHIPSET(0x9505, RV670_9505, RV670) 41 | CHIPSET(0x9506, RV670_9506, RV670) 42 | CHIPSET(0x9507, RV670_9507, RV670) 43 | CHIPSET(0x9508, RV670_9508, RV670) 44 | CHIPSET(0x9509, RV670_9509, RV670) 45 | CHIPSET(0x950F, RV670_950F, RV670) 46 | CHIPSET(0x9511, RV670_9511, RV670) 47 | CHIPSET(0x9515, RV670_9515, RV670) 48 | CHIPSET(0x9517, RV670_9517, RV670) 49 | CHIPSET(0x9519, RV670_9519, RV670) 50 | 51 | CHIPSET(0x95C0, RV620_95C0, RV620) 52 | CHIPSET(0x95C2, RV620_95C2, RV620) 53 | CHIPSET(0x95C4, RV620_95C4, RV620) 54 | CHIPSET(0x95C5, RV620_95C5, RV620) 55 | CHIPSET(0x95C6, RV620_95C6, RV620) 56 | CHIPSET(0x95C7, RV620_95C7, RV620) 57 | CHIPSET(0x95C9, RV620_95C9, RV620) 58 | CHIPSET(0x95CC, RV620_95CC, RV620) 59 | CHIPSET(0x95CD, RV620_95CD, RV620) 60 | CHIPSET(0x95CE, RV620_95CE, RV620) 61 | CHIPSET(0x95CF, RV620_95CF, RV620) 62 | 63 | CHIPSET(0x9590, RV635_9590, RV635) 64 | CHIPSET(0x9591, RV635_9591, RV635) 65 | CHIPSET(0x9593, RV635_9593, RV635) 66 | CHIPSET(0x9595, RV635_9595, RV635) 67 | CHIPSET(0x9596, RV635_9596, RV635) 68 | CHIPSET(0x9597, RV635_9597, RV635) 69 | CHIPSET(0x9598, RV635_9598, RV635) 70 | CHIPSET(0x9599, RV635_9599, RV635) 71 | CHIPSET(0x959B, RV635_959B, RV635) 72 | 73 | CHIPSET(0x9610, RS780_9610, RS780) 74 | CHIPSET(0x9611, RS780_9611, RS780) 75 | CHIPSET(0x9612, RS780_9612, RS780) 76 | CHIPSET(0x9613, RS780_9613, RS780) 77 | CHIPSET(0x9614, RS780_9614, RS780) 78 | CHIPSET(0x9615, RS780_9615, RS780) 79 | CHIPSET(0x9616, RS780_9616, RS780) 80 | 81 | CHIPSET(0x9710, RS880_9710, RS880) 82 | CHIPSET(0x9711, RS880_9711, RS880) 83 | CHIPSET(0x9712, RS880_9712, RS880) 84 | CHIPSET(0x9713, RS880_9713, RS880) 85 | CHIPSET(0x9714, RS880_9714, RS880) 86 | CHIPSET(0x9715, RS880_9715, RS880) 87 | 88 | CHIPSET(0x9440, RV770_9440, RV770) 89 | CHIPSET(0x9441, RV770_9441, RV770) 90 | CHIPSET(0x9442, RV770_9442, RV770) 91 | CHIPSET(0x9443, RV770_9443, RV770) 92 | CHIPSET(0x9444, RV770_9444, RV770) 93 | CHIPSET(0x9446, RV770_9446, RV770) 94 | CHIPSET(0x944A, RV770_944A, RV770) 95 | CHIPSET(0x944B, RV770_944B, RV770) 96 | CHIPSET(0x944C, RV770_944C, RV770) 97 | CHIPSET(0x944E, RV770_944E, RV770) 98 | CHIPSET(0x9450, RV770_9450, RV770) 99 | CHIPSET(0x9452, RV770_9452, RV770) 100 | CHIPSET(0x9456, RV770_9456, RV770) 101 | CHIPSET(0x945A, RV770_945A, RV770) 102 | CHIPSET(0x945B, RV770_945B, RV770) 103 | CHIPSET(0x945E, RV770_945E, RV770) 104 | CHIPSET(0x9460, RV790_9460, RV770) 105 | CHIPSET(0x9462, RV790_9462, RV770) 106 | CHIPSET(0x946A, RV770_946A, RV770) 107 | CHIPSET(0x946B, RV770_946B, RV770) 108 | CHIPSET(0x947A, RV770_947A, RV770) 109 | CHIPSET(0x947B, RV770_947B, RV770) 110 | 111 | CHIPSET(0x9480, RV730_9480, RV730) 112 | CHIPSET(0x9487, RV730_9487, RV730) 113 | CHIPSET(0x9488, RV730_9488, RV730) 114 | CHIPSET(0x9489, RV730_9489, RV730) 115 | CHIPSET(0x948A, RV730_948A, RV730) 116 | CHIPSET(0x948F, RV730_948F, RV730) 117 | CHIPSET(0x9490, RV730_9490, RV730) 118 | CHIPSET(0x9491, RV730_9491, RV730) 119 | CHIPSET(0x9495, RV730_9495, RV730) 120 | CHIPSET(0x9498, RV730_9498, RV730) 121 | CHIPSET(0x949C, RV730_949C, RV730) 122 | CHIPSET(0x949E, RV730_949E, RV730) 123 | CHIPSET(0x949F, RV730_949F, RV730) 124 | 125 | CHIPSET(0x9540, RV710_9540, RV710) 126 | CHIPSET(0x9541, RV710_9541, RV710) 127 | CHIPSET(0x9542, RV710_9542, RV710) 128 | CHIPSET(0x954E, RV710_954E, RV710) 129 | CHIPSET(0x954F, RV710_954F, RV710) 130 | CHIPSET(0x9552, RV710_9552, RV710) 131 | CHIPSET(0x9553, RV710_9553, RV710) 132 | CHIPSET(0x9555, RV710_9555, RV710) 133 | CHIPSET(0x9557, RV710_9557, RV710) 134 | CHIPSET(0x955F, RV710_955F, RV710) 135 | 136 | CHIPSET(0x94A0, RV740_94A0, RV740) 137 | CHIPSET(0x94A1, RV740_94A1, RV740) 138 | CHIPSET(0x94A3, RV740_94A3, RV740) 139 | CHIPSET(0x94B1, RV740_94B1, RV740) 140 | CHIPSET(0x94B3, RV740_94B3, RV740) 141 | CHIPSET(0x94B4, RV740_94B4, RV740) 142 | CHIPSET(0x94B5, RV740_94B5, RV740) 143 | CHIPSET(0x94B9, RV740_94B9, RV740) 144 | 145 | CHIPSET(0x68E0, CEDAR_68E0, CEDAR) 146 | CHIPSET(0x68E1, CEDAR_68E1, CEDAR) 147 | CHIPSET(0x68E4, CEDAR_68E4, CEDAR) 148 | CHIPSET(0x68E5, CEDAR_68E5, CEDAR) 149 | CHIPSET(0x68E8, CEDAR_68E8, CEDAR) 150 | CHIPSET(0x68E9, CEDAR_68E9, CEDAR) 151 | CHIPSET(0x68F1, CEDAR_68F1, CEDAR) 152 | CHIPSET(0x68F2, CEDAR_68F2, CEDAR) 153 | CHIPSET(0x68F8, CEDAR_68F8, CEDAR) 154 | CHIPSET(0x68F9, CEDAR_68F9, CEDAR) 155 | CHIPSET(0x68FE, CEDAR_68FE, CEDAR) 156 | 157 | CHIPSET(0x68C0, REDWOOD_68C0, REDWOOD) 158 | CHIPSET(0x68C1, REDWOOD_68C1, REDWOOD) 159 | CHIPSET(0x68C8, REDWOOD_68C8, REDWOOD) 160 | CHIPSET(0x68C9, REDWOOD_68C9, REDWOOD) 161 | CHIPSET(0x68D8, REDWOOD_68D8, REDWOOD) 162 | CHIPSET(0x68D9, REDWOOD_68D9, REDWOOD) 163 | CHIPSET(0x68DA, REDWOOD_68DA, REDWOOD) 164 | CHIPSET(0x68DE, REDWOOD_68DE, REDWOOD) 165 | 166 | CHIPSET(0x68A0, JUNIPER_68A0, JUNIPER) 167 | CHIPSET(0x68A1, JUNIPER_68A1, JUNIPER) 168 | CHIPSET(0x68A8, JUNIPER_68A8, JUNIPER) 169 | CHIPSET(0x68A9, JUNIPER_68A9, JUNIPER) 170 | CHIPSET(0x68B0, JUNIPER_68B0, JUNIPER) 171 | CHIPSET(0x68B8, JUNIPER_68B8, JUNIPER) 172 | CHIPSET(0x68B9, JUNIPER_68B9, JUNIPER) 173 | CHIPSET(0x68BA, JUNIPER_68BA, JUNIPER) 174 | CHIPSET(0x68BE, JUNIPER_68BE, JUNIPER) 175 | CHIPSET(0x68BF, JUNIPER_68BF, JUNIPER) 176 | 177 | CHIPSET(0x6880, CYPRESS_6880, CYPRESS) 178 | CHIPSET(0x6888, CYPRESS_6888, CYPRESS) 179 | CHIPSET(0x6889, CYPRESS_6889, CYPRESS) 180 | CHIPSET(0x688A, CYPRESS_688A, CYPRESS) 181 | CHIPSET(0x6898, CYPRESS_6898, CYPRESS) 182 | CHIPSET(0x6899, CYPRESS_6899, CYPRESS) 183 | CHIPSET(0x689B, CYPRESS_689B, CYPRESS) 184 | CHIPSET(0x689E, CYPRESS_689E, CYPRESS) 185 | 186 | CHIPSET(0x689C, HEMLOCK_689C, HEMLOCK) 187 | CHIPSET(0x689D, HEMLOCK_689D, HEMLOCK) 188 | 189 | CHIPSET(0x9802, PALM_9802, PALM) 190 | CHIPSET(0x9803, PALM_9803, PALM) 191 | CHIPSET(0x9804, PALM_9804, PALM) 192 | CHIPSET(0x9805, PALM_9805, PALM) 193 | CHIPSET(0x9806, PALM_9806, PALM) 194 | CHIPSET(0x9807, PALM_9807, PALM) 195 | 196 | CHIPSET(0x9640, SUMO_9640, SUMO) 197 | CHIPSET(0x9641, SUMO_9641, SUMO) 198 | CHIPSET(0x9642, SUMO2_9642, SUMO2) 199 | CHIPSET(0x9643, SUMO2_9643, SUMO2) 200 | CHIPSET(0x9644, SUMO2_9644, SUMO2) 201 | CHIPSET(0x9645, SUMO2_9645, SUMO2) 202 | CHIPSET(0x9647, SUMO_9647, SUMO) 203 | CHIPSET(0x9648, SUMO_9648, SUMO) 204 | CHIPSET(0x964a, SUMO_964A, SUMO) 205 | CHIPSET(0x964e, SUMO_964E, SUMO) 206 | CHIPSET(0x964f, SUMO_964F, SUMO) 207 | 208 | #ifndef RADEON_CLASSIC 209 | CHIPSET(0x6700, CAYMAN_6700, CAYMAN) 210 | CHIPSET(0x6701, CAYMAN_6701, CAYMAN) 211 | CHIPSET(0x6702, CAYMAN_6702, CAYMAN) 212 | CHIPSET(0x6703, CAYMAN_6703, CAYMAN) 213 | CHIPSET(0x6704, CAYMAN_6704, CAYMAN) 214 | CHIPSET(0x6705, CAYMAN_6705, CAYMAN) 215 | CHIPSET(0x6706, CAYMAN_6706, CAYMAN) 216 | CHIPSET(0x6707, CAYMAN_6707, CAYMAN) 217 | CHIPSET(0x6708, CAYMAN_6708, CAYMAN) 218 | CHIPSET(0x6709, CAYMAN_6709, CAYMAN) 219 | CHIPSET(0x6718, CAYMAN_6718, CAYMAN) 220 | CHIPSET(0x6719, CAYMAN_6719, CAYMAN) 221 | CHIPSET(0x671C, CAYMAN_671C, CAYMAN) 222 | CHIPSET(0x671D, CAYMAN_671D, CAYMAN) 223 | CHIPSET(0x671F, CAYMAN_671F, CAYMAN) 224 | #endif 225 | 226 | CHIPSET(0x6720, BARTS_6720, BARTS) 227 | CHIPSET(0x6721, BARTS_6721, BARTS) 228 | CHIPSET(0x6722, BARTS_6722, BARTS) 229 | CHIPSET(0x6723, BARTS_6723, BARTS) 230 | CHIPSET(0x6724, BARTS_6724, BARTS) 231 | CHIPSET(0x6725, BARTS_6725, BARTS) 232 | CHIPSET(0x6726, BARTS_6726, BARTS) 233 | CHIPSET(0x6727, BARTS_6727, BARTS) 234 | CHIPSET(0x6728, BARTS_6728, BARTS) 235 | CHIPSET(0x6729, BARTS_6729, BARTS) 236 | CHIPSET(0x6738, BARTS_6738, BARTS) 237 | CHIPSET(0x6739, BARTS_6739, BARTS) 238 | CHIPSET(0x673E, BARTS_673E, BARTS) 239 | CHIPSET(0x6740, TURKS_6740, TURKS) 240 | CHIPSET(0x6741, TURKS_6741, TURKS) 241 | CHIPSET(0x6742, TURKS_6742, TURKS) 242 | CHIPSET(0x6743, TURKS_6743, TURKS) 243 | CHIPSET(0x6744, TURKS_6744, TURKS) 244 | CHIPSET(0x6745, TURKS_6745, TURKS) 245 | CHIPSET(0x6746, TURKS_6746, TURKS) 246 | CHIPSET(0x6747, TURKS_6747, TURKS) 247 | CHIPSET(0x6748, TURKS_6748, TURKS) 248 | CHIPSET(0x6749, TURKS_6749, TURKS) 249 | CHIPSET(0x6750, TURKS_6750, TURKS) 250 | CHIPSET(0x6758, TURKS_6758, TURKS) 251 | CHIPSET(0x6759, TURKS_6759, TURKS) 252 | CHIPSET(0x675F, TURKS_675F, TURKS) 253 | 254 | CHIPSET(0x6760, CAICOS_6760, CAICOS) 255 | CHIPSET(0x6761, CAICOS_6761, CAICOS) 256 | CHIPSET(0x6762, CAICOS_6762, CAICOS) 257 | CHIPSET(0x6763, CAICOS_6763, CAICOS) 258 | CHIPSET(0x6764, CAICOS_6764, CAICOS) 259 | CHIPSET(0x6765, CAICOS_6765, CAICOS) 260 | CHIPSET(0x6766, CAICOS_6766, CAICOS) 261 | CHIPSET(0x6767, CAICOS_6767, CAICOS) 262 | CHIPSET(0x6768, CAICOS_6768, CAICOS) 263 | CHIPSET(0x6770, CAICOS_6770, CAICOS) 264 | CHIPSET(0x6778, CAICOS_6778, CAICOS) 265 | CHIPSET(0x6779, CAICOS_6779, CAICOS) 266 | -------------------------------------------------------------------------------- /gralloc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2011 Chia-I Wu 3 | * Copyright (C) 2010-2011 LunarG Inc. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a 6 | * copy of this software and associated documentation files (the "Software"), 7 | * to deal in the Software without restriction, including without limitation 8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 | * and/or sell copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included 13 | * in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 | * DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | #define LOG_TAG "GRALLOC-MOD" 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #include "gralloc_drm.h" 33 | 34 | struct drm_module_t { 35 | gralloc_module_t base; 36 | 37 | pthread_mutex_t mutex; 38 | struct gralloc_drm_t *drm; 39 | }; 40 | 41 | /* 42 | * Initialize the DRM device object, optionally with KMS. 43 | */ 44 | static int drm_init(struct drm_module_t *dmod, int kms) 45 | { 46 | int err = 0; 47 | 48 | pthread_mutex_lock(&dmod->mutex); 49 | if (!dmod->drm) { 50 | dmod->drm = gralloc_drm_create(); 51 | if (!dmod->drm) 52 | err = -EINVAL; 53 | } 54 | if (!err && kms) 55 | err = gralloc_drm_init_kms(dmod->drm); 56 | pthread_mutex_unlock(&dmod->mutex); 57 | 58 | return err; 59 | } 60 | 61 | static int drm_mod_perform(const struct gralloc_module_t *mod, int op, ...) 62 | { 63 | struct drm_module_t *dmod = (struct drm_module_t *) mod; 64 | va_list args; 65 | int err; 66 | 67 | err = drm_init(dmod, 0); 68 | if (err) 69 | return err; 70 | 71 | va_start(args, op); 72 | switch (op) { 73 | case GRALLOC_MODULE_PERFORM_GET_DRM_FD: 74 | { 75 | int *fd = va_arg(args, int *); 76 | *fd = gralloc_drm_get_fd(dmod->drm); 77 | err = 0; 78 | } 79 | break; 80 | /* should we remove this and next ops, and make it transparent? */ 81 | case GRALLOC_MODULE_PERFORM_GET_DRM_MAGIC: 82 | { 83 | int32_t *magic = va_arg(args, int32_t *); 84 | err = gralloc_drm_get_magic(dmod->drm, magic); 85 | } 86 | break; 87 | case GRALLOC_MODULE_PERFORM_AUTH_DRM_MAGIC: 88 | { 89 | int32_t magic = va_arg(args, int32_t); 90 | err = gralloc_drm_auth_magic(dmod->drm, magic); 91 | } 92 | break; 93 | case GRALLOC_MODULE_PERFORM_ENTER_VT: 94 | { 95 | err = gralloc_drm_set_master(dmod->drm); 96 | } 97 | break; 98 | case GRALLOC_MODULE_PERFORM_LEAVE_VT: 99 | { 100 | gralloc_drm_drop_master(dmod->drm); 101 | err = 0; 102 | } 103 | break; 104 | default: 105 | err = -EINVAL; 106 | break; 107 | } 108 | va_end(args); 109 | 110 | return err; 111 | } 112 | 113 | static int drm_mod_register_buffer(const gralloc_module_t *mod, 114 | buffer_handle_t handle) 115 | { 116 | struct drm_module_t *dmod = (struct drm_module_t *) mod; 117 | int err; 118 | 119 | err = drm_init(dmod, 0); 120 | if (err) 121 | return err; 122 | 123 | return gralloc_drm_handle_register(handle, dmod->drm); 124 | } 125 | 126 | static int drm_mod_unregister_buffer(const gralloc_module_t *mod, 127 | buffer_handle_t handle) 128 | { 129 | return gralloc_drm_handle_unregister(handle); 130 | } 131 | 132 | static int drm_mod_lock(const gralloc_module_t *mod, buffer_handle_t handle, 133 | int usage, int x, int y, int w, int h, void **ptr) 134 | { 135 | struct gralloc_drm_bo_t *bo; 136 | int err; 137 | 138 | bo = gralloc_drm_bo_from_handle(handle); 139 | if (!bo) 140 | return -EINVAL; 141 | 142 | return gralloc_drm_bo_lock(bo, usage, x, y, w, h, ptr); 143 | } 144 | 145 | static int drm_mod_unlock(const gralloc_module_t *mod, buffer_handle_t handle) 146 | { 147 | struct drm_module_t *dmod = (struct drm_module_t *) mod; 148 | struct gralloc_drm_bo_t *bo; 149 | 150 | bo = gralloc_drm_bo_from_handle(handle); 151 | if (!bo) 152 | return -EINVAL; 153 | 154 | gralloc_drm_bo_unlock(bo); 155 | 156 | return 0; 157 | } 158 | 159 | static int drm_mod_close_gpu0(struct hw_device_t *dev) 160 | { 161 | struct alloc_device_t *alloc = (struct alloc_device_t *) dev; 162 | 163 | free(alloc); 164 | 165 | return 0; 166 | } 167 | 168 | static int drm_mod_free_gpu0(alloc_device_t *dev, buffer_handle_t handle) 169 | { 170 | struct drm_module_t *dmod = (struct drm_module_t *) dev->common.module; 171 | struct gralloc_drm_bo_t *bo; 172 | 173 | bo = gralloc_drm_bo_from_handle(handle); 174 | if (!bo) 175 | return -EINVAL; 176 | 177 | if (gralloc_drm_bo_need_fb(bo)) 178 | gralloc_drm_bo_rm_fb(bo); 179 | gralloc_drm_bo_destroy(bo); 180 | 181 | return 0; 182 | } 183 | 184 | static int drm_mod_alloc_gpu0(alloc_device_t *dev, 185 | int w, int h, int format, int usage, 186 | buffer_handle_t *handle, int *stride) 187 | { 188 | struct drm_module_t *dmod = (struct drm_module_t *) dev->common.module; 189 | struct gralloc_drm_bo_t *bo; 190 | int size, bpp, err; 191 | 192 | bpp = gralloc_drm_get_bpp(format); 193 | if (!bpp) 194 | return -EINVAL; 195 | 196 | bo = gralloc_drm_bo_create(dmod->drm, w, h, format, usage); 197 | if (!bo) 198 | return -ENOMEM; 199 | 200 | if (gralloc_drm_bo_need_fb(bo)) { 201 | err = gralloc_drm_bo_add_fb(bo); 202 | if (err) { 203 | LOGE("failed to add fb"); 204 | gralloc_drm_bo_destroy(bo); 205 | return err; 206 | } 207 | } 208 | 209 | *handle = gralloc_drm_bo_get_handle(bo, stride); 210 | /* in pixels */ 211 | *stride /= bpp; 212 | 213 | return 0; 214 | } 215 | 216 | static int drm_mod_open_gpu0(struct drm_module_t *dmod, hw_device_t **dev) 217 | { 218 | struct alloc_device_t *alloc; 219 | int err; 220 | 221 | err = drm_init(dmod, 0); 222 | if (err) 223 | return err; 224 | 225 | alloc = calloc(1, sizeof(*alloc)); 226 | if (!alloc) 227 | return -EINVAL; 228 | 229 | alloc->common.tag = HARDWARE_DEVICE_TAG; 230 | alloc->common.version = 0; 231 | alloc->common.module = &dmod->base.common; 232 | alloc->common.close = drm_mod_close_gpu0; 233 | 234 | alloc->alloc = drm_mod_alloc_gpu0; 235 | alloc->free = drm_mod_free_gpu0; 236 | 237 | *dev = &alloc->common; 238 | 239 | return 0; 240 | } 241 | 242 | static int drm_mod_close_fb0(struct hw_device_t *dev) 243 | { 244 | struct framebuffer_device_t *fb = (struct framebuffer_device_t *) dev; 245 | 246 | free(fb); 247 | 248 | return 0; 249 | } 250 | 251 | static int drm_mod_set_swap_interval_fb0(struct framebuffer_device_t *fb, 252 | int interval) 253 | { 254 | if (interval < fb->minSwapInterval || interval > fb->maxSwapInterval) 255 | return -EINVAL; 256 | return 0; 257 | } 258 | 259 | static int drm_mod_post_fb0(struct framebuffer_device_t *fb, 260 | buffer_handle_t handle) 261 | { 262 | struct drm_module_t *dmod = (struct drm_module_t *) fb->common.module; 263 | struct gralloc_drm_bo_t *bo; 264 | 265 | bo = gralloc_drm_bo_from_handle(handle); 266 | if (!bo) 267 | return -EINVAL; 268 | 269 | return gralloc_drm_bo_post(bo); 270 | } 271 | 272 | #include 273 | static int drm_mod_composition_complete_fb0(struct framebuffer_device_t *fb) 274 | { 275 | struct drm_module_t *dmod = (struct drm_module_t *) fb->common.module; 276 | 277 | if (gralloc_drm_is_kms_pipelined(dmod->drm)) 278 | glFlush(); 279 | else 280 | glFinish(); 281 | 282 | return 0; 283 | } 284 | 285 | static int drm_mod_open_fb0(struct drm_module_t *dmod, struct hw_device_t **dev) 286 | { 287 | struct framebuffer_device_t *fb; 288 | int err; 289 | 290 | err = drm_init(dmod, 1); 291 | if (err) 292 | return err; 293 | 294 | fb = calloc(1, sizeof(*fb)); 295 | if (!fb) 296 | return -ENOMEM; 297 | 298 | fb->common.tag = HARDWARE_DEVICE_TAG; 299 | fb->common.version = 0; 300 | fb->common.module = &dmod->base.common; 301 | fb->common.close = drm_mod_close_fb0; 302 | 303 | fb->setSwapInterval = drm_mod_set_swap_interval_fb0; 304 | fb->post = drm_mod_post_fb0; 305 | fb->compositionComplete = drm_mod_composition_complete_fb0; 306 | 307 | gralloc_drm_get_kms_info(dmod->drm, fb); 308 | 309 | *dev = &fb->common; 310 | 311 | LOGI("mode.hdisplay %d\n" 312 | "mode.vdisplay %d\n" 313 | "mode.vrefresh %f\n" 314 | "format 0x%x\n" 315 | "xdpi %f\n" 316 | "ydpi %f\n", 317 | fb->width, 318 | fb->height, 319 | fb->fps, 320 | fb->format, 321 | fb->xdpi, fb->ydpi); 322 | 323 | return 0; 324 | } 325 | 326 | static int drm_mod_open(const struct hw_module_t *mod, 327 | const char *name, struct hw_device_t **dev) 328 | { 329 | struct drm_module_t *dmod = (struct drm_module_t *) mod; 330 | int err; 331 | 332 | if (strcmp(name, GRALLOC_HARDWARE_GPU0) == 0) 333 | err = drm_mod_open_gpu0(dmod, dev); 334 | else if (strcmp(name, GRALLOC_HARDWARE_FB0) == 0) 335 | err = drm_mod_open_fb0(dmod, dev); 336 | else 337 | err = -EINVAL; 338 | 339 | return err; 340 | } 341 | 342 | static struct hw_module_methods_t drm_mod_methods = { 343 | .open = drm_mod_open 344 | }; 345 | 346 | struct drm_module_t HAL_MODULE_INFO_SYM = { 347 | .base = { 348 | .common = { 349 | .tag = HARDWARE_MODULE_TAG, 350 | .version_major = 1, 351 | .version_minor = 0, 352 | .id = GRALLOC_HARDWARE_MODULE_ID, 353 | .name = "DRM Memory Allocator", 354 | .author = "Chia-I Wu", 355 | .methods = &drm_mod_methods 356 | }, 357 | .registerBuffer = drm_mod_register_buffer, 358 | .unregisterBuffer = drm_mod_unregister_buffer, 359 | .lock = drm_mod_lock, 360 | .unlock = drm_mod_unlock, 361 | .perform = drm_mod_perform 362 | }, 363 | .mutex = PTHREAD_MUTEX_INITIALIZER, 364 | .drm = NULL 365 | }; 366 | -------------------------------------------------------------------------------- /gralloc_drm.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2011 Chia-I Wu 3 | * Copyright (C) 2010-2011 LunarG Inc. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a 6 | * copy of this software and associated documentation files (the "Software"), 7 | * to deal in the Software without restriction, including without limitation 8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 | * and/or sell copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included 13 | * in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 | * DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | #define LOG_TAG "GRALLOC-DRM" 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #include "gralloc_drm.h" 35 | #include "gralloc_drm_priv.h" 36 | 37 | #define unlikely(x) __builtin_expect(!!(x), 0) 38 | 39 | #define GRALLOC_DRM_DEVICE "/dev/dri/card0" 40 | 41 | static int32_t gralloc_drm_pid = 0; 42 | 43 | /* 44 | * Return the pid of the process. 45 | */ 46 | static int gralloc_drm_get_pid(void) 47 | { 48 | if (unlikely(!gralloc_drm_pid)) 49 | android_atomic_write((int32_t) getpid(), &gralloc_drm_pid); 50 | 51 | return gralloc_drm_pid; 52 | } 53 | 54 | /* 55 | * Create the driver for a DRM fd. 56 | */ 57 | static struct gralloc_drm_drv_t * 58 | init_drv_from_fd(int fd) 59 | { 60 | struct gralloc_drm_drv_t *drv = NULL; 61 | drmVersionPtr version; 62 | 63 | /* get the kernel module name */ 64 | version = drmGetVersion(fd); 65 | if (!version) { 66 | LOGE("invalid DRM fd"); 67 | return NULL; 68 | } 69 | 70 | if (version->name) { 71 | #ifdef ENABLE_PIPE 72 | drv = gralloc_drm_drv_create_for_pipe(fd, version->name); 73 | #endif 74 | 75 | #ifdef ENABLE_INTEL 76 | if (!drv && !strcmp(version->name, "i915")) 77 | drv = gralloc_drm_drv_create_for_intel(fd); 78 | #endif 79 | #ifdef ENABLE_RADEON 80 | if (!drv && !strcmp(version->name, "radeon")) 81 | drv = gralloc_drm_drv_create_for_radeon(fd); 82 | #endif 83 | #ifdef ENABLE_NOUVEAU 84 | if (!drv && !strcmp(version->name, "nouveau")) 85 | drv = gralloc_drm_drv_create_for_nouveau(fd); 86 | #endif 87 | } 88 | 89 | if (!drv) { 90 | LOGE("unsupported driver: %s", (version->name) ? 91 | version->name : "NULL"); 92 | } 93 | 94 | drmFreeVersion(version); 95 | 96 | return drv; 97 | } 98 | 99 | /* 100 | * Create a DRM device object. 101 | */ 102 | struct gralloc_drm_t *gralloc_drm_create(void) 103 | { 104 | struct gralloc_drm_t *drm; 105 | int err; 106 | 107 | drm = calloc(1, sizeof(*drm)); 108 | if (!drm) 109 | return NULL; 110 | 111 | drm->fd = open(GRALLOC_DRM_DEVICE, O_RDWR); 112 | if (drm->fd < 0) { 113 | LOGE("failed to open %s", GRALLOC_DRM_DEVICE); 114 | return NULL; 115 | } 116 | 117 | drm->drv = init_drv_from_fd(drm->fd); 118 | if (!drm->drv) { 119 | close(drm->fd); 120 | free(drm); 121 | return NULL; 122 | } 123 | 124 | return drm; 125 | } 126 | 127 | /* 128 | * Destroy a DRM device object. 129 | */ 130 | void gralloc_drm_destroy(struct gralloc_drm_t *drm) 131 | { 132 | if (drm->drv) 133 | drm->drv->destroy(drm->drv); 134 | close(drm->fd); 135 | free(drm); 136 | } 137 | 138 | /* 139 | * Get the file descriptor of a DRM device object. 140 | */ 141 | int gralloc_drm_get_fd(struct gralloc_drm_t *drm) 142 | { 143 | return drm->fd; 144 | } 145 | 146 | /* 147 | * Get the magic for authentication. 148 | */ 149 | int gralloc_drm_get_magic(struct gralloc_drm_t *drm, int32_t *magic) 150 | { 151 | return drmGetMagic(drm->fd, (drm_magic_t *) magic); 152 | } 153 | 154 | /* 155 | * Authenticate a magic. 156 | */ 157 | int gralloc_drm_auth_magic(struct gralloc_drm_t *drm, int32_t magic) 158 | { 159 | return drmAuthMagic(drm->fd, (drm_magic_t) magic); 160 | } 161 | 162 | /* 163 | * Set as the master of a DRM device. 164 | */ 165 | int gralloc_drm_set_master(struct gralloc_drm_t *drm) 166 | { 167 | LOGD("set master"); 168 | drmSetMaster(drm->fd); 169 | drm->first_post = 1; 170 | 171 | return 0; 172 | } 173 | 174 | /* 175 | * Drop from the master of a DRM device. 176 | */ 177 | void gralloc_drm_drop_master(struct gralloc_drm_t *drm) 178 | { 179 | drmDropMaster(drm->fd); 180 | } 181 | 182 | /* 183 | * Validate a buffer handle and return the associated bo. 184 | */ 185 | static struct gralloc_drm_bo_t *validate_handle(buffer_handle_t _handle, 186 | struct gralloc_drm_t *drm) 187 | { 188 | struct gralloc_drm_handle_t *handle = gralloc_drm_handle(_handle); 189 | 190 | if (!handle) 191 | return NULL; 192 | 193 | /* the buffer handle is passed to a new process */ 194 | if (unlikely(handle->data_owner != gralloc_drm_pid)) { 195 | struct gralloc_drm_bo_t *bo; 196 | 197 | /* check only */ 198 | if (!drm) 199 | return NULL; 200 | 201 | /* create the struct gralloc_drm_bo_t locally */ 202 | if (handle->name) 203 | bo = drm->drv->alloc(drm->drv, handle); 204 | else /* an invalid handle */ 205 | bo = NULL; 206 | if (bo) { 207 | bo->drm = drm; 208 | bo->imported = 1; 209 | bo->handle = handle; 210 | } 211 | 212 | handle->data_owner = gralloc_drm_get_pid(); 213 | handle->data = (int) bo; 214 | } 215 | 216 | return (struct gralloc_drm_bo_t *) handle->data; 217 | } 218 | 219 | /* 220 | * Register a buffer handle. 221 | */ 222 | int gralloc_drm_handle_register(buffer_handle_t handle, struct gralloc_drm_t *drm) 223 | { 224 | return (validate_handle(handle, drm)) ? 0 : -EINVAL; 225 | } 226 | 227 | /* 228 | * Unregister a buffer handle. It is no-op for handles created locally. 229 | */ 230 | int gralloc_drm_handle_unregister(buffer_handle_t handle) 231 | { 232 | struct gralloc_drm_bo_t *bo; 233 | 234 | bo = validate_handle(handle, NULL); 235 | if (!bo) 236 | return -EINVAL; 237 | 238 | if (bo->imported) 239 | gralloc_drm_bo_destroy(bo); 240 | 241 | return 0; 242 | } 243 | 244 | /* 245 | * Create a buffer handle. 246 | */ 247 | static struct gralloc_drm_handle_t *create_bo_handle(int width, 248 | int height, int format, int usage) 249 | { 250 | struct gralloc_drm_handle_t *handle; 251 | 252 | handle = calloc(1, sizeof(*handle)); 253 | if (!handle) 254 | return NULL; 255 | 256 | handle->base.version = sizeof(handle->base); 257 | handle->base.numInts = GRALLOC_DRM_HANDLE_NUM_INTS; 258 | handle->base.numFds = GRALLOC_DRM_HANDLE_NUM_FDS; 259 | 260 | handle->magic = GRALLOC_DRM_HANDLE_MAGIC; 261 | handle->width = width; 262 | handle->height = height; 263 | handle->format = format; 264 | handle->usage = usage; 265 | 266 | return handle; 267 | } 268 | 269 | /* 270 | * Create a bo. 271 | */ 272 | struct gralloc_drm_bo_t *gralloc_drm_bo_create(struct gralloc_drm_t *drm, 273 | int width, int height, int format, int usage) 274 | { 275 | struct gralloc_drm_bo_t *bo; 276 | struct gralloc_drm_handle_t *handle; 277 | 278 | handle = create_bo_handle(width, height, format, usage); 279 | if (!handle) 280 | return NULL; 281 | 282 | bo = drm->drv->alloc(drm->drv, handle); 283 | if (!bo) { 284 | free(handle); 285 | return NULL; 286 | } 287 | 288 | bo->drm = drm; 289 | bo->imported = 0; 290 | bo->handle = handle; 291 | 292 | handle->data_owner = gralloc_drm_get_pid(); 293 | handle->data = (int) bo; 294 | 295 | return bo; 296 | } 297 | 298 | /* 299 | * Destroy a bo. 300 | */ 301 | void gralloc_drm_bo_destroy(struct gralloc_drm_bo_t *bo) 302 | { 303 | struct gralloc_drm_handle_t *handle = bo->handle; 304 | int imported = bo->imported; 305 | 306 | bo->drm->drv->free(bo->drm->drv, bo); 307 | if (imported) { 308 | handle->data_owner = 0; 309 | handle->data = 0; 310 | } 311 | else { 312 | free(handle); 313 | } 314 | } 315 | 316 | /* 317 | * Return the bo of a registered handle. 318 | */ 319 | struct gralloc_drm_bo_t *gralloc_drm_bo_from_handle(buffer_handle_t handle) 320 | { 321 | return validate_handle(handle, NULL); 322 | } 323 | 324 | /* 325 | * Get the buffer handle and stride of a bo. 326 | */ 327 | buffer_handle_t gralloc_drm_bo_get_handle(struct gralloc_drm_bo_t *bo, int *stride) 328 | { 329 | if (stride) 330 | *stride = bo->handle->stride; 331 | return &bo->handle->base; 332 | } 333 | 334 | /* 335 | * Lock a bo. XXX thread-safety? 336 | */ 337 | int gralloc_drm_bo_lock(struct gralloc_drm_bo_t *bo, 338 | int usage, int x, int y, int w, int h, 339 | void **addr) 340 | { 341 | if ((bo->handle->usage & usage) != usage) { 342 | /* make FB special for testing software renderer with */ 343 | if (!(bo->handle->usage & GRALLOC_USAGE_HW_FB)) 344 | return -EINVAL; 345 | } 346 | 347 | /* allow multiple locks with compatible usages */ 348 | if (bo->lock_count && (bo->locked_for & usage) != usage) 349 | return -EINVAL; 350 | 351 | usage |= bo->locked_for; 352 | 353 | if (usage & (GRALLOC_USAGE_SW_WRITE_MASK | 354 | GRALLOC_USAGE_SW_READ_MASK)) { 355 | /* the driver is supposed to wait for the bo */ 356 | int write = !!(usage & GRALLOC_USAGE_SW_WRITE_MASK); 357 | int err = bo->drm->drv->map(bo->drm->drv, bo, 358 | x, y, w, h, write, addr); 359 | if (err) 360 | return err; 361 | } 362 | else { 363 | /* kernel handles the synchronization here */ 364 | } 365 | 366 | bo->lock_count++; 367 | bo->locked_for |= usage; 368 | 369 | return 0; 370 | } 371 | 372 | /* 373 | * Unlock a bo. 374 | */ 375 | void gralloc_drm_bo_unlock(struct gralloc_drm_bo_t *bo) 376 | { 377 | int mapped = bo->locked_for & 378 | (GRALLOC_USAGE_SW_WRITE_MASK | GRALLOC_USAGE_SW_READ_MASK); 379 | 380 | if (!bo->lock_count) 381 | return; 382 | 383 | if (mapped) 384 | bo->drm->drv->unmap(bo->drm->drv, bo); 385 | 386 | bo->lock_count--; 387 | if (!bo->lock_count) 388 | bo->locked_for = 0; 389 | } 390 | -------------------------------------------------------------------------------- /gralloc_drm_nouveau.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Chia-I Wu 3 | * Copyright (C) 2011 LunarG Inc. 4 | * 5 | * Based on xf86-video-nouveau, which has 6 | * 7 | * Copyright © 2007 Red Hat, Inc. 8 | * Copyright © 2008 Maarten Maathuis 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a 11 | * copy of this software and associated documentation files (the "Software"), 12 | * to deal in the Software without restriction, including without limitation 13 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 14 | * and/or sell copies of the Software, and to permit persons to whom the 15 | * Software is furnished to do so, subject to the following conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be included 18 | * in all copies or substantial portions of the Software. 19 | * 20 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 23 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | * DEALINGS IN THE SOFTWARE. 27 | */ 28 | 29 | #define LOG_TAG "GRALLOC-NOUVEAU" 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | #include "gralloc_drm.h" 40 | #include "gralloc_drm_priv.h" 41 | 42 | #define MAX(a, b) (((a) > (b)) ? (a) : (b)) 43 | #define ALIGN(val, align) (((val) + (align) - 1) & ~((align) - 1)) 44 | 45 | #define NVC0_TILE_HEIGHT(m) (8 << ((m) >> 4)) 46 | 47 | enum { 48 | NvDmaFB = 0xd8000001, 49 | NvDmaTT = 0xd8000002, 50 | }; 51 | 52 | struct nouveau_info { 53 | struct gralloc_drm_drv_t base; 54 | 55 | int fd; 56 | struct nouveau_device *dev; 57 | struct nouveau_channel *chan; 58 | int arch; 59 | int tiled_scanout; 60 | }; 61 | 62 | struct nouveau_buffer { 63 | struct gralloc_drm_bo_t base; 64 | 65 | struct nouveau_bo *bo; 66 | }; 67 | 68 | static struct nouveau_bo *alloc_bo(struct nouveau_info *info, 69 | int width, int height, int cpp, int usage, int *pitch) 70 | { 71 | struct nouveau_bo *bo = NULL; 72 | int flags, tile_mode, tile_flags; 73 | int tiled, scanout; 74 | unsigned int align; 75 | 76 | flags = NOUVEAU_BO_MAP | NOUVEAU_BO_VRAM; 77 | tile_mode = 0; 78 | tile_flags = 0; 79 | 80 | scanout = !!(usage & GRALLOC_USAGE_HW_FB); 81 | 82 | tiled = !(usage & (GRALLOC_USAGE_SW_READ_OFTEN | 83 | GRALLOC_USAGE_SW_WRITE_OFTEN)); 84 | if (!info->chan) 85 | tiled = 0; 86 | else if (scanout && info->tiled_scanout) 87 | tiled = 1; 88 | 89 | /* calculate pitch align */ 90 | align = 64; 91 | if (info->arch >= 0x50) { 92 | if (scanout && !info->tiled_scanout) 93 | align = 256; 94 | else 95 | tiled = 1; 96 | } 97 | 98 | *pitch = ALIGN(width * cpp, align); 99 | 100 | if (tiled) { 101 | if (info->arch >= 0xc0) { 102 | if (height > 64) 103 | tile_mode = 0x40; 104 | else if (height > 32) 105 | tile_mode = 0x30; 106 | else if (height > 16) 107 | tile_mode = 0x20; 108 | else if (height > 8) 109 | tile_mode = 0x10; 110 | else 111 | tile_mode = 0x00; 112 | 113 | tile_flags = 0xfe00; 114 | 115 | align = NVC0_TILE_HEIGHT(tile_mode); 116 | height = ALIGN(height, align); 117 | } 118 | else if (info->arch >= 0x50) { 119 | if (height > 32) 120 | tile_mode = 4; 121 | else if (height > 16) 122 | tile_mode = 3; 123 | else if (height > 8) 124 | tile_mode = 2; 125 | else if (height > 4) 126 | tile_mode = 1; 127 | else 128 | tile_mode = 0; 129 | 130 | tile_flags = (scanout && cpp != 2) ? 0x7a00 : 0x7000; 131 | 132 | align = 1 << (tile_mode + 2); 133 | height = ALIGN(height, align); 134 | } 135 | else { 136 | align = *pitch / 4; 137 | 138 | /* round down to the previous power of two */ 139 | align >>= 1; 140 | align |= align >> 1; 141 | align |= align >> 2; 142 | align |= align >> 4; 143 | align |= align >> 8; 144 | align |= align >> 16; 145 | align++; 146 | 147 | align = MAX((info->dev->chipset >= 0x40) ? 1024 : 256, 148 | align); 149 | 150 | /* adjust pitch */ 151 | *pitch = ALIGN(*pitch, align); 152 | 153 | tile_mode = *pitch; 154 | } 155 | } 156 | 157 | if (cpp == 4) 158 | tile_flags |= NOUVEAU_BO_TILE_32BPP; 159 | else if (cpp == 2) 160 | tile_flags |= NOUVEAU_BO_TILE_16BPP; 161 | 162 | if (scanout) 163 | tile_flags |= NOUVEAU_BO_TILE_SCANOUT; 164 | 165 | if (nouveau_bo_new_tile(info->dev, flags, 0, *pitch * height, 166 | tile_mode, tile_flags, &bo)) { 167 | LOGE("failed to allocate bo (flags 0x%x, size %d, tile_mode 0x%x, tile_flags 0x%x)", 168 | flags, *pitch * height, tile_mode, tile_flags); 169 | bo = NULL; 170 | } 171 | 172 | return bo; 173 | } 174 | 175 | static struct gralloc_drm_bo_t * 176 | nouveau_alloc(struct gralloc_drm_drv_t *drv, struct gralloc_drm_handle_t *handle) 177 | { 178 | struct nouveau_info *info = (struct nouveau_info *) drv; 179 | struct nouveau_buffer *nb; 180 | int cpp; 181 | 182 | cpp = gralloc_drm_get_bpp(handle->format); 183 | if (!cpp) { 184 | LOGE("unrecognized format 0x%x", handle->format); 185 | return NULL; 186 | } 187 | 188 | nb = calloc(1, sizeof(*nb)); 189 | if (!nb) 190 | return NULL; 191 | 192 | if (handle->name) { 193 | if (nouveau_bo_handle_ref(info->dev, handle->name, &nb->bo)) { 194 | LOGE("failed to create nouveau bo from name %u", 195 | handle->name); 196 | free(nb); 197 | return NULL; 198 | } 199 | } 200 | else { 201 | int width, height, pitch; 202 | 203 | width = handle->width; 204 | height = handle->height; 205 | gralloc_drm_align_geometry(handle->format, &width, &height); 206 | 207 | nb->bo = alloc_bo(info, width, height, 208 | cpp, handle->usage, &pitch); 209 | if (!nb->bo) { 210 | LOGE("failed to allocate nouveau bo %dx%dx%d", 211 | handle->width, handle->height, cpp); 212 | free(nb); 213 | return NULL; 214 | } 215 | 216 | if (nouveau_bo_handle_get(nb->bo, 217 | (uint32_t *) &handle->name)) { 218 | LOGE("failed to flink nouveau bo"); 219 | nouveau_bo_ref(NULL, &nb->bo); 220 | free(nb); 221 | return NULL; 222 | } 223 | 224 | handle->stride = pitch; 225 | } 226 | 227 | if (handle->usage & GRALLOC_USAGE_HW_FB) 228 | nb->base.fb_handle = nb->bo->handle; 229 | 230 | nb->base.handle = handle; 231 | 232 | return &nb->base; 233 | } 234 | 235 | static void nouveau_free(struct gralloc_drm_drv_t *drv, 236 | struct gralloc_drm_bo_t *bo) 237 | { 238 | struct nouveau_buffer *nb = (struct nouveau_buffer *) bo; 239 | nouveau_bo_ref(NULL, &nb->bo); 240 | free(nb); 241 | } 242 | 243 | static int nouveau_map(struct gralloc_drm_drv_t *drv, 244 | struct gralloc_drm_bo_t *bo, int x, int y, int w, int h, 245 | int enable_write, void **addr) 246 | { 247 | struct nouveau_buffer *nb = (struct nouveau_buffer *) bo; 248 | uint32_t flags; 249 | int err; 250 | 251 | flags = NOUVEAU_BO_RD; 252 | if (enable_write) 253 | flags |= NOUVEAU_BO_WR; 254 | 255 | /* TODO if tiled, allocate a linear copy of bo in GART and map it */ 256 | err = nouveau_bo_map(nb->bo, flags); 257 | if (!err) 258 | *addr = nb->bo->map; 259 | 260 | return err; 261 | } 262 | 263 | static void nouveau_unmap(struct gralloc_drm_drv_t *drv, 264 | struct gralloc_drm_bo_t *bo) 265 | { 266 | struct nouveau_buffer *nb = (struct nouveau_buffer *) bo; 267 | /* TODO if tiled, unmap the linear bo and copy back */ 268 | nouveau_bo_unmap(nb->bo); 269 | } 270 | 271 | static void nouveau_init_kms_features(struct gralloc_drm_drv_t *drv, 272 | struct gralloc_drm_t *drm) 273 | { 274 | struct nouveau_info *info = (struct nouveau_info *) drv; 275 | 276 | switch (drm->fb_format) { 277 | case HAL_PIXEL_FORMAT_BGRA_8888: 278 | case HAL_PIXEL_FORMAT_RGB_565: 279 | break; 280 | default: 281 | drm->fb_format = HAL_PIXEL_FORMAT_BGRA_8888; 282 | break; 283 | } 284 | 285 | drm->mode_quirk_vmwgfx = 0; 286 | drm->swap_mode = (info->chan) ? DRM_SWAP_FLIP : DRM_SWAP_SETCRTC; 287 | drm->mode_sync_flip = 1; 288 | drm->swap_interval = 1; 289 | drm->vblank_secondary = 0; 290 | } 291 | 292 | static void nouveau_destroy(struct gralloc_drm_drv_t *drv) 293 | { 294 | struct nouveau_info *info = (struct nouveau_info *) drv; 295 | 296 | if (info->chan) 297 | nouveau_channel_free(&info->chan); 298 | nouveau_device_close(&info->dev); 299 | free(info); 300 | } 301 | 302 | static int nouveau_init(struct nouveau_info *info) 303 | { 304 | int err = 0; 305 | 306 | switch (info->dev->chipset & 0xf0) { 307 | case 0x00: 308 | info->arch = 0x04; 309 | break; 310 | case 0x10: 311 | info->arch = 0x10; 312 | break; 313 | case 0x20: 314 | info->arch = 0x20; 315 | break; 316 | case 0x30: 317 | info->arch = 0x30; 318 | break; 319 | case 0x40: 320 | case 0x60: 321 | info->arch = 0x40; 322 | break; 323 | case 0x50: 324 | case 0x80: 325 | case 0x90: 326 | case 0xa0: 327 | info->arch = 0x50; 328 | break; 329 | case 0xc0: 330 | info->arch = 0xc0; 331 | break; 332 | default: 333 | LOGE("unknown nouveau chipset 0x%x", info->dev->chipset); 334 | err = -EINVAL; 335 | break; 336 | } 337 | 338 | info->tiled_scanout = (info->chan != NULL); 339 | 340 | return err; 341 | } 342 | 343 | struct gralloc_drm_drv_t *gralloc_drm_drv_create_for_nouveau(int fd) 344 | { 345 | struct nouveau_info *info; 346 | int err; 347 | 348 | info = calloc(1, sizeof(*info)); 349 | if (!info) 350 | return NULL; 351 | 352 | info->fd = fd; 353 | err = nouveau_device_open_existing(&info->dev, 0, info->fd, 0); 354 | if (err) { 355 | LOGE("failed to create nouveau device"); 356 | free(info); 357 | return NULL; 358 | } 359 | 360 | err = nouveau_channel_alloc(info->dev, NvDmaFB, NvDmaTT, 361 | 24 * 1024, &info->chan); 362 | if (err) { 363 | /* make it non-fatal temporarily as it may require firmwares */ 364 | LOGW("failed to create nouveau channel"); 365 | info->chan = NULL; 366 | } 367 | 368 | err = nouveau_init(info); 369 | if (err) { 370 | if (info->chan) 371 | nouveau_channel_free(&info->chan); 372 | nouveau_device_close(&info->dev); 373 | free(info); 374 | return NULL; 375 | } 376 | 377 | info->base.destroy = nouveau_destroy; 378 | info->base.init_kms_features = nouveau_init_kms_features; 379 | info->base.alloc = nouveau_alloc; 380 | info->base.free = nouveau_free; 381 | info->base.map = nouveau_map; 382 | info->base.unmap = nouveau_unmap; 383 | 384 | return &info->base; 385 | } 386 | -------------------------------------------------------------------------------- /gralloc_drm_radeon.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2011 Chia-I Wu 3 | * Copyright (C) 2010-2011 LunarG Inc. 4 | * 5 | * Based on xf86-video-ati, which has 6 | * 7 | * Copyright © 2009 Red Hat, Inc. 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a 10 | * copy of this software and associated documentation files (the "Software"), 11 | * to deal in the Software without restriction, including without limitation 12 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 13 | * and/or sell copies of the Software, and to permit persons to whom the 14 | * Software is furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included 17 | * in all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 22 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 24 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | * DEALINGS IN THE SOFTWARE. 26 | */ 27 | 28 | /* XXX This driver assumes evergreen. */ 29 | 30 | #define LOG_TAG "GRALLOC-RADEON" 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | #include "gralloc_drm.h" 41 | #include "gralloc_drm_priv.h" 42 | 43 | #include "radeon/radeon.h" 44 | #include "radeon/radeon_chipinfo_gen.h" 45 | 46 | #define RADEON_GPU_PAGE_SIZE 4096 47 | 48 | #define MAX(a, b) (((a) > (b)) ? (a) : (b)) 49 | #define ALIGN(val, align) (((val) + (align) - 1) & ~((align) - 1)) 50 | 51 | struct radeon_info { 52 | struct gralloc_drm_drv_t base; 53 | 54 | int fd; 55 | struct radeon_bo_manager *bufmgr; 56 | 57 | uint32_t chipset; 58 | RADEONChipFamily chip_family; 59 | int is_mobility; 60 | int is_igp; 61 | 62 | uint32_t tile_config; 63 | int num_channels; 64 | int num_banks; 65 | int group_bytes; 66 | /* r6xx+ tile config */ 67 | int have_tiling_info; 68 | 69 | int allow_color_tiling; 70 | 71 | int vram_size; 72 | int gart_size; 73 | }; 74 | 75 | struct radeon_buffer { 76 | struct gralloc_drm_bo_t base; 77 | 78 | struct radeon_bo *rbo; 79 | }; 80 | 81 | /* returns pitch alignment in pixels */ 82 | static int radeon_get_pitch_align(struct radeon_info *info, int bpe, uint32_t tiling) 83 | { 84 | int pitch_align = 1; 85 | 86 | if (info->chip_family >= CHIP_FAMILY_R600) { 87 | if (tiling & RADEON_TILING_MACRO) { 88 | /* general surface requirements */ 89 | pitch_align = (((info->group_bytes / 8) / bpe) * 90 | info->num_banks) * 8; 91 | /* further restrictions for scanout */ 92 | pitch_align = MAX(info->num_banks * 8, pitch_align); 93 | } else if (tiling & RADEON_TILING_MICRO) { 94 | /* general surface requirements */ 95 | pitch_align = MAX(8, (info->group_bytes / (8 * bpe))); 96 | /* further restrictions for scanout */ 97 | pitch_align = MAX(info->group_bytes / bpe, pitch_align); 98 | } else { 99 | if (info->have_tiling_info) 100 | /* linear aligned requirements */ 101 | pitch_align = MAX(64, info->group_bytes / bpe); 102 | else 103 | /* default to 512 elements if we don't know the real 104 | * group size otherwise the kernel may reject the CS 105 | * if the group sizes don't match as the pitch won't 106 | * be aligned properly. 107 | */ 108 | pitch_align = 512; 109 | } 110 | } 111 | else { 112 | /* general surface requirements */ 113 | if (tiling) 114 | pitch_align = 256 / bpe; 115 | else 116 | pitch_align = 64; 117 | } 118 | 119 | return pitch_align; 120 | } 121 | 122 | /* returns height alignment in pixels */ 123 | static int radeon_get_height_align(struct radeon_info *info, uint32_t tiling) 124 | { 125 | int height_align = 1; 126 | 127 | if (info->chip_family >= CHIP_FAMILY_R600) { 128 | if (tiling & RADEON_TILING_MACRO) 129 | height_align = info->num_channels * 8; 130 | else if (tiling & RADEON_TILING_MICRO) 131 | height_align = 8; 132 | else 133 | height_align = 8; 134 | } 135 | else { 136 | if (tiling) 137 | height_align = 16; 138 | else 139 | height_align = 1; 140 | } 141 | 142 | return height_align; 143 | } 144 | 145 | /* returns base alignment in bytes */ 146 | static int radeon_get_base_align(struct radeon_info *info, 147 | int bpe, uint32_t tiling) 148 | { 149 | int pixel_align = radeon_get_pitch_align(info, bpe, tiling); 150 | int height_align = radeon_get_height_align(info, tiling); 151 | int base_align = RADEON_GPU_PAGE_SIZE; 152 | 153 | if (info->chip_family >= CHIP_FAMILY_R600) { 154 | if (tiling & RADEON_TILING_MACRO) 155 | base_align = MAX(info->num_banks * info->num_channels * 8 * 8 * bpe, 156 | pixel_align * bpe * height_align); 157 | else { 158 | if (info->have_tiling_info) 159 | base_align = info->group_bytes; 160 | else 161 | /* default to 512 if we don't know the real 162 | * group size otherwise the kernel may reject the CS 163 | * if the group sizes don't match as the base won't 164 | * be aligned properly. 165 | */ 166 | base_align = 512; 167 | } 168 | } 169 | return base_align; 170 | } 171 | 172 | static uint32_t radeon_get_tiling(struct radeon_info *info, 173 | const struct gralloc_drm_handle_t *handle) 174 | { 175 | int sw = (GRALLOC_USAGE_SW_WRITE_MASK | GRALLOC_USAGE_SW_READ_MASK); 176 | 177 | if ((handle->usage & sw) && !info->allow_color_tiling) 178 | return 0; 179 | 180 | if (info->chip_family >= CHIP_FAMILY_R600) 181 | return RADEON_TILING_MICRO; 182 | else 183 | return RADEON_TILING_MACRO; 184 | } 185 | 186 | static struct radeon_bo *radeon_alloc(struct radeon_info *info, 187 | struct gralloc_drm_handle_t *handle) 188 | { 189 | struct radeon_bo *rbo; 190 | int aligned_width, aligned_height; 191 | int pitch, size, base_align; 192 | uint32_t tiling, domain; 193 | int cpp; 194 | 195 | cpp = gralloc_drm_get_bpp(handle->format); 196 | if (!cpp) { 197 | LOGE("unrecognized format 0x%x", handle->format); 198 | return NULL; 199 | } 200 | 201 | tiling = radeon_get_tiling(info, handle); 202 | domain = RADEON_GEM_DOMAIN_VRAM; 203 | 204 | aligned_width = handle->width; 205 | aligned_height = handle->height; 206 | gralloc_drm_align_geometry(handle->format, 207 | &aligned_width, &aligned_height); 208 | 209 | if (handle->usage & (GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_HW_TEXTURE)) { 210 | aligned_width = ALIGN(aligned_width, 211 | radeon_get_pitch_align(info, cpp, tiling)); 212 | aligned_height = ALIGN(aligned_height, 213 | radeon_get_height_align(info, tiling)); 214 | } 215 | 216 | if (!(handle->usage & (GRALLOC_USAGE_HW_FB | 217 | GRALLOC_USAGE_HW_RENDER)) && 218 | (handle->usage & GRALLOC_USAGE_SW_READ_OFTEN)) 219 | domain = RADEON_GEM_DOMAIN_GTT; 220 | 221 | pitch = aligned_width * cpp; 222 | size = ALIGN(aligned_height * pitch, RADEON_GPU_PAGE_SIZE); 223 | base_align = radeon_get_base_align(info, cpp, tiling); 224 | 225 | rbo = radeon_bo_open(info->bufmgr, 0, size, base_align, domain, 0); 226 | if (!rbo) { 227 | LOGE("failed to allocate rbo %dx%dx%d", 228 | handle->width, handle->height, cpp); 229 | return NULL; 230 | } 231 | 232 | if (tiling) 233 | radeon_bo_set_tiling(rbo, tiling, pitch); 234 | 235 | if (radeon_gem_get_kernel_name(rbo, 236 | (uint32_t *) &handle->name)) { 237 | LOGE("failed to flink rbo"); 238 | radeon_bo_unref(rbo); 239 | return NULL; 240 | } 241 | 242 | handle->stride = pitch; 243 | 244 | return rbo; 245 | } 246 | 247 | static void radeon_zero(struct radeon_info *info, 248 | struct radeon_bo *rbo) 249 | { 250 | /* should use HW clear... */ 251 | if (!radeon_bo_map(rbo, 1)) { 252 | memset(rbo->ptr, 0, rbo->size); 253 | radeon_bo_unmap(rbo); 254 | } 255 | } 256 | 257 | static struct gralloc_drm_bo_t * 258 | drm_gem_radeon_alloc(struct gralloc_drm_drv_t *drv, struct gralloc_drm_handle_t *handle) 259 | { 260 | struct radeon_info *info = (struct radeon_info *) drv; 261 | struct radeon_buffer *rbuf; 262 | 263 | rbuf = calloc(1, sizeof(*rbuf)); 264 | if (!rbuf) 265 | return NULL; 266 | 267 | if (handle->name) { 268 | rbuf->rbo = radeon_bo_open(info->bufmgr, 269 | handle->name, 0, 0, 0, 0); 270 | if (!rbuf->rbo) { 271 | LOGE("failed to create rbo from name %u", 272 | handle->name); 273 | free(rbuf); 274 | return NULL; 275 | } 276 | } 277 | else { 278 | rbuf->rbo = radeon_alloc(info, handle); 279 | if (!rbuf->rbo) { 280 | free(rbuf); 281 | return NULL; 282 | } 283 | 284 | /* Android expects the buffer to be zeroed */ 285 | radeon_zero(info, rbuf->rbo); 286 | } 287 | 288 | if (handle->usage & GRALLOC_USAGE_HW_FB) 289 | rbuf->base.fb_handle = rbuf->rbo->handle; 290 | 291 | rbuf->base.handle = handle; 292 | 293 | return &rbuf->base; 294 | } 295 | 296 | static void drm_gem_radeon_free(struct gralloc_drm_drv_t *drv, 297 | struct gralloc_drm_bo_t *bo) 298 | { 299 | struct radeon_buffer *rbuf = (struct radeon_buffer *) bo; 300 | radeon_bo_unref(rbuf->rbo); 301 | } 302 | 303 | static int drm_gem_radeon_map(struct gralloc_drm_drv_t *drv, 304 | struct gralloc_drm_bo_t *bo, int x, int y, int w, int h, 305 | int enable_write, void **addr) 306 | { 307 | struct radeon_buffer *rbuf = (struct radeon_buffer *) bo; 308 | int err; 309 | 310 | err = radeon_bo_map(rbuf->rbo, enable_write); 311 | if (!err) 312 | *addr = rbuf->rbo->ptr; 313 | 314 | return err; 315 | } 316 | 317 | static void drm_gem_radeon_unmap(struct gralloc_drm_drv_t *drv, 318 | struct gralloc_drm_bo_t *bo) 319 | { 320 | struct radeon_buffer *rbuf = (struct radeon_buffer *) bo; 321 | radeon_bo_unmap(rbuf->rbo); 322 | } 323 | 324 | static void drm_gem_radeon_init_kms_features(struct gralloc_drm_drv_t *drv, 325 | struct gralloc_drm_t *drm) 326 | { 327 | switch (drm->fb_format) { 328 | case HAL_PIXEL_FORMAT_BGRA_8888: 329 | case HAL_PIXEL_FORMAT_RGB_565: 330 | break; 331 | default: 332 | drm->fb_format = HAL_PIXEL_FORMAT_BGRA_8888; 333 | break; 334 | } 335 | 336 | drm->mode_quirk_vmwgfx = 0; 337 | drm->swap_mode = DRM_SWAP_FLIP; 338 | drm->mode_sync_flip = 1; 339 | drm->swap_interval = 1; 340 | drm->vblank_secondary = 0; 341 | } 342 | 343 | static void drm_gem_radeon_destroy(struct gralloc_drm_drv_t *drv) 344 | { 345 | struct radeon_info *info = (struct radeon_info *) drv; 346 | 347 | radeon_bo_manager_gem_dtor(info->bufmgr); 348 | free(info); 349 | } 350 | 351 | static int radeon_init_tile_config(struct radeon_info *info) 352 | { 353 | struct drm_radeon_info ginfo; 354 | uint32_t val; 355 | int ret; 356 | 357 | memset(&ginfo, 0, sizeof(ginfo)); 358 | ginfo.request = RADEON_INFO_TILING_CONFIG; 359 | ginfo.value = (long) &val; 360 | ret = drmCommandWriteRead(info->fd, DRM_RADEON_INFO, 361 | &ginfo, sizeof(ginfo)); 362 | if (ret) 363 | return ret; 364 | 365 | info->tile_config = val; 366 | 367 | if (info->chip_family >= CHIP_FAMILY_CEDAR) { 368 | switch (info->tile_config & 0xf) { 369 | case 0: 370 | info->num_channels = 1; 371 | break; 372 | case 1: 373 | info->num_channels = 2; 374 | break; 375 | case 2: 376 | info->num_channels = 4; 377 | break; 378 | case 3: 379 | info->num_channels = 8; 380 | break; 381 | default: 382 | return -EINVAL; 383 | break; 384 | } 385 | 386 | switch ((info->tile_config & 0xf0) >> 4) { 387 | case 0: 388 | info->num_banks = 4; 389 | break; 390 | case 1: 391 | info->num_banks = 8; 392 | break; 393 | case 2: 394 | info->num_banks = 16; 395 | break; 396 | default: 397 | return -EINVAL; 398 | break; 399 | } 400 | 401 | switch ((info->tile_config & 0xf00) >> 8) { 402 | case 0: 403 | info->group_bytes = 256; 404 | break; 405 | case 1: 406 | info->group_bytes = 512; 407 | break; 408 | default: 409 | return -EINVAL; 410 | break; 411 | } 412 | } 413 | else { 414 | switch ((info->tile_config & 0xe) >> 1) { 415 | case 0: 416 | info->num_channels = 1; 417 | break; 418 | case 1: 419 | info->num_channels = 2; 420 | break; 421 | case 2: 422 | info->num_channels = 4; 423 | break; 424 | case 3: 425 | info->num_channels = 8; 426 | break; 427 | default: 428 | return -EINVAL; 429 | break; 430 | } 431 | 432 | switch ((info->tile_config & 0x30) >> 4) { 433 | case 0: 434 | info->num_banks = 4; 435 | break; 436 | case 1: 437 | info->num_banks = 8; 438 | break; 439 | default: 440 | return -EINVAL; 441 | break; 442 | } 443 | 444 | switch ((info->tile_config & 0xc0) >> 6) { 445 | case 0: 446 | info->group_bytes = 256; 447 | break; 448 | case 1: 449 | info->group_bytes = 512; 450 | break; 451 | default: 452 | return -EINVAL; 453 | break; 454 | } 455 | } 456 | 457 | info->have_tiling_info = 1; 458 | 459 | return 0; 460 | } 461 | 462 | static int radeon_probe(struct radeon_info *info) 463 | { 464 | struct drm_radeon_info kinfo; 465 | struct drm_radeon_gem_info mminfo; 466 | unsigned int i; 467 | int err; 468 | 469 | memset(&kinfo, 0, sizeof(kinfo)); 470 | kinfo.request = RADEON_INFO_DEVICE_ID; 471 | kinfo.value = (long) &info->chipset; 472 | err = drmCommandWriteRead(info->fd, DRM_RADEON_INFO, &kinfo, sizeof(kinfo)); 473 | if (err) { 474 | LOGE("failed to get device id"); 475 | return err; 476 | } 477 | 478 | for (i = 0; i < sizeof(RADEONCards) / sizeof(RADEONCards[0]); i++) { 479 | const RADEONCardInfo *card = &RADEONCards[i]; 480 | 481 | if (info->chipset == card->pci_device_id) { 482 | info->chip_family = card->chip_family; 483 | info->is_mobility = card->mobility; 484 | info->is_igp = card->igp; 485 | break; 486 | } 487 | } 488 | 489 | if (info->chip_family == CHIP_FAMILY_UNKNOW) { 490 | LOGE("unknown device id 0x%04x", info->chipset); 491 | return -EINVAL; 492 | } 493 | 494 | err = radeon_init_tile_config(info); 495 | if (err) { 496 | LOGE("failed to get tiling config"); 497 | return err; 498 | } 499 | 500 | /* CPU cannot handle tiled buffers (need scratch buffers) */ 501 | info->allow_color_tiling = 0; 502 | 503 | memset(&mminfo, 0, sizeof(mminfo)); 504 | err = drmCommandWriteRead(info->fd, DRM_RADEON_GEM_INFO, &mminfo, sizeof(mminfo)); 505 | if (err) { 506 | LOGE("failed to get gem info"); 507 | return err; 508 | } 509 | 510 | info->vram_size = mminfo.vram_visible; 511 | info->gart_size = mminfo.gart_size; 512 | 513 | LOGI("detected chipset 0x%04x family 0x%02x (vram size %dMiB, gart size %dMiB)", 514 | info->chipset, info->chip_family, 515 | info->vram_size / 1024 / 1024, 516 | info->gart_size / 1024 / 1024); 517 | 518 | return 0; 519 | } 520 | 521 | struct gralloc_drm_drv_t *gralloc_drm_drv_create_for_radeon(int fd) 522 | { 523 | struct radeon_info *info; 524 | 525 | info = calloc(1, sizeof(*info)); 526 | if (!info) 527 | return NULL; 528 | 529 | info->fd = fd; 530 | if (radeon_probe(info)) { 531 | free(info); 532 | return NULL; 533 | } 534 | 535 | info->bufmgr = radeon_bo_manager_gem_ctor(info->fd); 536 | if (!info->bufmgr) { 537 | LOGE("failed to create buffer manager"); 538 | free(info); 539 | return NULL; 540 | } 541 | 542 | info->base.destroy = drm_gem_radeon_destroy; 543 | info->base.init_kms_features = drm_gem_radeon_init_kms_features; 544 | info->base.alloc = drm_gem_radeon_alloc; 545 | info->base.free = drm_gem_radeon_free; 546 | info->base.map = drm_gem_radeon_map; 547 | info->base.unmap = drm_gem_radeon_unmap; 548 | 549 | return &info->base; 550 | } 551 | -------------------------------------------------------------------------------- /gralloc_drm_pipe.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2011 Chia-I Wu 3 | * Copyright (C) 2010-2011 LunarG Inc. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a 6 | * copy of this software and associated documentation files (the "Software"), 7 | * to deal in the Software without restriction, including without limitation 8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 | * and/or sell copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included 13 | * in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 | * DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | #define LOG_TAG "GRALLOC-PIPE" 25 | 26 | #include 27 | #include 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | #include "gralloc_drm.h" 36 | #include "gralloc_drm_priv.h" 37 | 38 | struct pipe_manager { 39 | struct gralloc_drm_drv_t base; 40 | 41 | int fd; 42 | char driver[16]; 43 | pthread_mutex_t mutex; 44 | struct pipe_screen *screen; 45 | struct pipe_context *context; 46 | }; 47 | 48 | struct pipe_buffer { 49 | struct gralloc_drm_bo_t base; 50 | 51 | struct pipe_resource *resource; 52 | struct winsys_handle winsys; 53 | 54 | struct pipe_transfer *transfer; 55 | }; 56 | 57 | static enum pipe_format get_pipe_format(int format) 58 | { 59 | enum pipe_format fmt; 60 | 61 | switch (format) { 62 | case HAL_PIXEL_FORMAT_RGBA_8888: 63 | fmt = PIPE_FORMAT_R8G8B8A8_UNORM; 64 | break; 65 | case HAL_PIXEL_FORMAT_RGBX_8888: 66 | fmt = PIPE_FORMAT_R8G8B8X8_UNORM; 67 | break; 68 | case HAL_PIXEL_FORMAT_RGB_888: 69 | fmt = PIPE_FORMAT_R8G8B8_UNORM; 70 | break; 71 | case HAL_PIXEL_FORMAT_RGB_565: 72 | fmt = PIPE_FORMAT_B5G6R5_UNORM; 73 | break; 74 | case HAL_PIXEL_FORMAT_BGRA_8888: 75 | fmt = PIPE_FORMAT_B8G8R8A8_UNORM; 76 | break; 77 | case HAL_PIXEL_FORMAT_RGBA_5551: 78 | case HAL_PIXEL_FORMAT_RGBA_4444: 79 | case HAL_PIXEL_FORMAT_YV12: 80 | case HAL_PIXEL_FORMAT_YCbCr_422_SP: 81 | case HAL_PIXEL_FORMAT_YCrCb_420_SP: 82 | default: 83 | fmt = PIPE_FORMAT_NONE; 84 | break; 85 | } 86 | 87 | return fmt; 88 | } 89 | 90 | static unsigned get_pipe_bind(int usage) 91 | { 92 | unsigned bind = PIPE_BIND_SHARED; 93 | 94 | if (usage & GRALLOC_USAGE_SW_READ_MASK) 95 | bind |= PIPE_BIND_TRANSFER_READ; 96 | if (usage & GRALLOC_USAGE_SW_WRITE_MASK) 97 | bind |= PIPE_BIND_TRANSFER_WRITE; 98 | 99 | if (usage & GRALLOC_USAGE_HW_TEXTURE) 100 | bind |= PIPE_BIND_SAMPLER_VIEW; 101 | if (usage & GRALLOC_USAGE_HW_RENDER) 102 | bind |= PIPE_BIND_RENDER_TARGET; 103 | if (usage & GRALLOC_USAGE_HW_FB) { 104 | bind |= PIPE_BIND_RENDER_TARGET; 105 | bind |= PIPE_BIND_SCANOUT; 106 | } 107 | 108 | return bind; 109 | } 110 | 111 | static struct pipe_buffer *get_pipe_buffer_locked(struct pipe_manager *pm, 112 | const struct gralloc_drm_handle_t *handle) 113 | { 114 | struct pipe_buffer *buf; 115 | struct pipe_resource templ; 116 | 117 | memset(&templ, 0, sizeof(templ)); 118 | templ.format = get_pipe_format(handle->format); 119 | templ.bind = get_pipe_bind(handle->usage); 120 | templ.target = PIPE_TEXTURE_2D; 121 | 122 | if (templ.format == PIPE_FORMAT_NONE || 123 | !pm->screen->is_format_supported(pm->screen, templ.format, 124 | templ.target, 0, templ.bind)) { 125 | LOGE("unsupported format 0x%x", handle->format); 126 | return NULL; 127 | } 128 | 129 | buf = CALLOC(1, sizeof(*buf)); 130 | if (!buf) { 131 | LOGE("failed to allocate pipe buffer"); 132 | return NULL; 133 | } 134 | 135 | templ.width0 = handle->width; 136 | templ.height0 = handle->height; 137 | templ.depth0 = 1; 138 | templ.array_size = 1; 139 | 140 | if (handle->name) { 141 | buf->winsys.type = DRM_API_HANDLE_TYPE_SHARED; 142 | buf->winsys.handle = handle->name; 143 | buf->winsys.stride = handle->stride; 144 | 145 | buf->resource = pm->screen->resource_from_handle(pm->screen, 146 | &templ, &buf->winsys); 147 | if (!buf->resource) 148 | goto fail; 149 | } 150 | else { 151 | buf->resource = 152 | pm->screen->resource_create(pm->screen, &templ); 153 | if (!buf->resource) 154 | goto fail; 155 | 156 | buf->winsys.type = DRM_API_HANDLE_TYPE_SHARED; 157 | if (!pm->screen->resource_get_handle(pm->screen, 158 | buf->resource, &buf->winsys)) 159 | goto fail; 160 | } 161 | 162 | /* need the gem handle for fb */ 163 | if (handle->usage & GRALLOC_USAGE_HW_FB) { 164 | struct winsys_handle tmp; 165 | 166 | memset(&tmp, 0, sizeof(tmp)); 167 | tmp.type = DRM_API_HANDLE_TYPE_KMS; 168 | if (!pm->screen->resource_get_handle(pm->screen, 169 | buf->resource, &tmp)) 170 | goto fail; 171 | 172 | buf->base.fb_handle = tmp.handle; 173 | } 174 | 175 | return buf; 176 | 177 | fail: 178 | LOGE("failed to allocate pipe buffer"); 179 | if (buf->resource) 180 | pipe_resource_reference(&buf->resource, NULL); 181 | FREE(buf); 182 | 183 | return NULL; 184 | } 185 | 186 | static struct gralloc_drm_bo_t *pipe_alloc(struct gralloc_drm_drv_t *drv, 187 | struct gralloc_drm_handle_t *handle) 188 | { 189 | struct pipe_manager *pm = (struct pipe_manager *) drv; 190 | struct pipe_buffer *buf; 191 | 192 | pthread_mutex_lock(&pm->mutex); 193 | buf = get_pipe_buffer_locked(pm, handle); 194 | pthread_mutex_unlock(&pm->mutex); 195 | 196 | if (buf) { 197 | handle->name = (int) buf->winsys.handle; 198 | handle->stride = (int) buf->winsys.stride; 199 | 200 | buf->base.handle = handle; 201 | } 202 | 203 | return &buf->base; 204 | } 205 | 206 | static void pipe_free(struct gralloc_drm_drv_t *drv, struct gralloc_drm_bo_t *bo) 207 | { 208 | struct pipe_manager *pm = (struct pipe_manager *) drv; 209 | struct pipe_buffer *buf = (struct pipe_buffer *) bo; 210 | 211 | pthread_mutex_lock(&pm->mutex); 212 | 213 | if (buf->transfer) 214 | pipe_transfer_destroy(pm->context, buf->transfer); 215 | pipe_resource_reference(&buf->resource, NULL); 216 | 217 | pthread_mutex_unlock(&pm->mutex); 218 | 219 | FREE(buf); 220 | } 221 | 222 | static int pipe_map(struct gralloc_drm_drv_t *drv, 223 | struct gralloc_drm_bo_t *bo, int x, int y, int w, int h, 224 | int enable_write, void **addr) 225 | { 226 | struct pipe_manager *pm = (struct pipe_manager *) drv; 227 | struct pipe_buffer *buf = (struct pipe_buffer *) bo; 228 | int err = 0; 229 | 230 | pthread_mutex_lock(&pm->mutex); 231 | 232 | /* need a context to get transfer */ 233 | if (!pm->context) { 234 | pm->context = pm->screen->context_create(pm->screen, NULL); 235 | if (!pm->context) { 236 | LOGE("failed to create pipe context"); 237 | err = -ENOMEM; 238 | } 239 | } 240 | 241 | if (!err) { 242 | enum pipe_transfer_usage usage; 243 | 244 | usage = PIPE_TRANSFER_READ; 245 | if (enable_write) 246 | usage |= PIPE_TRANSFER_WRITE; 247 | 248 | assert(!buf->transfer); 249 | 250 | /* 251 | * ignore x, y, w and h so that returned addr points at the 252 | * start of the buffer 253 | */ 254 | buf->transfer = pipe_get_transfer(pm->context, buf->resource, 255 | 0, 0, usage, 0, 0, 256 | buf->resource->width0, buf->resource->height0); 257 | if (buf->transfer) 258 | *addr = pipe_transfer_map(pm->context, buf->transfer); 259 | else 260 | err = -ENOMEM; 261 | } 262 | 263 | pthread_mutex_unlock(&pm->mutex); 264 | 265 | return err; 266 | } 267 | 268 | static void pipe_unmap(struct gralloc_drm_drv_t *drv, 269 | struct gralloc_drm_bo_t *bo) 270 | { 271 | struct pipe_manager *pm = (struct pipe_manager *) drv; 272 | struct pipe_buffer *buf = (struct pipe_buffer *) bo; 273 | 274 | pthread_mutex_lock(&pm->mutex); 275 | 276 | assert(buf && buf->transfer); 277 | 278 | pipe_transfer_unmap(pm->context, buf->transfer); 279 | pipe_transfer_destroy(pm->context, buf->transfer); 280 | buf->transfer = NULL; 281 | 282 | pm->context->flush(pm->context, NULL); 283 | 284 | pthread_mutex_unlock(&pm->mutex); 285 | } 286 | 287 | static void pipe_copy(struct gralloc_drm_drv_t *drv, 288 | struct gralloc_drm_bo_t *dst_bo, 289 | struct gralloc_drm_bo_t *src_bo, 290 | short x1, short y1, short x2, short y2) 291 | { 292 | struct pipe_manager *pm = (struct pipe_manager *) drv; 293 | struct pipe_buffer *dst = (struct pipe_buffer *) dst_bo; 294 | struct pipe_buffer *src = (struct pipe_buffer *) src_bo; 295 | struct pipe_box src_box; 296 | 297 | if (dst_bo->handle->width != src_bo->handle->width || 298 | dst_bo->handle->height != src_bo->handle->height || 299 | dst_bo->handle->stride != src_bo->handle->stride || 300 | dst_bo->handle->format != src_bo->handle->format) { 301 | LOGE("copy between incompatible buffers"); 302 | return; 303 | } 304 | 305 | if (x1 < 0) 306 | x1 = 0; 307 | if (y1 < 0) 308 | y1 = 0; 309 | if (x2 > dst_bo->handle->width) 310 | x2 = dst_bo->handle->width; 311 | if (y2 > dst_bo->handle->height) 312 | y2 = dst_bo->handle->height; 313 | 314 | if (x2 <= x1 || y2 <= y1) 315 | return; 316 | 317 | u_box_2d(x1, y1, x2 - x1, y2 - y1, &src_box); 318 | 319 | pthread_mutex_lock(&pm->mutex); 320 | 321 | /* need a context for copying */ 322 | if (!pm->context) { 323 | pm->context = pm->screen->context_create(pm->screen, NULL); 324 | if (!pm->context) { 325 | LOGE("failed to create pipe context"); 326 | pthread_mutex_unlock(&pm->mutex); 327 | return; 328 | } 329 | } 330 | 331 | pm->context->resource_copy_region(pm->context, 332 | dst->resource, 0, x1, y1, 0, 333 | src->resource, 0, &src_box); 334 | pm->context->flush(pm->context, NULL); 335 | 336 | pthread_mutex_unlock(&pm->mutex); 337 | } 338 | 339 | static void pipe_init_kms_features(struct gralloc_drm_drv_t *drv, struct gralloc_drm_t *drm) 340 | { 341 | struct pipe_manager *pm = (struct pipe_manager *) drv; 342 | 343 | switch (drm->fb_format) { 344 | case HAL_PIXEL_FORMAT_BGRA_8888: 345 | case HAL_PIXEL_FORMAT_RGB_565: 346 | break; 347 | default: 348 | drm->fb_format = HAL_PIXEL_FORMAT_BGRA_8888; 349 | break; 350 | } 351 | 352 | if (strcmp(pm->driver, "vmwgfx") == 0) { 353 | drm->mode_quirk_vmwgfx = 1; 354 | drm->swap_mode = DRM_SWAP_COPY; 355 | } 356 | else { 357 | drm->mode_quirk_vmwgfx = 0; 358 | drm->swap_mode = DRM_SWAP_FLIP; 359 | } 360 | drm->mode_sync_flip = 1; 361 | drm->swap_interval = 1; 362 | drm->vblank_secondary = 0; 363 | } 364 | 365 | static void pipe_destroy(struct gralloc_drm_drv_t *drv) 366 | { 367 | struct pipe_manager *pm = (struct pipe_manager *) drv; 368 | 369 | if (pm->context) 370 | pm->context->destroy(pm->context); 371 | pm->screen->destroy(pm->screen); 372 | FREE(pm); 373 | } 374 | 375 | /* for nouveau */ 376 | #include "nouveau/drm/nouveau_drm_public.h" 377 | /* for r300 */ 378 | #include "radeon/drm/radeon_drm_public.h" 379 | #include "r300/r300_public.h" 380 | /* for r600 */ 381 | #include "r600/drm/r600_drm_public.h" 382 | #include "r600/r600_public.h" 383 | /* for vmwgfx */ 384 | #include "svga/drm/svga_drm_public.h" 385 | #include "svga/svga_winsys.h" 386 | #include "svga/svga_public.h" 387 | /* for debug */ 388 | #include "target-helpers/inline_debug_helper.h" 389 | 390 | static int pipe_init_screen(struct pipe_manager *pm) 391 | { 392 | struct pipe_screen *screen = NULL; 393 | 394 | #ifdef ENABLE_PIPE_NOUVEAU 395 | if (strcmp(pm->driver, "nouveau") == 0) 396 | screen = nouveau_drm_screen_create(pm->fd); 397 | #endif 398 | #ifdef ENABLE_PIPE_R300 399 | if (strcmp(pm->driver, "r300") == 0) { 400 | struct radeon_winsys *sws = radeon_drm_winsys_create(pm->fd); 401 | 402 | if (sws) { 403 | screen = r300_screen_create(sws); 404 | if (!screen) 405 | sws->destroy(sws); 406 | } 407 | } 408 | #endif 409 | #ifdef ENABLE_PIPE_R600 410 | if (strcmp(pm->driver, "r600") == 0) { 411 | struct radeon *rw = r600_drm_winsys_create(pm->fd); 412 | 413 | if (rw) { 414 | screen = r600_screen_create(rw); 415 | if (!screen) 416 | FREE(rw); 417 | } 418 | } 419 | #endif 420 | #ifdef ENABLE_PIPE_VMWGFX 421 | if (strcmp(pm->driver, "vmwgfx") == 0) { 422 | struct svga_winsys_screen *sws = 423 | svga_drm_winsys_screen_create(pm->fd); 424 | 425 | if (sws) { 426 | screen = svga_screen_create(sws); 427 | if (!screen) 428 | sws->destroy(sws); 429 | } 430 | } 431 | #endif 432 | 433 | if (!screen) { 434 | LOGW("failed to create screen for %s", pm->driver); 435 | return -EINVAL; 436 | } 437 | 438 | pm->screen = debug_screen_wrap(screen); 439 | 440 | return 0; 441 | } 442 | 443 | #include 444 | #include 445 | #include 446 | static int pipe_get_pci_id(struct pipe_manager *pm, 447 | const char *name, int *vendor, int *device) 448 | { 449 | int err = -EINVAL; 450 | 451 | if (strcmp(name, "i915") == 0) { 452 | struct drm_i915_getparam gp; 453 | 454 | *vendor = 0x8086; 455 | 456 | memset(&gp, 0, sizeof(gp)); 457 | gp.param = I915_PARAM_CHIPSET_ID; 458 | gp.value = device; 459 | err = drmCommandWriteRead(pm->fd, DRM_I915_GETPARAM, &gp, sizeof(gp)); 460 | } 461 | else if (strcmp(name, "radeon") == 0) { 462 | struct drm_radeon_info info; 463 | 464 | *vendor = 0x1002; 465 | 466 | memset(&info, 0, sizeof(info)); 467 | info.request = RADEON_INFO_DEVICE_ID; 468 | info.value = (long) device; 469 | err = drmCommandWriteRead(pm->fd, DRM_RADEON_INFO, &info, sizeof(info)); 470 | } 471 | else if (strcmp(name, "nouveau") == 0) { 472 | *vendor = 0x10de; 473 | *device = 0; 474 | err = 0; 475 | } 476 | else if (strcmp(name, "vmwgfx") == 0) { 477 | *vendor = 0x15ad; 478 | /* assume SVGA II */ 479 | *device = 0x0405; 480 | err = 0; 481 | } 482 | else { 483 | err = -EINVAL; 484 | } 485 | 486 | return err; 487 | } 488 | 489 | #define DRIVER_MAP_GALLIUM_ONLY 490 | #include "pci_ids/pci_id_driver_map.h" 491 | static int pipe_find_driver(struct pipe_manager *pm, const char *name) 492 | { 493 | int vendor, device; 494 | int err; 495 | const char *driver; 496 | 497 | err = pipe_get_pci_id(pm, name, &vendor, &device); 498 | if (!err) { 499 | int idx; 500 | 501 | /* look up in the driver map */ 502 | for (idx = 0; driver_map[idx].driver; idx++) { 503 | int i; 504 | 505 | if (vendor != driver_map[idx].vendor_id) 506 | continue; 507 | 508 | if (driver_map[idx].num_chips_ids == -1) 509 | break; 510 | 511 | for (i = 0; i < driver_map[idx].num_chips_ids; i++) { 512 | if (driver_map[idx].chip_ids[i] == device) 513 | break; 514 | } 515 | if (i < driver_map[idx].num_chips_ids) 516 | break; 517 | } 518 | 519 | driver = driver_map[idx].driver; 520 | err = (driver) ? 0 : -ENODEV; 521 | } 522 | else { 523 | if (strcmp(name, "vmwgfx") == 0) { 524 | driver = "vmwgfx"; 525 | err = 0; 526 | } 527 | } 528 | 529 | if (!err) 530 | strncpy(pm->driver, driver, sizeof(pm->driver) - 1); 531 | 532 | return err; 533 | } 534 | 535 | struct gralloc_drm_drv_t *gralloc_drm_drv_create_for_pipe(int fd, const char *name) 536 | { 537 | struct pipe_manager *pm; 538 | 539 | pm = CALLOC(1, sizeof(*pm)); 540 | if (!pm) { 541 | LOGE("failed to allocate pipe manager for %s", name); 542 | return NULL; 543 | } 544 | 545 | pm->fd = fd; 546 | pthread_mutex_init(&pm->mutex, NULL); 547 | 548 | if (pipe_find_driver(pm, name)) { 549 | FREE(pm); 550 | return NULL; 551 | } 552 | 553 | if (pipe_init_screen(pm)) { 554 | FREE(pm); 555 | return NULL; 556 | } 557 | 558 | pm->base.destroy = pipe_destroy; 559 | pm->base.init_kms_features = pipe_init_kms_features; 560 | pm->base.alloc = pipe_alloc; 561 | pm->base.free = pipe_free; 562 | pm->base.map = pipe_map; 563 | pm->base.unmap = pipe_unmap; 564 | pm->base.copy = pipe_copy; 565 | 566 | return &pm->base; 567 | } 568 | -------------------------------------------------------------------------------- /gralloc_drm_kms.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2011 Chia-I Wu 3 | * Copyright (C) 2010-2011 LunarG Inc. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a 6 | * copy of this software and associated documentation files (the "Software"), 7 | * to deal in the Software without restriction, including without limitation 8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 | * and/or sell copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included 13 | * in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 | * DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | #define LOG_TAG "GRALLOC-KMS" 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include "gralloc_drm.h" 34 | #include "gralloc_drm_priv.h" 35 | 36 | /* 37 | * Return true if a bo needs fb. 38 | */ 39 | int gralloc_drm_bo_need_fb(const struct gralloc_drm_bo_t *bo) 40 | { 41 | return ((bo->handle->usage & GRALLOC_USAGE_HW_FB) && 42 | bo->drm->swap_mode != DRM_SWAP_COPY); 43 | } 44 | 45 | /* 46 | * Add a fb object for a bo. 47 | */ 48 | int gralloc_drm_bo_add_fb(struct gralloc_drm_bo_t *bo) 49 | { 50 | uint8_t bpp; 51 | 52 | if (bo->fb_id) 53 | return 0; 54 | 55 | bpp = gralloc_drm_get_bpp(bo->handle->format) * 8; 56 | 57 | return drmModeAddFB(bo->drm->fd, 58 | bo->handle->width, bo->handle->height, bpp, bpp, 59 | bo->handle->stride, bo->fb_handle, 60 | (uint32_t *) &bo->fb_id); 61 | } 62 | 63 | /* 64 | * Remove a fb object for a bo. 65 | */ 66 | void gralloc_drm_bo_rm_fb(struct gralloc_drm_bo_t *bo) 67 | { 68 | if (bo->fb_id) { 69 | drmModeRmFB(bo->drm->fd, bo->fb_id); 70 | bo->fb_id = 0; 71 | } 72 | } 73 | 74 | /* 75 | * Program CRTC. 76 | */ 77 | static int drm_kms_set_crtc(struct gralloc_drm_t *drm, int fb_id) 78 | { 79 | int ret; 80 | 81 | ret = drmModeSetCrtc(drm->fd, drm->crtc_id, fb_id, 82 | 0, 0, &drm->connector_id, 1, &drm->mode); 83 | if (ret) { 84 | LOGE("failed to set crtc"); 85 | return ret; 86 | } 87 | 88 | if (drm->mode_quirk_vmwgfx) 89 | ret = drmModeDirtyFB(drm->fd, fb_id, &drm->clip, 1); 90 | 91 | return ret; 92 | } 93 | 94 | /* 95 | * Callback for a page flip event. 96 | */ 97 | static void page_flip_handler(int fd, unsigned int sequence, 98 | unsigned int tv_sec, unsigned int tv_usec, 99 | void *user_data) 100 | { 101 | struct gralloc_drm_t *drm = (struct gralloc_drm_t *) user_data; 102 | 103 | /* ack the last scheduled flip */ 104 | drm->current_front = drm->next_front; 105 | drm->next_front = NULL; 106 | } 107 | 108 | /* 109 | * Schedule a page flip. 110 | */ 111 | static int drm_kms_page_flip(struct gralloc_drm_t *drm, 112 | struct gralloc_drm_bo_t *bo) 113 | { 114 | int ret; 115 | 116 | /* there is another flip pending */ 117 | while (drm->next_front) { 118 | drm->waiting_flip = 1; 119 | drmHandleEvent(drm->fd, &drm->evctx); 120 | drm->waiting_flip = 0; 121 | if (drm->next_front) { 122 | /* record an error and break */ 123 | LOGE("drmHandleEvent returned without flipping"); 124 | drm->current_front = drm->next_front; 125 | drm->next_front = NULL; 126 | } 127 | } 128 | 129 | if (!bo) 130 | return 0; 131 | 132 | ret = drmModePageFlip(drm->fd, drm->crtc_id, bo->fb_id, 133 | DRM_MODE_PAGE_FLIP_EVENT, (void *) drm); 134 | if (ret) 135 | LOGE("failed to perform page flip"); 136 | else 137 | drm->next_front = bo; 138 | 139 | return ret; 140 | } 141 | 142 | /* 143 | * Wait for the next post. 144 | */ 145 | static void drm_kms_wait_for_post(struct gralloc_drm_t *drm, int flip) 146 | { 147 | unsigned int current, target; 148 | drmVBlank vbl; 149 | int ret; 150 | 151 | if (drm->mode_quirk_vmwgfx) 152 | return; 153 | 154 | flip = !!flip; 155 | 156 | memset(&vbl, 0, sizeof(vbl)); 157 | vbl.request.type = DRM_VBLANK_RELATIVE; 158 | if (drm->vblank_secondary) 159 | vbl.request.type |= DRM_VBLANK_SECONDARY; 160 | vbl.request.sequence = 0; 161 | 162 | /* get the current vblank */ 163 | ret = drmWaitVBlank(drm->fd, &vbl); 164 | if (ret) { 165 | LOGW("failed to get vblank"); 166 | return; 167 | } 168 | 169 | current = vbl.reply.sequence; 170 | if (drm->first_post) 171 | target = current; 172 | else 173 | target = drm->last_swap + drm->swap_interval - flip; 174 | 175 | /* wait for vblank */ 176 | if (current < target || !flip) { 177 | memset(&vbl, 0, sizeof(vbl)); 178 | vbl.request.type = DRM_VBLANK_ABSOLUTE; 179 | if (drm->vblank_secondary) 180 | vbl.request.type |= DRM_VBLANK_SECONDARY; 181 | if (!flip) { 182 | vbl.request.type |= DRM_VBLANK_NEXTONMISS; 183 | if (target < current) 184 | target = current; 185 | } 186 | 187 | vbl.request.sequence = target; 188 | 189 | ret = drmWaitVBlank(drm->fd, &vbl); 190 | if (ret) { 191 | LOGW("failed to wait vblank"); 192 | return; 193 | } 194 | } 195 | 196 | drm->last_swap = vbl.reply.sequence + flip; 197 | } 198 | 199 | /* 200 | * Post a bo. This is not thread-safe. 201 | */ 202 | int gralloc_drm_bo_post(struct gralloc_drm_bo_t *bo) 203 | { 204 | struct gralloc_drm_t *drm = bo->drm; 205 | int ret; 206 | 207 | if (!bo->fb_id && drm->swap_mode != DRM_SWAP_COPY) { 208 | LOGE("unable to post bo %p without fb", bo); 209 | return -EINVAL; 210 | } 211 | 212 | /* TODO spawn a thread to avoid waiting and race */ 213 | 214 | if (drm->first_post) { 215 | if (drm->swap_mode == DRM_SWAP_COPY) { 216 | struct gralloc_drm_bo_t *dst; 217 | 218 | dst = (drm->next_front) ? 219 | drm->next_front : 220 | drm->current_front; 221 | drm->drv->copy(drm->drv, dst, bo, 0, 0, 222 | bo->handle->width, 223 | bo->handle->height); 224 | bo = dst; 225 | } 226 | 227 | ret = drm_kms_set_crtc(drm, bo->fb_id); 228 | if (!ret) { 229 | drm->first_post = 0; 230 | drm->current_front = bo; 231 | if (drm->next_front == bo) 232 | drm->next_front = NULL; 233 | } 234 | 235 | return ret; 236 | } 237 | 238 | switch (drm->swap_mode) { 239 | case DRM_SWAP_FLIP: 240 | if (drm->swap_interval > 1) 241 | drm_kms_wait_for_post(drm, 1); 242 | ret = drm_kms_page_flip(drm, bo); 243 | if (drm->next_front) { 244 | /* 245 | * wait if the driver says so or the current front 246 | * will be written by CPU 247 | */ 248 | if (drm->mode_sync_flip || 249 | (drm->current_front->handle->usage & 250 | GRALLOC_USAGE_SW_WRITE_MASK)) 251 | drm_kms_page_flip(drm, NULL); 252 | } 253 | break; 254 | case DRM_SWAP_COPY: 255 | drm_kms_wait_for_post(drm, 0); 256 | drm->drv->copy(drm->drv, drm->current_front, 257 | bo, 0, 0, 258 | bo->handle->width, 259 | bo->handle->height); 260 | if (drm->mode_quirk_vmwgfx) 261 | ret = drmModeDirtyFB(drm->fd, drm->current_front->fb_id, &drm->clip, 1); 262 | ret = 0; 263 | break; 264 | case DRM_SWAP_SETCRTC: 265 | drm_kms_wait_for_post(drm, 0); 266 | ret = drm_kms_set_crtc(drm, bo->fb_id); 267 | drm->current_front = bo; 268 | break; 269 | default: 270 | /* no-op */ 271 | ret = 0; 272 | break; 273 | } 274 | 275 | return ret; 276 | } 277 | 278 | static struct gralloc_drm_t *drm_singleton; 279 | 280 | static void on_signal(int sig) 281 | { 282 | struct gralloc_drm_t *drm = drm_singleton; 283 | 284 | /* wait the pending flip */ 285 | if (drm && drm->swap_mode == DRM_SWAP_FLIP && drm->next_front) { 286 | /* there is race, but this function is hacky enough to ignore that */ 287 | if (drm_singleton->waiting_flip) 288 | usleep(100 * 1000); /* 100ms */ 289 | else 290 | drm_kms_page_flip(drm_singleton, NULL); 291 | } 292 | 293 | exit(-1); 294 | } 295 | 296 | static void drm_kms_init_features(struct gralloc_drm_t *drm) 297 | { 298 | const char *swap_mode; 299 | 300 | /* call to the driver here, after KMS has been initialized */ 301 | drm->drv->init_kms_features(drm->drv, drm); 302 | 303 | if (drm->swap_mode == DRM_SWAP_FLIP) { 304 | struct sigaction act; 305 | 306 | memset(&drm->evctx, 0, sizeof(drm->evctx)); 307 | drm->evctx.version = DRM_EVENT_CONTEXT_VERSION; 308 | drm->evctx.page_flip_handler = page_flip_handler; 309 | 310 | /* 311 | * XXX GPU tends to freeze if the program is terminiated with a 312 | * flip pending. What is the right way to handle the 313 | * situation? 314 | */ 315 | sigemptyset(&act.sa_mask); 316 | act.sa_handler = on_signal; 317 | act.sa_flags = 0; 318 | sigaction(SIGINT, &act, NULL); 319 | sigaction(SIGTERM, &act, NULL); 320 | 321 | drm_singleton = drm; 322 | } 323 | else if (drm->swap_mode == DRM_SWAP_COPY) { 324 | struct gralloc_drm_bo_t *front; 325 | int stride; 326 | 327 | /* create the real front buffer */ 328 | front = gralloc_drm_bo_create(drm, 329 | drm->mode.hdisplay, 330 | drm->mode.vdisplay, 331 | drm->fb_format, 332 | GRALLOC_USAGE_HW_FB); 333 | if (front && gralloc_drm_bo_add_fb(front)) { 334 | gralloc_drm_bo_destroy(front); 335 | front = NULL; 336 | } 337 | 338 | /* abuse next_front */ 339 | if (front) 340 | drm->next_front = front; 341 | else 342 | drm->swap_mode = DRM_SWAP_SETCRTC; 343 | } 344 | 345 | switch (drm->swap_mode) { 346 | case DRM_SWAP_FLIP: 347 | swap_mode = "flip"; 348 | break; 349 | case DRM_SWAP_COPY: 350 | swap_mode = "copy"; 351 | break; 352 | case DRM_SWAP_SETCRTC: 353 | swap_mode = "set-crtc"; 354 | break; 355 | default: 356 | swap_mode = "no-op"; 357 | break; 358 | } 359 | 360 | LOGD("will use %s for fb posting", swap_mode); 361 | } 362 | 363 | static drmModeModeInfoPtr find_mode(drmModeConnectorPtr connector, int *bpp) 364 | { 365 | char value[PROPERTY_VALUE_MAX]; 366 | drmModeModeInfoPtr mode; 367 | int dist, i; 368 | int xres = 0, yres = 0; 369 | 370 | if (property_get("debug.drm.mode", value, NULL)) { 371 | char *p = value, *end; 372 | 373 | /* parse x[@] */ 374 | if (sscanf(value, "%dx%d@%d", &xres, &yres, bpp) != 3) { 375 | *bpp = 0; 376 | if (sscanf(value, "%dx%d", &xres, &yres) != 2) 377 | xres = yres = 0; 378 | } 379 | 380 | if ((xres && yres) || *bpp) { 381 | LOGI("will find the closest match for %dx%d@%d", 382 | xres, yres, *bpp); 383 | } 384 | } 385 | else { 386 | *bpp = 0; 387 | } 388 | 389 | mode = NULL; 390 | dist = INT_MAX; 391 | for (i = 0; i < connector->count_modes; i++) { 392 | drmModeModeInfoPtr m = &connector->modes[i]; 393 | int tmp; 394 | 395 | if (xres && yres) { 396 | tmp = (m->hdisplay - xres) * (m->hdisplay - xres) + 397 | (m->vdisplay - yres) * (m->vdisplay - yres); 398 | } 399 | else { 400 | /* use the first preferred mode */ 401 | tmp = (m->type & DRM_MODE_TYPE_PREFERRED) ? 0 : dist; 402 | } 403 | 404 | if (tmp < dist) { 405 | mode = m; 406 | dist = tmp; 407 | if (!dist) 408 | break; 409 | } 410 | } 411 | 412 | /* fallback to the first mode */ 413 | if (!mode) 414 | mode = &connector->modes[0]; 415 | 416 | *bpp /= 8; 417 | 418 | return mode; 419 | } 420 | 421 | /* 422 | * Initialize KMS with a connector. 423 | */ 424 | static int drm_kms_init_with_connector(struct gralloc_drm_t *drm, 425 | drmModeConnectorPtr connector) 426 | { 427 | drmModeEncoderPtr encoder; 428 | drmModeModeInfoPtr mode; 429 | int bpp, i; 430 | 431 | if (!connector->count_modes) 432 | return -EINVAL; 433 | 434 | encoder = drmModeGetEncoder(drm->fd, connector->encoders[0]); 435 | if (!encoder) 436 | return -EINVAL; 437 | 438 | for (i = 0; i < drm->resources->count_crtcs; i++) { 439 | if (encoder->possible_crtcs & (1 << i)) 440 | break; 441 | } 442 | drmModeFreeEncoder(encoder); 443 | if (i == drm->resources->count_crtcs) 444 | return -EINVAL; 445 | 446 | drm->crtc_id = drm->resources->crtcs[i]; 447 | drm->connector_id = connector->connector_id; 448 | 449 | /* print connector info */ 450 | if (connector->count_modes > 1) { 451 | LOGI("there are %d modes on connector 0x%x", 452 | connector->count_modes, 453 | connector->connector_id); 454 | for (i = 0; i < connector->count_modes; i++) 455 | LOGI(" %s", connector->modes[i].name); 456 | } 457 | else { 458 | LOGI("there is one mode on connector 0x%d: %s", 459 | connector->connector_id, 460 | connector->modes[0].name); 461 | } 462 | 463 | mode = find_mode(connector, &bpp); 464 | 465 | LOGI("the best mode is %s", mode->name); 466 | 467 | drm->mode = *mode; 468 | switch (bpp) { 469 | case 2: 470 | drm->fb_format = HAL_PIXEL_FORMAT_RGB_565; 471 | break; 472 | case 4: 473 | default: 474 | drm->fb_format = HAL_PIXEL_FORMAT_BGRA_8888; 475 | break; 476 | } 477 | 478 | if (connector->mmWidth && connector->mmHeight) { 479 | drm->xdpi = (drm->mode.hdisplay * 25.4 / connector->mmWidth); 480 | drm->ydpi = (drm->mode.vdisplay * 25.4 / connector->mmHeight); 481 | } 482 | else { 483 | drm->xdpi = 75; 484 | drm->ydpi = 75; 485 | } 486 | 487 | #ifdef DRM_MODE_FEATURE_DIRTYFB 488 | drm->clip.x1 = 0; 489 | drm->clip.y1 = 0; 490 | drm->clip.x2 = drm->mode.hdisplay; 491 | drm->clip.y2 = drm->mode.vdisplay; 492 | #endif 493 | 494 | return 0; 495 | } 496 | 497 | /* 498 | * Initialize KMS. 499 | */ 500 | int gralloc_drm_init_kms(struct gralloc_drm_t *drm) 501 | { 502 | int i, ret; 503 | 504 | if (drm->resources) 505 | return 0; 506 | 507 | drm->resources = drmModeGetResources(drm->fd); 508 | if (!drm->resources) { 509 | LOGE("failed to get modeset resources"); 510 | return -EINVAL; 511 | } 512 | 513 | /* find the crtc/connector/mode to use */ 514 | for (i = 0; i < drm->resources->count_connectors; i++) { 515 | drmModeConnectorPtr connector; 516 | 517 | connector = drmModeGetConnector(drm->fd, 518 | drm->resources->connectors[i]); 519 | if (connector) { 520 | if (connector->connection == DRM_MODE_CONNECTED) { 521 | if (!drm_kms_init_with_connector(drm, 522 | connector)) 523 | break; 524 | } 525 | 526 | drmModeFreeConnector(connector); 527 | } 528 | } 529 | if (i == drm->resources->count_connectors) { 530 | LOGE("failed to find a valid crtc/connector/mode combination"); 531 | drmModeFreeResources(drm->resources); 532 | drm->resources = NULL; 533 | 534 | return -EINVAL; 535 | } 536 | 537 | drm_kms_init_features(drm); 538 | drm->first_post = 1; 539 | 540 | return 0; 541 | } 542 | 543 | void gralloc_drm_fini_kms(struct gralloc_drm_t *drm) 544 | { 545 | switch (drm->swap_mode) { 546 | case DRM_SWAP_FLIP: 547 | drm_kms_page_flip(drm, NULL); 548 | break; 549 | case DRM_SWAP_COPY: 550 | { 551 | struct gralloc_drm_bo_t **bo = (drm->current_front) ? 552 | &drm->current_front : &drm->next_front; 553 | 554 | if (*bo) 555 | gralloc_drm_bo_destroy(*bo); 556 | *bo = NULL; 557 | } 558 | break; 559 | default: 560 | break; 561 | } 562 | 563 | /* restore crtc? */ 564 | 565 | if (drm->resources) { 566 | drmModeFreeResources(drm->resources); 567 | drm->resources = NULL; 568 | } 569 | 570 | drm_singleton = NULL; 571 | } 572 | 573 | int gralloc_drm_is_kms_initialized(struct gralloc_drm_t *drm) 574 | { 575 | return (drm->resources != NULL); 576 | } 577 | 578 | /* 579 | * Initialize a framebuffer device with KMS info. 580 | */ 581 | void gralloc_drm_get_kms_info(struct gralloc_drm_t *drm, 582 | struct framebuffer_device_t *fb) 583 | { 584 | *((uint32_t *) &fb->flags) = 0x0; 585 | *((uint32_t *) &fb->width) = drm->mode.hdisplay; 586 | *((uint32_t *) &fb->height) = drm->mode.vdisplay; 587 | *((int *) &fb->stride) = drm->mode.hdisplay; 588 | *((float *) &fb->fps) = drm->mode.vrefresh; 589 | 590 | *((int *) &fb->format) = drm->fb_format; 591 | *((float *) &fb->xdpi) = drm->xdpi; 592 | *((float *) &fb->ydpi) = drm->ydpi; 593 | *((int *) &fb->minSwapInterval) = drm->swap_interval; 594 | *((int *) &fb->maxSwapInterval) = drm->swap_interval; 595 | } 596 | 597 | /* 598 | * Return true if fb posting is pipelined. 599 | */ 600 | int gralloc_drm_is_kms_pipelined(struct gralloc_drm_t *drm) 601 | { 602 | return (drm->swap_mode != DRM_SWAP_SETCRTC); 603 | } 604 | -------------------------------------------------------------------------------- /gralloc_drm_intel.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2011 Chia-I Wu 3 | * Copyright (C) 2010-2011 LunarG Inc. 4 | * 5 | * drm_gem_intel_copy is based on xorg-driver-intel, which has 6 | * 7 | * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. 8 | * All Rights Reserved. 9 | * Copyright (c) 2005 Jesse Barnes 10 | * 11 | * Permission is hereby granted, free of charge, to any person obtaining a 12 | * copy of this software and associated documentation files (the "Software"), 13 | * to deal in the Software without restriction, including without limitation 14 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 15 | * and/or sell copies of the Software, and to permit persons to whom the 16 | * Software is furnished to do so, subject to the following conditions: 17 | * 18 | * The above copyright notice and this permission notice shall be included 19 | * in all copies or substantial portions of the Software. 20 | * 21 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 24 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 26 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 27 | * DEALINGS IN THE SOFTWARE. 28 | */ 29 | 30 | #define LOG_TAG "GRALLOC-I915" 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | #include "gralloc_drm.h" 41 | #include "gralloc_drm_priv.h" 42 | 43 | #define MI_NOOP (0) 44 | #define MI_BATCH_BUFFER_END (0x0a << 23) 45 | #define MI_FLUSH (0x04 << 23) 46 | #define MI_FLUSH_DW (0x26 << 23) 47 | #define MI_WRITE_DIRTY_STATE (1 << 4) 48 | #define MI_INVALIDATE_MAP_CACHE (1 << 0) 49 | #define XY_SRC_COPY_BLT_CMD ((2 << 29) | (0x53 << 22) | 6) 50 | #define XY_SRC_COPY_BLT_WRITE_ALPHA (1 << 21) 51 | #define XY_SRC_COPY_BLT_WRITE_RGB (1 << 20) 52 | #define XY_SRC_COPY_BLT_SRC_TILED (1 << 15) 53 | #define XY_SRC_COPY_BLT_DST_TILED (1 << 11) 54 | 55 | struct intel_info { 56 | struct gralloc_drm_drv_t base; 57 | 58 | int fd; 59 | drm_intel_bufmgr *bufmgr; 60 | int gen; 61 | 62 | drm_intel_bo *batch_ibo; 63 | uint32_t *batch, *cur; 64 | int capacity, size; 65 | }; 66 | 67 | struct intel_buffer { 68 | struct gralloc_drm_bo_t base; 69 | drm_intel_bo *ibo; 70 | uint32_t tiling; 71 | }; 72 | 73 | static int 74 | batch_next(struct intel_info *info) 75 | { 76 | info->cur = info->batch; 77 | 78 | if (info->batch_ibo) 79 | drm_intel_bo_unreference(info->batch_ibo); 80 | 81 | info->batch_ibo = drm_intel_bo_alloc(info->bufmgr, 82 | "gralloc-batchbuffer", info->size, 4096); 83 | 84 | return (info->batch_ibo) ? 0 : -ENOMEM; 85 | } 86 | 87 | static int 88 | batch_count(struct intel_info *info) 89 | { 90 | return info->cur - info->batch; 91 | } 92 | 93 | static void 94 | batch_dword(struct intel_info *info, uint32_t dword) 95 | { 96 | *info->cur++ = dword; 97 | } 98 | 99 | static int 100 | batch_reloc(struct intel_info *info, struct gralloc_drm_bo_t *bo, 101 | uint32_t read_domains, uint32_t write_domain) 102 | { 103 | struct intel_buffer *target = (struct intel_buffer *) bo; 104 | uint32_t offset = (info->cur - info->batch) * sizeof(info->batch[0]); 105 | int ret; 106 | 107 | ret = drm_intel_bo_emit_reloc(info->batch_ibo, offset, 108 | target->ibo, 0, read_domains, write_domain); 109 | if (!ret) 110 | batch_dword(info, target->ibo->offset); 111 | 112 | return ret; 113 | } 114 | 115 | static int 116 | batch_flush(struct intel_info *info) 117 | { 118 | int size, ret; 119 | 120 | batch_dword(info, MI_BATCH_BUFFER_END); 121 | size = batch_count(info); 122 | if (size & 1) { 123 | batch_dword(info, MI_NOOP); 124 | size = batch_count(info); 125 | } 126 | 127 | size *= sizeof(info->batch[0]); 128 | ret = drm_intel_bo_subdata(info->batch_ibo, 0, size, info->batch); 129 | if (ret) { 130 | LOGE("failed to subdata batch"); 131 | goto fail; 132 | } 133 | ret = drm_intel_bo_exec(info->batch_ibo, size, NULL, 0, 0); 134 | if (ret) { 135 | LOGE("failed to exec batch"); 136 | goto fail; 137 | } 138 | 139 | return batch_next(info); 140 | 141 | fail: 142 | info->cur = info->batch; 143 | 144 | return ret; 145 | } 146 | 147 | static int 148 | batch_reserve(struct intel_info *info, int count) 149 | { 150 | int ret = 0; 151 | 152 | if (batch_count(info) + count > info->capacity) 153 | ret = batch_flush(info); 154 | 155 | return ret; 156 | } 157 | 158 | static void 159 | batch_destroy(struct intel_info *info) 160 | { 161 | if (info->batch_ibo) { 162 | drm_intel_bo_unreference(info->batch_ibo); 163 | info->batch_ibo = NULL; 164 | } 165 | 166 | if (info->batch) { 167 | free(info->batch); 168 | info->batch = NULL; 169 | } 170 | } 171 | 172 | static int 173 | batch_init(struct intel_info *info) 174 | { 175 | int ret; 176 | 177 | info->capacity = 512; 178 | info->size = (info->capacity + 16) * sizeof(info->batch[0]); 179 | 180 | info->batch = malloc(info->size); 181 | if (!info->batch) 182 | return -ENOMEM; 183 | 184 | ret = batch_next(info); 185 | if (ret) { 186 | free(info->batch); 187 | info->batch = NULL; 188 | } 189 | 190 | return ret; 191 | } 192 | 193 | static void intel_copy(struct gralloc_drm_drv_t *drv, 194 | struct gralloc_drm_bo_t *dst, 195 | struct gralloc_drm_bo_t *src, 196 | short x1, short y1, short x2, short y2) 197 | { 198 | struct intel_info *info = (struct intel_info *) drv; 199 | struct intel_buffer *dst_ib = (struct intel_buffer *) dst; 200 | struct intel_buffer *src_ib = (struct intel_buffer *) src; 201 | drm_intel_bo *bo_table[3]; 202 | uint32_t cmd, br13, dst_pitch, src_pitch; 203 | 204 | if (dst->handle->width != src->handle->width || 205 | dst->handle->height != src->handle->height || 206 | dst->handle->stride != src->handle->stride || 207 | dst->handle->format != src->handle->format) { 208 | LOGE("copy between incompatible buffers"); 209 | return; 210 | } 211 | 212 | if (x1 < 0) 213 | x1 = 0; 214 | if (y1 < 0) 215 | y1 = 0; 216 | if (x2 > dst->handle->width) 217 | x2 = dst->handle->width; 218 | if (y2 > dst->handle->height) 219 | y2 = dst->handle->height; 220 | 221 | if (x2 <= x1 || y2 <= y1) 222 | return; 223 | 224 | bo_table[0] = info->batch_ibo; 225 | bo_table[1] = src_ib->ibo; 226 | bo_table[2] = dst_ib->ibo; 227 | if (drm_intel_bufmgr_check_aperture_space(bo_table, 3)) { 228 | if (batch_flush(info)) 229 | return; 230 | assert(!drm_intel_bufmgr_check_aperture_space(bo_table, 3)); 231 | } 232 | 233 | cmd = XY_SRC_COPY_BLT_CMD; 234 | br13 = 0xcc << 16; /* ROP_S/GXcopy */ 235 | dst_pitch = dst->handle->stride; 236 | src_pitch = src->handle->stride; 237 | 238 | switch (gralloc_drm_get_bpp(dst->handle->format)) { 239 | case 1: 240 | break; 241 | case 2: 242 | br13 |= (1 << 24); 243 | break; 244 | case 4: 245 | br13 |= (1 << 24) | (1 << 25); 246 | cmd |= XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB; 247 | break; 248 | default: 249 | LOGE("copy with unsupported format"); 250 | return; 251 | } 252 | 253 | if (info->gen >= 40) { 254 | if (dst_ib->tiling != I915_TILING_NONE) { 255 | assert(dst_pitch % 512 == 0); 256 | dst_pitch >>= 2; 257 | cmd |= XY_SRC_COPY_BLT_DST_TILED; 258 | } 259 | if (src_ib->tiling != I915_TILING_NONE) { 260 | assert(src_pitch % 512 == 0); 261 | src_pitch >>= 2; 262 | cmd |= XY_SRC_COPY_BLT_SRC_TILED; 263 | } 264 | } 265 | 266 | if (batch_reserve(info, 8)) 267 | return; 268 | 269 | batch_dword(info, cmd); 270 | batch_dword(info, br13 | dst_pitch); 271 | batch_dword(info, (y1 << 16) | x1); 272 | batch_dword(info, (y2 << 16) | x2); 273 | batch_reloc(info, dst, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER); 274 | batch_dword(info, (y1 << 16) | x1); 275 | batch_dword(info, src_pitch); 276 | batch_reloc(info, src, I915_GEM_DOMAIN_RENDER, 0); 277 | 278 | if (info->gen >= 60) { 279 | batch_reserve(info, 4); 280 | batch_dword(info, MI_FLUSH_DW | 2); 281 | batch_dword(info, 0); 282 | batch_dword(info, 0); 283 | batch_dword(info, 0); 284 | } 285 | else { 286 | int flags = (info->gen >= 40) ? 0 : 287 | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE; 288 | 289 | batch_reserve(info, 1); 290 | batch_dword(info, MI_FLUSH | flags); 291 | } 292 | 293 | batch_flush(info); 294 | } 295 | 296 | static drm_intel_bo *alloc_ibo(struct intel_info *info, 297 | const struct gralloc_drm_handle_t *handle, 298 | uint32_t *tiling, unsigned long *stride) 299 | { 300 | drm_intel_bo *ibo; 301 | const char *name; 302 | int aligned_width, aligned_height, bpp; 303 | unsigned long flags; 304 | 305 | flags = 0; 306 | bpp = gralloc_drm_get_bpp(handle->format); 307 | if (!bpp) { 308 | LOGE("unrecognized format 0x%x", handle->format); 309 | return NULL; 310 | } 311 | 312 | aligned_width = handle->width; 313 | aligned_height = handle->height; 314 | gralloc_drm_align_geometry(handle->format, 315 | &aligned_width, &aligned_height); 316 | 317 | if (handle->usage & GRALLOC_USAGE_HW_FB) { 318 | unsigned long max_stride; 319 | 320 | max_stride = 32 * 1024; 321 | if (info->gen < 50) 322 | max_stride /= 2; 323 | if (info->gen < 40) 324 | max_stride /= 2; 325 | 326 | name = "gralloc-fb"; 327 | aligned_width = (aligned_width + 63) & ~63; 328 | flags = BO_ALLOC_FOR_RENDER; 329 | 330 | *tiling = I915_TILING_X; 331 | *stride = aligned_width * bpp; 332 | if (*stride > max_stride) { 333 | *tiling = I915_TILING_NONE; 334 | max_stride = 32 * 1024; 335 | if (*stride > max_stride) 336 | return NULL; 337 | } 338 | 339 | while (1) { 340 | ibo = drm_intel_bo_alloc_tiled(info->bufmgr, name, 341 | aligned_width, aligned_height, 342 | bpp, tiling, stride, flags); 343 | if (!ibo || *stride > max_stride) { 344 | if (ibo) { 345 | drm_intel_bo_unreference(ibo); 346 | ibo = NULL; 347 | } 348 | 349 | if (*tiling != I915_TILING_NONE) { 350 | /* retry */ 351 | *tiling = I915_TILING_NONE; 352 | max_stride = 32 * 1024; 353 | continue; 354 | } 355 | } 356 | if (ibo) 357 | drm_intel_bo_disable_reuse(ibo); 358 | break; 359 | } 360 | } 361 | else { 362 | if (handle->usage & (GRALLOC_USAGE_SW_READ_OFTEN | 363 | GRALLOC_USAGE_SW_WRITE_OFTEN)) 364 | *tiling = I915_TILING_NONE; 365 | else if ((handle->usage & GRALLOC_USAGE_HW_RENDER) || 366 | ((handle->usage & GRALLOC_USAGE_HW_TEXTURE) && 367 | handle->width >= 64)) 368 | *tiling = I915_TILING_X; 369 | else 370 | *tiling = I915_TILING_NONE; 371 | 372 | if (handle->usage & GRALLOC_USAGE_HW_TEXTURE) { 373 | name = "gralloc-texture"; 374 | /* see 2D texture layout of DRI drivers */ 375 | aligned_width = (aligned_width + 3) & ~3; 376 | aligned_height = (aligned_height + 1) & ~1; 377 | } 378 | else { 379 | name = "gralloc-buffer"; 380 | } 381 | 382 | if (handle->usage & GRALLOC_USAGE_HW_RENDER) 383 | flags = BO_ALLOC_FOR_RENDER; 384 | 385 | ibo = drm_intel_bo_alloc_tiled(info->bufmgr, name, 386 | aligned_width, aligned_height, 387 | bpp, tiling, stride, flags); 388 | } 389 | 390 | return ibo; 391 | } 392 | 393 | static struct gralloc_drm_bo_t *intel_alloc(struct gralloc_drm_drv_t *drv, 394 | struct gralloc_drm_handle_t *handle) 395 | { 396 | struct intel_info *info = (struct intel_info *) drv; 397 | struct intel_buffer *ib; 398 | 399 | ib = calloc(1, sizeof(*ib)); 400 | if (!ib) 401 | return NULL; 402 | 403 | if (handle->name) { 404 | uint32_t dummy; 405 | 406 | ib->ibo = drm_intel_bo_gem_create_from_name(info->bufmgr, 407 | "gralloc-r", handle->name); 408 | if (!ib->ibo) { 409 | LOGE("failed to create ibo from name %u", 410 | handle->name); 411 | free(ib); 412 | return NULL; 413 | } 414 | 415 | if (drm_intel_bo_get_tiling(ib->ibo, &ib->tiling, &dummy)) { 416 | LOGE("failed to get ibo tiling"); 417 | drm_intel_bo_unreference(ib->ibo); 418 | free(ib); 419 | return NULL; 420 | } 421 | } 422 | else { 423 | unsigned long stride; 424 | 425 | ib->ibo = alloc_ibo(info, handle, &ib->tiling, &stride); 426 | if (!ib->ibo) { 427 | LOGE("failed to allocate ibo %dx%d (format %d)", 428 | handle->width, 429 | handle->height, 430 | handle->format); 431 | free(ib); 432 | return NULL; 433 | } 434 | 435 | handle->stride = stride; 436 | 437 | if (drm_intel_bo_flink(ib->ibo, (uint32_t *) &handle->name)) { 438 | LOGE("failed to flink ibo"); 439 | drm_intel_bo_unreference(ib->ibo); 440 | free(ib); 441 | return NULL; 442 | } 443 | } 444 | 445 | if (handle->usage & GRALLOC_USAGE_HW_FB) 446 | ib->base.fb_handle = ib->ibo->handle; 447 | 448 | ib->base.handle = handle; 449 | 450 | return &ib->base; 451 | } 452 | 453 | static void intel_free(struct gralloc_drm_drv_t *drv, 454 | struct gralloc_drm_bo_t *bo) 455 | { 456 | struct intel_buffer *ib = (struct intel_buffer *) bo; 457 | 458 | drm_intel_bo_unreference(ib->ibo); 459 | free(ib); 460 | } 461 | 462 | static int intel_map(struct gralloc_drm_drv_t *drv, 463 | struct gralloc_drm_bo_t *bo, 464 | int x, int y, int w, int h, 465 | int enable_write, void **addr) 466 | { 467 | struct intel_buffer *ib = (struct intel_buffer *) bo; 468 | int err; 469 | 470 | if (ib->tiling != I915_TILING_NONE || 471 | (ib->base.handle->usage & GRALLOC_USAGE_HW_FB)) 472 | err = drm_intel_gem_bo_map_gtt(ib->ibo); 473 | else 474 | err = drm_intel_bo_map(ib->ibo, enable_write); 475 | if (!err) 476 | *addr = ib->ibo->virtual; 477 | 478 | return err; 479 | } 480 | 481 | static void intel_unmap(struct gralloc_drm_drv_t *drv, 482 | struct gralloc_drm_bo_t *bo) 483 | { 484 | struct intel_buffer *ib = (struct intel_buffer *) bo; 485 | 486 | if (ib->tiling != I915_TILING_NONE || 487 | (ib->base.handle->usage & GRALLOC_USAGE_HW_FB)) 488 | drm_intel_gem_bo_unmap_gtt(ib->ibo); 489 | else 490 | drm_intel_bo_unmap(ib->ibo); 491 | } 492 | 493 | #include "dri/intel_chipset.h" /* for IS_965() */ 494 | static void intel_init_kms_features(struct gralloc_drm_drv_t *drv, 495 | struct gralloc_drm_t *drm) 496 | { 497 | struct intel_info *info = (struct intel_info *) drv; 498 | struct drm_i915_getparam gp; 499 | int pageflipping, id; 500 | 501 | switch (drm->fb_format) { 502 | case HAL_PIXEL_FORMAT_BGRA_8888: 503 | case HAL_PIXEL_FORMAT_RGB_565: 504 | break; 505 | default: 506 | drm->fb_format = HAL_PIXEL_FORMAT_BGRA_8888; 507 | break; 508 | } 509 | 510 | drm->mode_quirk_vmwgfx = 0; 511 | /* why? */ 512 | drm->mode_sync_flip = 1; 513 | 514 | memset(&gp, 0, sizeof(gp)); 515 | gp.param = I915_PARAM_HAS_PAGEFLIPPING; 516 | gp.value = &pageflipping; 517 | if (drmCommandWriteRead(drm->fd, DRM_I915_GETPARAM, &gp, sizeof(gp))) 518 | pageflipping = 0; 519 | 520 | memset(&gp, 0, sizeof(gp)); 521 | gp.param = I915_PARAM_CHIPSET_ID; 522 | gp.value = &id; 523 | if (drmCommandWriteRead(drm->fd, DRM_I915_GETPARAM, &gp, sizeof(gp))) 524 | id = 0; 525 | 526 | if (IS_965(id)) { 527 | if (IS_GEN6(id)) 528 | info->gen = 60; 529 | else if (IS_GEN5(id)) 530 | info->gen = 50; 531 | else 532 | info->gen = 40; 533 | } 534 | else { 535 | info->gen = 30; 536 | } 537 | 538 | if (pageflipping && info->gen > 30) 539 | drm->swap_mode = DRM_SWAP_FLIP; 540 | else if (info->batch && info->gen == 30) 541 | drm->swap_mode = DRM_SWAP_COPY; 542 | else 543 | drm->swap_mode = DRM_SWAP_SETCRTC; 544 | 545 | if (drm->resources) { 546 | int pipe; 547 | 548 | pipe = drm_intel_get_pipe_from_crtc_id(info->bufmgr, 549 | drm->crtc_id); 550 | drm->swap_interval = (pipe >= 0) ? 1 : 0; 551 | drm->vblank_secondary = (pipe > 0); 552 | } 553 | else { 554 | drm->swap_interval = 0; 555 | } 556 | } 557 | 558 | static void intel_destroy(struct gralloc_drm_drv_t *drv) 559 | { 560 | struct intel_info *info = (struct intel_info *) drv; 561 | 562 | batch_destroy(info); 563 | drm_intel_bufmgr_destroy(info->bufmgr); 564 | free(info); 565 | } 566 | 567 | struct gralloc_drm_drv_t *gralloc_drm_drv_create_for_intel(int fd) 568 | { 569 | struct intel_info *info; 570 | 571 | info = calloc(1, sizeof(*info)); 572 | if (!info) { 573 | LOGE("failed to allocate driver info"); 574 | return NULL; 575 | } 576 | 577 | info->fd = fd; 578 | info->bufmgr = drm_intel_bufmgr_gem_init(info->fd, 16 * 1024); 579 | if (!info->bufmgr) { 580 | LOGE("failed to create buffer manager"); 581 | free(info); 582 | return NULL; 583 | } 584 | 585 | batch_init(info); 586 | 587 | info->base.destroy = intel_destroy; 588 | info->base.init_kms_features = intel_init_kms_features; 589 | info->base.alloc = intel_alloc; 590 | info->base.free = intel_free; 591 | info->base.map = intel_map; 592 | info->base.unmap = intel_unmap; 593 | info->base.copy = intel_copy; 594 | 595 | return &info->base; 596 | } 597 | -------------------------------------------------------------------------------- /radeon/radeon_chipinfo_gen.h: -------------------------------------------------------------------------------- 1 | /* This file is autogenerated please do not edit */ 2 | static RADEONCardInfo RADEONCards[] = { 3 | { 0x3150, CHIP_FAMILY_RV380, 1, 0, 0, 0, 0 }, 4 | { 0x3151, CHIP_FAMILY_RV380, 0, 0, 0, 0, 0 }, 5 | { 0x3152, CHIP_FAMILY_RV380, 1, 0, 0, 0, 0 }, 6 | { 0x3154, CHIP_FAMILY_RV380, 1, 0, 0, 0, 0 }, 7 | { 0x3155, CHIP_FAMILY_RV380, 1, 0, 0, 0, 0 }, 8 | { 0x3E50, CHIP_FAMILY_RV380, 0, 0, 0, 0, 0 }, 9 | { 0x3E54, CHIP_FAMILY_RV380, 0, 0, 0, 0, 0 }, 10 | { 0x4136, CHIP_FAMILY_RS100, 0, 1, 0, 0, 1 }, 11 | { 0x4137, CHIP_FAMILY_RS200, 0, 1, 0, 0, 1 }, 12 | { 0x4144, CHIP_FAMILY_R300, 0, 0, 0, 0, 0 }, 13 | { 0x4145, CHIP_FAMILY_R300, 0, 0, 0, 0, 0 }, 14 | { 0x4146, CHIP_FAMILY_R300, 0, 0, 0, 0, 0 }, 15 | { 0x4147, CHIP_FAMILY_R300, 0, 0, 0, 0, 0 }, 16 | { 0x4148, CHIP_FAMILY_R350, 0, 0, 0, 0, 0 }, 17 | { 0x4149, CHIP_FAMILY_R350, 0, 0, 0, 0, 0 }, 18 | { 0x414A, CHIP_FAMILY_R350, 0, 0, 0, 0, 0 }, 19 | { 0x414B, CHIP_FAMILY_R350, 0, 0, 0, 0, 0 }, 20 | { 0x4150, CHIP_FAMILY_RV350, 0, 0, 0, 0, 0 }, 21 | { 0x4151, CHIP_FAMILY_RV350, 0, 0, 0, 0, 0 }, 22 | { 0x4152, CHIP_FAMILY_RV350, 0, 0, 0, 0, 0 }, 23 | { 0x4153, CHIP_FAMILY_RV350, 0, 0, 0, 0, 0 }, 24 | { 0x4154, CHIP_FAMILY_RV350, 0, 0, 0, 0, 0 }, 25 | { 0x4155, CHIP_FAMILY_RV350, 0, 0, 0, 0, 0 }, 26 | { 0x4156, CHIP_FAMILY_RV350, 0, 0, 0, 0, 0 }, 27 | { 0x4237, CHIP_FAMILY_RS200, 0, 1, 0, 0, 1 }, 28 | { 0x4242, CHIP_FAMILY_R200, 0, 0, 0, 1, 0 }, 29 | { 0x4336, CHIP_FAMILY_RS100, 1, 1, 0, 0, 1 }, 30 | { 0x4337, CHIP_FAMILY_RS200, 1, 1, 0, 0, 1 }, 31 | { 0x4437, CHIP_FAMILY_RS200, 1, 1, 0, 0, 1 }, 32 | { 0x4966, CHIP_FAMILY_RV250, 0, 0, 0, 0, 0 }, 33 | { 0x4967, CHIP_FAMILY_RV250, 0, 0, 0, 0, 0 }, 34 | { 0x4A48, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 }, 35 | { 0x4A49, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 }, 36 | { 0x4A4A, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 }, 37 | { 0x4A4B, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 }, 38 | { 0x4A4C, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 }, 39 | { 0x4A4D, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 }, 40 | { 0x4A4E, CHIP_FAMILY_R420, 1, 0, 0, 0, 0 }, 41 | { 0x4A4F, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 }, 42 | { 0x4A50, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 }, 43 | { 0x4A54, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 }, 44 | { 0x4B48, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 }, 45 | { 0x4B49, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 }, 46 | { 0x4B4A, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 }, 47 | { 0x4B4B, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 }, 48 | { 0x4B4C, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 }, 49 | { 0x4C57, CHIP_FAMILY_RV200, 1, 0, 0, 0, 0 }, 50 | { 0x4C58, CHIP_FAMILY_RV200, 1, 0, 0, 0, 0 }, 51 | { 0x4C59, CHIP_FAMILY_RV100, 1, 0, 0, 0, 0 }, 52 | { 0x4C5A, CHIP_FAMILY_RV100, 1, 0, 0, 0, 0 }, 53 | { 0x4C64, CHIP_FAMILY_RV250, 1, 0, 0, 0, 0 }, 54 | { 0x4C66, CHIP_FAMILY_RV250, 1, 0, 0, 0, 0 }, 55 | { 0x4C67, CHIP_FAMILY_RV250, 1, 0, 0, 0, 0 }, 56 | { 0x4E44, CHIP_FAMILY_R300, 0, 0, 0, 0, 0 }, 57 | { 0x4E45, CHIP_FAMILY_R300, 0, 0, 0, 0, 0 }, 58 | { 0x4E46, CHIP_FAMILY_R300, 0, 0, 0, 0, 0 }, 59 | { 0x4E47, CHIP_FAMILY_R300, 0, 0, 0, 0, 0 }, 60 | { 0x4E48, CHIP_FAMILY_R350, 0, 0, 0, 0, 0 }, 61 | { 0x4E49, CHIP_FAMILY_R350, 0, 0, 0, 0, 0 }, 62 | { 0x4E4A, CHIP_FAMILY_R350, 0, 0, 0, 0, 0 }, 63 | { 0x4E4B, CHIP_FAMILY_R350, 0, 0, 0, 0, 0 }, 64 | { 0x4E50, CHIP_FAMILY_RV350, 1, 0, 0, 0, 0 }, 65 | { 0x4E51, CHIP_FAMILY_RV350, 1, 0, 0, 0, 0 }, 66 | { 0x4E52, CHIP_FAMILY_RV350, 1, 0, 0, 0, 0 }, 67 | { 0x4E53, CHIP_FAMILY_RV350, 1, 0, 0, 0, 0 }, 68 | { 0x4E54, CHIP_FAMILY_RV350, 1, 0, 0, 0, 0 }, 69 | { 0x4E56, CHIP_FAMILY_RV350, 1, 0, 0, 0, 0 }, 70 | { 0x5144, CHIP_FAMILY_RADEON, 0, 0, 1, 1, 0 }, 71 | { 0x5145, CHIP_FAMILY_RADEON, 0, 0, 1, 1, 0 }, 72 | { 0x5146, CHIP_FAMILY_RADEON, 0, 0, 1, 1, 0 }, 73 | { 0x5147, CHIP_FAMILY_RADEON, 0, 0, 1, 1, 0 }, 74 | { 0x5148, CHIP_FAMILY_R200, 0, 0, 0, 1, 0 }, 75 | { 0x514C, CHIP_FAMILY_R200, 0, 0, 0, 1, 0 }, 76 | { 0x514D, CHIP_FAMILY_R200, 0, 0, 0, 1, 0 }, 77 | { 0x5157, CHIP_FAMILY_RV200, 0, 0, 0, 0, 0 }, 78 | { 0x5158, CHIP_FAMILY_RV200, 0, 0, 0, 0, 0 }, 79 | { 0x5159, CHIP_FAMILY_RV100, 0, 0, 0, 0, 0 }, 80 | { 0x515A, CHIP_FAMILY_RV100, 0, 0, 0, 0, 0 }, 81 | { 0x515E, CHIP_FAMILY_RV100, 0, 0, 1, 0, 0 }, 82 | { 0x5460, CHIP_FAMILY_RV380, 1, 0, 0, 0, 0 }, 83 | { 0x5462, CHIP_FAMILY_RV380, 1, 0, 0, 0, 0 }, 84 | { 0x5464, CHIP_FAMILY_RV380, 1, 0, 0, 0, 0 }, 85 | { 0x5548, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 }, 86 | { 0x5549, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 }, 87 | { 0x554A, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 }, 88 | { 0x554B, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 }, 89 | { 0x554C, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 }, 90 | { 0x554D, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 }, 91 | { 0x554E, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 }, 92 | { 0x554F, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 }, 93 | { 0x5550, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 }, 94 | { 0x5551, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 }, 95 | { 0x5552, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 }, 96 | { 0x5554, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 }, 97 | { 0x564A, CHIP_FAMILY_RV410, 1, 0, 0, 0, 0 }, 98 | { 0x564B, CHIP_FAMILY_RV410, 1, 0, 0, 0, 0 }, 99 | { 0x564F, CHIP_FAMILY_RV410, 1, 0, 0, 0, 0 }, 100 | { 0x5652, CHIP_FAMILY_RV410, 1, 0, 0, 0, 0 }, 101 | { 0x5653, CHIP_FAMILY_RV410, 1, 0, 0, 0, 0 }, 102 | { 0x5657, CHIP_FAMILY_RV410, 0, 0, 0, 0, 0 }, 103 | { 0x5834, CHIP_FAMILY_RS300, 0, 1, 0, 0, 1 }, 104 | { 0x5835, CHIP_FAMILY_RS300, 1, 1, 0, 0, 1 }, 105 | { 0x5954, CHIP_FAMILY_RS480, 0, 1, 0, 0, 1 }, 106 | { 0x5955, CHIP_FAMILY_RS480, 1, 1, 0, 0, 1 }, 107 | { 0x5960, CHIP_FAMILY_RV280, 0, 0, 0, 0, 0 }, 108 | { 0x5961, CHIP_FAMILY_RV280, 0, 0, 0, 0, 0 }, 109 | { 0x5962, CHIP_FAMILY_RV280, 0, 0, 0, 0, 0 }, 110 | { 0x5964, CHIP_FAMILY_RV280, 0, 0, 0, 0, 0 }, 111 | { 0x5965, CHIP_FAMILY_RV280, 0, 0, 0, 0, 0 }, 112 | { 0x5969, CHIP_FAMILY_RV100, 0, 0, 1, 0, 0 }, 113 | { 0x5974, CHIP_FAMILY_RS480, 1, 1, 0, 0, 1 }, 114 | { 0x5975, CHIP_FAMILY_RS480, 1, 1, 0, 0, 1 }, 115 | { 0x5A41, CHIP_FAMILY_RS400, 0, 1, 0, 0, 1 }, 116 | { 0x5A42, CHIP_FAMILY_RS400, 1, 1, 0, 0, 1 }, 117 | { 0x5A61, CHIP_FAMILY_RS400, 0, 1, 0, 0, 1 }, 118 | { 0x5A62, CHIP_FAMILY_RS400, 1, 1, 0, 0, 1 }, 119 | { 0x5B60, CHIP_FAMILY_RV380, 0, 0, 0, 0, 0 }, 120 | { 0x5B62, CHIP_FAMILY_RV380, 0, 0, 0, 0, 0 }, 121 | { 0x5B63, CHIP_FAMILY_RV380, 0, 0, 0, 0, 0 }, 122 | { 0x5B64, CHIP_FAMILY_RV380, 0, 0, 0, 0, 0 }, 123 | { 0x5B65, CHIP_FAMILY_RV380, 0, 0, 0, 0, 0 }, 124 | { 0x5C61, CHIP_FAMILY_RV280, 1, 0, 0, 0, 0 }, 125 | { 0x5C63, CHIP_FAMILY_RV280, 1, 0, 0, 0, 0 }, 126 | { 0x5D48, CHIP_FAMILY_R420, 1, 0, 0, 0, 0 }, 127 | { 0x5D49, CHIP_FAMILY_R420, 1, 0, 0, 0, 0 }, 128 | { 0x5D4A, CHIP_FAMILY_R420, 1, 0, 0, 0, 0 }, 129 | { 0x5D4C, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 }, 130 | { 0x5D4D, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 }, 131 | { 0x5D4E, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 }, 132 | { 0x5D4F, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 }, 133 | { 0x5D50, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 }, 134 | { 0x5D52, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 }, 135 | { 0x5D57, CHIP_FAMILY_R420, 0, 0, 0, 0, 0 }, 136 | { 0x5E48, CHIP_FAMILY_RV410, 0, 0, 0, 0, 0 }, 137 | { 0x5E4A, CHIP_FAMILY_RV410, 0, 0, 0, 0, 0 }, 138 | { 0x5E4B, CHIP_FAMILY_RV410, 0, 0, 0, 0, 0 }, 139 | { 0x5E4C, CHIP_FAMILY_RV410, 0, 0, 0, 0, 0 }, 140 | { 0x5E4D, CHIP_FAMILY_RV410, 0, 0, 0, 0, 0 }, 141 | { 0x5E4F, CHIP_FAMILY_RV410, 0, 0, 0, 0, 0 }, 142 | { 0x7100, CHIP_FAMILY_R520, 0, 0, 0, 0, 0 }, 143 | { 0x7101, CHIP_FAMILY_R520, 1, 0, 0, 0, 0 }, 144 | { 0x7102, CHIP_FAMILY_R520, 1, 0, 0, 0, 0 }, 145 | { 0x7103, CHIP_FAMILY_R520, 1, 0, 0, 0, 0 }, 146 | { 0x7104, CHIP_FAMILY_R520, 0, 0, 0, 0, 0 }, 147 | { 0x7105, CHIP_FAMILY_R520, 0, 0, 0, 0, 0 }, 148 | { 0x7106, CHIP_FAMILY_R520, 1, 0, 0, 0, 0 }, 149 | { 0x7108, CHIP_FAMILY_R520, 0, 0, 0, 0, 0 }, 150 | { 0x7109, CHIP_FAMILY_R520, 0, 0, 0, 0, 0 }, 151 | { 0x710A, CHIP_FAMILY_R520, 0, 0, 0, 0, 0 }, 152 | { 0x710B, CHIP_FAMILY_R520, 0, 0, 0, 0, 0 }, 153 | { 0x710C, CHIP_FAMILY_R520, 0, 0, 0, 0, 0 }, 154 | { 0x710E, CHIP_FAMILY_R520, 0, 0, 0, 0, 0 }, 155 | { 0x710F, CHIP_FAMILY_R520, 0, 0, 0, 0, 0 }, 156 | { 0x7140, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 }, 157 | { 0x7141, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 }, 158 | { 0x7142, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 }, 159 | { 0x7143, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 }, 160 | { 0x7144, CHIP_FAMILY_RV515, 1, 0, 0, 0, 0 }, 161 | { 0x7145, CHIP_FAMILY_RV515, 1, 0, 0, 0, 0 }, 162 | { 0x7146, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 }, 163 | { 0x7147, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 }, 164 | { 0x7149, CHIP_FAMILY_RV515, 1, 0, 0, 0, 0 }, 165 | { 0x714A, CHIP_FAMILY_RV515, 1, 0, 0, 0, 0 }, 166 | { 0x714B, CHIP_FAMILY_RV515, 1, 0, 0, 0, 0 }, 167 | { 0x714C, CHIP_FAMILY_RV515, 1, 0, 0, 0, 0 }, 168 | { 0x714D, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 }, 169 | { 0x714E, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 }, 170 | { 0x714F, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 }, 171 | { 0x7151, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 }, 172 | { 0x7152, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 }, 173 | { 0x7153, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 }, 174 | { 0x715E, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 }, 175 | { 0x715F, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 }, 176 | { 0x7180, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 }, 177 | { 0x7181, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 }, 178 | { 0x7183, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 }, 179 | { 0x7186, CHIP_FAMILY_RV515, 1, 0, 0, 0, 0 }, 180 | { 0x7187, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 }, 181 | { 0x7188, CHIP_FAMILY_RV515, 1, 0, 0, 0, 0 }, 182 | { 0x718A, CHIP_FAMILY_RV515, 1, 0, 0, 0, 0 }, 183 | { 0x718B, CHIP_FAMILY_RV515, 1, 0, 0, 0, 0 }, 184 | { 0x718C, CHIP_FAMILY_RV515, 1, 0, 0, 0, 0 }, 185 | { 0x718D, CHIP_FAMILY_RV515, 1, 0, 0, 0, 0 }, 186 | { 0x718F, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 }, 187 | { 0x7193, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 }, 188 | { 0x7196, CHIP_FAMILY_RV515, 1, 0, 0, 0, 0 }, 189 | { 0x719B, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 }, 190 | { 0x719F, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 }, 191 | { 0x71C0, CHIP_FAMILY_RV530, 0, 0, 0, 0, 0 }, 192 | { 0x71C1, CHIP_FAMILY_RV530, 0, 0, 0, 0, 0 }, 193 | { 0x71C2, CHIP_FAMILY_RV530, 0, 0, 0, 0, 0 }, 194 | { 0x71C3, CHIP_FAMILY_RV530, 0, 0, 0, 0, 0 }, 195 | { 0x71C4, CHIP_FAMILY_RV530, 1, 0, 0, 0, 0 }, 196 | { 0x71C5, CHIP_FAMILY_RV530, 1, 0, 0, 0, 0 }, 197 | { 0x71C6, CHIP_FAMILY_RV530, 0, 0, 0, 0, 0 }, 198 | { 0x71C7, CHIP_FAMILY_RV530, 0, 0, 0, 0, 0 }, 199 | { 0x71CD, CHIP_FAMILY_RV530, 0, 0, 0, 0, 0 }, 200 | { 0x71CE, CHIP_FAMILY_RV530, 0, 0, 0, 0, 0 }, 201 | { 0x71D2, CHIP_FAMILY_RV530, 0, 0, 0, 0, 0 }, 202 | { 0x71D4, CHIP_FAMILY_RV530, 1, 0, 0, 0, 0 }, 203 | { 0x71D5, CHIP_FAMILY_RV530, 1, 0, 0, 0, 0 }, 204 | { 0x71D6, CHIP_FAMILY_RV530, 1, 0, 0, 0, 0 }, 205 | { 0x71DA, CHIP_FAMILY_RV530, 0, 0, 0, 0, 0 }, 206 | { 0x71DE, CHIP_FAMILY_RV530, 1, 0, 0, 0, 0 }, 207 | { 0x7200, CHIP_FAMILY_RV515, 0, 0, 0, 0, 0 }, 208 | { 0x7210, CHIP_FAMILY_RV515, 1, 0, 0, 0, 0 }, 209 | { 0x7211, CHIP_FAMILY_RV515, 1, 0, 0, 0, 0 }, 210 | { 0x7240, CHIP_FAMILY_R580, 0, 0, 0, 0, 0 }, 211 | { 0x7243, CHIP_FAMILY_R580, 0, 0, 0, 0, 0 }, 212 | { 0x7244, CHIP_FAMILY_R580, 0, 0, 0, 0, 0 }, 213 | { 0x7245, CHIP_FAMILY_R580, 0, 0, 0, 0, 0 }, 214 | { 0x7246, CHIP_FAMILY_R580, 0, 0, 0, 0, 0 }, 215 | { 0x7247, CHIP_FAMILY_R580, 0, 0, 0, 0, 0 }, 216 | { 0x7248, CHIP_FAMILY_R580, 0, 0, 0, 0, 0 }, 217 | { 0x7249, CHIP_FAMILY_R580, 0, 0, 0, 0, 0 }, 218 | { 0x724A, CHIP_FAMILY_R580, 0, 0, 0, 0, 0 }, 219 | { 0x724B, CHIP_FAMILY_R580, 0, 0, 0, 0, 0 }, 220 | { 0x724C, CHIP_FAMILY_R580, 0, 0, 0, 0, 0 }, 221 | { 0x724D, CHIP_FAMILY_R580, 0, 0, 0, 0, 0 }, 222 | { 0x724E, CHIP_FAMILY_R580, 0, 0, 0, 0, 0 }, 223 | { 0x724F, CHIP_FAMILY_R580, 0, 0, 0, 0, 0 }, 224 | { 0x7280, CHIP_FAMILY_RV570, 0, 0, 0, 0, 0 }, 225 | { 0x7281, CHIP_FAMILY_RV560, 0, 0, 0, 0, 0 }, 226 | { 0x7283, CHIP_FAMILY_RV560, 0, 0, 0, 0, 0 }, 227 | { 0x7284, CHIP_FAMILY_R580, 1, 0, 0, 0, 0 }, 228 | { 0x7287, CHIP_FAMILY_RV560, 0, 0, 0, 0, 0 }, 229 | { 0x7288, CHIP_FAMILY_RV570, 0, 0, 0, 0, 0 }, 230 | { 0x7289, CHIP_FAMILY_RV570, 0, 0, 0, 0, 0 }, 231 | { 0x728B, CHIP_FAMILY_RV570, 0, 0, 0, 0, 0 }, 232 | { 0x728C, CHIP_FAMILY_RV570, 0, 0, 0, 0, 0 }, 233 | { 0x7290, CHIP_FAMILY_RV560, 0, 0, 0, 0, 0 }, 234 | { 0x7291, CHIP_FAMILY_RV560, 0, 0, 0, 0, 0 }, 235 | { 0x7293, CHIP_FAMILY_RV560, 0, 0, 0, 0, 0 }, 236 | { 0x7297, CHIP_FAMILY_RV560, 0, 0, 0, 0, 0 }, 237 | { 0x7834, CHIP_FAMILY_RS300, 0, 1, 0, 0, 1 }, 238 | { 0x7835, CHIP_FAMILY_RS300, 1, 1, 0, 0, 1 }, 239 | { 0x791E, CHIP_FAMILY_RS690, 0, 1, 0, 0, 1 }, 240 | { 0x791F, CHIP_FAMILY_RS690, 0, 1, 0, 0, 1 }, 241 | { 0x793F, CHIP_FAMILY_RS600, 0, 1, 0, 0, 1 }, 242 | { 0x7941, CHIP_FAMILY_RS600, 0, 1, 0, 0, 1 }, 243 | { 0x7942, CHIP_FAMILY_RS600, 0, 1, 0, 0, 1 }, 244 | { 0x796C, CHIP_FAMILY_RS740, 0, 1, 0, 0, 1 }, 245 | { 0x796D, CHIP_FAMILY_RS740, 0, 1, 0, 0, 1 }, 246 | { 0x796E, CHIP_FAMILY_RS740, 0, 1, 0, 0, 1 }, 247 | { 0x796F, CHIP_FAMILY_RS740, 0, 1, 0, 0, 1 }, 248 | { 0x9400, CHIP_FAMILY_R600, 0, 0, 0, 0, 0 }, 249 | { 0x9401, CHIP_FAMILY_R600, 0, 0, 0, 0, 0 }, 250 | { 0x9402, CHIP_FAMILY_R600, 0, 0, 0, 0, 0 }, 251 | { 0x9403, CHIP_FAMILY_R600, 0, 0, 0, 0, 0 }, 252 | { 0x9405, CHIP_FAMILY_R600, 0, 0, 0, 0, 0 }, 253 | { 0x940A, CHIP_FAMILY_R600, 0, 0, 0, 0, 0 }, 254 | { 0x940B, CHIP_FAMILY_R600, 0, 0, 0, 0, 0 }, 255 | { 0x940F, CHIP_FAMILY_R600, 0, 0, 0, 0, 0 }, 256 | { 0x9440, CHIP_FAMILY_RV770, 0, 0, 0, 0, 0 }, 257 | { 0x9441, CHIP_FAMILY_RV770, 0, 0, 0, 0, 0 }, 258 | { 0x9442, CHIP_FAMILY_RV770, 0, 0, 0, 0, 0 }, 259 | { 0x9443, CHIP_FAMILY_RV770, 0, 0, 0, 0, 0 }, 260 | { 0x9444, CHIP_FAMILY_RV770, 0, 0, 0, 0, 0 }, 261 | { 0x9446, CHIP_FAMILY_RV770, 0, 0, 0, 0, 0 }, 262 | { 0x944A, CHIP_FAMILY_RV770, 1, 0, 0, 0, 0 }, 263 | { 0x944B, CHIP_FAMILY_RV770, 1, 0, 0, 0, 0 }, 264 | { 0x944C, CHIP_FAMILY_RV770, 0, 0, 0, 0, 0 }, 265 | { 0x944E, CHIP_FAMILY_RV770, 0, 0, 0, 0, 0 }, 266 | { 0x9450, CHIP_FAMILY_RV770, 0, 0, 0, 0, 0 }, 267 | { 0x9452, CHIP_FAMILY_RV770, 0, 0, 0, 0, 0 }, 268 | { 0x9456, CHIP_FAMILY_RV770, 0, 0, 0, 0, 0 }, 269 | { 0x945A, CHIP_FAMILY_RV770, 1, 0, 0, 0, 0 }, 270 | { 0x945B, CHIP_FAMILY_RV770, 1, 0, 0, 0, 0 }, 271 | { 0x945E, CHIP_FAMILY_RV770, 1, 0, 0, 0, 0 }, 272 | { 0x9460, CHIP_FAMILY_RV770, 0, 0, 0, 0, 0 }, 273 | { 0x9462, CHIP_FAMILY_RV770, 0, 0, 0, 0, 0 }, 274 | { 0x946A, CHIP_FAMILY_RV770, 1, 0, 0, 0, 0 }, 275 | { 0x946B, CHIP_FAMILY_RV770, 1, 0, 0, 0, 0 }, 276 | { 0x947A, CHIP_FAMILY_RV770, 1, 0, 0, 0, 0 }, 277 | { 0x947B, CHIP_FAMILY_RV770, 1, 0, 0, 0, 0 }, 278 | { 0x9480, CHIP_FAMILY_RV730, 1, 0, 0, 0, 0 }, 279 | { 0x9487, CHIP_FAMILY_RV730, 0, 0, 0, 0, 0 }, 280 | { 0x9488, CHIP_FAMILY_RV730, 1, 0, 0, 0, 0 }, 281 | { 0x9489, CHIP_FAMILY_RV730, 1, 0, 0, 0, 0 }, 282 | { 0x948A, CHIP_FAMILY_RV730, 1, 0, 0, 0, 0 }, 283 | { 0x948F, CHIP_FAMILY_RV730, 0, 0, 0, 0, 0 }, 284 | { 0x9490, CHIP_FAMILY_RV730, 0, 0, 0, 0, 0 }, 285 | { 0x9491, CHIP_FAMILY_RV730, 0, 0, 0, 0, 0 }, 286 | { 0x9495, CHIP_FAMILY_RV730, 0, 0, 0, 0, 0 }, 287 | { 0x9498, CHIP_FAMILY_RV730, 0, 0, 0, 0, 0 }, 288 | { 0x949C, CHIP_FAMILY_RV730, 0, 0, 0, 0, 0 }, 289 | { 0x949E, CHIP_FAMILY_RV730, 0, 0, 0, 0, 0 }, 290 | { 0x949F, CHIP_FAMILY_RV730, 0, 0, 0, 0, 0 }, 291 | { 0x94A0, CHIP_FAMILY_RV740, 1, 0, 0, 0, 0 }, 292 | { 0x94A1, CHIP_FAMILY_RV740, 1, 0, 0, 0, 0 }, 293 | { 0x94A3, CHIP_FAMILY_RV740, 1, 0, 0, 0, 0 }, 294 | { 0x94B1, CHIP_FAMILY_RV740, 0, 0, 0, 0, 0 }, 295 | { 0x94B3, CHIP_FAMILY_RV740, 0, 0, 0, 0, 0 }, 296 | { 0x94B4, CHIP_FAMILY_RV740, 0, 0, 0, 0, 0 }, 297 | { 0x94B5, CHIP_FAMILY_RV740, 0, 0, 0, 0, 0 }, 298 | { 0x94B9, CHIP_FAMILY_RV740, 1, 0, 0, 0, 0 }, 299 | { 0x94C0, CHIP_FAMILY_RV610, 0, 0, 0, 0, 0 }, 300 | { 0x94C1, CHIP_FAMILY_RV610, 0, 0, 0, 0, 0 }, 301 | { 0x94C3, CHIP_FAMILY_RV610, 0, 0, 0, 0, 0 }, 302 | { 0x94C4, CHIP_FAMILY_RV610, 0, 0, 0, 0, 0 }, 303 | { 0x94C5, CHIP_FAMILY_RV610, 0, 0, 0, 0, 0 }, 304 | { 0x94C6, CHIP_FAMILY_RV610, 0, 0, 0, 0, 0 }, 305 | { 0x94C7, CHIP_FAMILY_RV610, 0, 0, 0, 0, 0 }, 306 | { 0x94C8, CHIP_FAMILY_RV610, 1, 0, 0, 0, 0 }, 307 | { 0x94C9, CHIP_FAMILY_RV610, 1, 0, 0, 0, 0 }, 308 | { 0x94CB, CHIP_FAMILY_RV610, 1, 0, 0, 0, 0 }, 309 | { 0x94CC, CHIP_FAMILY_RV610, 0, 0, 0, 0, 0 }, 310 | { 0x94CD, CHIP_FAMILY_RV610, 0, 0, 0, 0, 0 }, 311 | { 0x9500, CHIP_FAMILY_RV670, 0, 0, 0, 0, 0 }, 312 | { 0x9501, CHIP_FAMILY_RV670, 0, 0, 0, 0, 0 }, 313 | { 0x9504, CHIP_FAMILY_RV670, 1, 0, 0, 0, 0 }, 314 | { 0x9505, CHIP_FAMILY_RV670, 0, 0, 0, 0, 0 }, 315 | { 0x9506, CHIP_FAMILY_RV670, 1, 0, 0, 0, 0 }, 316 | { 0x9507, CHIP_FAMILY_RV670, 0, 0, 0, 0, 0 }, 317 | { 0x9508, CHIP_FAMILY_RV670, 1, 0, 0, 0, 0 }, 318 | { 0x9509, CHIP_FAMILY_RV670, 1, 0, 0, 0, 0 }, 319 | { 0x950F, CHIP_FAMILY_RV670, 0, 0, 0, 0, 0 }, 320 | { 0x9511, CHIP_FAMILY_RV670, 0, 0, 0, 0, 0 }, 321 | { 0x9515, CHIP_FAMILY_RV670, 0, 0, 0, 0, 0 }, 322 | { 0x9517, CHIP_FAMILY_RV670, 0, 0, 0, 0, 0 }, 323 | { 0x9519, CHIP_FAMILY_RV670, 0, 0, 0, 0, 0 }, 324 | { 0x9540, CHIP_FAMILY_RV710, 0, 0, 0, 0, 0 }, 325 | { 0x9541, CHIP_FAMILY_RV710, 0, 0, 0, 0, 0 }, 326 | { 0x9542, CHIP_FAMILY_RV710, 0, 0, 0, 0, 0 }, 327 | { 0x954E, CHIP_FAMILY_RV710, 0, 0, 0, 0, 0 }, 328 | { 0x954F, CHIP_FAMILY_RV710, 0, 0, 0, 0, 0 }, 329 | { 0x9552, CHIP_FAMILY_RV710, 1, 0, 0, 0, 0 }, 330 | { 0x9553, CHIP_FAMILY_RV710, 1, 0, 0, 0, 0 }, 331 | { 0x9555, CHIP_FAMILY_RV710, 1, 0, 0, 0, 0 }, 332 | { 0x9557, CHIP_FAMILY_RV710, 1, 0, 0, 0, 0 }, 333 | { 0x955F, CHIP_FAMILY_RV710, 1, 0, 0, 0, 0 }, 334 | { 0x9580, CHIP_FAMILY_RV630, 0, 0, 0, 0, 0 }, 335 | { 0x9581, CHIP_FAMILY_RV630, 1, 0, 0, 0, 0 }, 336 | { 0x9583, CHIP_FAMILY_RV630, 1, 0, 0, 0, 0 }, 337 | { 0x9586, CHIP_FAMILY_RV630, 0, 0, 0, 0, 0 }, 338 | { 0x9587, CHIP_FAMILY_RV630, 0, 0, 0, 0, 0 }, 339 | { 0x9588, CHIP_FAMILY_RV630, 0, 0, 0, 0, 0 }, 340 | { 0x9589, CHIP_FAMILY_RV630, 0, 0, 0, 0, 0 }, 341 | { 0x958A, CHIP_FAMILY_RV630, 0, 0, 0, 0, 0 }, 342 | { 0x958B, CHIP_FAMILY_RV630, 1, 0, 0, 0, 0 }, 343 | { 0x958C, CHIP_FAMILY_RV630, 0, 0, 0, 0, 0 }, 344 | { 0x958D, CHIP_FAMILY_RV630, 0, 0, 0, 0, 0 }, 345 | { 0x958E, CHIP_FAMILY_RV630, 0, 0, 0, 0, 0 }, 346 | { 0x958F, CHIP_FAMILY_RV630, 1, 0, 0, 0, 0 }, 347 | { 0x95C0, CHIP_FAMILY_RV620, 0, 0, 0, 0, 0 }, 348 | { 0x95C2, CHIP_FAMILY_RV620, 1, 0, 0, 0, 0 }, 349 | { 0x95C4, CHIP_FAMILY_RV620, 1, 0, 0, 0, 0 }, 350 | { 0x95C5, CHIP_FAMILY_RV620, 0, 0, 0, 0, 0 }, 351 | { 0x95C6, CHIP_FAMILY_RV620, 0, 0, 0, 0, 0 }, 352 | { 0x95C7, CHIP_FAMILY_RV620, 0, 0, 0, 0, 0 }, 353 | { 0x95C9, CHIP_FAMILY_RV620, 0, 0, 0, 0, 0 }, 354 | { 0x95CC, CHIP_FAMILY_RV620, 0, 0, 0, 0, 0 }, 355 | { 0x95CD, CHIP_FAMILY_RV620, 0, 0, 0, 0, 0 }, 356 | { 0x95CE, CHIP_FAMILY_RV620, 0, 0, 0, 0, 0 }, 357 | { 0x95CF, CHIP_FAMILY_RV620, 0, 0, 0, 0, 0 }, 358 | { 0x9590, CHIP_FAMILY_RV635, 0, 0, 0, 0, 0 }, 359 | { 0x9596, CHIP_FAMILY_RV635, 0, 0, 0, 0, 0 }, 360 | { 0x9597, CHIP_FAMILY_RV635, 0, 0, 0, 0, 0 }, 361 | { 0x9598, CHIP_FAMILY_RV635, 0, 0, 0, 0, 0 }, 362 | { 0x9599, CHIP_FAMILY_RV635, 0, 0, 0, 0, 0 }, 363 | { 0x9591, CHIP_FAMILY_RV635, 1, 0, 0, 0, 0 }, 364 | { 0x9593, CHIP_FAMILY_RV635, 1, 0, 0, 0, 0 }, 365 | { 0x9595, CHIP_FAMILY_RV635, 1, 0, 0, 0, 0 }, 366 | { 0x959B, CHIP_FAMILY_RV635, 1, 0, 0, 0, 0 }, 367 | { 0x9610, CHIP_FAMILY_RS780, 0, 1, 0, 0, 1 }, 368 | { 0x9611, CHIP_FAMILY_RS780, 0, 1, 0, 0, 1 }, 369 | { 0x9612, CHIP_FAMILY_RS780, 0, 1, 0, 0, 1 }, 370 | { 0x9613, CHIP_FAMILY_RS780, 0, 1, 0, 0, 1 }, 371 | { 0x9614, CHIP_FAMILY_RS780, 0, 1, 0, 0, 1 }, 372 | { 0x9615, CHIP_FAMILY_RS780, 0, 1, 0, 0, 1 }, 373 | { 0x9616, CHIP_FAMILY_RS780, 0, 1, 0, 0, 1 }, 374 | { 0x9640, CHIP_FAMILY_SUMO, 0, 1, 0, 0, 1 }, 375 | { 0x9641, CHIP_FAMILY_SUMO, 1, 1, 0, 0, 1 }, 376 | { 0x9642, CHIP_FAMILY_SUMO2, 0, 1, 0, 0, 1 }, 377 | { 0x9643, CHIP_FAMILY_SUMO2, 1, 1, 0, 0, 1 }, 378 | { 0x9644, CHIP_FAMILY_SUMO2, 0, 1, 0, 0, 1 }, 379 | { 0x9645, CHIP_FAMILY_SUMO2, 1, 1, 0, 0, 1 }, 380 | { 0x9647, CHIP_FAMILY_SUMO, 1, 1, 0, 0, 1 }, 381 | { 0x9648, CHIP_FAMILY_SUMO, 1, 1, 0, 0, 1 }, 382 | { 0x964A, CHIP_FAMILY_SUMO, 0, 1, 0, 0, 1 }, 383 | { 0x964E, CHIP_FAMILY_SUMO, 1, 1, 0, 0, 1 }, 384 | { 0x964F, CHIP_FAMILY_SUMO, 1, 1, 0, 0, 1 }, 385 | { 0x9710, CHIP_FAMILY_RS880, 0, 1, 0, 0, 1 }, 386 | { 0x9711, CHIP_FAMILY_RS880, 0, 1, 0, 0, 1 }, 387 | { 0x9712, CHIP_FAMILY_RS880, 1, 1, 0, 0, 1 }, 388 | { 0x9713, CHIP_FAMILY_RS880, 1, 1, 0, 0, 1 }, 389 | { 0x9714, CHIP_FAMILY_RS880, 0, 1, 0, 0, 1 }, 390 | { 0x9715, CHIP_FAMILY_RS880, 0, 1, 0, 0, 1 }, 391 | { 0x9802, CHIP_FAMILY_PALM, 0, 1, 0, 0, 1 }, 392 | { 0x9803, CHIP_FAMILY_PALM, 0, 1, 0, 0, 1 }, 393 | { 0x9804, CHIP_FAMILY_PALM, 0, 1, 0, 0, 1 }, 394 | { 0x9805, CHIP_FAMILY_PALM, 0, 1, 0, 0, 1 }, 395 | { 0x9806, CHIP_FAMILY_PALM, 0, 1, 0, 0, 1 }, 396 | { 0x9807, CHIP_FAMILY_PALM, 0, 1, 0, 0, 1 }, 397 | { 0x6880, CHIP_FAMILY_CYPRESS, 1, 0, 0, 0, 0 }, 398 | { 0x6888, CHIP_FAMILY_CYPRESS, 0, 0, 0, 0, 0 }, 399 | { 0x6889, CHIP_FAMILY_CYPRESS, 0, 0, 0, 0, 0 }, 400 | { 0x688A, CHIP_FAMILY_CYPRESS, 0, 0, 0, 0, 0 }, 401 | { 0x688C, CHIP_FAMILY_CYPRESS, 0, 0, 0, 0, 0 }, 402 | { 0x688D, CHIP_FAMILY_CYPRESS, 0, 0, 0, 0, 0 }, 403 | { 0x6898, CHIP_FAMILY_CYPRESS, 0, 0, 0, 0, 0 }, 404 | { 0x6899, CHIP_FAMILY_CYPRESS, 0, 0, 0, 0, 0 }, 405 | { 0x689B, CHIP_FAMILY_CYPRESS, 0, 0, 0, 0, 0 }, 406 | { 0x689E, CHIP_FAMILY_CYPRESS, 0, 0, 0, 0, 0 }, 407 | { 0x689C, CHIP_FAMILY_HEMLOCK, 0, 0, 0, 0, 0 }, 408 | { 0x689D, CHIP_FAMILY_HEMLOCK, 0, 0, 0, 0, 0 }, 409 | { 0x68A0, CHIP_FAMILY_JUNIPER, 1, 0, 0, 0, 0 }, 410 | { 0x68A1, CHIP_FAMILY_JUNIPER, 1, 0, 0, 0, 0 }, 411 | { 0x68A8, CHIP_FAMILY_JUNIPER, 0, 0, 0, 0, 0 }, 412 | { 0x68A9, CHIP_FAMILY_JUNIPER, 0, 0, 0, 0, 0 }, 413 | { 0x68B0, CHIP_FAMILY_JUNIPER, 1, 0, 0, 0, 0 }, 414 | { 0x68B8, CHIP_FAMILY_JUNIPER, 0, 0, 0, 0, 0 }, 415 | { 0x68B9, CHIP_FAMILY_JUNIPER, 0, 0, 0, 0, 0 }, 416 | { 0x68BA, CHIP_FAMILY_JUNIPER, 0, 0, 0, 0, 0 }, 417 | { 0x68BE, CHIP_FAMILY_JUNIPER, 0, 0, 0, 0, 0 }, 418 | { 0x68BF, CHIP_FAMILY_JUNIPER, 0, 0, 0, 0, 0 }, 419 | { 0x68C0, CHIP_FAMILY_REDWOOD, 1, 0, 0, 0, 0 }, 420 | { 0x68C1, CHIP_FAMILY_REDWOOD, 1, 0, 0, 0, 0 }, 421 | { 0x68C7, CHIP_FAMILY_REDWOOD, 1, 0, 0, 0, 0 }, 422 | { 0x68C8, CHIP_FAMILY_REDWOOD, 0, 0, 0, 0, 0 }, 423 | { 0x68C9, CHIP_FAMILY_REDWOOD, 0, 0, 0, 0, 0 }, 424 | { 0x68D8, CHIP_FAMILY_REDWOOD, 0, 0, 0, 0, 0 }, 425 | { 0x68D9, CHIP_FAMILY_REDWOOD, 0, 0, 0, 0, 0 }, 426 | { 0x68DA, CHIP_FAMILY_REDWOOD, 0, 0, 0, 0, 0 }, 427 | { 0x68DE, CHIP_FAMILY_REDWOOD, 0, 0, 0, 0, 0 }, 428 | { 0x68E0, CHIP_FAMILY_CEDAR, 1, 0, 0, 0, 0 }, 429 | { 0x68E1, CHIP_FAMILY_CEDAR, 1, 0, 0, 0, 0 }, 430 | { 0x68E4, CHIP_FAMILY_CEDAR, 1, 0, 0, 0, 0 }, 431 | { 0x68E5, CHIP_FAMILY_CEDAR, 1, 0, 0, 0, 0 }, 432 | { 0x68E8, CHIP_FAMILY_CEDAR, 0, 0, 0, 0, 0 }, 433 | { 0x68E9, CHIP_FAMILY_CEDAR, 0, 0, 0, 0, 0 }, 434 | { 0x68F1, CHIP_FAMILY_CEDAR, 0, 0, 0, 0, 0 }, 435 | { 0x68F2, CHIP_FAMILY_CEDAR, 0, 0, 0, 0, 0 }, 436 | { 0x68F8, CHIP_FAMILY_CEDAR, 0, 0, 0, 0, 0 }, 437 | { 0x68F9, CHIP_FAMILY_CEDAR, 0, 0, 0, 0, 0 }, 438 | { 0x68FE, CHIP_FAMILY_CEDAR, 0, 0, 0, 0, 0 }, 439 | { 0x6700, CHIP_FAMILY_CAYMAN, 0, 0, 0, 0, 0 }, 440 | { 0x6701, CHIP_FAMILY_CAYMAN, 0, 0, 0, 0, 0 }, 441 | { 0x6702, CHIP_FAMILY_CAYMAN, 0, 0, 0, 0, 0 }, 442 | { 0x6703, CHIP_FAMILY_CAYMAN, 0, 0, 0, 0, 0 }, 443 | { 0x6704, CHIP_FAMILY_CAYMAN, 0, 0, 0, 0, 0 }, 444 | { 0x6705, CHIP_FAMILY_CAYMAN, 0, 0, 0, 0, 0 }, 445 | { 0x6706, CHIP_FAMILY_CAYMAN, 0, 0, 0, 0, 0 }, 446 | { 0x6707, CHIP_FAMILY_CAYMAN, 0, 0, 0, 0, 0 }, 447 | { 0x6708, CHIP_FAMILY_CAYMAN, 0, 0, 0, 0, 0 }, 448 | { 0x6709, CHIP_FAMILY_CAYMAN, 0, 0, 0, 0, 0 }, 449 | { 0x6718, CHIP_FAMILY_CAYMAN, 0, 0, 0, 0, 0 }, 450 | { 0x6719, CHIP_FAMILY_CAYMAN, 0, 0, 0, 0, 0 }, 451 | { 0x671C, CHIP_FAMILY_CAYMAN, 0, 0, 0, 0, 0 }, 452 | { 0x671D, CHIP_FAMILY_CAYMAN, 0, 0, 0, 0, 0 }, 453 | { 0x671F, CHIP_FAMILY_CAYMAN, 0, 0, 0, 0, 0 }, 454 | { 0x6720, CHIP_FAMILY_BARTS, 1, 0, 0, 0, 0 }, 455 | { 0x6721, CHIP_FAMILY_BARTS, 1, 0, 0, 0, 0 }, 456 | { 0x6722, CHIP_FAMILY_BARTS, 0, 0, 0, 0, 0 }, 457 | { 0x6723, CHIP_FAMILY_BARTS, 0, 0, 0, 0, 0 }, 458 | { 0x6724, CHIP_FAMILY_BARTS, 1, 0, 0, 0, 0 }, 459 | { 0x6725, CHIP_FAMILY_BARTS, 1, 0, 0, 0, 0 }, 460 | { 0x6726, CHIP_FAMILY_BARTS, 0, 0, 0, 0, 0 }, 461 | { 0x6727, CHIP_FAMILY_BARTS, 0, 0, 0, 0, 0 }, 462 | { 0x6728, CHIP_FAMILY_BARTS, 0, 0, 0, 0, 0 }, 463 | { 0x6729, CHIP_FAMILY_BARTS, 0, 0, 0, 0, 0 }, 464 | { 0x6738, CHIP_FAMILY_BARTS, 0, 0, 0, 0, 0 }, 465 | { 0x6739, CHIP_FAMILY_BARTS, 0, 0, 0, 0, 0 }, 466 | { 0x673E, CHIP_FAMILY_BARTS, 0, 0, 0, 0, 0 }, 467 | { 0x6740, CHIP_FAMILY_TURKS, 1, 0, 0, 0, 0 }, 468 | { 0x6741, CHIP_FAMILY_TURKS, 1, 0, 0, 0, 0 }, 469 | { 0x6742, CHIP_FAMILY_TURKS, 1, 0, 0, 0, 0 }, 470 | { 0x6743, CHIP_FAMILY_TURKS, 1, 0, 0, 0, 0 }, 471 | { 0x6744, CHIP_FAMILY_TURKS, 1, 0, 0, 0, 0 }, 472 | { 0x6745, CHIP_FAMILY_TURKS, 1, 0, 0, 0, 0 }, 473 | { 0x6746, CHIP_FAMILY_TURKS, 0, 0, 0, 0, 0 }, 474 | { 0x6747, CHIP_FAMILY_TURKS, 0, 0, 0, 0, 0 }, 475 | { 0x6748, CHIP_FAMILY_TURKS, 0, 0, 0, 0, 0 }, 476 | { 0x6749, CHIP_FAMILY_TURKS, 0, 0, 0, 0, 0 }, 477 | { 0x6750, CHIP_FAMILY_TURKS, 0, 0, 0, 0, 0 }, 478 | { 0x6758, CHIP_FAMILY_TURKS, 0, 0, 0, 0, 0 }, 479 | { 0x6759, CHIP_FAMILY_TURKS, 0, 0, 0, 0, 0 }, 480 | { 0x675F, CHIP_FAMILY_TURKS, 0, 0, 0, 0, 0 }, 481 | { 0x6760, CHIP_FAMILY_CAICOS, 1, 0, 0, 0, 0 }, 482 | { 0x6761, CHIP_FAMILY_CAICOS, 1, 0, 0, 0, 0 }, 483 | { 0x6762, CHIP_FAMILY_CAICOS, 0, 0, 0, 0, 0 }, 484 | { 0x6763, CHIP_FAMILY_CAICOS, 0, 0, 0, 0, 0 }, 485 | { 0x6764, CHIP_FAMILY_CAICOS, 1, 0, 0, 0, 0 }, 486 | { 0x6765, CHIP_FAMILY_CAICOS, 1, 0, 0, 0, 0 }, 487 | { 0x6766, CHIP_FAMILY_CAICOS, 0, 0, 0, 0, 0 }, 488 | { 0x6767, CHIP_FAMILY_CAICOS, 0, 0, 0, 0, 0 }, 489 | { 0x6768, CHIP_FAMILY_CAICOS, 0, 0, 0, 0, 0 }, 490 | { 0x6770, CHIP_FAMILY_CAICOS, 0, 0, 0, 0, 0 }, 491 | { 0x6778, CHIP_FAMILY_CAICOS, 0, 0, 0, 0, 0 }, 492 | { 0x6779, CHIP_FAMILY_CAICOS, 0, 0, 0, 0, 0 }, 493 | }; 494 | --------------------------------------------------------------------------------