Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

gma500: Add the core DRM files and headers

Not really a nice way to split this up further for submission. This
provides all the DRM interfacing logic, the headers and relevant glue.

Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>

authored by

Alan Cox and committed by
Dave Airlie
5c49fd3a 5091b7eb

+3521
+207
drivers/gpu/drm/gma500/psb_drm.h
··· 1 + /************************************************************************** 2 + * Copyright (c) 2007-2011, Intel Corporation. 3 + * All Rights Reserved. 4 + * Copyright (c) 2008, Tungsten Graphics Inc. Cedar Park, TX., USA. 5 + * All Rights Reserved. 6 + * 7 + * This program is free software; you can redistribute it and/or modify it 8 + * under the terms and conditions of the GNU General Public License, 9 + * version 2, as published by the Free Software Foundation. 10 + * 11 + * This program is distributed in the hope it will be useful, but WITHOUT 12 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14 + * more details. 15 + * 16 + * You should have received a copy of the GNU General Public License along with 17 + * this program; if not, write to the Free Software Foundation, Inc., 18 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 19 + * 20 + **************************************************************************/ 21 + 22 + #ifndef _PSB_DRM_H_ 23 + #define _PSB_DRM_H_ 24 + 25 + #define PSB_NUM_PIPE 3 26 + 27 + #define PSB_GPU_ACCESS_READ (1ULL << 32) 28 + #define PSB_GPU_ACCESS_WRITE (1ULL << 33) 29 + #define PSB_GPU_ACCESS_MASK (PSB_GPU_ACCESS_READ | PSB_GPU_ACCESS_WRITE) 30 + 31 + #define PSB_BO_FLAG_COMMAND (1ULL << 52) 32 + 33 + /* 34 + * Feedback components: 35 + */ 36 + 37 + struct drm_psb_sizes_arg { 38 + u32 ta_mem_size; 39 + u32 mmu_size; 40 + u32 pds_size; 41 + u32 rastgeom_size; 42 + u32 tt_size; 43 + u32 vram_size; 44 + }; 45 + 46 + struct drm_psb_dpst_lut_arg { 47 + uint8_t lut[256]; 48 + int output_id; 49 + }; 50 + 51 + #define PSB_DC_CRTC_SAVE 0x01 52 + #define PSB_DC_CRTC_RESTORE 0x02 53 + #define PSB_DC_OUTPUT_SAVE 0x04 54 + #define PSB_DC_OUTPUT_RESTORE 0x08 55 + #define PSB_DC_CRTC_MASK 0x03 56 + #define PSB_DC_OUTPUT_MASK 0x0C 57 + 58 + struct drm_psb_dc_state_arg { 59 + u32 flags; 60 + u32 obj_id; 61 + }; 62 + 63 + struct drm_psb_mode_operation_arg { 64 + u32 obj_id; 65 + u16 operation; 66 + struct drm_mode_modeinfo mode; 67 + void *data; 68 + }; 69 + 70 + struct drm_psb_stolen_memory_arg { 71 + u32 base; 72 + u32 size; 73 + }; 74 + 75 + /*Display Register Bits*/ 76 + #define REGRWBITS_PFIT_CONTROLS (1 << 0) 77 + #define REGRWBITS_PFIT_AUTOSCALE_RATIOS (1 << 1) 78 + #define REGRWBITS_PFIT_PROGRAMMED_SCALE_RATIOS (1 << 2) 79 + #define REGRWBITS_PIPEASRC (1 << 3) 80 + #define REGRWBITS_PIPEBSRC (1 << 4) 81 + #define REGRWBITS_VTOTAL_A (1 << 5) 82 + #define REGRWBITS_VTOTAL_B (1 << 6) 83 + #define REGRWBITS_DSPACNTR (1 << 8) 84 + #define REGRWBITS_DSPBCNTR (1 << 9) 85 + #define REGRWBITS_DSPCCNTR (1 << 10) 86 + 87 + /*Overlay Register Bits*/ 88 + #define OV_REGRWBITS_OVADD (1 << 0) 89 + #define OV_REGRWBITS_OGAM_ALL (1 << 1) 90 + 91 + #define OVC_REGRWBITS_OVADD (1 << 2) 92 + #define OVC_REGRWBITS_OGAM_ALL (1 << 3) 93 + 94 + struct drm_psb_register_rw_arg { 95 + u32 b_force_hw_on; 96 + 97 + u32 display_read_mask; 98 + u32 display_write_mask; 99 + 100 + struct { 101 + u32 pfit_controls; 102 + u32 pfit_autoscale_ratios; 103 + u32 pfit_programmed_scale_ratios; 104 + u32 pipeasrc; 105 + u32 pipebsrc; 106 + u32 vtotal_a; 107 + u32 vtotal_b; 108 + } display; 109 + 110 + u32 overlay_read_mask; 111 + u32 overlay_write_mask; 112 + 113 + struct { 114 + u32 OVADD; 115 + u32 OGAMC0; 116 + u32 OGAMC1; 117 + u32 OGAMC2; 118 + u32 OGAMC3; 119 + u32 OGAMC4; 120 + u32 OGAMC5; 121 + u32 IEP_ENABLED; 122 + u32 IEP_BLE_MINMAX; 123 + u32 IEP_BSSCC_CONTROL; 124 + u32 b_wait_vblank; 125 + } overlay; 126 + 127 + u32 sprite_enable_mask; 128 + u32 sprite_disable_mask; 129 + 130 + struct { 131 + u32 dspa_control; 132 + u32 dspa_key_value; 133 + u32 dspa_key_mask; 134 + u32 dspc_control; 135 + u32 dspc_stride; 136 + u32 dspc_position; 137 + u32 dspc_linear_offset; 138 + u32 dspc_size; 139 + u32 dspc_surface; 140 + } sprite; 141 + 142 + u32 subpicture_enable_mask; 143 + u32 subpicture_disable_mask; 144 + }; 145 + 146 + /* Controlling the kernel modesetting buffers */ 147 + 148 + #define DRM_PSB_SIZES 0x07 149 + #define DRM_PSB_FUSE_REG 0x08 150 + #define DRM_PSB_DC_STATE 0x0A 151 + #define DRM_PSB_ADB 0x0B 152 + #define DRM_PSB_MODE_OPERATION 0x0C 153 + #define DRM_PSB_STOLEN_MEMORY 0x0D 154 + #define DRM_PSB_REGISTER_RW 0x0E 155 + 156 + /* 157 + * NOTE: Add new commands here, but increment 158 + * the values below and increment their 159 + * corresponding defines where they're 160 + * defined elsewhere. 161 + */ 162 + 163 + #define DRM_PSB_GEM_CREATE 0x10 164 + #define DRM_PSB_2D_OP 0x11 /* Will be merged later */ 165 + #define DRM_PSB_GEM_MMAP 0x12 166 + #define DRM_PSB_DPST 0x1B 167 + #define DRM_PSB_GAMMA 0x1C 168 + #define DRM_PSB_DPST_BL 0x1D 169 + #define DRM_PSB_GET_PIPE_FROM_CRTC_ID 0x1F 170 + 171 + #define PSB_MODE_OPERATION_MODE_VALID 0x01 172 + #define PSB_MODE_OPERATION_SET_DC_BASE 0x02 173 + 174 + struct drm_psb_get_pipe_from_crtc_id_arg { 175 + /** ID of CRTC being requested **/ 176 + u32 crtc_id; 177 + 178 + /** pipe of requested CRTC **/ 179 + u32 pipe; 180 + }; 181 + 182 + /* FIXME: move this into a medfield header once we are sure it isn't needed for an 183 + ioctl */ 184 + struct psb_drm_dpu_rect { 185 + int x, y; 186 + int width, height; 187 + }; 188 + 189 + struct drm_psb_gem_create { 190 + __u64 size; 191 + __u32 handle; 192 + __u32 flags; 193 + #define PSB_GEM_CREATE_STOLEN 1 /* Stolen memory can be used */ 194 + }; 195 + 196 + struct drm_psb_gem_mmap { 197 + __u32 handle; 198 + __u32 pad; 199 + /** 200 + * Fake offset to use for subsequent mmap call 201 + * 202 + * This is a fixed-size type for 32/64 compatibility. 203 + */ 204 + __u64 offset; 205 + }; 206 + 207 + #endif
+1210
drivers/gpu/drm/gma500/psb_drv.c
··· 1 + /************************************************************************** 2 + * Copyright (c) 2007-2011, Intel Corporation. 3 + * All Rights Reserved. 4 + * Copyright (c) 2008, Tungsten Graphics, Inc. Cedar Park, TX., USA. 5 + * All Rights Reserved. 6 + * 7 + * This program is free software; you can redistribute it and/or modify it 8 + * under the terms and conditions of the GNU General Public License, 9 + * version 2, as published by the Free Software Foundation. 10 + * 11 + * This program is distributed in the hope it will be useful, but WITHOUT 12 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14 + * more details. 15 + * 16 + * You should have received a copy of the GNU General Public License along with 17 + * this program; if not, write to the Free Software Foundation, Inc., 18 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 19 + * 20 + **************************************************************************/ 21 + 22 + #include <drm/drmP.h> 23 + #include <drm/drm.h> 24 + #include "psb_drm.h" 25 + #include "psb_drv.h" 26 + #include "framebuffer.h" 27 + #include "psb_reg.h" 28 + #include "psb_intel_reg.h" 29 + #include "intel_bios.h" 30 + #include "mid_bios.h" 31 + #include <drm/drm_pciids.h> 32 + #include "power.h" 33 + #include <linux/cpu.h> 34 + #include <linux/notifier.h> 35 + #include <linux/spinlock.h> 36 + #include <linux/pm_runtime.h> 37 + #include <acpi/video.h> 38 + 39 + static int drm_psb_trap_pagefaults; 40 + 41 + int drm_psb_no_fb; 42 + 43 + static int psb_probe(struct pci_dev *pdev, const struct pci_device_id *ent); 44 + 45 + MODULE_PARM_DESC(no_fb, "Disable FBdev"); 46 + MODULE_PARM_DESC(trap_pagefaults, "Error and reset on MMU pagefaults"); 47 + module_param_named(no_fb, drm_psb_no_fb, int, 0600); 48 + module_param_named(trap_pagefaults, drm_psb_trap_pagefaults, int, 0600); 49 + 50 + 51 + static DEFINE_PCI_DEVICE_TABLE(pciidlist) = { 52 + { 0x8086, 0x8108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &psb_chip_ops }, 53 + { 0x8086, 0x8109, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &psb_chip_ops }, 54 + #if defined(CONFIG_DRM_OAKTRAIL) 55 + { 0x8086, 0x4100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &oaktrail_chip_ops}, 56 + { 0x8086, 0x4101, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &oaktrail_chip_ops}, 57 + { 0x8086, 0x4102, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &oaktrail_chip_ops}, 58 + { 0x8086, 0x4103, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &oaktrail_chip_ops}, 59 + { 0x8086, 0x4104, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &oaktrail_chip_ops}, 60 + { 0x8086, 0x4105, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &oaktrail_chip_ops}, 61 + { 0x8086, 0x4106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &oaktrail_chip_ops}, 62 + { 0x8086, 0x4107, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &oaktrail_chip_ops}, 63 + #endif 64 + #if defined(CONFIG_DRM_CDV) 65 + { 0x8086, 0x0be0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops}, 66 + { 0x8086, 0x0be1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops}, 67 + { 0x8086, 0x0be2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops}, 68 + { 0x8086, 0x0be3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops}, 69 + { 0x8086, 0x0be4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops}, 70 + { 0x8086, 0x0be5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops}, 71 + { 0x8086, 0x0be6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops}, 72 + { 0x8086, 0x0be7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops}, 73 + #endif 74 + { 0, 0, 0} 75 + }; 76 + MODULE_DEVICE_TABLE(pci, pciidlist); 77 + 78 + /* 79 + * Standard IOCTLs. 80 + */ 81 + 82 + #define DRM_IOCTL_PSB_SIZES \ 83 + DRM_IOR(DRM_PSB_SIZES + DRM_COMMAND_BASE, \ 84 + struct drm_psb_sizes_arg) 85 + #define DRM_IOCTL_PSB_FUSE_REG \ 86 + DRM_IOWR(DRM_PSB_FUSE_REG + DRM_COMMAND_BASE, uint32_t) 87 + #define DRM_IOCTL_PSB_DC_STATE \ 88 + DRM_IOW(DRM_PSB_DC_STATE + DRM_COMMAND_BASE, \ 89 + struct drm_psb_dc_state_arg) 90 + #define DRM_IOCTL_PSB_ADB \ 91 + DRM_IOWR(DRM_PSB_ADB + DRM_COMMAND_BASE, uint32_t) 92 + #define DRM_IOCTL_PSB_MODE_OPERATION \ 93 + DRM_IOWR(DRM_PSB_MODE_OPERATION + DRM_COMMAND_BASE, \ 94 + struct drm_psb_mode_operation_arg) 95 + #define DRM_IOCTL_PSB_STOLEN_MEMORY \ 96 + DRM_IOWR(DRM_PSB_STOLEN_MEMORY + DRM_COMMAND_BASE, \ 97 + struct drm_psb_stolen_memory_arg) 98 + #define DRM_IOCTL_PSB_REGISTER_RW \ 99 + DRM_IOWR(DRM_PSB_REGISTER_RW + DRM_COMMAND_BASE, \ 100 + struct drm_psb_register_rw_arg) 101 + #define DRM_IOCTL_PSB_DPST \ 102 + DRM_IOWR(DRM_PSB_DPST + DRM_COMMAND_BASE, \ 103 + uint32_t) 104 + #define DRM_IOCTL_PSB_GAMMA \ 105 + DRM_IOWR(DRM_PSB_GAMMA + DRM_COMMAND_BASE, \ 106 + struct drm_psb_dpst_lut_arg) 107 + #define DRM_IOCTL_PSB_DPST_BL \ 108 + DRM_IOWR(DRM_PSB_DPST_BL + DRM_COMMAND_BASE, \ 109 + uint32_t) 110 + #define DRM_IOCTL_PSB_GET_PIPE_FROM_CRTC_ID \ 111 + DRM_IOWR(DRM_PSB_GET_PIPE_FROM_CRTC_ID + DRM_COMMAND_BASE, \ 112 + struct drm_psb_get_pipe_from_crtc_id_arg) 113 + #define DRM_IOCTL_PSB_GEM_CREATE \ 114 + DRM_IOWR(DRM_PSB_GEM_CREATE + DRM_COMMAND_BASE, \ 115 + struct drm_psb_gem_create) 116 + #define DRM_IOCTL_PSB_GEM_MMAP \ 117 + DRM_IOWR(DRM_PSB_GEM_MMAP + DRM_COMMAND_BASE, \ 118 + struct drm_psb_gem_mmap) 119 + 120 + static int psb_sizes_ioctl(struct drm_device *dev, void *data, 121 + struct drm_file *file_priv); 122 + static int psb_dc_state_ioctl(struct drm_device *dev, void * data, 123 + struct drm_file *file_priv); 124 + static int psb_adb_ioctl(struct drm_device *dev, void *data, 125 + struct drm_file *file_priv); 126 + static int psb_mode_operation_ioctl(struct drm_device *dev, void *data, 127 + struct drm_file *file_priv); 128 + static int psb_stolen_memory_ioctl(struct drm_device *dev, void *data, 129 + struct drm_file *file_priv); 130 + static int psb_register_rw_ioctl(struct drm_device *dev, void *data, 131 + struct drm_file *file_priv); 132 + static int psb_dpst_ioctl(struct drm_device *dev, void *data, 133 + struct drm_file *file_priv); 134 + static int psb_gamma_ioctl(struct drm_device *dev, void *data, 135 + struct drm_file *file_priv); 136 + static int psb_dpst_bl_ioctl(struct drm_device *dev, void *data, 137 + struct drm_file *file_priv); 138 + 139 + #define PSB_IOCTL_DEF(ioctl, func, flags) \ 140 + [DRM_IOCTL_NR(ioctl) - DRM_COMMAND_BASE] = {ioctl, flags, func} 141 + 142 + static struct drm_ioctl_desc psb_ioctls[] = { 143 + PSB_IOCTL_DEF(DRM_IOCTL_PSB_SIZES, psb_sizes_ioctl, DRM_AUTH), 144 + PSB_IOCTL_DEF(DRM_IOCTL_PSB_DC_STATE, psb_dc_state_ioctl, DRM_AUTH), 145 + PSB_IOCTL_DEF(DRM_IOCTL_PSB_ADB, psb_adb_ioctl, DRM_AUTH), 146 + PSB_IOCTL_DEF(DRM_IOCTL_PSB_MODE_OPERATION, psb_mode_operation_ioctl, 147 + DRM_AUTH), 148 + PSB_IOCTL_DEF(DRM_IOCTL_PSB_STOLEN_MEMORY, psb_stolen_memory_ioctl, 149 + DRM_AUTH), 150 + PSB_IOCTL_DEF(DRM_IOCTL_PSB_REGISTER_RW, psb_register_rw_ioctl, 151 + DRM_AUTH), 152 + PSB_IOCTL_DEF(DRM_IOCTL_PSB_DPST, psb_dpst_ioctl, DRM_AUTH), 153 + PSB_IOCTL_DEF(DRM_IOCTL_PSB_GAMMA, psb_gamma_ioctl, DRM_AUTH), 154 + PSB_IOCTL_DEF(DRM_IOCTL_PSB_DPST_BL, psb_dpst_bl_ioctl, DRM_AUTH), 155 + PSB_IOCTL_DEF(DRM_IOCTL_PSB_GET_PIPE_FROM_CRTC_ID, 156 + psb_intel_get_pipe_from_crtc_id, 0), 157 + PSB_IOCTL_DEF(DRM_IOCTL_PSB_GEM_CREATE, psb_gem_create_ioctl, 158 + DRM_UNLOCKED | DRM_AUTH), 159 + PSB_IOCTL_DEF(DRM_IOCTL_PSB_GEM_MMAP, psb_gem_mmap_ioctl, 160 + DRM_UNLOCKED | DRM_AUTH), 161 + }; 162 + 163 + static void psb_lastclose(struct drm_device *dev) 164 + { 165 + return; 166 + } 167 + 168 + static void psb_do_takedown(struct drm_device *dev) 169 + { 170 + /* FIXME: do we need to clean up the gtt here ? */ 171 + } 172 + 173 + static int psb_do_init(struct drm_device *dev) 174 + { 175 + struct drm_psb_private *dev_priv = dev->dev_private; 176 + struct psb_gtt *pg = &dev_priv->gtt; 177 + 178 + uint32_t stolen_gtt; 179 + 180 + int ret = -ENOMEM; 181 + 182 + if (pg->mmu_gatt_start & 0x0FFFFFFF) { 183 + dev_err(dev->dev, "Gatt must be 256M aligned. This is a bug.\n"); 184 + ret = -EINVAL; 185 + goto out_err; 186 + } 187 + 188 + 189 + stolen_gtt = (pg->stolen_size >> PAGE_SHIFT) * 4; 190 + stolen_gtt = (stolen_gtt + PAGE_SIZE - 1) >> PAGE_SHIFT; 191 + stolen_gtt = 192 + (stolen_gtt < pg->gtt_pages) ? stolen_gtt : pg->gtt_pages; 193 + 194 + dev_priv->gatt_free_offset = pg->mmu_gatt_start + 195 + (stolen_gtt << PAGE_SHIFT) * 1024; 196 + 197 + if (1 || drm_debug) { 198 + uint32_t core_id = PSB_RSGX32(PSB_CR_CORE_ID); 199 + uint32_t core_rev = PSB_RSGX32(PSB_CR_CORE_REVISION); 200 + DRM_INFO("SGX core id = 0x%08x\n", core_id); 201 + DRM_INFO("SGX core rev major = 0x%02x, minor = 0x%02x\n", 202 + (core_rev & _PSB_CC_REVISION_MAJOR_MASK) >> 203 + _PSB_CC_REVISION_MAJOR_SHIFT, 204 + (core_rev & _PSB_CC_REVISION_MINOR_MASK) >> 205 + _PSB_CC_REVISION_MINOR_SHIFT); 206 + DRM_INFO 207 + ("SGX core rev maintenance = 0x%02x, designer = 0x%02x\n", 208 + (core_rev & _PSB_CC_REVISION_MAINTENANCE_MASK) >> 209 + _PSB_CC_REVISION_MAINTENANCE_SHIFT, 210 + (core_rev & _PSB_CC_REVISION_DESIGNER_MASK) >> 211 + _PSB_CC_REVISION_DESIGNER_SHIFT); 212 + } 213 + 214 + 215 + spin_lock_init(&dev_priv->irqmask_lock); 216 + mutex_init(&dev_priv->mutex_2d); 217 + 218 + PSB_WSGX32(0x00000000, PSB_CR_BIF_BANK0); 219 + PSB_WSGX32(0x00000000, PSB_CR_BIF_BANK1); 220 + PSB_RSGX32(PSB_CR_BIF_BANK1); 221 + PSB_WSGX32(PSB_RSGX32(PSB_CR_BIF_CTRL) | _PSB_MMU_ER_MASK, 222 + PSB_CR_BIF_CTRL); 223 + psb_spank(dev_priv); 224 + 225 + /* mmu_gatt ?? */ 226 + PSB_WSGX32(pg->gatt_start, PSB_CR_BIF_TWOD_REQ_BASE); 227 + return 0; 228 + out_err: 229 + psb_do_takedown(dev); 230 + return ret; 231 + } 232 + 233 + static int psb_driver_unload(struct drm_device *dev) 234 + { 235 + struct drm_psb_private *dev_priv = dev->dev_private; 236 + 237 + /* Kill vblank etc here */ 238 + 239 + gma_backlight_exit(dev); 240 + 241 + if (drm_psb_no_fb == 0) 242 + psb_modeset_cleanup(dev); 243 + 244 + if (dev_priv) { 245 + psb_lid_timer_takedown(dev_priv); 246 + gma_intel_opregion_exit(dev); 247 + 248 + if (dev_priv->ops->chip_teardown) 249 + dev_priv->ops->chip_teardown(dev); 250 + psb_do_takedown(dev); 251 + 252 + 253 + if (dev_priv->pf_pd) { 254 + psb_mmu_free_pagedir(dev_priv->pf_pd); 255 + dev_priv->pf_pd = NULL; 256 + } 257 + if (dev_priv->mmu) { 258 + struct psb_gtt *pg = &dev_priv->gtt; 259 + 260 + down_read(&pg->sem); 261 + psb_mmu_remove_pfn_sequence( 262 + psb_mmu_get_default_pd 263 + (dev_priv->mmu), 264 + pg->mmu_gatt_start, 265 + dev_priv->vram_stolen_size >> PAGE_SHIFT); 266 + up_read(&pg->sem); 267 + psb_mmu_driver_takedown(dev_priv->mmu); 268 + dev_priv->mmu = NULL; 269 + } 270 + psb_gtt_takedown(dev); 271 + if (dev_priv->scratch_page) { 272 + __free_page(dev_priv->scratch_page); 273 + dev_priv->scratch_page = NULL; 274 + } 275 + if (dev_priv->vdc_reg) { 276 + iounmap(dev_priv->vdc_reg); 277 + dev_priv->vdc_reg = NULL; 278 + } 279 + if (dev_priv->sgx_reg) { 280 + iounmap(dev_priv->sgx_reg); 281 + dev_priv->sgx_reg = NULL; 282 + } 283 + 284 + kfree(dev_priv); 285 + dev->dev_private = NULL; 286 + 287 + /*destroy VBT data*/ 288 + psb_intel_destroy_bios(dev); 289 + } 290 + 291 + gma_power_uninit(dev); 292 + 293 + return 0; 294 + } 295 + 296 + 297 + static int psb_driver_load(struct drm_device *dev, unsigned long chipset) 298 + { 299 + struct drm_psb_private *dev_priv; 300 + unsigned long resource_start; 301 + struct psb_gtt *pg; 302 + unsigned long irqflags; 303 + int ret = -ENOMEM; 304 + uint32_t tt_pages; 305 + struct drm_connector *connector; 306 + struct psb_intel_output *psb_intel_output; 307 + 308 + dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL); 309 + if (dev_priv == NULL) 310 + return -ENOMEM; 311 + 312 + dev_priv->ops = (struct psb_ops *)chipset; 313 + dev_priv->dev = dev; 314 + dev->dev_private = (void *) dev_priv; 315 + 316 + dev_priv->num_pipe = dev_priv->ops->pipes; 317 + 318 + resource_start = pci_resource_start(dev->pdev, PSB_MMIO_RESOURCE); 319 + 320 + dev_priv->vdc_reg = 321 + ioremap(resource_start + PSB_VDC_OFFSET, PSB_VDC_SIZE); 322 + if (!dev_priv->vdc_reg) 323 + goto out_err; 324 + 325 + dev_priv->sgx_reg = ioremap(resource_start + dev_priv->ops->sgx_offset, 326 + PSB_SGX_SIZE); 327 + if (!dev_priv->sgx_reg) 328 + goto out_err; 329 + 330 + ret = dev_priv->ops->chip_setup(dev); 331 + if (ret) 332 + goto out_err; 333 + 334 + /* Init OSPM support */ 335 + gma_power_init(dev); 336 + 337 + ret = -ENOMEM; 338 + 339 + dev_priv->scratch_page = alloc_page(GFP_DMA32 | __GFP_ZERO); 340 + if (!dev_priv->scratch_page) 341 + goto out_err; 342 + 343 + set_pages_uc(dev_priv->scratch_page, 1); 344 + 345 + ret = psb_gtt_init(dev, 0); 346 + if (ret) 347 + goto out_err; 348 + 349 + dev_priv->mmu = psb_mmu_driver_init((void *)0, 350 + drm_psb_trap_pagefaults, 0, 351 + dev_priv); 352 + if (!dev_priv->mmu) 353 + goto out_err; 354 + 355 + pg = &dev_priv->gtt; 356 + 357 + tt_pages = (pg->gatt_pages < PSB_TT_PRIV0_PLIMIT) ? 358 + (pg->gatt_pages) : PSB_TT_PRIV0_PLIMIT; 359 + 360 + 361 + dev_priv->pf_pd = psb_mmu_alloc_pd(dev_priv->mmu, 1, 0); 362 + if (!dev_priv->pf_pd) 363 + goto out_err; 364 + 365 + psb_mmu_set_pd_context(psb_mmu_get_default_pd(dev_priv->mmu), 0); 366 + psb_mmu_set_pd_context(dev_priv->pf_pd, 1); 367 + 368 + ret = psb_do_init(dev); 369 + if (ret) 370 + return ret; 371 + 372 + PSB_WSGX32(0x20000000, PSB_CR_PDS_EXEC_BASE); 373 + PSB_WSGX32(0x30000000, PSB_CR_BIF_3D_REQ_BASE); 374 + 375 + /* igd_opregion_init(&dev_priv->opregion_dev); */ 376 + acpi_video_register(); 377 + if (dev_priv->lid_state) 378 + psb_lid_timer_init(dev_priv); 379 + 380 + ret = drm_vblank_init(dev, dev_priv->num_pipe); 381 + if (ret) 382 + goto out_err; 383 + 384 + /* 385 + * Install interrupt handlers prior to powering off SGX or else we will 386 + * crash. 387 + */ 388 + dev_priv->vdc_irq_mask = 0; 389 + dev_priv->pipestat[0] = 0; 390 + dev_priv->pipestat[1] = 0; 391 + dev_priv->pipestat[2] = 0; 392 + spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); 393 + PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM); 394 + PSB_WVDC32(0x00000000, PSB_INT_ENABLE_R); 395 + PSB_WVDC32(0xFFFFFFFF, PSB_INT_MASK_R); 396 + spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); 397 + if (drm_core_check_feature(dev, DRIVER_MODESET)) 398 + drm_irq_install(dev); 399 + 400 + dev->vblank_disable_allowed = 1; 401 + 402 + dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ 403 + 404 + dev->driver->get_vblank_counter = psb_get_vblank_counter; 405 + 406 + if (drm_psb_no_fb == 0) { 407 + psb_modeset_init(dev); 408 + psb_fbdev_init(dev); 409 + drm_kms_helper_poll_init(dev); 410 + } 411 + 412 + /* Only add backlight support if we have LVDS output */ 413 + list_for_each_entry(connector, &dev->mode_config.connector_list, 414 + head) { 415 + psb_intel_output = to_psb_intel_output(connector); 416 + 417 + switch (psb_intel_output->type) { 418 + case INTEL_OUTPUT_LVDS: 419 + case INTEL_OUTPUT_MIPI: 420 + ret = gma_backlight_init(dev); 421 + break; 422 + } 423 + } 424 + 425 + if (ret) 426 + return ret; 427 + #if 0 428 + /*enable runtime pm at last*/ 429 + pm_runtime_enable(&dev->pdev->dev); 430 + pm_runtime_set_active(&dev->pdev->dev); 431 + #endif 432 + /*Intel drm driver load is done, continue doing pvr load*/ 433 + return 0; 434 + out_err: 435 + psb_driver_unload(dev); 436 + return ret; 437 + } 438 + 439 + int psb_driver_device_is_agp(struct drm_device *dev) 440 + { 441 + return 0; 442 + } 443 + 444 + 445 + static int psb_sizes_ioctl(struct drm_device *dev, void *data, 446 + struct drm_file *file_priv) 447 + { 448 + struct drm_psb_private *dev_priv = psb_priv(dev); 449 + struct drm_psb_sizes_arg *arg = 450 + (struct drm_psb_sizes_arg *) data; 451 + 452 + *arg = dev_priv->sizes; 453 + return 0; 454 + } 455 + 456 + static int psb_dc_state_ioctl(struct drm_device *dev, void * data, 457 + struct drm_file *file_priv) 458 + { 459 + uint32_t flags; 460 + uint32_t obj_id; 461 + struct drm_mode_object *obj; 462 + struct drm_connector *connector; 463 + struct drm_crtc *crtc; 464 + struct drm_psb_dc_state_arg *arg = data; 465 + 466 + 467 + /* Double check MRST case */ 468 + if (IS_MRST(dev) || IS_MFLD(dev)) 469 + return -EOPNOTSUPP; 470 + 471 + flags = arg->flags; 472 + obj_id = arg->obj_id; 473 + 474 + if (flags & PSB_DC_CRTC_MASK) { 475 + obj = drm_mode_object_find(dev, obj_id, 476 + DRM_MODE_OBJECT_CRTC); 477 + if (!obj) { 478 + dev_dbg(dev->dev, "Invalid CRTC object.\n"); 479 + return -EINVAL; 480 + } 481 + 482 + crtc = obj_to_crtc(obj); 483 + 484 + mutex_lock(&dev->mode_config.mutex); 485 + if (drm_helper_crtc_in_use(crtc)) { 486 + if (flags & PSB_DC_CRTC_SAVE) 487 + crtc->funcs->save(crtc); 488 + else 489 + crtc->funcs->restore(crtc); 490 + } 491 + mutex_unlock(&dev->mode_config.mutex); 492 + 493 + return 0; 494 + } else if (flags & PSB_DC_OUTPUT_MASK) { 495 + obj = drm_mode_object_find(dev, obj_id, 496 + DRM_MODE_OBJECT_CONNECTOR); 497 + if (!obj) { 498 + dev_dbg(dev->dev, "Invalid connector id.\n"); 499 + return -EINVAL; 500 + } 501 + 502 + connector = obj_to_connector(obj); 503 + if (flags & PSB_DC_OUTPUT_SAVE) 504 + connector->funcs->save(connector); 505 + else 506 + connector->funcs->restore(connector); 507 + 508 + return 0; 509 + } 510 + return -EINVAL; 511 + } 512 + 513 + static inline void get_brightness(struct backlight_device *bd) 514 + { 515 + #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE 516 + if (bd) { 517 + bd->props.brightness = bd->ops->get_brightness(bd); 518 + backlight_update_status(bd); 519 + } 520 + #endif 521 + } 522 + 523 + static int psb_dpst_bl_ioctl(struct drm_device *dev, void *data, 524 + struct drm_file *file_priv) 525 + { 526 + struct drm_psb_private *dev_priv = psb_priv(dev); 527 + uint32_t *arg = data; 528 + 529 + dev_priv->blc_adj2 = *arg; 530 + get_brightness(dev_priv->backlight_device); 531 + return 0; 532 + } 533 + 534 + static int psb_adb_ioctl(struct drm_device *dev, void *data, 535 + struct drm_file *file_priv) 536 + { 537 + struct drm_psb_private *dev_priv = psb_priv(dev); 538 + uint32_t *arg = data; 539 + 540 + dev_priv->blc_adj1 = *arg; 541 + get_brightness(dev_priv->backlight_device); 542 + return 0; 543 + } 544 + 545 + /* return the current mode to the dpst module */ 546 + static int psb_dpst_ioctl(struct drm_device *dev, void *data, 547 + struct drm_file *file_priv) 548 + { 549 + struct drm_psb_private *dev_priv = psb_priv(dev); 550 + uint32_t *arg = data; 551 + uint32_t x; 552 + uint32_t y; 553 + uint32_t reg; 554 + 555 + if (!gma_power_begin(dev, 0)) 556 + return -EIO; 557 + 558 + reg = PSB_RVDC32(PIPEASRC); 559 + 560 + gma_power_end(dev); 561 + 562 + /* horizontal is the left 16 bits */ 563 + x = reg >> 16; 564 + /* vertical is the right 16 bits */ 565 + y = reg & 0x0000ffff; 566 + 567 + /* the values are the image size minus one */ 568 + x++; 569 + y++; 570 + 571 + *arg = (x << 16) | y; 572 + 573 + return 0; 574 + } 575 + static int psb_gamma_ioctl(struct drm_device *dev, void *data, 576 + struct drm_file *file_priv) 577 + { 578 + struct drm_psb_dpst_lut_arg *lut_arg = data; 579 + struct drm_mode_object *obj; 580 + struct drm_crtc *crtc; 581 + struct drm_connector *connector; 582 + struct psb_intel_crtc *psb_intel_crtc; 583 + int i = 0; 584 + int32_t obj_id; 585 + 586 + obj_id = lut_arg->output_id; 587 + obj = drm_mode_object_find(dev, obj_id, DRM_MODE_OBJECT_CONNECTOR); 588 + if (!obj) { 589 + dev_dbg(dev->dev, "Invalid Connector object.\n"); 590 + return -EINVAL; 591 + } 592 + 593 + connector = obj_to_connector(obj); 594 + crtc = connector->encoder->crtc; 595 + psb_intel_crtc = to_psb_intel_crtc(crtc); 596 + 597 + for (i = 0; i < 256; i++) 598 + psb_intel_crtc->lut_adj[i] = lut_arg->lut[i]; 599 + 600 + psb_intel_crtc_load_lut(crtc); 601 + 602 + return 0; 603 + } 604 + 605 + static int psb_mode_operation_ioctl(struct drm_device *dev, void *data, 606 + struct drm_file *file_priv) 607 + { 608 + uint32_t obj_id; 609 + uint16_t op; 610 + struct drm_mode_modeinfo *umode; 611 + struct drm_display_mode *mode = NULL; 612 + struct drm_psb_mode_operation_arg *arg; 613 + struct drm_mode_object *obj; 614 + struct drm_connector *connector; 615 + struct drm_framebuffer *drm_fb; 616 + struct psb_framebuffer *psb_fb; 617 + struct drm_connector_helper_funcs *connector_funcs; 618 + int ret = 0; 619 + int resp = MODE_OK; 620 + struct drm_psb_private *dev_priv = psb_priv(dev); 621 + 622 + arg = (struct drm_psb_mode_operation_arg *)data; 623 + obj_id = arg->obj_id; 624 + op = arg->operation; 625 + 626 + switch (op) { 627 + case PSB_MODE_OPERATION_SET_DC_BASE: 628 + obj = drm_mode_object_find(dev, obj_id, DRM_MODE_OBJECT_FB); 629 + if (!obj) { 630 + dev_dbg(dev->dev, "Invalid FB id %d\n", obj_id); 631 + return -EINVAL; 632 + } 633 + 634 + drm_fb = obj_to_fb(obj); 635 + psb_fb = to_psb_fb(drm_fb); 636 + 637 + if (gma_power_begin(dev, 0)) { 638 + REG_WRITE(DSPASURF, psb_fb->gtt->offset); 639 + REG_READ(DSPASURF); 640 + gma_power_end(dev); 641 + } else { 642 + dev_priv->saveDSPASURF = psb_fb->gtt->offset; 643 + } 644 + 645 + return 0; 646 + case PSB_MODE_OPERATION_MODE_VALID: 647 + umode = &arg->mode; 648 + 649 + mutex_lock(&dev->mode_config.mutex); 650 + 651 + obj = drm_mode_object_find(dev, obj_id, 652 + DRM_MODE_OBJECT_CONNECTOR); 653 + if (!obj) { 654 + ret = -EINVAL; 655 + goto mode_op_out; 656 + } 657 + 658 + connector = obj_to_connector(obj); 659 + 660 + mode = drm_mode_create(dev); 661 + if (!mode) { 662 + ret = -ENOMEM; 663 + goto mode_op_out; 664 + } 665 + 666 + /* drm_crtc_convert_umode(mode, umode); */ 667 + { 668 + mode->clock = umode->clock; 669 + mode->hdisplay = umode->hdisplay; 670 + mode->hsync_start = umode->hsync_start; 671 + mode->hsync_end = umode->hsync_end; 672 + mode->htotal = umode->htotal; 673 + mode->hskew = umode->hskew; 674 + mode->vdisplay = umode->vdisplay; 675 + mode->vsync_start = umode->vsync_start; 676 + mode->vsync_end = umode->vsync_end; 677 + mode->vtotal = umode->vtotal; 678 + mode->vscan = umode->vscan; 679 + mode->vrefresh = umode->vrefresh; 680 + mode->flags = umode->flags; 681 + mode->type = umode->type; 682 + strncpy(mode->name, umode->name, DRM_DISPLAY_MODE_LEN); 683 + mode->name[DRM_DISPLAY_MODE_LEN-1] = 0; 684 + } 685 + 686 + connector_funcs = (struct drm_connector_helper_funcs *) 687 + connector->helper_private; 688 + 689 + if (connector_funcs->mode_valid) { 690 + resp = connector_funcs->mode_valid(connector, mode); 691 + arg->data = (void *)resp; 692 + } 693 + 694 + /*do some clean up work*/ 695 + if (mode) 696 + drm_mode_destroy(dev, mode); 697 + mode_op_out: 698 + mutex_unlock(&dev->mode_config.mutex); 699 + return ret; 700 + 701 + default: 702 + dev_dbg(dev->dev, "Unsupported psb mode operation\n"); 703 + return -EOPNOTSUPP; 704 + } 705 + 706 + return 0; 707 + } 708 + 709 + static int psb_stolen_memory_ioctl(struct drm_device *dev, void *data, 710 + struct drm_file *file_priv) 711 + { 712 + struct drm_psb_private *dev_priv = psb_priv(dev); 713 + struct drm_psb_stolen_memory_arg *arg = data; 714 + 715 + arg->base = dev_priv->stolen_base; 716 + arg->size = dev_priv->vram_stolen_size; 717 + 718 + return 0; 719 + } 720 + 721 + /* FIXME: needs Medfield changes */ 722 + static int psb_register_rw_ioctl(struct drm_device *dev, void *data, 723 + struct drm_file *file_priv) 724 + { 725 + struct drm_psb_private *dev_priv = psb_priv(dev); 726 + struct drm_psb_register_rw_arg *arg = data; 727 + bool usage = arg->b_force_hw_on ? true : false; 728 + 729 + if (arg->display_write_mask != 0) { 730 + if (gma_power_begin(dev, usage)) { 731 + if (arg->display_write_mask & REGRWBITS_PFIT_CONTROLS) 732 + PSB_WVDC32(arg->display.pfit_controls, 733 + PFIT_CONTROL); 734 + if (arg->display_write_mask & 735 + REGRWBITS_PFIT_AUTOSCALE_RATIOS) 736 + PSB_WVDC32(arg->display.pfit_autoscale_ratios, 737 + PFIT_AUTO_RATIOS); 738 + if (arg->display_write_mask & 739 + REGRWBITS_PFIT_PROGRAMMED_SCALE_RATIOS) 740 + PSB_WVDC32( 741 + arg->display.pfit_programmed_scale_ratios, 742 + PFIT_PGM_RATIOS); 743 + if (arg->display_write_mask & REGRWBITS_PIPEASRC) 744 + PSB_WVDC32(arg->display.pipeasrc, 745 + PIPEASRC); 746 + if (arg->display_write_mask & REGRWBITS_PIPEBSRC) 747 + PSB_WVDC32(arg->display.pipebsrc, 748 + PIPEBSRC); 749 + if (arg->display_write_mask & REGRWBITS_VTOTAL_A) 750 + PSB_WVDC32(arg->display.vtotal_a, 751 + VTOTAL_A); 752 + if (arg->display_write_mask & REGRWBITS_VTOTAL_B) 753 + PSB_WVDC32(arg->display.vtotal_b, 754 + VTOTAL_B); 755 + gma_power_end(dev); 756 + } else { 757 + if (arg->display_write_mask & REGRWBITS_PFIT_CONTROLS) 758 + dev_priv->savePFIT_CONTROL = 759 + arg->display.pfit_controls; 760 + if (arg->display_write_mask & 761 + REGRWBITS_PFIT_AUTOSCALE_RATIOS) 762 + dev_priv->savePFIT_AUTO_RATIOS = 763 + arg->display.pfit_autoscale_ratios; 764 + if (arg->display_write_mask & 765 + REGRWBITS_PFIT_PROGRAMMED_SCALE_RATIOS) 766 + dev_priv->savePFIT_PGM_RATIOS = 767 + arg->display.pfit_programmed_scale_ratios; 768 + if (arg->display_write_mask & REGRWBITS_PIPEASRC) 769 + dev_priv->savePIPEASRC = arg->display.pipeasrc; 770 + if (arg->display_write_mask & REGRWBITS_PIPEBSRC) 771 + dev_priv->savePIPEBSRC = arg->display.pipebsrc; 772 + if (arg->display_write_mask & REGRWBITS_VTOTAL_A) 773 + dev_priv->saveVTOTAL_A = arg->display.vtotal_a; 774 + if (arg->display_write_mask & REGRWBITS_VTOTAL_B) 775 + dev_priv->saveVTOTAL_B = arg->display.vtotal_b; 776 + } 777 + } 778 + 779 + if (arg->display_read_mask != 0) { 780 + if (gma_power_begin(dev, usage)) { 781 + if (arg->display_read_mask & 782 + REGRWBITS_PFIT_CONTROLS) 783 + arg->display.pfit_controls = 784 + PSB_RVDC32(PFIT_CONTROL); 785 + if (arg->display_read_mask & 786 + REGRWBITS_PFIT_AUTOSCALE_RATIOS) 787 + arg->display.pfit_autoscale_ratios = 788 + PSB_RVDC32(PFIT_AUTO_RATIOS); 789 + if (arg->display_read_mask & 790 + REGRWBITS_PFIT_PROGRAMMED_SCALE_RATIOS) 791 + arg->display.pfit_programmed_scale_ratios = 792 + PSB_RVDC32(PFIT_PGM_RATIOS); 793 + if (arg->display_read_mask & REGRWBITS_PIPEASRC) 794 + arg->display.pipeasrc = PSB_RVDC32(PIPEASRC); 795 + if (arg->display_read_mask & REGRWBITS_PIPEBSRC) 796 + arg->display.pipebsrc = PSB_RVDC32(PIPEBSRC); 797 + if (arg->display_read_mask & REGRWBITS_VTOTAL_A) 798 + arg->display.vtotal_a = PSB_RVDC32(VTOTAL_A); 799 + if (arg->display_read_mask & REGRWBITS_VTOTAL_B) 800 + arg->display.vtotal_b = PSB_RVDC32(VTOTAL_B); 801 + gma_power_end(dev); 802 + } else { 803 + if (arg->display_read_mask & 804 + REGRWBITS_PFIT_CONTROLS) 805 + arg->display.pfit_controls = 806 + dev_priv->savePFIT_CONTROL; 807 + if (arg->display_read_mask & 808 + REGRWBITS_PFIT_AUTOSCALE_RATIOS) 809 + arg->display.pfit_autoscale_ratios = 810 + dev_priv->savePFIT_AUTO_RATIOS; 811 + if (arg->display_read_mask & 812 + REGRWBITS_PFIT_PROGRAMMED_SCALE_RATIOS) 813 + arg->display.pfit_programmed_scale_ratios = 814 + dev_priv->savePFIT_PGM_RATIOS; 815 + if (arg->display_read_mask & REGRWBITS_PIPEASRC) 816 + arg->display.pipeasrc = dev_priv->savePIPEASRC; 817 + if (arg->display_read_mask & REGRWBITS_PIPEBSRC) 818 + arg->display.pipebsrc = dev_priv->savePIPEBSRC; 819 + if (arg->display_read_mask & REGRWBITS_VTOTAL_A) 820 + arg->display.vtotal_a = dev_priv->saveVTOTAL_A; 821 + if (arg->display_read_mask & REGRWBITS_VTOTAL_B) 822 + arg->display.vtotal_b = dev_priv->saveVTOTAL_B; 823 + } 824 + } 825 + 826 + if (arg->overlay_write_mask != 0) { 827 + if (gma_power_begin(dev, usage)) { 828 + if (arg->overlay_write_mask & OV_REGRWBITS_OGAM_ALL) { 829 + PSB_WVDC32(arg->overlay.OGAMC5, OV_OGAMC5); 830 + PSB_WVDC32(arg->overlay.OGAMC4, OV_OGAMC4); 831 + PSB_WVDC32(arg->overlay.OGAMC3, OV_OGAMC3); 832 + PSB_WVDC32(arg->overlay.OGAMC2, OV_OGAMC2); 833 + PSB_WVDC32(arg->overlay.OGAMC1, OV_OGAMC1); 834 + PSB_WVDC32(arg->overlay.OGAMC0, OV_OGAMC0); 835 + } 836 + if (arg->overlay_write_mask & OVC_REGRWBITS_OGAM_ALL) { 837 + PSB_WVDC32(arg->overlay.OGAMC5, OVC_OGAMC5); 838 + PSB_WVDC32(arg->overlay.OGAMC4, OVC_OGAMC4); 839 + PSB_WVDC32(arg->overlay.OGAMC3, OVC_OGAMC3); 840 + PSB_WVDC32(arg->overlay.OGAMC2, OVC_OGAMC2); 841 + PSB_WVDC32(arg->overlay.OGAMC1, OVC_OGAMC1); 842 + PSB_WVDC32(arg->overlay.OGAMC0, OVC_OGAMC0); 843 + } 844 + 845 + if (arg->overlay_write_mask & OV_REGRWBITS_OVADD) { 846 + PSB_WVDC32(arg->overlay.OVADD, OV_OVADD); 847 + 848 + if (arg->overlay.b_wait_vblank) { 849 + /* Wait for 20ms.*/ 850 + unsigned long vblank_timeout = jiffies 851 + + HZ/50; 852 + uint32_t temp; 853 + while (time_before_eq(jiffies, 854 + vblank_timeout)) { 855 + temp = PSB_RVDC32(OV_DOVASTA); 856 + if ((temp & (0x1 << 31)) != 0) 857 + break; 858 + cpu_relax(); 859 + } 860 + } 861 + } 862 + if (arg->overlay_write_mask & OVC_REGRWBITS_OVADD) { 863 + PSB_WVDC32(arg->overlay.OVADD, OVC_OVADD); 864 + if (arg->overlay.b_wait_vblank) { 865 + /* Wait for 20ms.*/ 866 + unsigned long vblank_timeout = 867 + jiffies + HZ/50; 868 + uint32_t temp; 869 + while (time_before_eq(jiffies, 870 + vblank_timeout)) { 871 + temp = PSB_RVDC32(OVC_DOVCSTA); 872 + if ((temp & (0x1 << 31)) != 0) 873 + break; 874 + cpu_relax(); 875 + } 876 + } 877 + } 878 + gma_power_end(dev); 879 + } else { 880 + if (arg->overlay_write_mask & OV_REGRWBITS_OGAM_ALL) { 881 + dev_priv->saveOV_OGAMC5 = arg->overlay.OGAMC5; 882 + dev_priv->saveOV_OGAMC4 = arg->overlay.OGAMC4; 883 + dev_priv->saveOV_OGAMC3 = arg->overlay.OGAMC3; 884 + dev_priv->saveOV_OGAMC2 = arg->overlay.OGAMC2; 885 + dev_priv->saveOV_OGAMC1 = arg->overlay.OGAMC1; 886 + dev_priv->saveOV_OGAMC0 = arg->overlay.OGAMC0; 887 + } 888 + if (arg->overlay_write_mask & OVC_REGRWBITS_OGAM_ALL) { 889 + dev_priv->saveOVC_OGAMC5 = arg->overlay.OGAMC5; 890 + dev_priv->saveOVC_OGAMC4 = arg->overlay.OGAMC4; 891 + dev_priv->saveOVC_OGAMC3 = arg->overlay.OGAMC3; 892 + dev_priv->saveOVC_OGAMC2 = arg->overlay.OGAMC2; 893 + dev_priv->saveOVC_OGAMC1 = arg->overlay.OGAMC1; 894 + dev_priv->saveOVC_OGAMC0 = arg->overlay.OGAMC0; 895 + } 896 + if (arg->overlay_write_mask & OV_REGRWBITS_OVADD) 897 + dev_priv->saveOV_OVADD = arg->overlay.OVADD; 898 + if (arg->overlay_write_mask & OVC_REGRWBITS_OVADD) 899 + dev_priv->saveOVC_OVADD = arg->overlay.OVADD; 900 + } 901 + } 902 + 903 + if (arg->overlay_read_mask != 0) { 904 + if (gma_power_begin(dev, usage)) { 905 + if (arg->overlay_read_mask & OV_REGRWBITS_OGAM_ALL) { 906 + arg->overlay.OGAMC5 = PSB_RVDC32(OV_OGAMC5); 907 + arg->overlay.OGAMC4 = PSB_RVDC32(OV_OGAMC4); 908 + arg->overlay.OGAMC3 = PSB_RVDC32(OV_OGAMC3); 909 + arg->overlay.OGAMC2 = PSB_RVDC32(OV_OGAMC2); 910 + arg->overlay.OGAMC1 = PSB_RVDC32(OV_OGAMC1); 911 + arg->overlay.OGAMC0 = PSB_RVDC32(OV_OGAMC0); 912 + } 913 + if (arg->overlay_read_mask & OVC_REGRWBITS_OGAM_ALL) { 914 + arg->overlay.OGAMC5 = PSB_RVDC32(OVC_OGAMC5); 915 + arg->overlay.OGAMC4 = PSB_RVDC32(OVC_OGAMC4); 916 + arg->overlay.OGAMC3 = PSB_RVDC32(OVC_OGAMC3); 917 + arg->overlay.OGAMC2 = PSB_RVDC32(OVC_OGAMC2); 918 + arg->overlay.OGAMC1 = PSB_RVDC32(OVC_OGAMC1); 919 + arg->overlay.OGAMC0 = PSB_RVDC32(OVC_OGAMC0); 920 + } 921 + if (arg->overlay_read_mask & OV_REGRWBITS_OVADD) 922 + arg->overlay.OVADD = PSB_RVDC32(OV_OVADD); 923 + if (arg->overlay_read_mask & OVC_REGRWBITS_OVADD) 924 + arg->overlay.OVADD = PSB_RVDC32(OVC_OVADD); 925 + gma_power_end(dev); 926 + } else { 927 + if (arg->overlay_read_mask & OV_REGRWBITS_OGAM_ALL) { 928 + arg->overlay.OGAMC5 = dev_priv->saveOV_OGAMC5; 929 + arg->overlay.OGAMC4 = dev_priv->saveOV_OGAMC4; 930 + arg->overlay.OGAMC3 = dev_priv->saveOV_OGAMC3; 931 + arg->overlay.OGAMC2 = dev_priv->saveOV_OGAMC2; 932 + arg->overlay.OGAMC1 = dev_priv->saveOV_OGAMC1; 933 + arg->overlay.OGAMC0 = dev_priv->saveOV_OGAMC0; 934 + } 935 + if (arg->overlay_read_mask & OVC_REGRWBITS_OGAM_ALL) { 936 + arg->overlay.OGAMC5 = dev_priv->saveOVC_OGAMC5; 937 + arg->overlay.OGAMC4 = dev_priv->saveOVC_OGAMC4; 938 + arg->overlay.OGAMC3 = dev_priv->saveOVC_OGAMC3; 939 + arg->overlay.OGAMC2 = dev_priv->saveOVC_OGAMC2; 940 + arg->overlay.OGAMC1 = dev_priv->saveOVC_OGAMC1; 941 + arg->overlay.OGAMC0 = dev_priv->saveOVC_OGAMC0; 942 + } 943 + if (arg->overlay_read_mask & OV_REGRWBITS_OVADD) 944 + arg->overlay.OVADD = dev_priv->saveOV_OVADD; 945 + if (arg->overlay_read_mask & OVC_REGRWBITS_OVADD) 946 + arg->overlay.OVADD = dev_priv->saveOVC_OVADD; 947 + } 948 + } 949 + 950 + if (arg->sprite_enable_mask != 0) { 951 + if (gma_power_begin(dev, usage)) { 952 + PSB_WVDC32(0x1F3E, DSPARB); 953 + PSB_WVDC32(arg->sprite.dspa_control 954 + | PSB_RVDC32(DSPACNTR), DSPACNTR); 955 + PSB_WVDC32(arg->sprite.dspa_key_value, DSPAKEYVAL); 956 + PSB_WVDC32(arg->sprite.dspa_key_mask, DSPAKEYMASK); 957 + PSB_WVDC32(PSB_RVDC32(DSPASURF), DSPASURF); 958 + PSB_RVDC32(DSPASURF); 959 + PSB_WVDC32(arg->sprite.dspc_control, DSPCCNTR); 960 + PSB_WVDC32(arg->sprite.dspc_stride, DSPCSTRIDE); 961 + PSB_WVDC32(arg->sprite.dspc_position, DSPCPOS); 962 + PSB_WVDC32(arg->sprite.dspc_linear_offset, DSPCLINOFF); 963 + PSB_WVDC32(arg->sprite.dspc_size, DSPCSIZE); 964 + PSB_WVDC32(arg->sprite.dspc_surface, DSPCSURF); 965 + PSB_RVDC32(DSPCSURF); 966 + gma_power_end(dev); 967 + } 968 + } 969 + 970 + if (arg->sprite_disable_mask != 0) { 971 + if (gma_power_begin(dev, usage)) { 972 + PSB_WVDC32(0x3F3E, DSPARB); 973 + PSB_WVDC32(0x0, DSPCCNTR); 974 + PSB_WVDC32(arg->sprite.dspc_surface, DSPCSURF); 975 + PSB_RVDC32(DSPCSURF); 976 + gma_power_end(dev); 977 + } 978 + } 979 + 980 + if (arg->subpicture_enable_mask != 0) { 981 + if (gma_power_begin(dev, usage)) { 982 + uint32_t temp; 983 + if (arg->subpicture_enable_mask & REGRWBITS_DSPACNTR) { 984 + temp = PSB_RVDC32(DSPACNTR); 985 + temp &= ~DISPPLANE_PIXFORMAT_MASK; 986 + temp &= ~DISPPLANE_BOTTOM; 987 + temp |= DISPPLANE_32BPP; 988 + PSB_WVDC32(temp, DSPACNTR); 989 + 990 + temp = PSB_RVDC32(DSPABASE); 991 + PSB_WVDC32(temp, DSPABASE); 992 + PSB_RVDC32(DSPABASE); 993 + temp = PSB_RVDC32(DSPASURF); 994 + PSB_WVDC32(temp, DSPASURF); 995 + PSB_RVDC32(DSPASURF); 996 + } 997 + if (arg->subpicture_enable_mask & REGRWBITS_DSPBCNTR) { 998 + temp = PSB_RVDC32(DSPBCNTR); 999 + temp &= ~DISPPLANE_PIXFORMAT_MASK; 1000 + temp &= ~DISPPLANE_BOTTOM; 1001 + temp |= DISPPLANE_32BPP; 1002 + PSB_WVDC32(temp, DSPBCNTR); 1003 + 1004 + temp = PSB_RVDC32(DSPBBASE); 1005 + PSB_WVDC32(temp, DSPBBASE); 1006 + PSB_RVDC32(DSPBBASE); 1007 + temp = PSB_RVDC32(DSPBSURF); 1008 + PSB_WVDC32(temp, DSPBSURF); 1009 + PSB_RVDC32(DSPBSURF); 1010 + } 1011 + if (arg->subpicture_enable_mask & REGRWBITS_DSPCCNTR) { 1012 + temp = PSB_RVDC32(DSPCCNTR); 1013 + temp &= ~DISPPLANE_PIXFORMAT_MASK; 1014 + temp &= ~DISPPLANE_BOTTOM; 1015 + temp |= DISPPLANE_32BPP; 1016 + PSB_WVDC32(temp, DSPCCNTR); 1017 + 1018 + temp = PSB_RVDC32(DSPCBASE); 1019 + PSB_WVDC32(temp, DSPCBASE); 1020 + PSB_RVDC32(DSPCBASE); 1021 + temp = PSB_RVDC32(DSPCSURF); 1022 + PSB_WVDC32(temp, DSPCSURF); 1023 + PSB_RVDC32(DSPCSURF); 1024 + } 1025 + gma_power_end(dev); 1026 + } 1027 + } 1028 + 1029 + if (arg->subpicture_disable_mask != 0) { 1030 + if (gma_power_begin(dev, usage)) { 1031 + uint32_t temp; 1032 + if (arg->subpicture_disable_mask & REGRWBITS_DSPACNTR) { 1033 + temp = PSB_RVDC32(DSPACNTR); 1034 + temp &= ~DISPPLANE_PIXFORMAT_MASK; 1035 + temp |= DISPPLANE_32BPP_NO_ALPHA; 1036 + PSB_WVDC32(temp, DSPACNTR); 1037 + 1038 + temp = PSB_RVDC32(DSPABASE); 1039 + PSB_WVDC32(temp, DSPABASE); 1040 + PSB_RVDC32(DSPABASE); 1041 + temp = PSB_RVDC32(DSPASURF); 1042 + PSB_WVDC32(temp, DSPASURF); 1043 + PSB_RVDC32(DSPASURF); 1044 + } 1045 + if (arg->subpicture_disable_mask & REGRWBITS_DSPBCNTR) { 1046 + temp = PSB_RVDC32(DSPBCNTR); 1047 + temp &= ~DISPPLANE_PIXFORMAT_MASK; 1048 + temp |= DISPPLANE_32BPP_NO_ALPHA; 1049 + PSB_WVDC32(temp, DSPBCNTR); 1050 + 1051 + temp = PSB_RVDC32(DSPBBASE); 1052 + PSB_WVDC32(temp, DSPBBASE); 1053 + PSB_RVDC32(DSPBBASE); 1054 + temp = PSB_RVDC32(DSPBSURF); 1055 + PSB_WVDC32(temp, DSPBSURF); 1056 + PSB_RVDC32(DSPBSURF); 1057 + } 1058 + if (arg->subpicture_disable_mask & REGRWBITS_DSPCCNTR) { 1059 + temp = PSB_RVDC32(DSPCCNTR); 1060 + temp &= ~DISPPLANE_PIXFORMAT_MASK; 1061 + temp |= DISPPLANE_32BPP_NO_ALPHA; 1062 + PSB_WVDC32(temp, DSPCCNTR); 1063 + 1064 + temp = PSB_RVDC32(DSPCBASE); 1065 + PSB_WVDC32(temp, DSPCBASE); 1066 + PSB_RVDC32(DSPCBASE); 1067 + temp = PSB_RVDC32(DSPCSURF); 1068 + PSB_WVDC32(temp, DSPCSURF); 1069 + PSB_RVDC32(DSPCSURF); 1070 + } 1071 + gma_power_end(dev); 1072 + } 1073 + } 1074 + 1075 + return 0; 1076 + } 1077 + 1078 + static int psb_driver_open(struct drm_device *dev, struct drm_file *priv) 1079 + { 1080 + return 0; 1081 + } 1082 + 1083 + static void psb_driver_close(struct drm_device *dev, struct drm_file *priv) 1084 + { 1085 + } 1086 + 1087 + static long psb_unlocked_ioctl(struct file *filp, unsigned int cmd, 1088 + unsigned long arg) 1089 + { 1090 + struct drm_file *file_priv = filp->private_data; 1091 + struct drm_device *dev = file_priv->minor->dev; 1092 + struct drm_psb_private *dev_priv = dev->dev_private; 1093 + static unsigned int runtime_allowed; 1094 + 1095 + if (runtime_allowed == 1 && dev_priv->is_lvds_on) { 1096 + runtime_allowed++; 1097 + pm_runtime_allow(&dev->pdev->dev); 1098 + dev_priv->rpm_enabled = 1; 1099 + } 1100 + return drm_ioctl(filp, cmd, arg); 1101 + /* FIXME: do we need to wrap the other side of this */ 1102 + } 1103 + 1104 + 1105 + /* When a client dies: 1106 + * - Check for and clean up flipped page state 1107 + */ 1108 + void psb_driver_preclose(struct drm_device *dev, struct drm_file *priv) 1109 + { 1110 + } 1111 + 1112 + static void psb_remove(struct pci_dev *pdev) 1113 + { 1114 + struct drm_device *dev = pci_get_drvdata(pdev); 1115 + drm_put_dev(dev); 1116 + } 1117 + 1118 + static const struct dev_pm_ops psb_pm_ops = { 1119 + .resume = gma_power_resume, 1120 + .suspend = gma_power_suspend, 1121 + .runtime_suspend = psb_runtime_suspend, 1122 + .runtime_resume = psb_runtime_resume, 1123 + .runtime_idle = psb_runtime_idle, 1124 + }; 1125 + 1126 + static struct vm_operations_struct psb_gem_vm_ops = { 1127 + .fault = psb_gem_fault, 1128 + .open = drm_gem_vm_open, 1129 + .close = drm_gem_vm_close, 1130 + }; 1131 + 1132 + static struct drm_driver driver = { 1133 + .driver_features = DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | \ 1134 + DRIVER_IRQ_VBL | DRIVER_MODESET | DRIVER_GEM , 1135 + .load = psb_driver_load, 1136 + .unload = psb_driver_unload, 1137 + 1138 + .ioctls = psb_ioctls, 1139 + .num_ioctls = DRM_ARRAY_SIZE(psb_ioctls), 1140 + .device_is_agp = psb_driver_device_is_agp, 1141 + .irq_preinstall = psb_irq_preinstall, 1142 + .irq_postinstall = psb_irq_postinstall, 1143 + .irq_uninstall = psb_irq_uninstall, 1144 + .irq_handler = psb_irq_handler, 1145 + .enable_vblank = psb_enable_vblank, 1146 + .disable_vblank = psb_disable_vblank, 1147 + .get_vblank_counter = psb_get_vblank_counter, 1148 + .lastclose = psb_lastclose, 1149 + .open = psb_driver_open, 1150 + .preclose = psb_driver_preclose, 1151 + .postclose = psb_driver_close, 1152 + .reclaim_buffers = drm_core_reclaim_buffers, 1153 + 1154 + .gem_init_object = psb_gem_init_object, 1155 + .gem_free_object = psb_gem_free_object, 1156 + .gem_vm_ops = &psb_gem_vm_ops, 1157 + .dumb_create = psb_gem_dumb_create, 1158 + .dumb_map_offset = psb_gem_dumb_map_gtt, 1159 + .dumb_destroy = psb_gem_dumb_destroy, 1160 + 1161 + .fops = { 1162 + .owner = THIS_MODULE, 1163 + .open = drm_open, 1164 + .release = drm_release, 1165 + .unlocked_ioctl = psb_unlocked_ioctl, 1166 + .mmap = drm_gem_mmap, 1167 + .poll = drm_poll, 1168 + .fasync = drm_fasync, 1169 + .read = drm_read, 1170 + }, 1171 + .name = DRIVER_NAME, 1172 + .desc = DRIVER_DESC, 1173 + .date = PSB_DRM_DRIVER_DATE, 1174 + .major = PSB_DRM_DRIVER_MAJOR, 1175 + .minor = PSB_DRM_DRIVER_MINOR, 1176 + .patchlevel = PSB_DRM_DRIVER_PATCHLEVEL 1177 + }; 1178 + 1179 + static struct pci_driver psb_pci_driver = { 1180 + .name = DRIVER_NAME, 1181 + .id_table = pciidlist, 1182 + .probe = psb_probe, 1183 + .remove = psb_remove, 1184 + .driver.pm = &psb_pm_ops, 1185 + }; 1186 + 1187 + static int psb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 1188 + { 1189 + /* MLD Added this from Inaky's patch */ 1190 + if (pci_enable_msi(pdev)) 1191 + dev_warn(&pdev->dev, "Enable MSI failed!\n"); 1192 + return drm_get_pci_dev(pdev, ent, &driver); 1193 + } 1194 + 1195 + static int __init psb_init(void) 1196 + { 1197 + return drm_pci_init(&driver, &psb_pci_driver); 1198 + } 1199 + 1200 + static void __exit psb_exit(void) 1201 + { 1202 + drm_pci_exit(&driver, &psb_pci_driver); 1203 + } 1204 + 1205 + late_initcall(psb_init); 1206 + module_exit(psb_exit); 1207 + 1208 + MODULE_AUTHOR("Alan Cox <alan@linux.intel.com> and others"); 1209 + MODULE_DESCRIPTION(DRIVER_DESC); 1210 + MODULE_LICENSE("GPL");
+924
drivers/gpu/drm/gma500/psb_drv.h
··· 1 + /************************************************************************** 2 + * Copyright (c) 2007-2011, Intel Corporation. 3 + * All Rights Reserved. 4 + * 5 + * This program is free software; you can redistribute it and/or modify it 6 + * under the terms and conditions of the GNU General Public License, 7 + * version 2, as published by the Free Software Foundation. 8 + * 9 + * This program is distributed in the hope it will be useful, but WITHOUT 10 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 + * more details. 13 + * 14 + * You should have received a copy of the GNU General Public License along with 15 + * this program; if not, write to the Free Software Foundation, Inc., 16 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 17 + * 18 + **************************************************************************/ 19 + 20 + #ifndef _PSB_DRV_H_ 21 + #define _PSB_DRV_H_ 22 + 23 + #include <linux/kref.h> 24 + 25 + #include <drm/drmP.h> 26 + #include "drm_global.h" 27 + #include "gem_glue.h" 28 + #include "psb_drm.h" 29 + #include "psb_reg.h" 30 + #include "psb_intel_drv.h" 31 + #include "gtt.h" 32 + #include "power.h" 33 + #include "oaktrail.h" 34 + 35 + /* Append new drm mode definition here, align with libdrm definition */ 36 + #define DRM_MODE_SCALE_NO_SCALE 2 37 + 38 + enum { 39 + CHIP_PSB_8108 = 0, /* Poulsbo */ 40 + CHIP_PSB_8109 = 1, /* Poulsbo */ 41 + CHIP_MRST_4100 = 2, /* Moorestown/Oaktrail */ 42 + CHIP_MFLD_0130 = 3, /* Medfield */ 43 + }; 44 + 45 + #define IS_MRST(dev) (((dev)->pci_device & 0xfffc) == 0x4100) 46 + #define IS_MFLD(dev) (((dev)->pci_device & 0xfff8) == 0x0130) 47 + 48 + /* 49 + * Driver definitions 50 + */ 51 + 52 + #define DRIVER_NAME "gma500" 53 + #define DRIVER_DESC "DRM driver for the Intel GMA500" 54 + 55 + #define PSB_DRM_DRIVER_DATE "2011-06-06" 56 + #define PSB_DRM_DRIVER_MAJOR 1 57 + #define PSB_DRM_DRIVER_MINOR 0 58 + #define PSB_DRM_DRIVER_PATCHLEVEL 0 59 + 60 + /* 61 + * Hardware offsets 62 + */ 63 + #define PSB_VDC_OFFSET 0x00000000 64 + #define PSB_VDC_SIZE 0x000080000 65 + #define MRST_MMIO_SIZE 0x0000C0000 66 + #define MDFLD_MMIO_SIZE 0x000100000 67 + #define PSB_SGX_SIZE 0x8000 68 + #define PSB_SGX_OFFSET 0x00040000 69 + #define MRST_SGX_OFFSET 0x00080000 70 + /* 71 + * PCI resource identifiers 72 + */ 73 + #define PSB_MMIO_RESOURCE 0 74 + #define PSB_GATT_RESOURCE 2 75 + #define PSB_GTT_RESOURCE 3 76 + /* 77 + * PCI configuration 78 + */ 79 + #define PSB_GMCH_CTRL 0x52 80 + #define PSB_BSM 0x5C 81 + #define _PSB_GMCH_ENABLED 0x4 82 + #define PSB_PGETBL_CTL 0x2020 83 + #define _PSB_PGETBL_ENABLED 0x00000001 84 + #define PSB_SGX_2D_SLAVE_PORT 0x4000 85 + 86 + /* To get rid of */ 87 + #define PSB_TT_PRIV0_LIMIT (256*1024*1024) 88 + #define PSB_TT_PRIV0_PLIMIT (PSB_TT_PRIV0_LIMIT >> PAGE_SHIFT) 89 + 90 + /* 91 + * SGX side MMU definitions (these can probably go) 92 + */ 93 + 94 + /* 95 + * Flags for external memory type field. 96 + */ 97 + #define PSB_MMU_CACHED_MEMORY 0x0001 /* Bind to MMU only */ 98 + #define PSB_MMU_RO_MEMORY 0x0002 /* MMU RO memory */ 99 + #define PSB_MMU_WO_MEMORY 0x0004 /* MMU WO memory */ 100 + /* 101 + * PTE's and PDE's 102 + */ 103 + #define PSB_PDE_MASK 0x003FFFFF 104 + #define PSB_PDE_SHIFT 22 105 + #define PSB_PTE_SHIFT 12 106 + /* 107 + * Cache control 108 + */ 109 + #define PSB_PTE_VALID 0x0001 /* PTE / PDE valid */ 110 + #define PSB_PTE_WO 0x0002 /* Write only */ 111 + #define PSB_PTE_RO 0x0004 /* Read only */ 112 + #define PSB_PTE_CACHED 0x0008 /* CPU cache coherent */ 113 + 114 + /* 115 + * VDC registers and bits 116 + */ 117 + #define PSB_MSVDX_CLOCKGATING 0x2064 118 + #define PSB_TOPAZ_CLOCKGATING 0x2068 119 + #define PSB_HWSTAM 0x2098 120 + #define PSB_INSTPM 0x20C0 121 + #define PSB_INT_IDENTITY_R 0x20A4 122 + #define _MDFLD_PIPEC_EVENT_FLAG (1<<2) 123 + #define _MDFLD_PIPEC_VBLANK_FLAG (1<<3) 124 + #define _PSB_DPST_PIPEB_FLAG (1<<4) 125 + #define _MDFLD_PIPEB_EVENT_FLAG (1<<4) 126 + #define _PSB_VSYNC_PIPEB_FLAG (1<<5) 127 + #define _PSB_DPST_PIPEA_FLAG (1<<6) 128 + #define _PSB_PIPEA_EVENT_FLAG (1<<6) 129 + #define _PSB_VSYNC_PIPEA_FLAG (1<<7) 130 + #define _MDFLD_MIPIA_FLAG (1<<16) 131 + #define _MDFLD_MIPIC_FLAG (1<<17) 132 + #define _PSB_IRQ_SGX_FLAG (1<<18) 133 + #define _PSB_IRQ_MSVDX_FLAG (1<<19) 134 + #define _LNC_IRQ_TOPAZ_FLAG (1<<20) 135 + 136 + /* This flag includes all the display IRQ bits excepts the vblank irqs. */ 137 + #define _MDFLD_DISP_ALL_IRQ_FLAG (_MDFLD_PIPEC_EVENT_FLAG | \ 138 + _MDFLD_PIPEB_EVENT_FLAG | \ 139 + _PSB_PIPEA_EVENT_FLAG | \ 140 + _PSB_VSYNC_PIPEA_FLAG | \ 141 + _MDFLD_MIPIA_FLAG | \ 142 + _MDFLD_MIPIC_FLAG) 143 + #define PSB_INT_IDENTITY_R 0x20A4 144 + #define PSB_INT_MASK_R 0x20A8 145 + #define PSB_INT_ENABLE_R 0x20A0 146 + 147 + #define _PSB_MMU_ER_MASK 0x0001FF00 148 + #define _PSB_MMU_ER_HOST (1 << 16) 149 + #define GPIOA 0x5010 150 + #define GPIOB 0x5014 151 + #define GPIOC 0x5018 152 + #define GPIOD 0x501c 153 + #define GPIOE 0x5020 154 + #define GPIOF 0x5024 155 + #define GPIOG 0x5028 156 + #define GPIOH 0x502c 157 + #define GPIO_CLOCK_DIR_MASK (1 << 0) 158 + #define GPIO_CLOCK_DIR_IN (0 << 1) 159 + #define GPIO_CLOCK_DIR_OUT (1 << 1) 160 + #define GPIO_CLOCK_VAL_MASK (1 << 2) 161 + #define GPIO_CLOCK_VAL_OUT (1 << 3) 162 + #define GPIO_CLOCK_VAL_IN (1 << 4) 163 + #define GPIO_CLOCK_PULLUP_DISABLE (1 << 5) 164 + #define GPIO_DATA_DIR_MASK (1 << 8) 165 + #define GPIO_DATA_DIR_IN (0 << 9) 166 + #define GPIO_DATA_DIR_OUT (1 << 9) 167 + #define GPIO_DATA_VAL_MASK (1 << 10) 168 + #define GPIO_DATA_VAL_OUT (1 << 11) 169 + #define GPIO_DATA_VAL_IN (1 << 12) 170 + #define GPIO_DATA_PULLUP_DISABLE (1 << 13) 171 + 172 + #define VCLK_DIVISOR_VGA0 0x6000 173 + #define VCLK_DIVISOR_VGA1 0x6004 174 + #define VCLK_POST_DIV 0x6010 175 + 176 + #define PSB_COMM_2D (PSB_ENGINE_2D << 4) 177 + #define PSB_COMM_3D (PSB_ENGINE_3D << 4) 178 + #define PSB_COMM_TA (PSB_ENGINE_TA << 4) 179 + #define PSB_COMM_HP (PSB_ENGINE_HP << 4) 180 + #define PSB_COMM_USER_IRQ (1024 >> 2) 181 + #define PSB_COMM_USER_IRQ_LOST (PSB_COMM_USER_IRQ + 1) 182 + #define PSB_COMM_FW (2048 >> 2) 183 + 184 + #define PSB_UIRQ_VISTEST 1 185 + #define PSB_UIRQ_OOM_REPLY 2 186 + #define PSB_UIRQ_FIRE_TA_REPLY 3 187 + #define PSB_UIRQ_FIRE_RASTER_REPLY 4 188 + 189 + #define PSB_2D_SIZE (256*1024*1024) 190 + #define PSB_MAX_RELOC_PAGES 1024 191 + 192 + #define PSB_LOW_REG_OFFS 0x0204 193 + #define PSB_HIGH_REG_OFFS 0x0600 194 + 195 + #define PSB_NUM_VBLANKS 2 196 + 197 + 198 + #define PSB_2D_SIZE (256*1024*1024) 199 + #define PSB_MAX_RELOC_PAGES 1024 200 + 201 + #define PSB_LOW_REG_OFFS 0x0204 202 + #define PSB_HIGH_REG_OFFS 0x0600 203 + 204 + #define PSB_NUM_VBLANKS 2 205 + #define PSB_WATCHDOG_DELAY (DRM_HZ * 2) 206 + #define PSB_LID_DELAY (DRM_HZ / 10) 207 + 208 + #define MDFLD_PNW_B0 0x04 209 + #define MDFLD_PNW_C0 0x08 210 + 211 + #define MDFLD_DSR_2D_3D_0 (1 << 0) 212 + #define MDFLD_DSR_2D_3D_2 (1 << 1) 213 + #define MDFLD_DSR_CURSOR_0 (1 << 2) 214 + #define MDFLD_DSR_CURSOR_2 (1 << 3) 215 + #define MDFLD_DSR_OVERLAY_0 (1 << 4) 216 + #define MDFLD_DSR_OVERLAY_2 (1 << 5) 217 + #define MDFLD_DSR_MIPI_CONTROL (1 << 6) 218 + #define MDFLD_DSR_DAMAGE_MASK_0 ((1 << 0) | (1 << 2) | (1 << 4)) 219 + #define MDFLD_DSR_DAMAGE_MASK_2 ((1 << 1) | (1 << 3) | (1 << 5)) 220 + #define MDFLD_DSR_2D_3D (MDFLD_DSR_2D_3D_0 | MDFLD_DSR_2D_3D_2) 221 + 222 + #define MDFLD_DSR_RR 45 223 + #define MDFLD_DPU_ENABLE (1 << 31) 224 + #define MDFLD_DSR_FULLSCREEN (1 << 30) 225 + #define MDFLD_DSR_DELAY (DRM_HZ / MDFLD_DSR_RR) 226 + 227 + #define PSB_PWR_STATE_ON 1 228 + #define PSB_PWR_STATE_OFF 2 229 + 230 + #define PSB_PMPOLICY_NOPM 0 231 + #define PSB_PMPOLICY_CLOCKGATING 1 232 + #define PSB_PMPOLICY_POWERDOWN 2 233 + 234 + #define PSB_PMSTATE_POWERUP 0 235 + #define PSB_PMSTATE_CLOCKGATED 1 236 + #define PSB_PMSTATE_POWERDOWN 2 237 + #define PSB_PCIx_MSI_ADDR_LOC 0x94 238 + #define PSB_PCIx_MSI_DATA_LOC 0x98 239 + 240 + /* Medfield crystal settings */ 241 + #define KSEL_CRYSTAL_19 1 242 + #define KSEL_BYPASS_19 5 243 + #define KSEL_BYPASS_25 6 244 + #define KSEL_BYPASS_83_100 7 245 + 246 + struct opregion_header; 247 + struct opregion_acpi; 248 + struct opregion_swsci; 249 + struct opregion_asle; 250 + 251 + struct psb_intel_opregion { 252 + struct opregion_header *header; 253 + struct opregion_acpi *acpi; 254 + struct opregion_swsci *swsci; 255 + struct opregion_asle *asle; 256 + int enabled; 257 + }; 258 + 259 + struct psb_ops; 260 + 261 + struct drm_psb_private { 262 + struct drm_device *dev; 263 + const struct psb_ops *ops; 264 + 265 + struct psb_gtt gtt; 266 + 267 + /* GTT Memory manager */ 268 + struct psb_gtt_mm *gtt_mm; 269 + struct page *scratch_page; 270 + u32 *gtt_map; 271 + uint32_t stolen_base; 272 + void *vram_addr; 273 + unsigned long vram_stolen_size; 274 + int gtt_initialized; 275 + u16 gmch_ctrl; /* Saved GTT setup */ 276 + u32 pge_ctl; 277 + 278 + struct mutex gtt_mutex; 279 + struct resource *gtt_mem; /* Our PCI resource */ 280 + 281 + struct psb_mmu_driver *mmu; 282 + struct psb_mmu_pd *pf_pd; 283 + 284 + /* 285 + * Register base 286 + */ 287 + 288 + uint8_t *sgx_reg; 289 + uint8_t *vdc_reg; 290 + uint32_t gatt_free_offset; 291 + 292 + /* 293 + * Fencing / irq. 294 + */ 295 + 296 + uint32_t vdc_irq_mask; 297 + uint32_t pipestat[PSB_NUM_PIPE]; 298 + 299 + spinlock_t irqmask_lock; 300 + 301 + /* 302 + * Power 303 + */ 304 + 305 + bool suspended; 306 + bool display_power; 307 + int display_count; 308 + 309 + /* 310 + * Modesetting 311 + */ 312 + struct psb_intel_mode_device mode_dev; 313 + 314 + struct drm_crtc *plane_to_crtc_mapping[PSB_NUM_PIPE]; 315 + struct drm_crtc *pipe_to_crtc_mapping[PSB_NUM_PIPE]; 316 + uint32_t num_pipe; 317 + 318 + /* 319 + * OSPM info (Power management base) (can go ?) 320 + */ 321 + uint32_t ospm_base; 322 + 323 + /* 324 + * Sizes info 325 + */ 326 + 327 + struct drm_psb_sizes_arg sizes; 328 + 329 + u32 fuse_reg_value; 330 + u32 video_device_fuse; 331 + 332 + /* PCI revision ID for B0:D2:F0 */ 333 + uint8_t platform_rev_id; 334 + 335 + /* 336 + * LVDS info 337 + */ 338 + int backlight_duty_cycle; /* restore backlight to this value */ 339 + bool panel_wants_dither; 340 + struct drm_display_mode *panel_fixed_mode; 341 + struct drm_display_mode *lfp_lvds_vbt_mode; 342 + struct drm_display_mode *sdvo_lvds_vbt_mode; 343 + 344 + struct bdb_lvds_backlight *lvds_bl; /* LVDS backlight info from VBT */ 345 + struct psb_intel_i2c_chan *lvds_i2c_bus; 346 + 347 + /* Feature bits from the VBIOS */ 348 + unsigned int int_tv_support:1; 349 + unsigned int lvds_dither:1; 350 + unsigned int lvds_vbt:1; 351 + unsigned int int_crt_support:1; 352 + unsigned int lvds_use_ssc:1; 353 + int lvds_ssc_freq; 354 + bool is_lvds_on; 355 + bool is_mipi_on; 356 + u32 mipi_ctrl_display; 357 + 358 + unsigned int core_freq; 359 + uint32_t iLVDS_enable; 360 + 361 + /* Runtime PM state */ 362 + int rpm_enabled; 363 + 364 + /* MID specific */ 365 + struct oaktrail_vbt vbt_data; 366 + struct oaktrail_gct_data gct_data; 367 + 368 + /* MIPI Panel type etc */ 369 + int panel_id; 370 + bool dual_mipi; /* dual display - DPI & DBI */ 371 + bool dpi_panel_on; /* The DPI panel power is on */ 372 + bool dpi_panel_on2; /* The DPI panel power is on */ 373 + bool dbi_panel_on; /* The DBI panel power is on */ 374 + bool dbi_panel_on2; /* The DBI panel power is on */ 375 + u32 dsr_fb_update; /* DSR FB update counter */ 376 + 377 + /* Moorestown HDMI state */ 378 + struct oaktrail_hdmi_dev *hdmi_priv; 379 + 380 + /* Moorestown pipe config register value cache */ 381 + uint32_t pipeconf; 382 + uint32_t pipeconf1; 383 + uint32_t pipeconf2; 384 + 385 + /* Moorestown plane control register value cache */ 386 + uint32_t dspcntr; 387 + uint32_t dspcntr1; 388 + uint32_t dspcntr2; 389 + 390 + /* Moorestown MM backlight cache */ 391 + uint8_t saveBKLTCNT; 392 + uint8_t saveBKLTREQ; 393 + uint8_t saveBKLTBRTL; 394 + 395 + /* 396 + * Register state 397 + */ 398 + uint32_t saveDSPACNTR; 399 + uint32_t saveDSPBCNTR; 400 + uint32_t savePIPEACONF; 401 + uint32_t savePIPEBCONF; 402 + uint32_t savePIPEASRC; 403 + uint32_t savePIPEBSRC; 404 + uint32_t saveFPA0; 405 + uint32_t saveFPA1; 406 + uint32_t saveDPLL_A; 407 + uint32_t saveDPLL_A_MD; 408 + uint32_t saveHTOTAL_A; 409 + uint32_t saveHBLANK_A; 410 + uint32_t saveHSYNC_A; 411 + uint32_t saveVTOTAL_A; 412 + uint32_t saveVBLANK_A; 413 + uint32_t saveVSYNC_A; 414 + uint32_t saveDSPASTRIDE; 415 + uint32_t saveDSPASIZE; 416 + uint32_t saveDSPAPOS; 417 + uint32_t saveDSPABASE; 418 + uint32_t saveDSPASURF; 419 + uint32_t saveDSPASTATUS; 420 + uint32_t saveFPB0; 421 + uint32_t saveFPB1; 422 + uint32_t saveDPLL_B; 423 + uint32_t saveDPLL_B_MD; 424 + uint32_t saveHTOTAL_B; 425 + uint32_t saveHBLANK_B; 426 + uint32_t saveHSYNC_B; 427 + uint32_t saveVTOTAL_B; 428 + uint32_t saveVBLANK_B; 429 + uint32_t saveVSYNC_B; 430 + uint32_t saveDSPBSTRIDE; 431 + uint32_t saveDSPBSIZE; 432 + uint32_t saveDSPBPOS; 433 + uint32_t saveDSPBBASE; 434 + uint32_t saveDSPBSURF; 435 + uint32_t saveDSPBSTATUS; 436 + uint32_t saveVCLK_DIVISOR_VGA0; 437 + uint32_t saveVCLK_DIVISOR_VGA1; 438 + uint32_t saveVCLK_POST_DIV; 439 + uint32_t saveVGACNTRL; 440 + uint32_t saveADPA; 441 + uint32_t saveLVDS; 442 + uint32_t saveDVOA; 443 + uint32_t saveDVOB; 444 + uint32_t saveDVOC; 445 + uint32_t savePP_ON; 446 + uint32_t savePP_OFF; 447 + uint32_t savePP_CONTROL; 448 + uint32_t savePP_CYCLE; 449 + uint32_t savePFIT_CONTROL; 450 + uint32_t savePaletteA[256]; 451 + uint32_t savePaletteB[256]; 452 + uint32_t saveBLC_PWM_CTL2; 453 + uint32_t saveBLC_PWM_CTL; 454 + uint32_t saveCLOCKGATING; 455 + uint32_t saveDSPARB; 456 + uint32_t saveDSPATILEOFF; 457 + uint32_t saveDSPBTILEOFF; 458 + uint32_t saveDSPAADDR; 459 + uint32_t saveDSPBADDR; 460 + uint32_t savePFIT_AUTO_RATIOS; 461 + uint32_t savePFIT_PGM_RATIOS; 462 + uint32_t savePP_ON_DELAYS; 463 + uint32_t savePP_OFF_DELAYS; 464 + uint32_t savePP_DIVISOR; 465 + uint32_t saveBSM; 466 + uint32_t saveVBT; 467 + uint32_t saveBCLRPAT_A; 468 + uint32_t saveBCLRPAT_B; 469 + uint32_t saveDSPALINOFF; 470 + uint32_t saveDSPBLINOFF; 471 + uint32_t savePERF_MODE; 472 + uint32_t saveDSPFW1; 473 + uint32_t saveDSPFW2; 474 + uint32_t saveDSPFW3; 475 + uint32_t saveDSPFW4; 476 + uint32_t saveDSPFW5; 477 + uint32_t saveDSPFW6; 478 + uint32_t saveCHICKENBIT; 479 + uint32_t saveDSPACURSOR_CTRL; 480 + uint32_t saveDSPBCURSOR_CTRL; 481 + uint32_t saveDSPACURSOR_BASE; 482 + uint32_t saveDSPBCURSOR_BASE; 483 + uint32_t saveDSPACURSOR_POS; 484 + uint32_t saveDSPBCURSOR_POS; 485 + uint32_t save_palette_a[256]; 486 + uint32_t save_palette_b[256]; 487 + uint32_t saveOV_OVADD; 488 + uint32_t saveOV_OGAMC0; 489 + uint32_t saveOV_OGAMC1; 490 + uint32_t saveOV_OGAMC2; 491 + uint32_t saveOV_OGAMC3; 492 + uint32_t saveOV_OGAMC4; 493 + uint32_t saveOV_OGAMC5; 494 + uint32_t saveOVC_OVADD; 495 + uint32_t saveOVC_OGAMC0; 496 + uint32_t saveOVC_OGAMC1; 497 + uint32_t saveOVC_OGAMC2; 498 + uint32_t saveOVC_OGAMC3; 499 + uint32_t saveOVC_OGAMC4; 500 + uint32_t saveOVC_OGAMC5; 501 + 502 + /* MSI reg save */ 503 + uint32_t msi_addr; 504 + uint32_t msi_data; 505 + 506 + /* Medfield specific register save state */ 507 + uint32_t saveHDMIPHYMISCCTL; 508 + uint32_t saveHDMIB_CONTROL; 509 + uint32_t saveDSPCCNTR; 510 + uint32_t savePIPECCONF; 511 + uint32_t savePIPECSRC; 512 + uint32_t saveHTOTAL_C; 513 + uint32_t saveHBLANK_C; 514 + uint32_t saveHSYNC_C; 515 + uint32_t saveVTOTAL_C; 516 + uint32_t saveVBLANK_C; 517 + uint32_t saveVSYNC_C; 518 + uint32_t saveDSPCSTRIDE; 519 + uint32_t saveDSPCSIZE; 520 + uint32_t saveDSPCPOS; 521 + uint32_t saveDSPCSURF; 522 + uint32_t saveDSPCSTATUS; 523 + uint32_t saveDSPCLINOFF; 524 + uint32_t saveDSPCTILEOFF; 525 + uint32_t saveDSPCCURSOR_CTRL; 526 + uint32_t saveDSPCCURSOR_BASE; 527 + uint32_t saveDSPCCURSOR_POS; 528 + uint32_t save_palette_c[256]; 529 + uint32_t saveOV_OVADD_C; 530 + uint32_t saveOV_OGAMC0_C; 531 + uint32_t saveOV_OGAMC1_C; 532 + uint32_t saveOV_OGAMC2_C; 533 + uint32_t saveOV_OGAMC3_C; 534 + uint32_t saveOV_OGAMC4_C; 535 + uint32_t saveOV_OGAMC5_C; 536 + 537 + /* DSI register save */ 538 + uint32_t saveDEVICE_READY_REG; 539 + uint32_t saveINTR_EN_REG; 540 + uint32_t saveDSI_FUNC_PRG_REG; 541 + uint32_t saveHS_TX_TIMEOUT_REG; 542 + uint32_t saveLP_RX_TIMEOUT_REG; 543 + uint32_t saveTURN_AROUND_TIMEOUT_REG; 544 + uint32_t saveDEVICE_RESET_REG; 545 + uint32_t saveDPI_RESOLUTION_REG; 546 + uint32_t saveHORIZ_SYNC_PAD_COUNT_REG; 547 + uint32_t saveHORIZ_BACK_PORCH_COUNT_REG; 548 + uint32_t saveHORIZ_FRONT_PORCH_COUNT_REG; 549 + uint32_t saveHORIZ_ACTIVE_AREA_COUNT_REG; 550 + uint32_t saveVERT_SYNC_PAD_COUNT_REG; 551 + uint32_t saveVERT_BACK_PORCH_COUNT_REG; 552 + uint32_t saveVERT_FRONT_PORCH_COUNT_REG; 553 + uint32_t saveHIGH_LOW_SWITCH_COUNT_REG; 554 + uint32_t saveINIT_COUNT_REG; 555 + uint32_t saveMAX_RET_PAK_REG; 556 + uint32_t saveVIDEO_FMT_REG; 557 + uint32_t saveEOT_DISABLE_REG; 558 + uint32_t saveLP_BYTECLK_REG; 559 + uint32_t saveHS_LS_DBI_ENABLE_REG; 560 + uint32_t saveTXCLKESC_REG; 561 + uint32_t saveDPHY_PARAM_REG; 562 + uint32_t saveMIPI_CONTROL_REG; 563 + uint32_t saveMIPI; 564 + uint32_t saveMIPI_C; 565 + 566 + /* DPST register save */ 567 + uint32_t saveHISTOGRAM_INT_CONTROL_REG; 568 + uint32_t saveHISTOGRAM_LOGIC_CONTROL_REG; 569 + uint32_t savePWM_CONTROL_LOGIC; 570 + 571 + /* 572 + * DSI info. 573 + */ 574 + void * dbi_dsr_info; 575 + void * dbi_dpu_info; 576 + void * dsi_configs[2]; 577 + /* 578 + * LID-Switch 579 + */ 580 + spinlock_t lid_lock; 581 + struct timer_list lid_timer; 582 + struct psb_intel_opregion opregion; 583 + u32 *lid_state; 584 + u32 lid_last_state; 585 + 586 + /* 587 + * Watchdog 588 + */ 589 + 590 + uint32_t apm_reg; 591 + uint16_t apm_base; 592 + 593 + /* 594 + * Used for modifying backlight from 595 + * xrandr -- consider removing and using HAL instead 596 + */ 597 + struct backlight_device *backlight_device; 598 + struct drm_property *backlight_property; 599 + uint32_t blc_adj1; 600 + uint32_t blc_adj2; 601 + 602 + void *fbdev; 603 + 604 + /* 2D acceleration */ 605 + struct mutex mutex_2d; 606 + }; 607 + 608 + 609 + /* 610 + * Operations for each board type 611 + */ 612 + 613 + struct psb_ops { 614 + const char *name; 615 + unsigned int accel_2d:1; 616 + int pipes; /* Number of output pipes */ 617 + int crtcs; /* Number of CRTCs */ 618 + int sgx_offset; /* Base offset of SGX device */ 619 + 620 + /* Sub functions */ 621 + struct drm_crtc_helper_funcs const *crtc_helper; 622 + struct drm_crtc_funcs const *crtc_funcs; 623 + 624 + /* Setup hooks */ 625 + int (*chip_setup)(struct drm_device *dev); 626 + void (*chip_teardown)(struct drm_device *dev); 627 + 628 + /* Display management hooks */ 629 + int (*output_init)(struct drm_device *dev); 630 + /* Power management hooks */ 631 + void (*init_pm)(struct drm_device *dev); 632 + int (*save_regs)(struct drm_device *dev); 633 + int (*restore_regs)(struct drm_device *dev); 634 + int (*power_up)(struct drm_device *dev); 635 + int (*power_down)(struct drm_device *dev); 636 + 637 + void (*lvds_bl_power)(struct drm_device *dev, bool on); 638 + #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE 639 + /* Backlight */ 640 + int (*backlight_init)(struct drm_device *dev); 641 + #endif 642 + int i2c_bus; /* I2C bus identifier for Moorestown */ 643 + }; 644 + 645 + 646 + 647 + struct psb_mmu_driver; 648 + 649 + extern int drm_crtc_probe_output_modes(struct drm_device *dev, int, int); 650 + extern int drm_pick_crtcs(struct drm_device *dev); 651 + 652 + static inline struct drm_psb_private *psb_priv(struct drm_device *dev) 653 + { 654 + return (struct drm_psb_private *) dev->dev_private; 655 + } 656 + 657 + /* 658 + * MMU stuff. 659 + */ 660 + 661 + extern struct psb_mmu_driver *psb_mmu_driver_init(uint8_t __iomem * registers, 662 + int trap_pagefaults, 663 + int invalid_type, 664 + struct drm_psb_private *dev_priv); 665 + extern void psb_mmu_driver_takedown(struct psb_mmu_driver *driver); 666 + extern struct psb_mmu_pd *psb_mmu_get_default_pd(struct psb_mmu_driver 667 + *driver); 668 + extern void psb_mmu_mirror_gtt(struct psb_mmu_pd *pd, uint32_t mmu_offset, 669 + uint32_t gtt_start, uint32_t gtt_pages); 670 + extern struct psb_mmu_pd *psb_mmu_alloc_pd(struct psb_mmu_driver *driver, 671 + int trap_pagefaults, 672 + int invalid_type); 673 + extern void psb_mmu_free_pagedir(struct psb_mmu_pd *pd); 674 + extern void psb_mmu_flush(struct psb_mmu_driver *driver, int rc_prot); 675 + extern void psb_mmu_remove_pfn_sequence(struct psb_mmu_pd *pd, 676 + unsigned long address, 677 + uint32_t num_pages); 678 + extern int psb_mmu_insert_pfn_sequence(struct psb_mmu_pd *pd, 679 + uint32_t start_pfn, 680 + unsigned long address, 681 + uint32_t num_pages, int type); 682 + extern int psb_mmu_virtual_to_pfn(struct psb_mmu_pd *pd, uint32_t virtual, 683 + unsigned long *pfn); 684 + 685 + /* 686 + * Enable / disable MMU for different requestors. 687 + */ 688 + 689 + 690 + extern void psb_mmu_set_pd_context(struct psb_mmu_pd *pd, int hw_context); 691 + extern int psb_mmu_insert_pages(struct psb_mmu_pd *pd, struct page **pages, 692 + unsigned long address, uint32_t num_pages, 693 + uint32_t desired_tile_stride, 694 + uint32_t hw_tile_stride, int type); 695 + extern void psb_mmu_remove_pages(struct psb_mmu_pd *pd, 696 + unsigned long address, uint32_t num_pages, 697 + uint32_t desired_tile_stride, 698 + uint32_t hw_tile_stride); 699 + /* 700 + *psb_irq.c 701 + */ 702 + 703 + extern irqreturn_t psb_irq_handler(DRM_IRQ_ARGS); 704 + extern int psb_irq_enable_dpst(struct drm_device *dev); 705 + extern int psb_irq_disable_dpst(struct drm_device *dev); 706 + extern void psb_irq_preinstall(struct drm_device *dev); 707 + extern int psb_irq_postinstall(struct drm_device *dev); 708 + extern void psb_irq_uninstall(struct drm_device *dev); 709 + extern void psb_irq_turn_on_dpst(struct drm_device *dev); 710 + extern void psb_irq_turn_off_dpst(struct drm_device *dev); 711 + 712 + extern void psb_irq_uninstall_islands(struct drm_device *dev, int hw_islands); 713 + extern int psb_vblank_wait2(struct drm_device *dev, unsigned int *sequence); 714 + extern int psb_vblank_wait(struct drm_device *dev, unsigned int *sequence); 715 + extern int psb_enable_vblank(struct drm_device *dev, int crtc); 716 + extern void psb_disable_vblank(struct drm_device *dev, int crtc); 717 + void 718 + psb_enable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask); 719 + 720 + void 721 + psb_disable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask); 722 + 723 + extern u32 psb_get_vblank_counter(struct drm_device *dev, int crtc); 724 + 725 + /* 726 + * intel_opregion.c 727 + */ 728 + extern int gma_intel_opregion_init(struct drm_device *dev); 729 + extern int gma_intel_opregion_exit(struct drm_device *dev); 730 + 731 + /* 732 + * framebuffer.c 733 + */ 734 + extern int psbfb_probed(struct drm_device *dev); 735 + extern int psbfb_remove(struct drm_device *dev, 736 + struct drm_framebuffer *fb); 737 + /* 738 + * accel_2d.c 739 + */ 740 + extern void psbfb_copyarea(struct fb_info *info, 741 + const struct fb_copyarea *region); 742 + extern int psbfb_sync(struct fb_info *info); 743 + extern void psb_spank(struct drm_psb_private *dev_priv); 744 + 745 + /* 746 + * psb_reset.c 747 + */ 748 + 749 + extern void psb_lid_timer_init(struct drm_psb_private *dev_priv); 750 + extern void psb_lid_timer_takedown(struct drm_psb_private *dev_priv); 751 + extern void psb_print_pagefault(struct drm_psb_private *dev_priv); 752 + 753 + /* modesetting */ 754 + extern void psb_modeset_init(struct drm_device *dev); 755 + extern void psb_modeset_cleanup(struct drm_device *dev); 756 + extern int psb_fbdev_init(struct drm_device *dev); 757 + 758 + /* backlight.c */ 759 + int gma_backlight_init(struct drm_device *dev); 760 + void gma_backlight_exit(struct drm_device *dev); 761 + 762 + /* oaktrail_crtc.c */ 763 + extern const struct drm_crtc_helper_funcs oaktrail_helper_funcs; 764 + 765 + /* oaktrail_lvds.c */ 766 + extern void oaktrail_lvds_init(struct drm_device *dev, 767 + struct psb_intel_mode_device *mode_dev); 768 + 769 + /* psb_intel_display.c */ 770 + extern const struct drm_crtc_helper_funcs psb_intel_helper_funcs; 771 + extern const struct drm_crtc_funcs psb_intel_crtc_funcs; 772 + 773 + /* psb_intel_lvds.c */ 774 + extern const struct drm_connector_helper_funcs 775 + psb_intel_lvds_connector_helper_funcs; 776 + extern const struct drm_connector_funcs psb_intel_lvds_connector_funcs; 777 + 778 + /* gem.c */ 779 + extern int psb_gem_init_object(struct drm_gem_object *obj); 780 + extern void psb_gem_free_object(struct drm_gem_object *obj); 781 + extern int psb_gem_get_aperture(struct drm_device *dev, void *data, 782 + struct drm_file *file); 783 + extern int psb_gem_dumb_create(struct drm_file *file, struct drm_device *dev, 784 + struct drm_mode_create_dumb *args); 785 + extern int psb_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev, 786 + uint32_t handle); 787 + extern int psb_gem_dumb_map_gtt(struct drm_file *file, struct drm_device *dev, 788 + uint32_t handle, uint64_t *offset); 789 + extern int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); 790 + extern int psb_gem_create_ioctl(struct drm_device *dev, void *data, 791 + struct drm_file *file); 792 + extern int psb_gem_mmap_ioctl(struct drm_device *dev, void *data, 793 + struct drm_file *file); 794 + 795 + /* psb_device.c */ 796 + extern const struct psb_ops psb_chip_ops; 797 + 798 + /* oaktrail_device.c */ 799 + extern const struct psb_ops oaktrail_chip_ops; 800 + 801 + /* cdv_device.c */ 802 + extern const struct psb_ops cdv_chip_ops; 803 + 804 + /* 805 + * Debug print bits setting 806 + */ 807 + #define PSB_D_GENERAL (1 << 0) 808 + #define PSB_D_INIT (1 << 1) 809 + #define PSB_D_IRQ (1 << 2) 810 + #define PSB_D_ENTRY (1 << 3) 811 + /* debug the get H/V BP/FP count */ 812 + #define PSB_D_HV (1 << 4) 813 + #define PSB_D_DBI_BF (1 << 5) 814 + #define PSB_D_PM (1 << 6) 815 + #define PSB_D_RENDER (1 << 7) 816 + #define PSB_D_REG (1 << 8) 817 + #define PSB_D_MSVDX (1 << 9) 818 + #define PSB_D_TOPAZ (1 << 10) 819 + 820 + extern int drm_psb_no_fb; 821 + extern int drm_idle_check_interval; 822 + 823 + /* 824 + * Utilities 825 + */ 826 + 827 + static inline u32 MRST_MSG_READ32(uint port, uint offset) 828 + { 829 + int mcr = (0xD0<<24) | (port << 16) | (offset << 8); 830 + uint32_t ret_val = 0; 831 + struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0); 832 + pci_write_config_dword(pci_root, 0xD0, mcr); 833 + pci_read_config_dword(pci_root, 0xD4, &ret_val); 834 + pci_dev_put(pci_root); 835 + return ret_val; 836 + } 837 + static inline void MRST_MSG_WRITE32(uint port, uint offset, u32 value) 838 + { 839 + int mcr = (0xE0<<24) | (port << 16) | (offset << 8) | 0xF0; 840 + struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0); 841 + pci_write_config_dword(pci_root, 0xD4, value); 842 + pci_write_config_dword(pci_root, 0xD0, mcr); 843 + pci_dev_put(pci_root); 844 + } 845 + static inline u32 MDFLD_MSG_READ32(uint port, uint offset) 846 + { 847 + int mcr = (0x10<<24) | (port << 16) | (offset << 8); 848 + uint32_t ret_val = 0; 849 + struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0); 850 + pci_write_config_dword(pci_root, 0xD0, mcr); 851 + pci_read_config_dword(pci_root, 0xD4, &ret_val); 852 + pci_dev_put(pci_root); 853 + return ret_val; 854 + } 855 + static inline void MDFLD_MSG_WRITE32(uint port, uint offset, u32 value) 856 + { 857 + int mcr = (0x11<<24) | (port << 16) | (offset << 8) | 0xF0; 858 + struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0); 859 + pci_write_config_dword(pci_root, 0xD4, value); 860 + pci_write_config_dword(pci_root, 0xD0, mcr); 861 + pci_dev_put(pci_root); 862 + } 863 + 864 + static inline uint32_t REGISTER_READ(struct drm_device *dev, uint32_t reg) 865 + { 866 + struct drm_psb_private *dev_priv = dev->dev_private; 867 + return ioread32(dev_priv->vdc_reg + reg); 868 + } 869 + 870 + #define REG_READ(reg) REGISTER_READ(dev, (reg)) 871 + 872 + static inline void REGISTER_WRITE(struct drm_device *dev, uint32_t reg, 873 + uint32_t val) 874 + { 875 + struct drm_psb_private *dev_priv = dev->dev_private; 876 + iowrite32((val), dev_priv->vdc_reg + (reg)); 877 + } 878 + 879 + #define REG_WRITE(reg, val) REGISTER_WRITE(dev, (reg), (val)) 880 + 881 + static inline void REGISTER_WRITE16(struct drm_device *dev, 882 + uint32_t reg, uint32_t val) 883 + { 884 + struct drm_psb_private *dev_priv = dev->dev_private; 885 + iowrite16((val), dev_priv->vdc_reg + (reg)); 886 + } 887 + 888 + #define REG_WRITE16(reg, val) REGISTER_WRITE16(dev, (reg), (val)) 889 + 890 + static inline void REGISTER_WRITE8(struct drm_device *dev, 891 + uint32_t reg, uint32_t val) 892 + { 893 + struct drm_psb_private *dev_priv = dev->dev_private; 894 + iowrite8((val), dev_priv->vdc_reg + (reg)); 895 + } 896 + 897 + #define REG_WRITE8(reg, val) REGISTER_WRITE8(dev, (reg), (val)) 898 + 899 + #define PSB_WVDC32(_val, _offs) iowrite32(_val, dev_priv->vdc_reg + (_offs)) 900 + #define PSB_RVDC32(_offs) ioread32(dev_priv->vdc_reg + (_offs)) 901 + 902 + /* #define TRAP_SGX_PM_FAULT 1 */ 903 + #ifdef TRAP_SGX_PM_FAULT 904 + #define PSB_RSGX32(_offs) \ 905 + ({ \ 906 + if (inl(dev_priv->apm_base + PSB_APM_STS) & 0x3) { \ 907 + printk(KERN_ERR \ 908 + "access sgx when it's off!! (READ) %s, %d\n", \ 909 + __FILE__, __LINE__); \ 910 + melay(1000); \ 911 + } \ 912 + ioread32(dev_priv->sgx_reg + (_offs)); \ 913 + }) 914 + #else 915 + #define PSB_RSGX32(_offs) ioread32(dev_priv->sgx_reg + (_offs)) 916 + #endif 917 + #define PSB_WSGX32(_val, _offs) iowrite32(_val, dev_priv->sgx_reg + (_offs)) 918 + 919 + #define MSVDX_REG_DUMP 0 920 + 921 + #define PSB_WMSVDX32(_val, _offs) iowrite32(_val, dev_priv->msvdx_reg + (_offs)) 922 + #define PSB_RMSVDX32(_offs) ioread32(dev_priv->msvdx_reg + (_offs)) 923 + 924 + #endif
+553
drivers/gpu/drm/gma500/psb_irq.c
··· 1 + /************************************************************************** 2 + * Copyright (c) 2007, Intel Corporation. 3 + * All Rights Reserved. 4 + * 5 + * This program is free software; you can redistribute it and/or modify it 6 + * under the terms and conditions of the GNU General Public License, 7 + * version 2, as published by the Free Software Foundation. 8 + * 9 + * This program is distributed in the hope it will be useful, but WITHOUT 10 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 + * more details. 13 + * 14 + * You should have received a copy of the GNU General Public License along with 15 + * this program; if not, write to the Free Software Foundation, Inc., 16 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 17 + * 18 + * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to 19 + * develop this driver. 20 + * 21 + **************************************************************************/ 22 + /* 23 + */ 24 + 25 + #include <drm/drmP.h> 26 + #include "psb_drv.h" 27 + #include "psb_reg.h" 28 + #include "psb_intel_reg.h" 29 + #include "power.h" 30 + 31 + /* 32 + * inline functions 33 + */ 34 + 35 + static inline u32 36 + psb_pipestat(int pipe) 37 + { 38 + if (pipe == 0) 39 + return PIPEASTAT; 40 + if (pipe == 1) 41 + return PIPEBSTAT; 42 + if (pipe == 2) 43 + return PIPECSTAT; 44 + BUG(); 45 + } 46 + 47 + static inline u32 48 + mid_pipe_event(int pipe) 49 + { 50 + if (pipe == 0) 51 + return _PSB_PIPEA_EVENT_FLAG; 52 + if (pipe == 1) 53 + return _MDFLD_PIPEB_EVENT_FLAG; 54 + if (pipe == 2) 55 + return _MDFLD_PIPEC_EVENT_FLAG; 56 + BUG(); 57 + } 58 + 59 + static inline u32 60 + mid_pipe_vsync(int pipe) 61 + { 62 + if (pipe == 0) 63 + return _PSB_VSYNC_PIPEA_FLAG; 64 + if (pipe == 1) 65 + return _PSB_VSYNC_PIPEB_FLAG; 66 + if (pipe == 2) 67 + return _MDFLD_PIPEC_VBLANK_FLAG; 68 + BUG(); 69 + } 70 + 71 + static inline u32 72 + mid_pipeconf(int pipe) 73 + { 74 + if (pipe == 0) 75 + return PIPEACONF; 76 + if (pipe == 1) 77 + return PIPEBCONF; 78 + if (pipe == 2) 79 + return PIPECCONF; 80 + BUG(); 81 + } 82 + 83 + void 84 + psb_enable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask) 85 + { 86 + if ((dev_priv->pipestat[pipe] & mask) != mask) { 87 + u32 reg = psb_pipestat(pipe); 88 + dev_priv->pipestat[pipe] |= mask; 89 + /* Enable the interrupt, clear any pending status */ 90 + if (gma_power_begin(dev_priv->dev, false)) { 91 + u32 writeVal = PSB_RVDC32(reg); 92 + writeVal |= (mask | (mask >> 16)); 93 + PSB_WVDC32(writeVal, reg); 94 + (void) PSB_RVDC32(reg); 95 + gma_power_end(dev_priv->dev); 96 + } 97 + } 98 + } 99 + 100 + void 101 + psb_disable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask) 102 + { 103 + if ((dev_priv->pipestat[pipe] & mask) != 0) { 104 + u32 reg = psb_pipestat(pipe); 105 + dev_priv->pipestat[pipe] &= ~mask; 106 + if (gma_power_begin(dev_priv->dev, false)) { 107 + u32 writeVal = PSB_RVDC32(reg); 108 + writeVal &= ~mask; 109 + PSB_WVDC32(writeVal, reg); 110 + (void) PSB_RVDC32(reg); 111 + gma_power_end(dev_priv->dev); 112 + } 113 + } 114 + } 115 + 116 + void mid_enable_pipe_event(struct drm_psb_private *dev_priv, int pipe) 117 + { 118 + if (gma_power_begin(dev_priv->dev, false)) { 119 + u32 pipe_event = mid_pipe_event(pipe); 120 + dev_priv->vdc_irq_mask |= pipe_event; 121 + PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R); 122 + PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R); 123 + gma_power_end(dev_priv->dev); 124 + } 125 + } 126 + 127 + void mid_disable_pipe_event(struct drm_psb_private *dev_priv, int pipe) 128 + { 129 + if (dev_priv->pipestat[pipe] == 0) { 130 + if (gma_power_begin(dev_priv->dev, false)) { 131 + u32 pipe_event = mid_pipe_event(pipe); 132 + dev_priv->vdc_irq_mask &= ~pipe_event; 133 + PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R); 134 + PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R); 135 + gma_power_end(dev_priv->dev); 136 + } 137 + } 138 + } 139 + 140 + /** 141 + * Display controller interrupt handler for vsync/vblank. 142 + * 143 + */ 144 + static void mid_vblank_handler(struct drm_device *dev, uint32_t pipe) 145 + { 146 + drm_handle_vblank(dev, pipe); 147 + } 148 + 149 + 150 + /** 151 + * Display controller interrupt handler for pipe event. 152 + * 153 + */ 154 + #define WAIT_STATUS_CLEAR_LOOP_COUNT 0xffff 155 + static void mid_pipe_event_handler(struct drm_device *dev, uint32_t pipe) 156 + { 157 + struct drm_psb_private *dev_priv = 158 + (struct drm_psb_private *) dev->dev_private; 159 + 160 + uint32_t pipe_stat_val = 0; 161 + uint32_t pipe_stat_reg = psb_pipestat(pipe); 162 + uint32_t pipe_enable = dev_priv->pipestat[pipe]; 163 + uint32_t pipe_status = dev_priv->pipestat[pipe] >> 16; 164 + uint32_t i = 0; 165 + 166 + spin_lock(&dev_priv->irqmask_lock); 167 + 168 + pipe_stat_val = PSB_RVDC32(pipe_stat_reg); 169 + pipe_stat_val &= pipe_enable | pipe_status; 170 + pipe_stat_val &= pipe_stat_val >> 16; 171 + 172 + spin_unlock(&dev_priv->irqmask_lock); 173 + 174 + /* clear the 2nd level interrupt status bits */ 175 + /** 176 + * FIXME: shouldn't use while loop here. However, the interrupt 177 + * status 'sticky' bits cannot be cleared by setting '1' to that 178 + * bit once... 179 + */ 180 + for (i = 0; i < WAIT_STATUS_CLEAR_LOOP_COUNT; i++) { 181 + PSB_WVDC32(PSB_RVDC32(pipe_stat_reg), pipe_stat_reg); 182 + (void) PSB_RVDC32(pipe_stat_reg); 183 + 184 + if ((PSB_RVDC32(pipe_stat_reg) & pipe_status) == 0) 185 + break; 186 + } 187 + 188 + if (i == WAIT_STATUS_CLEAR_LOOP_COUNT) 189 + dev_err(dev->dev, 190 + "%s, can't clear the status bits in pipe_stat_reg, its value = 0x%x.\n", 191 + __func__, PSB_RVDC32(pipe_stat_reg)); 192 + 193 + if (pipe_stat_val & PIPE_VBLANK_STATUS) 194 + mid_vblank_handler(dev, pipe); 195 + 196 + if (pipe_stat_val & PIPE_TE_STATUS) 197 + drm_handle_vblank(dev, pipe); 198 + } 199 + 200 + /* 201 + * Display controller interrupt handler. 202 + */ 203 + static void psb_vdc_interrupt(struct drm_device *dev, uint32_t vdc_stat) 204 + { 205 + if (vdc_stat & _PSB_PIPEA_EVENT_FLAG) 206 + mid_pipe_event_handler(dev, 0); 207 + } 208 + 209 + irqreturn_t psb_irq_handler(DRM_IRQ_ARGS) 210 + { 211 + struct drm_device *dev = (struct drm_device *) arg; 212 + struct drm_psb_private *dev_priv = 213 + (struct drm_psb_private *) dev->dev_private; 214 + 215 + uint32_t vdc_stat, dsp_int = 0, sgx_int = 0; 216 + int handled = 0; 217 + 218 + spin_lock(&dev_priv->irqmask_lock); 219 + 220 + vdc_stat = PSB_RVDC32(PSB_INT_IDENTITY_R); 221 + 222 + if (vdc_stat & _MDFLD_DISP_ALL_IRQ_FLAG) 223 + dsp_int = 1; 224 + 225 + if (vdc_stat & _PSB_IRQ_SGX_FLAG) 226 + sgx_int = 1; 227 + 228 + vdc_stat &= dev_priv->vdc_irq_mask; 229 + spin_unlock(&dev_priv->irqmask_lock); 230 + 231 + if (dsp_int && gma_power_is_on(dev)) { 232 + psb_vdc_interrupt(dev, vdc_stat); 233 + handled = 1; 234 + } 235 + 236 + if (sgx_int) { 237 + /* Not expected - we have it masked, shut it up */ 238 + u32 s, s2; 239 + s = PSB_RSGX32(PSB_CR_EVENT_STATUS); 240 + s2 = PSB_RSGX32(PSB_CR_EVENT_STATUS2); 241 + PSB_WSGX32(s, PSB_CR_EVENT_HOST_CLEAR); 242 + PSB_WSGX32(s2, PSB_CR_EVENT_HOST_CLEAR2); 243 + /* if s & _PSB_CE_TWOD_COMPLETE we have 2D done but 244 + we may as well poll even if we add that ! */ 245 + handled = 1; 246 + } 247 + 248 + PSB_WVDC32(vdc_stat, PSB_INT_IDENTITY_R); 249 + (void) PSB_RVDC32(PSB_INT_IDENTITY_R); 250 + DRM_READMEMORYBARRIER(); 251 + 252 + if (!handled) 253 + return IRQ_NONE; 254 + 255 + return IRQ_HANDLED; 256 + } 257 + 258 + void psb_irq_preinstall(struct drm_device *dev) 259 + { 260 + struct drm_psb_private *dev_priv = 261 + (struct drm_psb_private *) dev->dev_private; 262 + unsigned long irqflags; 263 + 264 + spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); 265 + 266 + if (gma_power_is_on(dev)) 267 + PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM); 268 + if (dev->vblank_enabled[0]) 269 + dev_priv->vdc_irq_mask |= _PSB_PIPEA_EVENT_FLAG; 270 + if (dev->vblank_enabled[1]) 271 + dev_priv->vdc_irq_mask |= _MDFLD_PIPEB_EVENT_FLAG; 272 + if (dev->vblank_enabled[2]) 273 + dev_priv->vdc_irq_mask |= _MDFLD_PIPEC_EVENT_FLAG; 274 + 275 + /*This register is safe even if display island is off*/ 276 + PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R); 277 + spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); 278 + } 279 + 280 + int psb_irq_postinstall(struct drm_device *dev) 281 + { 282 + struct drm_psb_private *dev_priv = 283 + (struct drm_psb_private *) dev->dev_private; 284 + unsigned long irqflags; 285 + 286 + spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); 287 + 288 + /* This register is safe even if display island is off */ 289 + PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R); 290 + PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM); 291 + 292 + if (dev->vblank_enabled[0]) 293 + psb_enable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE); 294 + else 295 + psb_disable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE); 296 + 297 + if (dev->vblank_enabled[1]) 298 + psb_enable_pipestat(dev_priv, 1, PIPE_VBLANK_INTERRUPT_ENABLE); 299 + else 300 + psb_disable_pipestat(dev_priv, 1, PIPE_VBLANK_INTERRUPT_ENABLE); 301 + 302 + if (dev->vblank_enabled[2]) 303 + psb_enable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE); 304 + else 305 + psb_disable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE); 306 + 307 + spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); 308 + return 0; 309 + } 310 + 311 + void psb_irq_uninstall(struct drm_device *dev) 312 + { 313 + struct drm_psb_private *dev_priv = 314 + (struct drm_psb_private *) dev->dev_private; 315 + unsigned long irqflags; 316 + 317 + spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); 318 + 319 + PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM); 320 + 321 + if (dev->vblank_enabled[0]) 322 + psb_disable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE); 323 + 324 + if (dev->vblank_enabled[1]) 325 + psb_disable_pipestat(dev_priv, 1, PIPE_VBLANK_INTERRUPT_ENABLE); 326 + 327 + if (dev->vblank_enabled[2]) 328 + psb_disable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE); 329 + 330 + dev_priv->vdc_irq_mask &= _PSB_IRQ_SGX_FLAG | 331 + _PSB_IRQ_MSVDX_FLAG | 332 + _LNC_IRQ_TOPAZ_FLAG; 333 + 334 + /* These two registers are safe even if display island is off */ 335 + PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R); 336 + PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R); 337 + 338 + wmb(); 339 + 340 + /* This register is safe even if display island is off */ 341 + PSB_WVDC32(PSB_RVDC32(PSB_INT_IDENTITY_R), PSB_INT_IDENTITY_R); 342 + spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); 343 + } 344 + 345 + void psb_irq_turn_on_dpst(struct drm_device *dev) 346 + { 347 + struct drm_psb_private *dev_priv = 348 + (struct drm_psb_private *) dev->dev_private; 349 + u32 hist_reg; 350 + u32 pwm_reg; 351 + 352 + if (gma_power_begin(dev, false)) { 353 + PSB_WVDC32(1 << 31, HISTOGRAM_LOGIC_CONTROL); 354 + hist_reg = PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL); 355 + PSB_WVDC32(1 << 31, HISTOGRAM_INT_CONTROL); 356 + hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL); 357 + 358 + PSB_WVDC32(0x80010100, PWM_CONTROL_LOGIC); 359 + pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC); 360 + PSB_WVDC32(pwm_reg | PWM_PHASEIN_ENABLE 361 + | PWM_PHASEIN_INT_ENABLE, 362 + PWM_CONTROL_LOGIC); 363 + pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC); 364 + 365 + psb_enable_pipestat(dev_priv, 0, PIPE_DPST_EVENT_ENABLE); 366 + 367 + hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL); 368 + PSB_WVDC32(hist_reg | HISTOGRAM_INT_CTRL_CLEAR, 369 + HISTOGRAM_INT_CONTROL); 370 + pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC); 371 + PSB_WVDC32(pwm_reg | 0x80010100 | PWM_PHASEIN_ENABLE, 372 + PWM_CONTROL_LOGIC); 373 + 374 + gma_power_end(dev); 375 + } 376 + } 377 + 378 + int psb_irq_enable_dpst(struct drm_device *dev) 379 + { 380 + struct drm_psb_private *dev_priv = 381 + (struct drm_psb_private *) dev->dev_private; 382 + unsigned long irqflags; 383 + 384 + spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); 385 + 386 + /* enable DPST */ 387 + mid_enable_pipe_event(dev_priv, 0); 388 + psb_irq_turn_on_dpst(dev); 389 + 390 + spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); 391 + return 0; 392 + } 393 + 394 + void psb_irq_turn_off_dpst(struct drm_device *dev) 395 + { 396 + struct drm_psb_private *dev_priv = 397 + (struct drm_psb_private *) dev->dev_private; 398 + u32 hist_reg; 399 + u32 pwm_reg; 400 + 401 + if (gma_power_begin(dev, false)) { 402 + PSB_WVDC32(0x00000000, HISTOGRAM_INT_CONTROL); 403 + hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL); 404 + 405 + psb_disable_pipestat(dev_priv, 0, PIPE_DPST_EVENT_ENABLE); 406 + 407 + pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC); 408 + PSB_WVDC32(pwm_reg & !(PWM_PHASEIN_INT_ENABLE), 409 + PWM_CONTROL_LOGIC); 410 + pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC); 411 + 412 + gma_power_end(dev); 413 + } 414 + } 415 + 416 + int psb_irq_disable_dpst(struct drm_device *dev) 417 + { 418 + struct drm_psb_private *dev_priv = 419 + (struct drm_psb_private *) dev->dev_private; 420 + unsigned long irqflags; 421 + 422 + spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); 423 + 424 + mid_disable_pipe_event(dev_priv, 0); 425 + psb_irq_turn_off_dpst(dev); 426 + 427 + spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); 428 + 429 + return 0; 430 + } 431 + 432 + #ifdef PSB_FIXME 433 + static int psb_vblank_do_wait(struct drm_device *dev, 434 + unsigned int *sequence, atomic_t *counter) 435 + { 436 + unsigned int cur_vblank; 437 + int ret = 0; 438 + DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, 439 + (((cur_vblank = atomic_read(counter)) 440 + - *sequence) <= (1 << 23))); 441 + *sequence = cur_vblank; 442 + 443 + return ret; 444 + } 445 + #endif 446 + 447 + /* 448 + * It is used to enable VBLANK interrupt 449 + */ 450 + int psb_enable_vblank(struct drm_device *dev, int pipe) 451 + { 452 + struct drm_psb_private *dev_priv = dev->dev_private; 453 + unsigned long irqflags; 454 + uint32_t reg_val = 0; 455 + uint32_t pipeconf_reg = mid_pipeconf(pipe); 456 + 457 + if (gma_power_begin(dev, false)) { 458 + reg_val = REG_READ(pipeconf_reg); 459 + gma_power_end(dev); 460 + } 461 + 462 + if (!(reg_val & PIPEACONF_ENABLE)) 463 + return -EINVAL; 464 + 465 + spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); 466 + 467 + mid_enable_pipe_event(dev_priv, pipe); 468 + psb_enable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE); 469 + 470 + spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); 471 + 472 + return 0; 473 + } 474 + 475 + /* 476 + * It is used to disable VBLANK interrupt 477 + */ 478 + void psb_disable_vblank(struct drm_device *dev, int pipe) 479 + { 480 + struct drm_psb_private *dev_priv = dev->dev_private; 481 + unsigned long irqflags; 482 + 483 + spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); 484 + 485 + mid_disable_pipe_event(dev_priv, pipe); 486 + psb_disable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE); 487 + 488 + spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); 489 + } 490 + 491 + /* Called from drm generic code, passed a 'crtc', which 492 + * we use as a pipe index 493 + */ 494 + u32 psb_get_vblank_counter(struct drm_device *dev, int pipe) 495 + { 496 + uint32_t high_frame = PIPEAFRAMEHIGH; 497 + uint32_t low_frame = PIPEAFRAMEPIXEL; 498 + uint32_t pipeconf_reg = PIPEACONF; 499 + uint32_t reg_val = 0; 500 + uint32_t high1 = 0, high2 = 0, low = 0, count = 0; 501 + 502 + switch (pipe) { 503 + case 0: 504 + break; 505 + case 1: 506 + high_frame = PIPEBFRAMEHIGH; 507 + low_frame = PIPEBFRAMEPIXEL; 508 + pipeconf_reg = PIPEBCONF; 509 + break; 510 + case 2: 511 + high_frame = PIPECFRAMEHIGH; 512 + low_frame = PIPECFRAMEPIXEL; 513 + pipeconf_reg = PIPECCONF; 514 + break; 515 + default: 516 + dev_err(dev->dev, "%s, invalid pipe.\n", __func__); 517 + return 0; 518 + } 519 + 520 + if (!gma_power_begin(dev, false)) 521 + return 0; 522 + 523 + reg_val = REG_READ(pipeconf_reg); 524 + 525 + if (!(reg_val & PIPEACONF_ENABLE)) { 526 + dev_err(dev->dev, "trying to get vblank count for disabled pipe %d\n", 527 + pipe); 528 + goto psb_get_vblank_counter_exit; 529 + } 530 + 531 + /* 532 + * High & low register fields aren't synchronized, so make sure 533 + * we get a low value that's stable across two reads of the high 534 + * register. 535 + */ 536 + do { 537 + high1 = ((REG_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >> 538 + PIPE_FRAME_HIGH_SHIFT); 539 + low = ((REG_READ(low_frame) & PIPE_FRAME_LOW_MASK) >> 540 + PIPE_FRAME_LOW_SHIFT); 541 + high2 = ((REG_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >> 542 + PIPE_FRAME_HIGH_SHIFT); 543 + } while (high1 != high2); 544 + 545 + count = (high1 << 8) | low; 546 + 547 + psb_get_vblank_counter_exit: 548 + 549 + gma_power_end(dev); 550 + 551 + return count; 552 + } 553 +
+45
drivers/gpu/drm/gma500/psb_irq.h
··· 1 + /************************************************************************** 2 + * Copyright (c) 2009-2011, Intel Corporation. 3 + * All Rights Reserved. 4 + * 5 + * This program is free software; you can redistribute it and/or modify it 6 + * under the terms and conditions of the GNU General Public License, 7 + * version 2, as published by the Free Software Foundation. 8 + * 9 + * This program is distributed in the hope it will be useful, but WITHOUT 10 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 + * more details. 13 + * 14 + * You should have received a copy of the GNU General Public License along with 15 + * this program; if not, write to the Free Software Foundation, Inc., 16 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 17 + * 18 + * Authors: 19 + * Benjamin Defnet <benjamin.r.defnet@intel.com> 20 + * Rajesh Poornachandran <rajesh.poornachandran@intel.com> 21 + * 22 + **************************************************************************/ 23 + 24 + #ifndef _SYSIRQ_H_ 25 + #define _SYSIRQ_H_ 26 + 27 + #include <drm/drmP.h> 28 + 29 + bool sysirq_init(struct drm_device *dev); 30 + void sysirq_uninit(struct drm_device *dev); 31 + 32 + void psb_irq_preinstall(struct drm_device *dev); 33 + int psb_irq_postinstall(struct drm_device *dev); 34 + void psb_irq_uninstall(struct drm_device *dev); 35 + irqreturn_t psb_irq_handler(DRM_IRQ_ARGS); 36 + 37 + int psb_irq_enable_dpst(struct drm_device *dev); 38 + int psb_irq_disable_dpst(struct drm_device *dev); 39 + void psb_irq_turn_on_dpst(struct drm_device *dev); 40 + void psb_irq_turn_off_dpst(struct drm_device *dev); 41 + int psb_enable_vblank(struct drm_device *dev, int pipe); 42 + void psb_disable_vblank(struct drm_device *dev, int pipe); 43 + u32 psb_get_vblank_counter(struct drm_device *dev, int pipe); 44 + 45 + #endif /* _SYSIRQ_H_ */
+582
drivers/gpu/drm/gma500/psb_reg.h
··· 1 + /************************************************************************** 2 + * 3 + * Copyright (c) (2005-2007) Imagination Technologies Limited. 4 + * Copyright (c) 2007, Intel Corporation. 5 + * All Rights Reserved. 6 + * 7 + * This program is free software; you can redistribute it and/or modify it 8 + * under the terms and conditions of the GNU General Public License, 9 + * version 2, as published by the Free Software Foundation. 10 + * 11 + * This program is distributed in the hope it will be useful, but WITHOUT 12 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14 + * more details. 15 + * 16 + * You should have received a copy of the GNU General Public License along with 17 + * this program; if not, write to the Free Software Foundation, Inc., 18 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.. 19 + * 20 + **************************************************************************/ 21 + 22 + #ifndef _PSB_REG_H_ 23 + #define _PSB_REG_H_ 24 + 25 + #define PSB_CR_CLKGATECTL 0x0000 26 + #define _PSB_C_CLKGATECTL_AUTO_MAN_REG (1 << 24) 27 + #define _PSB_C_CLKGATECTL_USE_CLKG_SHIFT (20) 28 + #define _PSB_C_CLKGATECTL_USE_CLKG_MASK (0x3 << 20) 29 + #define _PSB_C_CLKGATECTL_DPM_CLKG_SHIFT (16) 30 + #define _PSB_C_CLKGATECTL_DPM_CLKG_MASK (0x3 << 16) 31 + #define _PSB_C_CLKGATECTL_TA_CLKG_SHIFT (12) 32 + #define _PSB_C_CLKGATECTL_TA_CLKG_MASK (0x3 << 12) 33 + #define _PSB_C_CLKGATECTL_TSP_CLKG_SHIFT (8) 34 + #define _PSB_C_CLKGATECTL_TSP_CLKG_MASK (0x3 << 8) 35 + #define _PSB_C_CLKGATECTL_ISP_CLKG_SHIFT (4) 36 + #define _PSB_C_CLKGATECTL_ISP_CLKG_MASK (0x3 << 4) 37 + #define _PSB_C_CLKGATECTL_2D_CLKG_SHIFT (0) 38 + #define _PSB_C_CLKGATECTL_2D_CLKG_MASK (0x3 << 0) 39 + #define _PSB_C_CLKGATECTL_CLKG_ENABLED (0) 40 + #define _PSB_C_CLKGATECTL_CLKG_DISABLED (1) 41 + #define _PSB_C_CLKGATECTL_CLKG_AUTO (2) 42 + 43 + #define PSB_CR_CORE_ID 0x0010 44 + #define _PSB_CC_ID_ID_SHIFT (16) 45 + #define _PSB_CC_ID_ID_MASK (0xFFFF << 16) 46 + #define _PSB_CC_ID_CONFIG_SHIFT (0) 47 + #define _PSB_CC_ID_CONFIG_MASK (0xFFFF << 0) 48 + 49 + #define PSB_CR_CORE_REVISION 0x0014 50 + #define _PSB_CC_REVISION_DESIGNER_SHIFT (24) 51 + #define _PSB_CC_REVISION_DESIGNER_MASK (0xFF << 24) 52 + #define _PSB_CC_REVISION_MAJOR_SHIFT (16) 53 + #define _PSB_CC_REVISION_MAJOR_MASK (0xFF << 16) 54 + #define _PSB_CC_REVISION_MINOR_SHIFT (8) 55 + #define _PSB_CC_REVISION_MINOR_MASK (0xFF << 8) 56 + #define _PSB_CC_REVISION_MAINTENANCE_SHIFT (0) 57 + #define _PSB_CC_REVISION_MAINTENANCE_MASK (0xFF << 0) 58 + 59 + #define PSB_CR_DESIGNER_REV_FIELD1 0x0018 60 + 61 + #define PSB_CR_SOFT_RESET 0x0080 62 + #define _PSB_CS_RESET_TSP_RESET (1 << 6) 63 + #define _PSB_CS_RESET_ISP_RESET (1 << 5) 64 + #define _PSB_CS_RESET_USE_RESET (1 << 4) 65 + #define _PSB_CS_RESET_TA_RESET (1 << 3) 66 + #define _PSB_CS_RESET_DPM_RESET (1 << 2) 67 + #define _PSB_CS_RESET_TWOD_RESET (1 << 1) 68 + #define _PSB_CS_RESET_BIF_RESET (1 << 0) 69 + 70 + #define PSB_CR_DESIGNER_REV_FIELD2 0x001C 71 + 72 + #define PSB_CR_EVENT_HOST_ENABLE2 0x0110 73 + 74 + #define PSB_CR_EVENT_STATUS2 0x0118 75 + 76 + #define PSB_CR_EVENT_HOST_CLEAR2 0x0114 77 + #define _PSB_CE2_BIF_REQUESTER_FAULT (1 << 4) 78 + 79 + #define PSB_CR_EVENT_STATUS 0x012C 80 + 81 + #define PSB_CR_EVENT_HOST_ENABLE 0x0130 82 + 83 + #define PSB_CR_EVENT_HOST_CLEAR 0x0134 84 + #define _PSB_CE_MASTER_INTERRUPT (1 << 31) 85 + #define _PSB_CE_TA_DPM_FAULT (1 << 28) 86 + #define _PSB_CE_TWOD_COMPLETE (1 << 27) 87 + #define _PSB_CE_DPM_OUT_OF_MEMORY_ZLS (1 << 25) 88 + #define _PSB_CE_DPM_TA_MEM_FREE (1 << 24) 89 + #define _PSB_CE_PIXELBE_END_RENDER (1 << 18) 90 + #define _PSB_CE_SW_EVENT (1 << 14) 91 + #define _PSB_CE_TA_FINISHED (1 << 13) 92 + #define _PSB_CE_TA_TERMINATE (1 << 12) 93 + #define _PSB_CE_DPM_REACHED_MEM_THRESH (1 << 3) 94 + #define _PSB_CE_DPM_OUT_OF_MEMORY_GBL (1 << 2) 95 + #define _PSB_CE_DPM_OUT_OF_MEMORY_MT (1 << 1) 96 + #define _PSB_CE_DPM_3D_MEM_FREE (1 << 0) 97 + 98 + 99 + #define PSB_USE_OFFSET_MASK 0x0007FFFF 100 + #define PSB_USE_OFFSET_SIZE (PSB_USE_OFFSET_MASK + 1) 101 + #define PSB_CR_USE_CODE_BASE0 0x0A0C 102 + #define PSB_CR_USE_CODE_BASE1 0x0A10 103 + #define PSB_CR_USE_CODE_BASE2 0x0A14 104 + #define PSB_CR_USE_CODE_BASE3 0x0A18 105 + #define PSB_CR_USE_CODE_BASE4 0x0A1C 106 + #define PSB_CR_USE_CODE_BASE5 0x0A20 107 + #define PSB_CR_USE_CODE_BASE6 0x0A24 108 + #define PSB_CR_USE_CODE_BASE7 0x0A28 109 + #define PSB_CR_USE_CODE_BASE8 0x0A2C 110 + #define PSB_CR_USE_CODE_BASE9 0x0A30 111 + #define PSB_CR_USE_CODE_BASE10 0x0A34 112 + #define PSB_CR_USE_CODE_BASE11 0x0A38 113 + #define PSB_CR_USE_CODE_BASE12 0x0A3C 114 + #define PSB_CR_USE_CODE_BASE13 0x0A40 115 + #define PSB_CR_USE_CODE_BASE14 0x0A44 116 + #define PSB_CR_USE_CODE_BASE15 0x0A48 117 + #define PSB_CR_USE_CODE_BASE(_i) (0x0A0C + ((_i) << 2)) 118 + #define _PSB_CUC_BASE_DM_SHIFT (25) 119 + #define _PSB_CUC_BASE_DM_MASK (0x3 << 25) 120 + #define _PSB_CUC_BASE_ADDR_SHIFT (0) /* 1024-bit aligned address? */ 121 + #define _PSB_CUC_BASE_ADDR_ALIGNSHIFT (7) 122 + #define _PSB_CUC_BASE_ADDR_MASK (0x1FFFFFF << 0) 123 + #define _PSB_CUC_DM_VERTEX (0) 124 + #define _PSB_CUC_DM_PIXEL (1) 125 + #define _PSB_CUC_DM_RESERVED (2) 126 + #define _PSB_CUC_DM_EDM (3) 127 + 128 + #define PSB_CR_PDS_EXEC_BASE 0x0AB8 129 + #define _PSB_CR_PDS_EXEC_BASE_ADDR_SHIFT (20) /* 1MB aligned address */ 130 + #define _PSB_CR_PDS_EXEC_BASE_ADDR_ALIGNSHIFT (20) 131 + 132 + #define PSB_CR_EVENT_KICKER 0x0AC4 133 + #define _PSB_CE_KICKER_ADDRESS_SHIFT (4) /* 128-bit aligned address */ 134 + 135 + #define PSB_CR_EVENT_KICK 0x0AC8 136 + #define _PSB_CE_KICK_NOW (1 << 0) 137 + 138 + #define PSB_CR_BIF_DIR_LIST_BASE1 0x0C38 139 + 140 + #define PSB_CR_BIF_CTRL 0x0C00 141 + #define _PSB_CB_CTRL_CLEAR_FAULT (1 << 4) 142 + #define _PSB_CB_CTRL_INVALDC (1 << 3) 143 + #define _PSB_CB_CTRL_FLUSH (1 << 2) 144 + 145 + #define PSB_CR_BIF_INT_STAT 0x0C04 146 + 147 + #define PSB_CR_BIF_FAULT 0x0C08 148 + #define _PSB_CBI_STAT_PF_N_RW (1 << 14) 149 + #define _PSB_CBI_STAT_FAULT_SHIFT (0) 150 + #define _PSB_CBI_STAT_FAULT_MASK (0x3FFF << 0) 151 + #define _PSB_CBI_STAT_FAULT_CACHE (1 << 1) 152 + #define _PSB_CBI_STAT_FAULT_TA (1 << 2) 153 + #define _PSB_CBI_STAT_FAULT_VDM (1 << 3) 154 + #define _PSB_CBI_STAT_FAULT_2D (1 << 4) 155 + #define _PSB_CBI_STAT_FAULT_PBE (1 << 5) 156 + #define _PSB_CBI_STAT_FAULT_TSP (1 << 6) 157 + #define _PSB_CBI_STAT_FAULT_ISP (1 << 7) 158 + #define _PSB_CBI_STAT_FAULT_USSEPDS (1 << 8) 159 + #define _PSB_CBI_STAT_FAULT_HOST (1 << 9) 160 + 161 + #define PSB_CR_BIF_BANK0 0x0C78 162 + #define PSB_CR_BIF_BANK1 0x0C7C 163 + #define PSB_CR_BIF_DIR_LIST_BASE0 0x0C84 164 + #define PSB_CR_BIF_TWOD_REQ_BASE 0x0C88 165 + #define PSB_CR_BIF_3D_REQ_BASE 0x0CAC 166 + 167 + #define PSB_CR_2D_SOCIF 0x0E18 168 + #define _PSB_C2_SOCIF_FREESPACE_SHIFT (0) 169 + #define _PSB_C2_SOCIF_FREESPACE_MASK (0xFF << 0) 170 + #define _PSB_C2_SOCIF_EMPTY (0x80 << 0) 171 + 172 + #define PSB_CR_2D_BLIT_STATUS 0x0E04 173 + #define _PSB_C2B_STATUS_BUSY (1 << 24) 174 + #define _PSB_C2B_STATUS_COMPLETE_SHIFT (0) 175 + #define _PSB_C2B_STATUS_COMPLETE_MASK (0xFFFFFF << 0) 176 + 177 + /* 178 + * 2D defs. 179 + */ 180 + 181 + /* 182 + * 2D Slave Port Data : Block Header's Object Type 183 + */ 184 + 185 + #define PSB_2D_CLIP_BH (0x00000000) 186 + #define PSB_2D_PAT_BH (0x10000000) 187 + #define PSB_2D_CTRL_BH (0x20000000) 188 + #define PSB_2D_SRC_OFF_BH (0x30000000) 189 + #define PSB_2D_MASK_OFF_BH (0x40000000) 190 + #define PSB_2D_RESERVED1_BH (0x50000000) 191 + #define PSB_2D_RESERVED2_BH (0x60000000) 192 + #define PSB_2D_FENCE_BH (0x70000000) 193 + #define PSB_2D_BLIT_BH (0x80000000) 194 + #define PSB_2D_SRC_SURF_BH (0x90000000) 195 + #define PSB_2D_DST_SURF_BH (0xA0000000) 196 + #define PSB_2D_PAT_SURF_BH (0xB0000000) 197 + #define PSB_2D_SRC_PAL_BH (0xC0000000) 198 + #define PSB_2D_PAT_PAL_BH (0xD0000000) 199 + #define PSB_2D_MASK_SURF_BH (0xE0000000) 200 + #define PSB_2D_FLUSH_BH (0xF0000000) 201 + 202 + /* 203 + * Clip Definition block (PSB_2D_CLIP_BH) 204 + */ 205 + #define PSB_2D_CLIPCOUNT_MAX (1) 206 + #define PSB_2D_CLIPCOUNT_MASK (0x00000000) 207 + #define PSB_2D_CLIPCOUNT_CLRMASK (0xFFFFFFFF) 208 + #define PSB_2D_CLIPCOUNT_SHIFT (0) 209 + /* clip rectangle min & max */ 210 + #define PSB_2D_CLIP_XMAX_MASK (0x00FFF000) 211 + #define PSB_2D_CLIP_XMAX_CLRMASK (0xFF000FFF) 212 + #define PSB_2D_CLIP_XMAX_SHIFT (12) 213 + #define PSB_2D_CLIP_XMIN_MASK (0x00000FFF) 214 + #define PSB_2D_CLIP_XMIN_CLRMASK (0x00FFF000) 215 + #define PSB_2D_CLIP_XMIN_SHIFT (0) 216 + /* clip rectangle offset */ 217 + #define PSB_2D_CLIP_YMAX_MASK (0x00FFF000) 218 + #define PSB_2D_CLIP_YMAX_CLRMASK (0xFF000FFF) 219 + #define PSB_2D_CLIP_YMAX_SHIFT (12) 220 + #define PSB_2D_CLIP_YMIN_MASK (0x00000FFF) 221 + #define PSB_2D_CLIP_YMIN_CLRMASK (0x00FFF000) 222 + #define PSB_2D_CLIP_YMIN_SHIFT (0) 223 + 224 + /* 225 + * Pattern Control (PSB_2D_PAT_BH) 226 + */ 227 + #define PSB_2D_PAT_HEIGHT_MASK (0x0000001F) 228 + #define PSB_2D_PAT_HEIGHT_SHIFT (0) 229 + #define PSB_2D_PAT_WIDTH_MASK (0x000003E0) 230 + #define PSB_2D_PAT_WIDTH_SHIFT (5) 231 + #define PSB_2D_PAT_YSTART_MASK (0x00007C00) 232 + #define PSB_2D_PAT_YSTART_SHIFT (10) 233 + #define PSB_2D_PAT_XSTART_MASK (0x000F8000) 234 + #define PSB_2D_PAT_XSTART_SHIFT (15) 235 + 236 + /* 237 + * 2D Control block (PSB_2D_CTRL_BH) 238 + */ 239 + /* Present Flags */ 240 + #define PSB_2D_SRCCK_CTRL (0x00000001) 241 + #define PSB_2D_DSTCK_CTRL (0x00000002) 242 + #define PSB_2D_ALPHA_CTRL (0x00000004) 243 + /* Colour Key Colour (SRC/DST)*/ 244 + #define PSB_2D_CK_COL_MASK (0xFFFFFFFF) 245 + #define PSB_2D_CK_COL_CLRMASK (0x00000000) 246 + #define PSB_2D_CK_COL_SHIFT (0) 247 + /* Colour Key Mask (SRC/DST)*/ 248 + #define PSB_2D_CK_MASK_MASK (0xFFFFFFFF) 249 + #define PSB_2D_CK_MASK_CLRMASK (0x00000000) 250 + #define PSB_2D_CK_MASK_SHIFT (0) 251 + /* Alpha Control (Alpha/RGB)*/ 252 + #define PSB_2D_GBLALPHA_MASK (0x000FF000) 253 + #define PSB_2D_GBLALPHA_CLRMASK (0xFFF00FFF) 254 + #define PSB_2D_GBLALPHA_SHIFT (12) 255 + #define PSB_2D_SRCALPHA_OP_MASK (0x00700000) 256 + #define PSB_2D_SRCALPHA_OP_CLRMASK (0xFF8FFFFF) 257 + #define PSB_2D_SRCALPHA_OP_SHIFT (20) 258 + #define PSB_2D_SRCALPHA_OP_ONE (0x00000000) 259 + #define PSB_2D_SRCALPHA_OP_SRC (0x00100000) 260 + #define PSB_2D_SRCALPHA_OP_DST (0x00200000) 261 + #define PSB_2D_SRCALPHA_OP_SG (0x00300000) 262 + #define PSB_2D_SRCALPHA_OP_DG (0x00400000) 263 + #define PSB_2D_SRCALPHA_OP_GBL (0x00500000) 264 + #define PSB_2D_SRCALPHA_OP_ZERO (0x00600000) 265 + #define PSB_2D_SRCALPHA_INVERT (0x00800000) 266 + #define PSB_2D_SRCALPHA_INVERT_CLR (0xFF7FFFFF) 267 + #define PSB_2D_DSTALPHA_OP_MASK (0x07000000) 268 + #define PSB_2D_DSTALPHA_OP_CLRMASK (0xF8FFFFFF) 269 + #define PSB_2D_DSTALPHA_OP_SHIFT (24) 270 + #define PSB_2D_DSTALPHA_OP_ONE (0x00000000) 271 + #define PSB_2D_DSTALPHA_OP_SRC (0x01000000) 272 + #define PSB_2D_DSTALPHA_OP_DST (0x02000000) 273 + #define PSB_2D_DSTALPHA_OP_SG (0x03000000) 274 + #define PSB_2D_DSTALPHA_OP_DG (0x04000000) 275 + #define PSB_2D_DSTALPHA_OP_GBL (0x05000000) 276 + #define PSB_2D_DSTALPHA_OP_ZERO (0x06000000) 277 + #define PSB_2D_DSTALPHA_INVERT (0x08000000) 278 + #define PSB_2D_DSTALPHA_INVERT_CLR (0xF7FFFFFF) 279 + 280 + #define PSB_2D_PRE_MULTIPLICATION_ENABLE (0x10000000) 281 + #define PSB_2D_PRE_MULTIPLICATION_CLRMASK (0xEFFFFFFF) 282 + #define PSB_2D_ZERO_SOURCE_ALPHA_ENABLE (0x20000000) 283 + #define PSB_2D_ZERO_SOURCE_ALPHA_CLRMASK (0xDFFFFFFF) 284 + 285 + /* 286 + *Source Offset (PSB_2D_SRC_OFF_BH) 287 + */ 288 + #define PSB_2D_SRCOFF_XSTART_MASK ((0x00000FFF) << 12) 289 + #define PSB_2D_SRCOFF_XSTART_SHIFT (12) 290 + #define PSB_2D_SRCOFF_YSTART_MASK (0x00000FFF) 291 + #define PSB_2D_SRCOFF_YSTART_SHIFT (0) 292 + 293 + /* 294 + * Mask Offset (PSB_2D_MASK_OFF_BH) 295 + */ 296 + #define PSB_2D_MASKOFF_XSTART_MASK ((0x00000FFF) << 12) 297 + #define PSB_2D_MASKOFF_XSTART_SHIFT (12) 298 + #define PSB_2D_MASKOFF_YSTART_MASK (0x00000FFF) 299 + #define PSB_2D_MASKOFF_YSTART_SHIFT (0) 300 + 301 + /* 302 + * 2D Fence (see PSB_2D_FENCE_BH): bits 0:27 are ignored 303 + */ 304 + 305 + /* 306 + *Blit Rectangle (PSB_2D_BLIT_BH) 307 + */ 308 + 309 + #define PSB_2D_ROT_MASK (3 << 25) 310 + #define PSB_2D_ROT_CLRMASK (~PSB_2D_ROT_MASK) 311 + #define PSB_2D_ROT_NONE (0 << 25) 312 + #define PSB_2D_ROT_90DEGS (1 << 25) 313 + #define PSB_2D_ROT_180DEGS (2 << 25) 314 + #define PSB_2D_ROT_270DEGS (3 << 25) 315 + 316 + #define PSB_2D_COPYORDER_MASK (3 << 23) 317 + #define PSB_2D_COPYORDER_CLRMASK (~PSB_2D_COPYORDER_MASK) 318 + #define PSB_2D_COPYORDER_TL2BR (0 << 23) 319 + #define PSB_2D_COPYORDER_BR2TL (1 << 23) 320 + #define PSB_2D_COPYORDER_TR2BL (2 << 23) 321 + #define PSB_2D_COPYORDER_BL2TR (3 << 23) 322 + 323 + #define PSB_2D_DSTCK_CLRMASK (0xFF9FFFFF) 324 + #define PSB_2D_DSTCK_DISABLE (0x00000000) 325 + #define PSB_2D_DSTCK_PASS (0x00200000) 326 + #define PSB_2D_DSTCK_REJECT (0x00400000) 327 + 328 + #define PSB_2D_SRCCK_CLRMASK (0xFFE7FFFF) 329 + #define PSB_2D_SRCCK_DISABLE (0x00000000) 330 + #define PSB_2D_SRCCK_PASS (0x00080000) 331 + #define PSB_2D_SRCCK_REJECT (0x00100000) 332 + 333 + #define PSB_2D_CLIP_ENABLE (0x00040000) 334 + 335 + #define PSB_2D_ALPHA_ENABLE (0x00020000) 336 + 337 + #define PSB_2D_PAT_CLRMASK (0xFFFEFFFF) 338 + #define PSB_2D_PAT_MASK (0x00010000) 339 + #define PSB_2D_USE_PAT (0x00010000) 340 + #define PSB_2D_USE_FILL (0x00000000) 341 + /* 342 + * Tungsten Graphics note on rop codes: If rop A and rop B are 343 + * identical, the mask surface will not be read and need not be 344 + * set up. 345 + */ 346 + 347 + #define PSB_2D_ROP3B_MASK (0x0000FF00) 348 + #define PSB_2D_ROP3B_CLRMASK (0xFFFF00FF) 349 + #define PSB_2D_ROP3B_SHIFT (8) 350 + /* rop code A */ 351 + #define PSB_2D_ROP3A_MASK (0x000000FF) 352 + #define PSB_2D_ROP3A_CLRMASK (0xFFFFFF00) 353 + #define PSB_2D_ROP3A_SHIFT (0) 354 + 355 + #define PSB_2D_ROP4_MASK (0x0000FFFF) 356 + /* 357 + * DWORD0: (Only pass if Pattern control == Use Fill Colour) 358 + * Fill Colour RGBA8888 359 + */ 360 + #define PSB_2D_FILLCOLOUR_MASK (0xFFFFFFFF) 361 + #define PSB_2D_FILLCOLOUR_SHIFT (0) 362 + /* 363 + * DWORD1: (Always Present) 364 + * X Start (Dest) 365 + * Y Start (Dest) 366 + */ 367 + #define PSB_2D_DST_XSTART_MASK (0x00FFF000) 368 + #define PSB_2D_DST_XSTART_CLRMASK (0xFF000FFF) 369 + #define PSB_2D_DST_XSTART_SHIFT (12) 370 + #define PSB_2D_DST_YSTART_MASK (0x00000FFF) 371 + #define PSB_2D_DST_YSTART_CLRMASK (0xFFFFF000) 372 + #define PSB_2D_DST_YSTART_SHIFT (0) 373 + /* 374 + * DWORD2: (Always Present) 375 + * X Size (Dest) 376 + * Y Size (Dest) 377 + */ 378 + #define PSB_2D_DST_XSIZE_MASK (0x00FFF000) 379 + #define PSB_2D_DST_XSIZE_CLRMASK (0xFF000FFF) 380 + #define PSB_2D_DST_XSIZE_SHIFT (12) 381 + #define PSB_2D_DST_YSIZE_MASK (0x00000FFF) 382 + #define PSB_2D_DST_YSIZE_CLRMASK (0xFFFFF000) 383 + #define PSB_2D_DST_YSIZE_SHIFT (0) 384 + 385 + /* 386 + * Source Surface (PSB_2D_SRC_SURF_BH) 387 + */ 388 + /* 389 + * WORD 0 390 + */ 391 + 392 + #define PSB_2D_SRC_FORMAT_MASK (0x00078000) 393 + #define PSB_2D_SRC_1_PAL (0x00000000) 394 + #define PSB_2D_SRC_2_PAL (0x00008000) 395 + #define PSB_2D_SRC_4_PAL (0x00010000) 396 + #define PSB_2D_SRC_8_PAL (0x00018000) 397 + #define PSB_2D_SRC_8_ALPHA (0x00020000) 398 + #define PSB_2D_SRC_4_ALPHA (0x00028000) 399 + #define PSB_2D_SRC_332RGB (0x00030000) 400 + #define PSB_2D_SRC_4444ARGB (0x00038000) 401 + #define PSB_2D_SRC_555RGB (0x00040000) 402 + #define PSB_2D_SRC_1555ARGB (0x00048000) 403 + #define PSB_2D_SRC_565RGB (0x00050000) 404 + #define PSB_2D_SRC_0888ARGB (0x00058000) 405 + #define PSB_2D_SRC_8888ARGB (0x00060000) 406 + #define PSB_2D_SRC_8888UYVY (0x00068000) 407 + #define PSB_2D_SRC_RESERVED (0x00070000) 408 + #define PSB_2D_SRC_1555ARGB_LOOKUP (0x00078000) 409 + 410 + 411 + #define PSB_2D_SRC_STRIDE_MASK (0x00007FFF) 412 + #define PSB_2D_SRC_STRIDE_CLRMASK (0xFFFF8000) 413 + #define PSB_2D_SRC_STRIDE_SHIFT (0) 414 + /* 415 + * WORD 1 - Base Address 416 + */ 417 + #define PSB_2D_SRC_ADDR_MASK (0x0FFFFFFC) 418 + #define PSB_2D_SRC_ADDR_CLRMASK (0x00000003) 419 + #define PSB_2D_SRC_ADDR_SHIFT (2) 420 + #define PSB_2D_SRC_ADDR_ALIGNSHIFT (2) 421 + 422 + /* 423 + * Pattern Surface (PSB_2D_PAT_SURF_BH) 424 + */ 425 + /* 426 + * WORD 0 427 + */ 428 + 429 + #define PSB_2D_PAT_FORMAT_MASK (0x00078000) 430 + #define PSB_2D_PAT_1_PAL (0x00000000) 431 + #define PSB_2D_PAT_2_PAL (0x00008000) 432 + #define PSB_2D_PAT_4_PAL (0x00010000) 433 + #define PSB_2D_PAT_8_PAL (0x00018000) 434 + #define PSB_2D_PAT_8_ALPHA (0x00020000) 435 + #define PSB_2D_PAT_4_ALPHA (0x00028000) 436 + #define PSB_2D_PAT_332RGB (0x00030000) 437 + #define PSB_2D_PAT_4444ARGB (0x00038000) 438 + #define PSB_2D_PAT_555RGB (0x00040000) 439 + #define PSB_2D_PAT_1555ARGB (0x00048000) 440 + #define PSB_2D_PAT_565RGB (0x00050000) 441 + #define PSB_2D_PAT_0888ARGB (0x00058000) 442 + #define PSB_2D_PAT_8888ARGB (0x00060000) 443 + 444 + #define PSB_2D_PAT_STRIDE_MASK (0x00007FFF) 445 + #define PSB_2D_PAT_STRIDE_CLRMASK (0xFFFF8000) 446 + #define PSB_2D_PAT_STRIDE_SHIFT (0) 447 + /* 448 + * WORD 1 - Base Address 449 + */ 450 + #define PSB_2D_PAT_ADDR_MASK (0x0FFFFFFC) 451 + #define PSB_2D_PAT_ADDR_CLRMASK (0x00000003) 452 + #define PSB_2D_PAT_ADDR_SHIFT (2) 453 + #define PSB_2D_PAT_ADDR_ALIGNSHIFT (2) 454 + 455 + /* 456 + * Destination Surface (PSB_2D_DST_SURF_BH) 457 + */ 458 + /* 459 + * WORD 0 460 + */ 461 + 462 + #define PSB_2D_DST_FORMAT_MASK (0x00078000) 463 + #define PSB_2D_DST_332RGB (0x00030000) 464 + #define PSB_2D_DST_4444ARGB (0x00038000) 465 + #define PSB_2D_DST_555RGB (0x00040000) 466 + #define PSB_2D_DST_1555ARGB (0x00048000) 467 + #define PSB_2D_DST_565RGB (0x00050000) 468 + #define PSB_2D_DST_0888ARGB (0x00058000) 469 + #define PSB_2D_DST_8888ARGB (0x00060000) 470 + #define PSB_2D_DST_8888AYUV (0x00070000) 471 + 472 + #define PSB_2D_DST_STRIDE_MASK (0x00007FFF) 473 + #define PSB_2D_DST_STRIDE_CLRMASK (0xFFFF8000) 474 + #define PSB_2D_DST_STRIDE_SHIFT (0) 475 + /* 476 + * WORD 1 - Base Address 477 + */ 478 + #define PSB_2D_DST_ADDR_MASK (0x0FFFFFFC) 479 + #define PSB_2D_DST_ADDR_CLRMASK (0x00000003) 480 + #define PSB_2D_DST_ADDR_SHIFT (2) 481 + #define PSB_2D_DST_ADDR_ALIGNSHIFT (2) 482 + 483 + /* 484 + * Mask Surface (PSB_2D_MASK_SURF_BH) 485 + */ 486 + /* 487 + * WORD 0 488 + */ 489 + #define PSB_2D_MASK_STRIDE_MASK (0x00007FFF) 490 + #define PSB_2D_MASK_STRIDE_CLRMASK (0xFFFF8000) 491 + #define PSB_2D_MASK_STRIDE_SHIFT (0) 492 + /* 493 + * WORD 1 - Base Address 494 + */ 495 + #define PSB_2D_MASK_ADDR_MASK (0x0FFFFFFC) 496 + #define PSB_2D_MASK_ADDR_CLRMASK (0x00000003) 497 + #define PSB_2D_MASK_ADDR_SHIFT (2) 498 + #define PSB_2D_MASK_ADDR_ALIGNSHIFT (2) 499 + 500 + /* 501 + * Source Palette (PSB_2D_SRC_PAL_BH) 502 + */ 503 + 504 + #define PSB_2D_SRCPAL_ADDR_SHIFT (0) 505 + #define PSB_2D_SRCPAL_ADDR_CLRMASK (0xF0000007) 506 + #define PSB_2D_SRCPAL_ADDR_MASK (0x0FFFFFF8) 507 + #define PSB_2D_SRCPAL_BYTEALIGN (1024) 508 + 509 + /* 510 + * Pattern Palette (PSB_2D_PAT_PAL_BH) 511 + */ 512 + 513 + #define PSB_2D_PATPAL_ADDR_SHIFT (0) 514 + #define PSB_2D_PATPAL_ADDR_CLRMASK (0xF0000007) 515 + #define PSB_2D_PATPAL_ADDR_MASK (0x0FFFFFF8) 516 + #define PSB_2D_PATPAL_BYTEALIGN (1024) 517 + 518 + /* 519 + * Rop3 Codes (2 LS bytes) 520 + */ 521 + 522 + #define PSB_2D_ROP3_SRCCOPY (0xCCCC) 523 + #define PSB_2D_ROP3_PATCOPY (0xF0F0) 524 + #define PSB_2D_ROP3_WHITENESS (0xFFFF) 525 + #define PSB_2D_ROP3_BLACKNESS (0x0000) 526 + #define PSB_2D_ROP3_SRC (0xCC) 527 + #define PSB_2D_ROP3_PAT (0xF0) 528 + #define PSB_2D_ROP3_DST (0xAA) 529 + 530 + /* 531 + * Sizes. 532 + */ 533 + 534 + #define PSB_SCENE_HW_COOKIE_SIZE 16 535 + #define PSB_TA_MEM_HW_COOKIE_SIZE 16 536 + 537 + /* 538 + * Scene stuff. 539 + */ 540 + 541 + #define PSB_NUM_HW_SCENES 2 542 + 543 + /* 544 + * Scheduler completion actions. 545 + */ 546 + 547 + #define PSB_RASTER_BLOCK 0 548 + #define PSB_RASTER 1 549 + #define PSB_RETURN 2 550 + #define PSB_TA 3 551 + 552 + /* Power management */ 553 + #define PSB_PUNIT_PORT 0x04 554 + #define PSB_OSPMBA 0x78 555 + #define PSB_APMBA 0x7a 556 + #define PSB_APM_CMD 0x0 557 + #define PSB_APM_STS 0x04 558 + #define PSB_PWRGT_VID_ENC_MASK 0x30 559 + #define PSB_PWRGT_VID_DEC_MASK 0xc 560 + #define PSB_PWRGT_GL3_MASK 0xc0 561 + 562 + #define PSB_PM_SSC 0x20 563 + #define PSB_PM_SSS 0x30 564 + #define PSB_PWRGT_DISPLAY_MASK 0xc /*on a different BA than video/gfx*/ 565 + #define MDFLD_PWRGT_DISPLAY_A_CNTR 0x0000000c 566 + #define MDFLD_PWRGT_DISPLAY_B_CNTR 0x0000c000 567 + #define MDFLD_PWRGT_DISPLAY_C_CNTR 0x00030000 568 + #define MDFLD_PWRGT_DISP_MIPI_CNTR 0x000c0000 569 + #define MDFLD_PWRGT_DISPLAY_CNTR (MDFLD_PWRGT_DISPLAY_A_CNTR | MDFLD_PWRGT_DISPLAY_B_CNTR | MDFLD_PWRGT_DISPLAY_C_CNTR | MDFLD_PWRGT_DISP_MIPI_CNTR) /* 0x000fc00c */ 570 + /* Display SSS register bits are different in A0 vs. B0 */ 571 + #define PSB_PWRGT_GFX_MASK 0x3 572 + #define MDFLD_PWRGT_DISPLAY_A_STS 0x000000c0 573 + #define MDFLD_PWRGT_DISPLAY_B_STS 0x00000300 574 + #define MDFLD_PWRGT_DISPLAY_C_STS 0x00000c00 575 + #define PSB_PWRGT_GFX_MASK_B0 0xc3 576 + #define MDFLD_PWRGT_DISPLAY_A_STS_B0 0x0000000c 577 + #define MDFLD_PWRGT_DISPLAY_B_STS_B0 0x0000c000 578 + #define MDFLD_PWRGT_DISPLAY_C_STS_B0 0x00030000 579 + #define MDFLD_PWRGT_DISP_MIPI_STS 0x000c0000 580 + #define MDFLD_PWRGT_DISPLAY_STS_A0 (MDFLD_PWRGT_DISPLAY_A_STS | MDFLD_PWRGT_DISPLAY_B_STS | MDFLD_PWRGT_DISPLAY_C_STS | MDFLD_PWRGT_DISP_MIPI_STS) /* 0x000fc00c */ 581 + #define MDFLD_PWRGT_DISPLAY_STS_B0 (MDFLD_PWRGT_DISPLAY_A_STS_B0 | MDFLD_PWRGT_DISPLAY_B_STS_B0 | MDFLD_PWRGT_DISPLAY_C_STS_B0 | MDFLD_PWRGT_DISP_MIPI_STS) /* 0x000fc00c */ 582 + #endif