mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2026-05-01 10:28:00 +02:00
radeon: add initial atombios modesetting and GEM -> TTM translation layer.
This is an initial import of the atom bios parser with modesetting support for r500 hw using atombios. It also includes a simple memory manager layer that translates a radeon GEM style interface onto TTM internally. So far this memory manager has only been used for pinned object allocation for the DDX to test modesetting.
This commit is contained in:
parent
31da9492a4
commit
df9871064e
41 changed files with 19166 additions and 352 deletions
|
|
@ -13,9 +13,9 @@ drm-objs := drm_auth.o drm_bufs.o drm_context.o drm_dma.o drm_drawable.o \
|
|||
drm_sysfs.o drm_pci.o drm_agpsupport.o drm_scatter.o \
|
||||
drm_memory_debug.o ati_pcigart.o drm_sman.o \
|
||||
drm_hashtab.o drm_memrange.o drm_object.o drm_compat.o \
|
||||
drm_fence.o drm_ttm.o drm_bo.o drm_bo_move.o drm_crtc.o \
|
||||
drm_edid.o drm_modes.o drm_bo_lock.o drm_regman.o \
|
||||
drm_vm_nopage_compat.o drm_crtc_helper.o drm_gem.o
|
||||
drm_fence.o drm_ttm.o drm_bo.o drm_bo_move.o drm_bo_lock.o \
|
||||
drm_crtc.o drm_edid.o drm_modes.o drm_crtc_helper.o \
|
||||
drm_regman.o drm_vm_nopage_compat.o drm_gem.o
|
||||
tdfx-objs := tdfx_drv.o
|
||||
r128-objs := r128_drv.o r128_cce.o r128_state.o r128_irq.o
|
||||
mga-objs := mga_drv.o mga_dma.o mga_state.o mga_warp.o mga_irq.o
|
||||
|
|
@ -40,15 +40,9 @@ nouveau-objs := nouveau_drv.o nouveau_state.o nouveau_fifo.o nouveau_mem.o \
|
|||
nv50_crtc.o nv50_cursor.o nv50_lut.o nv50_fb.o nv50_output.o nv50_sor.o nv50_dac.o nv50_connector.o nv50_i2c.o nv50_display.o \
|
||||
nv50_kms_wrapper.o \
|
||||
nv50_fbcon.o
|
||||
radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o r300_cmdbuf.o
|
||||
radeon_ms-objs := radeon_ms_drv.o radeon_ms_drm.o radeon_ms_family.o \
|
||||
radeon_ms_state.o radeon_ms_bo.o radeon_ms_irq.o \
|
||||
radeon_ms_bus.o radeon_ms_fence.o \
|
||||
radeon_ms_cp.o radeon_ms_cp_mc.o radeon_ms_i2c.o \
|
||||
radeon_ms_output.o radeon_ms_crtc.o radeon_ms_fb.o \
|
||||
radeon_ms_exec.o radeon_ms_gpu.o radeon_ms_dac.o \
|
||||
radeon_ms_properties.o radeon_ms_rom.o radeon_ms_combios.o \
|
||||
amd_legacy_cbuffer.o
|
||||
radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o r300_cmdbuf.o radeon_gem.o \
|
||||
radeon_buffer.o radeon_fence.o atom.o radeon_display.o radeon_atombios.o radeon_i2c.o radeon_connectors.o \
|
||||
atombios_crtc.o radeon_encoders.o radeon_fb.o radeon_combios.o
|
||||
sis-objs := sis_drv.o sis_mm.o
|
||||
ffb-objs := ffb_drv.o ffb_context.o
|
||||
savage-objs := savage_drv.o savage_bci.o savage_state.o
|
||||
|
|
|
|||
484
linux-core/ObjectID.h
Normal file
484
linux-core/ObjectID.h
Normal file
|
|
@ -0,0 +1,484 @@
|
|||
/*
|
||||
* Copyright 2006-2007 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
/* based on stg/asic_reg/drivers/inc/asic_reg/ObjectID.h ver 23 */
|
||||
|
||||
#ifndef _OBJECTID_H
|
||||
#define _OBJECTID_H
|
||||
|
||||
#if defined(_X86_)
|
||||
#pragma pack(1)
|
||||
#endif
|
||||
|
||||
/****************************************************/
|
||||
/* Graphics Object Type Definition */
|
||||
/****************************************************/
|
||||
#define GRAPH_OBJECT_TYPE_NONE 0x0
|
||||
#define GRAPH_OBJECT_TYPE_GPU 0x1
|
||||
#define GRAPH_OBJECT_TYPE_ENCODER 0x2
|
||||
#define GRAPH_OBJECT_TYPE_CONNECTOR 0x3
|
||||
#define GRAPH_OBJECT_TYPE_ROUTER 0x4
|
||||
/* deleted */
|
||||
|
||||
/****************************************************/
|
||||
/* Encoder Object ID Definition */
|
||||
/****************************************************/
|
||||
#define ENCODER_OBJECT_ID_NONE 0x00
|
||||
|
||||
/* Radeon Class Display Hardware */
|
||||
#define ENCODER_OBJECT_ID_INTERNAL_LVDS 0x01
|
||||
#define ENCODER_OBJECT_ID_INTERNAL_TMDS1 0x02
|
||||
#define ENCODER_OBJECT_ID_INTERNAL_TMDS2 0x03
|
||||
#define ENCODER_OBJECT_ID_INTERNAL_DAC1 0x04
|
||||
#define ENCODER_OBJECT_ID_INTERNAL_DAC2 0x05 /* TV/CV DAC */
|
||||
#define ENCODER_OBJECT_ID_INTERNAL_SDVOA 0x06
|
||||
#define ENCODER_OBJECT_ID_INTERNAL_SDVOB 0x07
|
||||
|
||||
/* External Third Party Encoders */
|
||||
#define ENCODER_OBJECT_ID_SI170B 0x08
|
||||
#define ENCODER_OBJECT_ID_CH7303 0x09
|
||||
#define ENCODER_OBJECT_ID_CH7301 0x0A
|
||||
#define ENCODER_OBJECT_ID_INTERNAL_DVO1 0x0B /* This belongs to Radeon Class Display Hardware */
|
||||
#define ENCODER_OBJECT_ID_EXTERNAL_SDVOA 0x0C
|
||||
#define ENCODER_OBJECT_ID_EXTERNAL_SDVOB 0x0D
|
||||
#define ENCODER_OBJECT_ID_TITFP513 0x0E
|
||||
#define ENCODER_OBJECT_ID_INTERNAL_LVTM1 0x0F /* not used for Radeon */
|
||||
#define ENCODER_OBJECT_ID_VT1623 0x10
|
||||
#define ENCODER_OBJECT_ID_HDMI_SI1930 0x11
|
||||
#define ENCODER_OBJECT_ID_HDMI_INTERNAL 0x12
|
||||
/* Kaleidoscope (KLDSCP) Class Display Hardware (internal) */
|
||||
#define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1 0x13
|
||||
#define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1 0x14
|
||||
#define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1 0x15
|
||||
#define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2 0x16 /* Shared with CV/TV and CRT */
|
||||
#define ENCODER_OBJECT_ID_SI178 0X17 /* External TMDS (dual link, no HDCP.) */
|
||||
#define ENCODER_OBJECT_ID_MVPU_FPGA 0x18 /* MVPU FPGA chip */
|
||||
#define ENCODER_OBJECT_ID_INTERNAL_DDI 0x19
|
||||
#define ENCODER_OBJECT_ID_VT1625 0x1A
|
||||
#define ENCODER_OBJECT_ID_HDMI_SI1932 0x1B
|
||||
#define ENCODER_OBJECT_ID_DP_AN9801 0x1C
|
||||
#define ENCODER_OBJECT_ID_DP_DP501 0x1D
|
||||
#define ENCODER_OBJECT_ID_INTERNAL_UNIPHY 0x1E
|
||||
#define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA 0x1F
|
||||
|
||||
/****************************************************/
|
||||
/* Connector Object ID Definition */
|
||||
/****************************************************/
|
||||
#define CONNECTOR_OBJECT_ID_NONE 0x00
|
||||
#define CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I 0x01
|
||||
#define CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I 0x02
|
||||
#define CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D 0x03
|
||||
#define CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D 0x04
|
||||
#define CONNECTOR_OBJECT_ID_VGA 0x05
|
||||
#define CONNECTOR_OBJECT_ID_COMPOSITE 0x06
|
||||
#define CONNECTOR_OBJECT_ID_SVIDEO 0x07
|
||||
#define CONNECTOR_OBJECT_ID_YPbPr 0x08
|
||||
#define CONNECTOR_OBJECT_ID_D_CONNECTOR 0x09
|
||||
#define CONNECTOR_OBJECT_ID_9PIN_DIN 0x0A /* Supports both CV & TV */
|
||||
#define CONNECTOR_OBJECT_ID_SCART 0x0B
|
||||
#define CONNECTOR_OBJECT_ID_HDMI_TYPE_A 0x0C
|
||||
#define CONNECTOR_OBJECT_ID_HDMI_TYPE_B 0x0D
|
||||
#define CONNECTOR_OBJECT_ID_LVDS 0x0E
|
||||
#define CONNECTOR_OBJECT_ID_7PIN_DIN 0x0F
|
||||
#define CONNECTOR_OBJECT_ID_PCIE_CONNECTOR 0x10
|
||||
#define CONNECTOR_OBJECT_ID_CROSSFIRE 0x11
|
||||
#define CONNECTOR_OBJECT_ID_HARDCODE_DVI 0x12
|
||||
#define CONNECTOR_OBJECT_ID_DISPLAYPORT 0x13
|
||||
|
||||
/* deleted */
|
||||
|
||||
/****************************************************/
|
||||
/* Router Object ID Definition */
|
||||
/****************************************************/
|
||||
#define ROUTER_OBJECT_ID_NONE 0x00
|
||||
#define ROUTER_OBJECT_ID_I2C_EXTENDER_CNTL 0x01
|
||||
|
||||
/****************************************************/
|
||||
// Graphics Object ENUM ID Definition */
|
||||
/****************************************************/
|
||||
#define GRAPH_OBJECT_ENUM_ID1 0x01
|
||||
#define GRAPH_OBJECT_ENUM_ID2 0x02
|
||||
#define GRAPH_OBJECT_ENUM_ID3 0x03
|
||||
#define GRAPH_OBJECT_ENUM_ID4 0x04
|
||||
|
||||
/****************************************************/
|
||||
/* Graphics Object ID Bit definition */
|
||||
/****************************************************/
|
||||
#define OBJECT_ID_MASK 0x00FF
|
||||
#define ENUM_ID_MASK 0x0700
|
||||
#define RESERVED1_ID_MASK 0x0800
|
||||
#define OBJECT_TYPE_MASK 0x7000
|
||||
#define RESERVED2_ID_MASK 0x8000
|
||||
|
||||
#define OBJECT_ID_SHIFT 0x00
|
||||
#define ENUM_ID_SHIFT 0x08
|
||||
#define OBJECT_TYPE_SHIFT 0x0C
|
||||
|
||||
|
||||
/****************************************************/
|
||||
/* Graphics Object family definition */
|
||||
/****************************************************/
|
||||
#define CONSTRUCTOBJECTFAMILYID(GRAPHICS_OBJECT_TYPE, GRAPHICS_OBJECT_ID) (GRAPHICS_OBJECT_TYPE << OBJECT_TYPE_SHIFT | \
|
||||
GRAPHICS_OBJECT_ID << OBJECT_ID_SHIFT)
|
||||
/****************************************************/
|
||||
/* GPU Object ID definition - Shared with BIOS */
|
||||
/****************************************************/
|
||||
#define GPU_ENUM_ID1 ( GRAPH_OBJECT_TYPE_GPU << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT)
|
||||
|
||||
/****************************************************/
|
||||
/* Encoder Object ID definition - Shared with BIOS */
|
||||
/****************************************************/
|
||||
/*
|
||||
#define ENCODER_INTERNAL_LVDS_ENUM_ID1 0x2101
|
||||
#define ENCODER_INTERNAL_TMDS1_ENUM_ID1 0x2102
|
||||
#define ENCODER_INTERNAL_TMDS2_ENUM_ID1 0x2103
|
||||
#define ENCODER_INTERNAL_DAC1_ENUM_ID1 0x2104
|
||||
#define ENCODER_INTERNAL_DAC2_ENUM_ID1 0x2105
|
||||
#define ENCODER_INTERNAL_SDVOA_ENUM_ID1 0x2106
|
||||
#define ENCODER_INTERNAL_SDVOB_ENUM_ID1 0x2107
|
||||
#define ENCODER_SIL170B_ENUM_ID1 0x2108
|
||||
#define ENCODER_CH7303_ENUM_ID1 0x2109
|
||||
#define ENCODER_CH7301_ENUM_ID1 0x210A
|
||||
#define ENCODER_INTERNAL_DVO1_ENUM_ID1 0x210B
|
||||
#define ENCODER_EXTERNAL_SDVOA_ENUM_ID1 0x210C
|
||||
#define ENCODER_EXTERNAL_SDVOB_ENUM_ID1 0x210D
|
||||
#define ENCODER_TITFP513_ENUM_ID1 0x210E
|
||||
#define ENCODER_INTERNAL_LVTM1_ENUM_ID1 0x210F
|
||||
#define ENCODER_VT1623_ENUM_ID1 0x2110
|
||||
#define ENCODER_HDMI_SI1930_ENUM_ID1 0x2111
|
||||
#define ENCODER_HDMI_INTERNAL_ENUM_ID1 0x2112
|
||||
#define ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID1 0x2113
|
||||
#define ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1 0x2114
|
||||
#define ENCODER_INTERNAL_KLDSCP_DAC1_ENUM_ID1 0x2115
|
||||
#define ENCODER_INTERNAL_KLDSCP_DAC2_ENUM_ID1 0x2116
|
||||
#define ENCODER_SI178_ENUM_ID1 0x2117
|
||||
#define ENCODER_MVPU_FPGA_ENUM_ID1 0x2118
|
||||
#define ENCODER_INTERNAL_DDI_ENUM_ID1 0x2119
|
||||
#define ENCODER_VT1625_ENUM_ID1 0x211A
|
||||
#define ENCODER_HDMI_SI1932_ENUM_ID1 0x211B
|
||||
#define ENCODER_ENCODER_DP_AN9801_ENUM_ID1 0x211C
|
||||
#define ENCODER_DP_DP501_ENUM_ID1 0x211D
|
||||
#define ENCODER_INTERNAL_UNIPHY_ENUM_ID1 0x211E
|
||||
*/
|
||||
#define ENCODER_INTERNAL_LVDS_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_INTERNAL_LVDS << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_INTERNAL_TMDS1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_INTERNAL_TMDS1 << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_INTERNAL_TMDS2_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_INTERNAL_TMDS2 << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_INTERNAL_DAC1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_INTERNAL_DAC1 << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_INTERNAL_DAC2_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_INTERNAL_DAC2 << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_INTERNAL_SDVOA_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_INTERNAL_SDVOA << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_INTERNAL_SDVOA_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_INTERNAL_SDVOA << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_INTERNAL_SDVOB_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_INTERNAL_SDVOB << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_SIL170B_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_SI170B << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_CH7303_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_CH7303 << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_CH7301_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_CH7301 << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_INTERNAL_DVO1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_INTERNAL_DVO1 << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_EXTERNAL_SDVOA_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_EXTERNAL_SDVOA << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_EXTERNAL_SDVOA_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_EXTERNAL_SDVOA << OBJECT_ID_SHIFT)
|
||||
|
||||
|
||||
#define ENCODER_EXTERNAL_SDVOB_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_EXTERNAL_SDVOB << OBJECT_ID_SHIFT)
|
||||
|
||||
|
||||
#define ENCODER_TITFP513_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_TITFP513 << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_INTERNAL_LVTM1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_INTERNAL_LVTM1 << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_VT1623_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_VT1623 << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_HDMI_SI1930_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_HDMI_SI1930 << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_HDMI_INTERNAL_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_HDMI_INTERNAL << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1 << OBJECT_ID_SHIFT)
|
||||
|
||||
|
||||
#define ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1 << OBJECT_ID_SHIFT)
|
||||
|
||||
|
||||
#define ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1 << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_INTERNAL_KLDSCP_DAC1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1 << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_INTERNAL_KLDSCP_DAC2_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2 << OBJECT_ID_SHIFT) // Shared with CV/TV and CRT
|
||||
|
||||
#define ENCODER_SI178_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_SI178 << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_MVPU_FPGA_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_MVPU_FPGA << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_INTERNAL_DDI_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_INTERNAL_DDI << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_VT1625_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_VT1625 << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_HDMI_SI1932_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_HDMI_SI1932 << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_DP_DP501_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_DP_DP501 << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_DP_AN9801_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_DP_AN9801 << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_INTERNAL_UNIPHY_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_INTERNAL_UNIPHY << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_INTERNAL_UNIPHY_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_INTERNAL_UNIPHY << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_INTERNAL_KLDSCP_LVTMA_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA << OBJECT_ID_SHIFT)
|
||||
|
||||
/****************************************************/
|
||||
/* Connector Object ID definition - Shared with BIOS */
|
||||
/****************************************************/
|
||||
/*
|
||||
#define CONNECTOR_SINGLE_LINK_DVI_I_ENUM_ID1 0x3101
|
||||
#define CONNECTOR_DUAL_LINK_DVI_I_ENUM_ID1 0x3102
|
||||
#define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID1 0x3103
|
||||
#define CONNECTOR_DUAL_LINK_DVI_D_ENUM_ID1 0x3104
|
||||
#define CONNECTOR_VGA_ENUM_ID1 0x3105
|
||||
#define CONNECTOR_COMPOSITE_ENUM_ID1 0x3106
|
||||
#define CONNECTOR_SVIDEO_ENUM_ID1 0x3107
|
||||
#define CONNECTOR_YPbPr_ENUM_ID1 0x3108
|
||||
#define CONNECTOR_D_CONNECTORE_ENUM_ID1 0x3109
|
||||
#define CONNECTOR_9PIN_DIN_ENUM_ID1 0x310A
|
||||
#define CONNECTOR_SCART_ENUM_ID1 0x310B
|
||||
#define CONNECTOR_HDMI_TYPE_A_ENUM_ID1 0x310C
|
||||
#define CONNECTOR_HDMI_TYPE_B_ENUM_ID1 0x310D
|
||||
#define CONNECTOR_LVDS_ENUM_ID1 0x310E
|
||||
#define CONNECTOR_7PIN_DIN_ENUM_ID1 0x310F
|
||||
#define CONNECTOR_PCIE_CONNECTOR_ENUM_ID1 0x3110
|
||||
*/
|
||||
#define CONNECTOR_LVDS_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_LVDS << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_SINGLE_LINK_DVI_I_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_SINGLE_LINK_DVI_I_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_DUAL_LINK_DVI_I_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_DUAL_LINK_DVI_I_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_DUAL_LINK_DVI_D_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_VGA_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_VGA << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_VGA_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_VGA << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_COMPOSITE_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_COMPOSITE << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_SVIDEO_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_SVIDEO << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_YPbPr_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_YPbPr << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_D_CONNECTOR_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_D_CONNECTOR << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_9PIN_DIN_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_9PIN_DIN << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_SCART_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_SCART << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_HDMI_TYPE_A_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_HDMI_TYPE_A << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_HDMI_TYPE_B_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_HDMI_TYPE_B << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_7PIN_DIN_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_7PIN_DIN << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_PCIE_CONNECTOR_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_PCIE_CONNECTOR << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_PCIE_CONNECTOR_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_PCIE_CONNECTOR << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_CROSSFIRE_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_CROSSFIRE << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_CROSSFIRE_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_CROSSFIRE << OBJECT_ID_SHIFT)
|
||||
|
||||
|
||||
#define CONNECTOR_HARDCODE_DVI_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_HARDCODE_DVI << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_HARDCODE_DVI_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_HARDCODE_DVI << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_DISPLAYPORT_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_DISPLAYPORT_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT)
|
||||
|
||||
/****************************************************/
|
||||
/* Router Object ID definition - Shared with BIOS */
|
||||
/****************************************************/
|
||||
#define ROUTER_I2C_EXTENDER_CNTL_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ROUTER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ROUTER_OBJECT_ID_I2C_EXTENDER_CNTL << OBJECT_ID_SHIFT)
|
||||
|
||||
/* deleted */
|
||||
|
||||
/****************************************************/
|
||||
/* Object Cap definition - Shared with BIOS */
|
||||
/****************************************************/
|
||||
#define GRAPHICS_OBJECT_CAP_I2C 0x00000001L
|
||||
#define GRAPHICS_OBJECT_CAP_TABLE_ID 0x00000002L
|
||||
|
||||
|
||||
#define GRAPHICS_OBJECT_I2CCOMMAND_TABLE_ID 0x01
|
||||
#define GRAPHICS_OBJECT_HOTPLUGDETECTIONINTERUPT_TABLE_ID 0x02
|
||||
#define GRAPHICS_OBJECT_ENCODER_OUTPUT_PROTECTION_TABLE_ID 0x03
|
||||
|
||||
#if defined(_X86_)
|
||||
#pragma pack()
|
||||
#endif
|
||||
|
||||
#endif /*GRAPHICTYPE */
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -39,8 +39,50 @@
|
|||
#define ATI_PCIE_WRITE 0x4
|
||||
#define ATI_PCIE_READ 0x8
|
||||
|
||||
static int drm_ati_alloc_pcigart_table(struct drm_device *dev,
|
||||
struct drm_ati_pcigart_info *gart_info)
|
||||
static __inline__ void gart_insert_page_into_table(struct drm_ati_pcigart_info *gart_info, dma_addr_t addr, u32 *pci_gart)
|
||||
{
|
||||
u32 page_base;
|
||||
|
||||
page_base = (u32)addr & ATI_PCIGART_PAGE_MASK;
|
||||
switch(gart_info->gart_reg_if) {
|
||||
case DRM_ATI_GART_IGP:
|
||||
page_base |= (upper_32_bits(addr) & 0xff) << 4;
|
||||
page_base |= 0xc;
|
||||
break;
|
||||
case DRM_ATI_GART_PCIE:
|
||||
page_base >>= 8;
|
||||
page_base |= (upper_32_bits(addr) & 0xff) << 24;
|
||||
page_base |= ATI_PCIE_READ | ATI_PCIE_WRITE;
|
||||
break;
|
||||
default:
|
||||
case DRM_ATI_GART_PCI:
|
||||
break;
|
||||
}
|
||||
*pci_gart = cpu_to_le32(page_base);
|
||||
}
|
||||
|
||||
static __inline__ dma_addr_t gart_get_page_from_table(struct drm_ati_pcigart_info *gart_info, u32 *pci_gart)
|
||||
{
|
||||
dma_addr_t retval;
|
||||
switch(gart_info->gart_reg_if) {
|
||||
case DRM_ATI_GART_IGP:
|
||||
retval = (*pci_gart & ATI_PCIGART_PAGE_MASK);
|
||||
retval += (((*pci_gart & 0xf0) >> 4) << 16) << 16;
|
||||
break;
|
||||
case DRM_ATI_GART_PCIE:
|
||||
retval = (*pci_gart & ~0xc);
|
||||
retval <<= 8;
|
||||
break;
|
||||
case DRM_ATI_GART_PCI:
|
||||
retval = *pci_gart;
|
||||
break;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int drm_ati_alloc_pcigart_table(struct drm_device *dev,
|
||||
struct drm_ati_pcigart_info *gart_info)
|
||||
{
|
||||
gart_info->table_handle = drm_pci_alloc(dev, gart_info->table_size,
|
||||
PAGE_SIZE,
|
||||
|
|
@ -48,8 +90,10 @@ static int drm_ati_alloc_pcigart_table(struct drm_device *dev,
|
|||
if (gart_info->table_handle == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(gart_info->table_handle, 0, gart_info->table_size);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_ati_alloc_pcigart_table);
|
||||
|
||||
static void drm_ati_free_pcigart_table(struct drm_device *dev,
|
||||
struct drm_ati_pcigart_info *gart_info)
|
||||
|
|
@ -80,7 +124,7 @@ int drm_ati_pcigart_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info
|
|||
for (i = 0; i < pages; i++) {
|
||||
if (!entry->busaddr[i])
|
||||
break;
|
||||
pci_unmap_single(dev->pdev, entry->busaddr[i],
|
||||
pci_unmap_page(dev->pdev, entry->busaddr[i],
|
||||
PAGE_SIZE, PCI_DMA_TODEVICE);
|
||||
}
|
||||
|
||||
|
|
@ -104,18 +148,14 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga
|
|||
struct drm_sg_mem *entry = dev->sg;
|
||||
void *address = NULL;
|
||||
unsigned long pages;
|
||||
u32 *pci_gart, page_base;
|
||||
u32 *pci_gart;
|
||||
dma_addr_t bus_address = 0;
|
||||
int i, j, ret = 0;
|
||||
int max_pages;
|
||||
dma_addr_t entry_addr;
|
||||
|
||||
if (!entry) {
|
||||
DRM_ERROR("no scatter/gather memory!\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) {
|
||||
if (gart_info->gart_table_location == DRM_ATI_GART_MAIN && gart_info->table_handle == NULL) {
|
||||
DRM_DEBUG("PCI: no table in VRAM: using normal RAM\n");
|
||||
|
||||
ret = drm_ati_alloc_pcigart_table(dev, gart_info);
|
||||
|
|
@ -123,14 +163,19 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga
|
|||
DRM_ERROR("cannot allocate PCI GART page!\n");
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) {
|
||||
address = gart_info->table_handle->vaddr;
|
||||
bus_address = gart_info->table_handle->busaddr;
|
||||
} else {
|
||||
address = gart_info->addr;
|
||||
bus_address = gart_info->bus_addr;
|
||||
DRM_DEBUG("PCI: Gart Table: VRAM %08X mapped at %08lX\n",
|
||||
bus_address, (unsigned long)address);
|
||||
}
|
||||
|
||||
if (!entry) {
|
||||
DRM_ERROR("no scatter/gather memory!\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
pci_gart = (u32 *) address;
|
||||
|
|
@ -139,14 +184,10 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga
|
|||
pages = (entry->pages <= max_pages)
|
||||
? entry->pages : max_pages;
|
||||
|
||||
memset(pci_gart, 0, max_pages * sizeof(u32));
|
||||
|
||||
for (i = 0; i < pages; i++) {
|
||||
/* we need to support large memory configurations */
|
||||
entry->busaddr[i] = pci_map_single(dev->pdev,
|
||||
page_address(entry->
|
||||
pagelist[i]),
|
||||
PAGE_SIZE, PCI_DMA_TODEVICE);
|
||||
entry->busaddr[i] = pci_map_page(dev->pdev, entry->pagelist[i],
|
||||
0, PAGE_SIZE, PCI_DMA_TODEVICE);
|
||||
if (entry->busaddr[i] == 0) {
|
||||
DRM_ERROR("unable to map PCIGART pages!\n");
|
||||
drm_ati_pcigart_cleanup(dev, gart_info);
|
||||
|
|
@ -157,22 +198,7 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga
|
|||
|
||||
entry_addr = entry->busaddr[i];
|
||||
for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) {
|
||||
page_base = (u32) entry_addr & ATI_PCIGART_PAGE_MASK;
|
||||
switch(gart_info->gart_reg_if) {
|
||||
case DRM_ATI_GART_IGP:
|
||||
page_base |= (upper_32_bits(entry_addr) & 0xff) << 4;
|
||||
page_base |= 0xc;
|
||||
break;
|
||||
case DRM_ATI_GART_PCIE:
|
||||
page_base >>= 8;
|
||||
page_base |= (upper_32_bits(entry_addr) & 0xff) << 24;
|
||||
page_base |= ATI_PCIE_READ | ATI_PCIE_WRITE;
|
||||
break;
|
||||
default:
|
||||
case DRM_ATI_GART_PCI:
|
||||
break;
|
||||
}
|
||||
*pci_gart = cpu_to_le32(page_base);
|
||||
gart_insert_page_into_table(gart_info, entry_addr, pci_gart);
|
||||
pci_gart++;
|
||||
entry_addr += ATI_PCIGART_PAGE_SIZE;
|
||||
}
|
||||
|
|
@ -192,3 +218,145 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga
|
|||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_ati_pcigart_init);
|
||||
|
||||
static int ati_pcigart_needs_unbind_cache_adjust(struct drm_ttm_backend *backend)
|
||||
{
|
||||
return ((backend->flags & DRM_BE_FLAG_BOUND_CACHED) ? 0 : 1);
|
||||
}
|
||||
|
||||
static int ati_pcigart_populate(struct drm_ttm_backend *backend,
|
||||
unsigned long num_pages,
|
||||
struct page **pages,
|
||||
struct page *dummy_read_page)
|
||||
{
|
||||
struct ati_pcigart_ttm_backend *atipci_be =
|
||||
container_of(backend, struct ati_pcigart_ttm_backend, backend);
|
||||
|
||||
atipci_be->pages = pages;
|
||||
atipci_be->num_pages = num_pages;
|
||||
atipci_be->populated = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ati_pcigart_bind_ttm(struct drm_ttm_backend *backend,
|
||||
struct drm_bo_mem_reg *bo_mem)
|
||||
{
|
||||
struct ati_pcigart_ttm_backend *atipci_be =
|
||||
container_of(backend, struct ati_pcigart_ttm_backend, backend);
|
||||
off_t j;
|
||||
int i;
|
||||
struct drm_ati_pcigart_info *info = atipci_be->gart_info;
|
||||
u32 *pci_gart;
|
||||
dma_addr_t offset = bo_mem->mm_node->start;
|
||||
dma_addr_t page_base;
|
||||
|
||||
pci_gart = info->addr;
|
||||
|
||||
j = offset;
|
||||
while (j < (offset + atipci_be->num_pages)) {
|
||||
if (gart_get_page_from_table(info, pci_gart+j))
|
||||
return -EBUSY;
|
||||
j++;
|
||||
}
|
||||
|
||||
for (i = 0, j = offset; i < atipci_be->num_pages; i++, j++) {
|
||||
struct page *cur_page = atipci_be->pages[i];
|
||||
/* write value */
|
||||
page_base = page_to_phys(cur_page);
|
||||
gart_insert_page_into_table(info, page_base, pci_gart + j);
|
||||
}
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
wbinvd();
|
||||
#else
|
||||
mb();
|
||||
#endif
|
||||
|
||||
atipci_be->gart_flush_fn(atipci_be->dev);
|
||||
|
||||
atipci_be->bound = 1;
|
||||
atipci_be->offset = offset;
|
||||
/* need to traverse table and add entries */
|
||||
DRM_DEBUG("\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ati_pcigart_unbind_ttm(struct drm_ttm_backend *backend)
|
||||
{
|
||||
struct ati_pcigart_ttm_backend *atipci_be =
|
||||
container_of(backend, struct ati_pcigart_ttm_backend, backend);
|
||||
struct drm_ati_pcigart_info *info = atipci_be->gart_info;
|
||||
unsigned long offset = atipci_be->offset;
|
||||
int i;
|
||||
off_t j;
|
||||
u32 *pci_gart = info->addr;
|
||||
|
||||
if (atipci_be->bound != 1)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0, j = offset; i < atipci_be->num_pages; i++, j++) {
|
||||
*(pci_gart + j) = 0;
|
||||
}
|
||||
atipci_be->gart_flush_fn(atipci_be->dev);
|
||||
atipci_be->bound = 0;
|
||||
atipci_be->offset = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ati_pcigart_clear_ttm(struct drm_ttm_backend *backend)
|
||||
{
|
||||
struct ati_pcigart_ttm_backend *atipci_be =
|
||||
container_of(backend, struct ati_pcigart_ttm_backend, backend);
|
||||
|
||||
DRM_DEBUG("\n");
|
||||
if (atipci_be->pages) {
|
||||
backend->func->unbind(backend);
|
||||
atipci_be->pages = NULL;
|
||||
|
||||
}
|
||||
atipci_be->num_pages = 0;
|
||||
}
|
||||
|
||||
static void ati_pcigart_destroy_ttm(struct drm_ttm_backend *backend)
|
||||
{
|
||||
struct ati_pcigart_ttm_backend *atipci_be;
|
||||
if (backend) {
|
||||
DRM_DEBUG("\n");
|
||||
atipci_be = container_of(backend, struct ati_pcigart_ttm_backend, backend);
|
||||
if (atipci_be) {
|
||||
if (atipci_be->pages) {
|
||||
backend->func->clear(backend);
|
||||
}
|
||||
drm_ctl_free(atipci_be, sizeof(*atipci_be), DRM_MEM_TTM);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static struct drm_ttm_backend_func ati_pcigart_ttm_backend =
|
||||
{
|
||||
.needs_ub_cache_adjust = ati_pcigart_needs_unbind_cache_adjust,
|
||||
.populate = ati_pcigart_populate,
|
||||
.clear = ati_pcigart_clear_ttm,
|
||||
.bind = ati_pcigart_bind_ttm,
|
||||
.unbind = ati_pcigart_unbind_ttm,
|
||||
.destroy = ati_pcigart_destroy_ttm,
|
||||
};
|
||||
|
||||
struct drm_ttm_backend *ati_pcigart_init_ttm(struct drm_device *dev, struct drm_ati_pcigart_info *info, void (*gart_flush_fn)(struct drm_device *dev))
|
||||
{
|
||||
struct ati_pcigart_ttm_backend *atipci_be;
|
||||
|
||||
atipci_be = drm_ctl_calloc(1, sizeof (*atipci_be), DRM_MEM_TTM);
|
||||
if (!atipci_be)
|
||||
return NULL;
|
||||
|
||||
atipci_be->populated = 0;
|
||||
atipci_be->backend.func = &ati_pcigart_ttm_backend;
|
||||
// atipci_be->backend.mem_type = DRM_BO_MEM_TT;
|
||||
atipci_be->gart_info = info;
|
||||
atipci_be->gart_flush_fn = gart_flush_fn;
|
||||
atipci_be->dev = dev;
|
||||
|
||||
return &atipci_be->backend;
|
||||
}
|
||||
EXPORT_SYMBOL(ati_pcigart_init_ttm);
|
||||
|
|
|
|||
48
linux-core/atom-bits.h
Normal file
48
linux-core/atom-bits.h
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright 2008 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Author: Stanislaw Skowronek
|
||||
*/
|
||||
|
||||
#ifndef ATOM_BITS_H
|
||||
#define ATOM_BITS_H
|
||||
|
||||
static inline uint8_t get_u8(void *bios, int ptr)
|
||||
{
|
||||
return ((unsigned char *)bios)[ptr];
|
||||
}
|
||||
#define U8(ptr) get_u8(ctx->ctx->bios,(ptr))
|
||||
#define CU8(ptr) get_u8(ctx->bios,(ptr))
|
||||
static inline uint16_t get_u16(void *bios, int ptr)
|
||||
{
|
||||
return get_u8(bios,ptr)|(((uint16_t)get_u8(bios,ptr+1))<<8);
|
||||
}
|
||||
#define U16(ptr) get_u16(ctx->ctx->bios,(ptr))
|
||||
#define CU16(ptr) get_u16(ctx->bios,(ptr))
|
||||
static inline uint32_t get_u32(void *bios, int ptr)
|
||||
{
|
||||
return get_u16(bios,ptr)|(((uint32_t)get_u16(bios,ptr+2))<<16);
|
||||
}
|
||||
#define U32(ptr) get_u32(ctx->ctx->bios,(ptr))
|
||||
#define CU32(ptr) get_u32(ctx->bios,(ptr))
|
||||
#define CSTR(ptr) (((char *)(ctx->bios))+(ptr))
|
||||
|
||||
#endif
|
||||
100
linux-core/atom-names.h
Normal file
100
linux-core/atom-names.h
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* Copyright 2008 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Author: Stanislaw Skowronek
|
||||
*/
|
||||
|
||||
#ifndef ATOM_NAMES_H
|
||||
#define ATOM_NAMES_H
|
||||
|
||||
#include "atom.h"
|
||||
|
||||
#ifdef ATOM_DEBUG
|
||||
|
||||
#define ATOM_OP_NAMES_CNT 123
|
||||
static char *atom_op_names[ATOM_OP_NAMES_CNT]={
|
||||
"RESERVED", "MOVE_REG", "MOVE_PS", "MOVE_WS", "MOVE_FB", "MOVE_PLL",
|
||||
"MOVE_MC", "AND_REG", "AND_PS", "AND_WS", "AND_FB", "AND_PLL", "AND_MC",
|
||||
"OR_REG", "OR_PS", "OR_WS", "OR_FB", "OR_PLL", "OR_MC", "SHIFT_LEFT_REG",
|
||||
"SHIFT_LEFT_PS", "SHIFT_LEFT_WS", "SHIFT_LEFT_FB", "SHIFT_LEFT_PLL",
|
||||
"SHIFT_LEFT_MC", "SHIFT_RIGHT_REG", "SHIFT_RIGHT_PS", "SHIFT_RIGHT_WS",
|
||||
"SHIFT_RIGHT_FB", "SHIFT_RIGHT_PLL", "SHIFT_RIGHT_MC", "MUL_REG",
|
||||
"MUL_PS", "MUL_WS", "MUL_FB", "MUL_PLL", "MUL_MC", "DIV_REG", "DIV_PS",
|
||||
"DIV_WS", "DIV_FB", "DIV_PLL", "DIV_MC", "ADD_REG", "ADD_PS", "ADD_WS",
|
||||
"ADD_FB", "ADD_PLL", "ADD_MC", "SUB_REG", "SUB_PS", "SUB_WS", "SUB_FB",
|
||||
"SUB_PLL", "SUB_MC", "SET_ATI_PORT", "SET_PCI_PORT", "SET_SYS_IO_PORT",
|
||||
"SET_REG_BLOCK", "SET_FB_BASE", "COMPARE_REG", "COMPARE_PS",
|
||||
"COMPARE_WS", "COMPARE_FB", "COMPARE_PLL", "COMPARE_MC", "SWITCH",
|
||||
"JUMP", "JUMP_EQUAL", "JUMP_BELOW", "JUMP_ABOVE", "JUMP_BELOW_OR_EQUAL",
|
||||
"JUMP_ABOVE_OR_EQUAL", "JUMP_NOT_EQUAL", "TEST_REG", "TEST_PS", "TEST_WS",
|
||||
"TEST_FB", "TEST_PLL", "TEST_MC", "DELAY_MILLISEC", "DELAY_MICROSEC",
|
||||
"CALL_TABLE", "REPEAT", "CLEAR_REG", "CLEAR_PS", "CLEAR_WS", "CLEAR_FB",
|
||||
"CLEAR_PLL", "CLEAR_MC", "NOP", "EOT", "MASK_REG", "MASK_PS", "MASK_WS",
|
||||
"MASK_FB", "MASK_PLL", "MASK_MC", "POST_CARD", "BEEP", "SAVE_REG",
|
||||
"RESTORE_REG", "SET_DATA_BLOCK", "XOR_REG", "XOR_PS", "XOR_WS", "XOR_FB",
|
||||
"XOR_PLL", "XOR_MC", "SHL_REG", "SHL_PS", "SHL_WS", "SHL_FB", "SHL_PLL",
|
||||
"SHL_MC", "SHR_REG", "SHR_PS", "SHR_WS", "SHR_FB", "SHR_PLL", "SHR_MC",
|
||||
"DEBUG", "CTB_DS",
|
||||
};
|
||||
|
||||
#define ATOM_TABLE_NAMES_CNT 74
|
||||
static char *atom_table_names[ATOM_TABLE_NAMES_CNT]={
|
||||
"ASIC_Init", "GetDisplaySurfaceSize", "ASIC_RegistersInit",
|
||||
"VRAM_BlockVenderDetection", "SetClocksRatio", "MemoryControllerInit",
|
||||
"GPIO_PinInit", "MemoryParamAdjust", "DVOEncoderControl",
|
||||
"GPIOPinControl", "SetEngineClock", "SetMemoryClock", "SetPixelClock",
|
||||
"DynamicClockGating", "ResetMemoryDLL", "ResetMemoryDevice",
|
||||
"MemoryPLLInit", "EnableMemorySelfRefresh", "AdjustMemoryController",
|
||||
"EnableASIC_StaticPwrMgt", "ASIC_StaticPwrMgtStatusChange",
|
||||
"DAC_LoadDetection", "TMDS2EncoderControl", "LCD1OutputControl",
|
||||
"DAC1EncoderControl", "DAC2EncoderControl", "DVOOutputControl",
|
||||
"CV1OutputControl", "SetCRTC_DPM_State", "TVEncoderControl",
|
||||
"TMDS1EncoderControl", "LVDSEncoderControl", "TV1OutputControl",
|
||||
"EnableScaler", "BlankCRTC", "EnableCRTC", "GetPixelClock",
|
||||
"EnableVGA_Render", "EnableVGA_Access", "SetCRTC_Timing",
|
||||
"SetCRTC_OverScan", "SetCRTC_Replication", "SelectCRTC_Source",
|
||||
"EnableGraphSurfaces", "UpdateCRTC_DoubleBufferRegisters",
|
||||
"LUT_AutoFill", "EnableHW_IconCursor", "GetMemoryClock",
|
||||
"GetEngineClock", "SetCRTC_UsingDTDTiming", "TVBootUpStdPinDetection",
|
||||
"DFP2OutputControl", "VRAM_BlockDetectionByStrap", "MemoryCleanUp",
|
||||
"ReadEDIDFromHWAssistedI2C", "WriteOneByteToHWAssistedI2C",
|
||||
"ReadHWAssistedI2CStatus", "SpeedFanControl", "PowerConnectorDetection",
|
||||
"MC_Synchronization", "ComputeMemoryEnginePLL", "MemoryRefreshConversion",
|
||||
"VRAM_GetCurrentInfoBlock", "DynamicMemorySettings", "MemoryTraining",
|
||||
"EnableLVDS_SS", "DFP1OutputControl", "SetVoltage", "CRT1OutputControl",
|
||||
"CRT2OutputControl", "SetupHWAssistedI2CStatus", "ClockSource",
|
||||
"MemoryDeviceInit", "EnableYUV",
|
||||
};
|
||||
|
||||
#define ATOM_IO_NAMES_CNT 5
|
||||
static char *atom_io_names[ATOM_IO_NAMES_CNT]={
|
||||
"MM", "PLL", "MC", "PCIE", "PCIE PORT",
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
#define ATOM_OP_NAMES_CNT 0
|
||||
#define ATOM_TABLE_NAMES_CNT 0
|
||||
#define ATOM_IO_NAMES_CNT 0
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
42
linux-core/atom-types.h
Normal file
42
linux-core/atom-types.h
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright 2008 Red Hat Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Author: Dave Airlie
|
||||
*/
|
||||
|
||||
#ifndef ATOM_TYPES_H
|
||||
#define ATOM_TYPES_H
|
||||
|
||||
/* sync atom types to kernel types */
|
||||
|
||||
typedef uint16_t USHORT;
|
||||
typedef uint32_t ULONG;
|
||||
typedef uint8_t UCHAR;
|
||||
|
||||
|
||||
#ifndef ATOM_BIG_ENDIAN
|
||||
#if defined(__BIG_ENDIAN)
|
||||
#define ATOM_BIG_ENDIAN 1
|
||||
#else
|
||||
#define ATOM_BIG_ENDIAN 0
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
1145
linux-core/atom.c
Normal file
1145
linux-core/atom.c
Normal file
File diff suppressed because it is too large
Load diff
148
linux-core/atom.h
Normal file
148
linux-core/atom.h
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* Copyright 2008 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Author: Stanislaw Skowronek
|
||||
*/
|
||||
|
||||
#ifndef ATOM_H
|
||||
#define ATOM_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include "drmP.h"
|
||||
|
||||
#define ATOM_BIOS_MAGIC 0xAA55
|
||||
#define ATOM_ATI_MAGIC_PTR 0x30
|
||||
#define ATOM_ATI_MAGIC " 761295520"
|
||||
#define ATOM_ROM_TABLE_PTR 0x48
|
||||
|
||||
#define ATOM_ROM_MAGIC "ATOM"
|
||||
#define ATOM_ROM_MAGIC_PTR 4
|
||||
|
||||
#define ATOM_ROM_MSG_PTR 0x10
|
||||
#define ATOM_ROM_CMD_PTR 0x1E
|
||||
#define ATOM_ROM_DATA_PTR 0x20
|
||||
|
||||
#define ATOM_CMD_INIT 0
|
||||
#define ATOM_CMD_SETSCLK 0x0A
|
||||
#define ATOM_CMD_SETMCLK 0x0B
|
||||
#define ATOM_CMD_SETPCLK 0x0C
|
||||
|
||||
#define ATOM_DATA_FWI_PTR 0xC
|
||||
#define ATOM_DATA_IIO_PTR 0x32
|
||||
|
||||
#define ATOM_FWI_DEFSCLK_PTR 8
|
||||
#define ATOM_FWI_DEFMCLK_PTR 0xC
|
||||
#define ATOM_FWI_MAXSCLK_PTR 0x24
|
||||
#define ATOM_FWI_MAXMCLK_PTR 0x28
|
||||
|
||||
#define ATOM_CT_SIZE_PTR 0
|
||||
#define ATOM_CT_WS_PTR 4
|
||||
#define ATOM_CT_PS_PTR 5
|
||||
#define ATOM_CT_PS_MASK 0x7F
|
||||
#define ATOM_CT_CODE_PTR 6
|
||||
|
||||
#define ATOM_OP_CNT 123
|
||||
#define ATOM_OP_EOT 91
|
||||
|
||||
#define ATOM_CASE_MAGIC 0x63
|
||||
#define ATOM_CASE_END 0x5A5A
|
||||
|
||||
#define ATOM_ARG_REG 0
|
||||
#define ATOM_ARG_PS 1
|
||||
#define ATOM_ARG_WS 2
|
||||
#define ATOM_ARG_ID 4
|
||||
#define ATOM_ARG_FB 3
|
||||
#define ATOM_ARG_IMM 5
|
||||
#define ATOM_ARG_PLL 6
|
||||
#define ATOM_ARG_MC 7
|
||||
|
||||
#define ATOM_SRC_DWORD 0
|
||||
#define ATOM_SRC_WORD0 1
|
||||
#define ATOM_SRC_WORD8 2
|
||||
#define ATOM_SRC_WORD16 3
|
||||
#define ATOM_SRC_BYTE0 4
|
||||
#define ATOM_SRC_BYTE8 5
|
||||
#define ATOM_SRC_BYTE16 6
|
||||
#define ATOM_SRC_BYTE24 7
|
||||
|
||||
#define ATOM_WS_QUOTIENT 0x40
|
||||
#define ATOM_WS_REMAINDER 0x41
|
||||
#define ATOM_WS_DATAPTR 0x42
|
||||
#define ATOM_WS_SHIFT 0x43
|
||||
#define ATOM_WS_OR_MASK 0x44
|
||||
#define ATOM_WS_AND_MASK 0x45
|
||||
#define ATOM_WS_FB_WINDOW 0x46
|
||||
#define ATOM_WS_ATTRIBUTES 0x47
|
||||
|
||||
#define ATOM_IIO_NOP 0
|
||||
#define ATOM_IIO_START 1
|
||||
#define ATOM_IIO_READ 2
|
||||
#define ATOM_IIO_WRITE 3
|
||||
#define ATOM_IIO_CLEAR 4
|
||||
#define ATOM_IIO_SET 5
|
||||
#define ATOM_IIO_MOVE_INDEX 6
|
||||
#define ATOM_IIO_MOVE_ATTR 7
|
||||
#define ATOM_IIO_MOVE_DATA 8
|
||||
#define ATOM_IIO_END 9
|
||||
|
||||
#define ATOM_IO_MM 0
|
||||
#define ATOM_IO_PCI 1
|
||||
#define ATOM_IO_SYSIO 2
|
||||
#define ATOM_IO_IIO 0x80
|
||||
|
||||
struct card_info {
|
||||
struct drm_device *dev;
|
||||
void (* reg_write)(struct card_info *, uint32_t, uint32_t); // filled by driver
|
||||
uint32_t (* reg_read)(struct card_info *, uint32_t); // filled by driver
|
||||
void (* mc_write)(struct card_info *, uint32_t, uint32_t); // filled by driver
|
||||
uint32_t (* mc_read)(struct card_info *, uint32_t); // filled by driver
|
||||
// int (* read_rom)(struct card_info *, uint8_t *); // filled by driver
|
||||
};
|
||||
|
||||
struct atom_context {
|
||||
struct card_info *card;
|
||||
void *bios;
|
||||
uint32_t cmd_table, data_table;
|
||||
uint16_t *iio;
|
||||
|
||||
uint16_t data_block;
|
||||
uint32_t fb_base;
|
||||
uint32_t divmul[2];
|
||||
uint16_t io_attr;
|
||||
uint16_t reg_block;
|
||||
uint8_t shift;
|
||||
int cs_equal, cs_above;
|
||||
int io_mode;
|
||||
};
|
||||
|
||||
extern int atom_debug;
|
||||
|
||||
struct atom_context *atom_parse(struct card_info *, void *);
|
||||
void atom_execute_table(struct atom_context *, int, uint32_t *);
|
||||
int atom_asic_init(struct atom_context *);
|
||||
void atom_destroy(struct atom_context *);
|
||||
void atom_parse_data_header(struct atom_context *ctx, int index, uint16_t *size, uint8_t *frev, uint8_t *crev, uint16_t *data_start);
|
||||
void atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t *frev, uint8_t *crev);
|
||||
#include "atom-types.h"
|
||||
#include "atombios.h"
|
||||
#include "ObjectID.h"
|
||||
|
||||
#endif
|
||||
4498
linux-core/atombios.h
Normal file
4498
linux-core/atombios.h
Normal file
File diff suppressed because it is too large
Load diff
382
linux-core/atombios_crtc.c
Normal file
382
linux-core/atombios_crtc.c
Normal file
|
|
@ -0,0 +1,382 @@
|
|||
/*
|
||||
* Copyright 2007-8 Advanced Micro Devices, Inc.
|
||||
* Copyright 2008 Red Hat Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: Dave Airlie
|
||||
* Alex Deucher
|
||||
*/
|
||||
#include "drmP.h"
|
||||
#include "radeon_drm.h"
|
||||
#include "radeon_drv.h"
|
||||
|
||||
#include "drm_crtc_helper.h"
|
||||
#include "atom.h"
|
||||
#include "atom-bits.h"
|
||||
|
||||
static void atombios_enable_crtc(struct drm_crtc *crtc, int state)
|
||||
{
|
||||
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
int index = GetIndexIntoMasterTable(COMMAND, EnableCRTC);
|
||||
ENABLE_CRTC_PS_ALLOCATION args;
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
|
||||
args.ucCRTC = radeon_crtc->crtc_id;
|
||||
args.ucEnable = state;
|
||||
|
||||
atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
|
||||
}
|
||||
|
||||
static void atombios_enable_crtc_memreq(struct drm_crtc *crtc, int state)
|
||||
{
|
||||
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
int index = GetIndexIntoMasterTable(COMMAND, EnableCRTCMemReq);
|
||||
ENABLE_CRTC_PS_ALLOCATION args;
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
|
||||
args.ucCRTC = radeon_crtc->crtc_id;
|
||||
args.ucEnable = state;
|
||||
|
||||
atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
|
||||
}
|
||||
|
||||
static void atombios_blank_crtc(struct drm_crtc *crtc, int state)
|
||||
{
|
||||
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
int index = GetIndexIntoMasterTable(COMMAND, BlankCRTC);
|
||||
BLANK_CRTC_PS_ALLOCATION args;
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
|
||||
args.ucCRTC = radeon_crtc->crtc_id;
|
||||
args.ucBlanking = state;
|
||||
|
||||
atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
|
||||
}
|
||||
|
||||
void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
|
||||
{
|
||||
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
|
||||
switch(mode) {
|
||||
case DRM_MODE_DPMS_ON:
|
||||
case DRM_MODE_DPMS_STANDBY:
|
||||
case DRM_MODE_DPMS_SUSPEND:
|
||||
if (radeon_is_dce3(dev_priv))
|
||||
atombios_enable_crtc_memreq(crtc, 1);
|
||||
atombios_enable_crtc(crtc, 1);
|
||||
atombios_blank_crtc(crtc, 0);
|
||||
|
||||
radeon_crtc_load_lut(crtc);
|
||||
break;
|
||||
case DRM_MODE_DPMS_OFF:
|
||||
atombios_blank_crtc(crtc, 1);
|
||||
atombios_enable_crtc(crtc, 0);
|
||||
if (radeon_is_dce3(dev_priv))
|
||||
atombios_enable_crtc_memreq(crtc, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void atombios_crtc_set_timing(struct drm_crtc *crtc, SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION *crtc_param)
|
||||
{
|
||||
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION conv_param;
|
||||
int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_Timing);
|
||||
|
||||
conv_param.usH_Total = cpu_to_le16(crtc_param->usH_Total);
|
||||
conv_param.usH_Disp = cpu_to_le16(crtc_param->usH_Disp);
|
||||
conv_param.usH_SyncStart = cpu_to_le16(crtc_param->usH_SyncStart);
|
||||
conv_param.usH_SyncWidth = cpu_to_le16(crtc_param->usH_SyncWidth);
|
||||
conv_param.usV_Total = cpu_to_le16(crtc_param->usV_Total);
|
||||
conv_param.usV_Disp = cpu_to_le16(crtc_param->usV_Disp);
|
||||
conv_param.usV_SyncStart = cpu_to_le16(crtc_param->usV_SyncStart);
|
||||
conv_param.usV_SyncWidth = cpu_to_le16(crtc_param->usV_SyncWidth);
|
||||
conv_param.susModeMiscInfo.usAccess = cpu_to_le16(crtc_param->susModeMiscInfo.usAccess);
|
||||
conv_param.ucCRTC = crtc_param->ucCRTC;
|
||||
conv_param.ucOverscanRight = crtc_param->ucOverscanRight;
|
||||
conv_param.ucOverscanLeft = crtc_param->ucOverscanLeft;
|
||||
conv_param.ucOverscanBottom = crtc_param->ucOverscanBottom;
|
||||
conv_param.ucOverscanTop = crtc_param->ucOverscanTop;
|
||||
conv_param.ucReserved = crtc_param->ucReserved;
|
||||
|
||||
printk("executing set crtc timing\n");
|
||||
atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&conv_param);
|
||||
}
|
||||
|
||||
void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode,
|
||||
int pll_flags)
|
||||
{
|
||||
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
uint8_t frev, crev;
|
||||
int index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
|
||||
SET_PIXEL_CLOCK_PS_ALLOCATION spc_param;
|
||||
PIXEL_CLOCK_PARAMETERS_V2 *spc2_ptr;
|
||||
PIXEL_CLOCK_PARAMETERS_V3 *spc3_ptr;
|
||||
uint32_t sclock = mode->clock;
|
||||
uint32_t ref_div = 0, fb_div = 0, post_div = 0;
|
||||
|
||||
memset(&spc_param, 0, sizeof(SET_PIXEL_CLOCK_PS_ALLOCATION));
|
||||
|
||||
if (radeon_is_avivo(dev_priv)) {
|
||||
uint32_t temp;
|
||||
|
||||
pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
|
||||
|
||||
radeon_compute_pll(&dev_priv->mode_info.pll, mode->clock,
|
||||
&temp, &fb_div, &ref_div, &post_div, pll_flags);
|
||||
sclock = temp;
|
||||
|
||||
if (radeon_crtc->crtc_id == 0) {
|
||||
temp = RADEON_READ(AVIVO_P1PLL_INT_SS_CNTL);
|
||||
RADEON_WRITE(AVIVO_P1PLL_INT_SS_CNTL, temp & ~1);
|
||||
} else {
|
||||
temp = RADEON_READ(AVIVO_P2PLL_INT_SS_CNTL);
|
||||
RADEON_WRITE(AVIVO_P2PLL_INT_SS_CNTL, temp & ~1);
|
||||
}
|
||||
} else {
|
||||
#if 0 // TODO r400
|
||||
sclock = save->dot_clock_freq;
|
||||
fb_div = save->feedback_div;
|
||||
post_div = save->post_div;
|
||||
ref_div = save->ppll_ref_div;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* */
|
||||
|
||||
atom_parse_cmd_header(dev_priv->mode_info.atom_context, index, &frev, &crev);
|
||||
|
||||
switch(frev) {
|
||||
case 1:
|
||||
switch(crev) {
|
||||
case 1:
|
||||
case 2:
|
||||
spc2_ptr = (PIXEL_CLOCK_PARAMETERS_V2*)&spc_param.sPCLKInput;
|
||||
spc2_ptr->usPixelClock = cpu_to_le16(sclock);
|
||||
spc2_ptr->usRefDiv = cpu_to_le16(ref_div);
|
||||
spc2_ptr->usFbDiv = cpu_to_le16(fb_div);
|
||||
spc2_ptr->ucPostDiv = post_div;
|
||||
spc2_ptr->ucPpll = radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1;
|
||||
spc2_ptr->ucCRTC = radeon_crtc->crtc_id;
|
||||
spc2_ptr->ucRefDivSrc = 1;
|
||||
break;
|
||||
case 3:
|
||||
spc3_ptr = (PIXEL_CLOCK_PARAMETERS_V3*)&spc_param.sPCLKInput;
|
||||
spc3_ptr->usPixelClock = cpu_to_le16(sclock);
|
||||
spc3_ptr->usRefDiv = cpu_to_le16(ref_div);
|
||||
spc3_ptr->usFbDiv = cpu_to_le16(fb_div);
|
||||
spc3_ptr->ucPostDiv = post_div;
|
||||
spc3_ptr->ucPpll = radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1;
|
||||
spc3_ptr->ucMiscInfo = (radeon_crtc->crtc_id << 2);
|
||||
|
||||
/* TODO insert output encoder object stuff herre for r600 */
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("Unknown table version %d %d\n", frev, crev);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("Unknown table version %d %d\n", frev, crev);
|
||||
return;
|
||||
}
|
||||
|
||||
printk("executing set pll\n");
|
||||
atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&spc_param);
|
||||
}
|
||||
|
||||
void atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y)
|
||||
{
|
||||
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct radeon_framebuffer *radeon_fb;
|
||||
struct drm_radeon_gem_object *obj_priv;
|
||||
uint32_t fb_location, fb_format, fb_pitch_pixels;
|
||||
|
||||
if (!crtc->fb)
|
||||
return;
|
||||
|
||||
radeon_fb = to_radeon_framebuffer(crtc->fb);
|
||||
|
||||
obj_priv = radeon_fb->obj->driver_private;
|
||||
|
||||
fb_location = obj_priv->bo->offset + dev_priv->fb_location;
|
||||
|
||||
switch(crtc->fb->bits_per_pixel) {
|
||||
case 15:
|
||||
fb_format = AVIVO_D1GRPH_CONTROL_DEPTH_16BPP | AVIVO_D1GRPH_CONTROL_16BPP_ARGB1555;
|
||||
break;
|
||||
case 16:
|
||||
fb_format = AVIVO_D1GRPH_CONTROL_DEPTH_16BPP | AVIVO_D1GRPH_CONTROL_16BPP_RGB565;
|
||||
break;
|
||||
case 24:
|
||||
case 32:
|
||||
fb_format = AVIVO_D1GRPH_CONTROL_DEPTH_32BPP | AVIVO_D1GRPH_CONTROL_32BPP_ARGB8888;
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("Unsupported screen depth %d\n", crtc->fb->bits_per_pixel);
|
||||
return;
|
||||
}
|
||||
|
||||
/* TODO tiling */
|
||||
if (radeon_crtc->crtc_id == 0)
|
||||
RADEON_WRITE(AVIVO_D1VGA_CONTROL, 0);
|
||||
else
|
||||
RADEON_WRITE(AVIVO_D2VGA_CONTROL, 0);
|
||||
|
||||
RADEON_WRITE(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset, AVIVO_D1GRPH_UPDATE_LOCK);
|
||||
|
||||
RADEON_WRITE(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, fb_location);
|
||||
RADEON_WRITE(AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, fb_location);
|
||||
RADEON_WRITE(AVIVO_D1GRPH_CONTROL + radeon_crtc->crtc_offset, fb_format);
|
||||
|
||||
RADEON_WRITE(AVIVO_D1GRPH_SURFACE_OFFSET_X + radeon_crtc->crtc_offset, 0);
|
||||
RADEON_WRITE(AVIVO_D1GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0);
|
||||
RADEON_WRITE(AVIVO_D1GRPH_X_START + radeon_crtc->crtc_offset, x);
|
||||
RADEON_WRITE(AVIVO_D1GRPH_Y_START + radeon_crtc->crtc_offset, y);
|
||||
RADEON_WRITE(AVIVO_D1GRPH_X_END + radeon_crtc->crtc_offset, x + crtc->mode.hdisplay);
|
||||
RADEON_WRITE(AVIVO_D1GRPH_Y_END + radeon_crtc->crtc_offset, y + crtc->mode.vdisplay);
|
||||
|
||||
fb_pitch_pixels = crtc->fb->pitch / (crtc->fb->bits_per_pixel / 8);
|
||||
RADEON_WRITE(AVIVO_D1GRPH_PITCH + radeon_crtc->crtc_offset, fb_pitch_pixels);
|
||||
RADEON_WRITE(AVIVO_D1GRPH_ENABLE + radeon_crtc->crtc_offset, 1);
|
||||
|
||||
/* unlock the grph regs */
|
||||
RADEON_WRITE(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset, 0);
|
||||
|
||||
/* lock the mode regs */
|
||||
RADEON_WRITE(AVIVO_D1SCL_UPDATE + radeon_crtc->crtc_offset, AVIVO_D1SCL_UPDATE_LOCK);
|
||||
|
||||
RADEON_WRITE(AVIVO_D1MODE_DESKTOP_HEIGHT + radeon_crtc->crtc_offset,
|
||||
crtc->mode.vdisplay);
|
||||
RADEON_WRITE(AVIVO_D1MODE_VIEWPORT_START + radeon_crtc->crtc_offset, (x << 16) | y);
|
||||
RADEON_WRITE(AVIVO_D1MODE_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
|
||||
(crtc->mode.hdisplay << 16) | crtc->mode.vdisplay);
|
||||
/* unlock the mode regs */
|
||||
RADEON_WRITE(AVIVO_D1SCL_UPDATE + radeon_crtc->crtc_offset, 0);
|
||||
}
|
||||
|
||||
void atombios_crtc_mode_set(struct drm_crtc *crtc,
|
||||
struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode,
|
||||
int x, int y)
|
||||
{
|
||||
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct drm_encoder *encoder;
|
||||
SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION crtc_timing;
|
||||
int pll_flags = 0;
|
||||
/* TODO color tiling */
|
||||
|
||||
memset(&crtc_timing, 0, sizeof(crtc_timing));
|
||||
|
||||
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
crtc_timing.ucCRTC = radeon_crtc->crtc_id;
|
||||
crtc_timing.usH_Total = adjusted_mode->crtc_htotal;
|
||||
crtc_timing.usH_Disp = adjusted_mode->crtc_hdisplay;
|
||||
crtc_timing.usH_SyncStart = adjusted_mode->crtc_hsync_start;
|
||||
crtc_timing.usH_SyncWidth = adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start;
|
||||
|
||||
crtc_timing.usV_Total = adjusted_mode->crtc_vtotal;
|
||||
crtc_timing.usV_Disp = adjusted_mode->crtc_vdisplay;
|
||||
crtc_timing.usV_SyncStart = adjusted_mode->crtc_vsync_start;
|
||||
crtc_timing.usV_SyncWidth = adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start;
|
||||
|
||||
if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC)
|
||||
crtc_timing.susModeMiscInfo.usAccess |= ATOM_VSYNC_POLARITY;
|
||||
|
||||
if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC)
|
||||
crtc_timing.susModeMiscInfo.usAccess |= ATOM_HSYNC_POLARITY;
|
||||
|
||||
if (adjusted_mode->flags & DRM_MODE_FLAG_CSYNC)
|
||||
crtc_timing.susModeMiscInfo.usAccess |= ATOM_COMPOSITESYNC;
|
||||
|
||||
if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
|
||||
crtc_timing.susModeMiscInfo.usAccess |= ATOM_INTERLACE;
|
||||
|
||||
if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
|
||||
crtc_timing.susModeMiscInfo.usAccess |= ATOM_DOUBLE_CLOCK_MODE;
|
||||
|
||||
if (radeon_is_avivo(dev_priv)) {
|
||||
atombios_crtc_set_base(crtc, x, y);
|
||||
}
|
||||
|
||||
atombios_crtc_set_pll(crtc, adjusted_mode, pll_flags);
|
||||
|
||||
atombios_crtc_set_timing(crtc, &crtc_timing);
|
||||
}
|
||||
|
||||
static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc,
|
||||
struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static void atombios_crtc_prepare(struct drm_crtc *crtc)
|
||||
{
|
||||
atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
|
||||
}
|
||||
|
||||
static void atombios_crtc_commit(struct drm_crtc *crtc)
|
||||
{
|
||||
atombios_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
|
||||
}
|
||||
|
||||
static const struct drm_crtc_helper_funcs atombios_helper_funcs = {
|
||||
.dpms = atombios_crtc_dpms,
|
||||
.mode_fixup = atombios_crtc_mode_fixup,
|
||||
.mode_set = atombios_crtc_mode_set,
|
||||
.mode_set_base = atombios_crtc_set_base,
|
||||
.prepare = atombios_crtc_prepare,
|
||||
.commit = atombios_crtc_commit,
|
||||
};
|
||||
|
||||
void radeon_atombios_init_crtc(struct drm_device *dev,
|
||||
struct radeon_crtc *radeon_crtc)
|
||||
{
|
||||
if (radeon_crtc->crtc_id == 1)
|
||||
radeon_crtc->crtc_offset = AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL;
|
||||
drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs);
|
||||
}
|
||||
|
|
@ -1046,8 +1046,7 @@ struct drm_agp_ttm_backend {
|
|||
int populated;
|
||||
};
|
||||
#endif
|
||||
|
||||
typedef struct ati_pcigart_ttm_backend {
|
||||
struct ati_pcigart_ttm_backend {
|
||||
struct drm_ttm_backend backend;
|
||||
int populated;
|
||||
void (*gart_flush_fn)(struct drm_device *dev);
|
||||
|
|
@ -1057,7 +1056,8 @@ typedef struct ati_pcigart_ttm_backend {
|
|||
int num_pages;
|
||||
int bound;
|
||||
struct drm_device *dev;
|
||||
} ati_pcigart_ttm_backend_t;
|
||||
};
|
||||
extern struct drm_ttm_backend *ati_pcigart_init_ttm(struct drm_device *dev, struct drm_ati_pcigart_info *info, void (*gart_flush_fn)(struct drm_device *dev));
|
||||
|
||||
static __inline__ int drm_core_check_feature(struct drm_device *dev,
|
||||
int feature)
|
||||
|
|
@ -1396,6 +1396,8 @@ extern int drm_sg_free(struct drm_device *dev, void *data,
|
|||
/* ATI PCIGART support (ati_pcigart.h) */
|
||||
extern int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info);
|
||||
extern int drm_ati_pcigart_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info);
|
||||
extern int drm_ati_alloc_pcigart_table(struct drm_device *dev,
|
||||
struct drm_ati_pcigart_info *gart_info);
|
||||
|
||||
extern drm_dma_handle_t *drm_pci_alloc(struct drm_device *dev, size_t size,
|
||||
size_t align, dma_addr_t maxaddr);
|
||||
|
|
|
|||
|
|
@ -51,7 +51,6 @@
|
|||
|
||||
static void drm_bo_destroy_locked(struct drm_buffer_object *bo);
|
||||
static int drm_bo_setup_vm_locked(struct drm_buffer_object *bo);
|
||||
static void drm_bo_takedown_vm_locked(struct drm_buffer_object *bo);
|
||||
static void drm_bo_unmap_virtual(struct drm_buffer_object *bo);
|
||||
|
||||
static inline uint64_t drm_bo_type_flags(unsigned type)
|
||||
|
|
@ -458,6 +457,7 @@ static void drm_bo_destroy_locked(struct drm_buffer_object *bo)
|
|||
|
||||
DRM_ASSERT_LOCKED(&dev->struct_mutex);
|
||||
|
||||
DRM_DEBUG("freeing %p\n", bo);
|
||||
if (list_empty(&bo->lru) && bo->mem.mm_node == NULL &&
|
||||
list_empty(&bo->pinned_lru) && bo->pinned_node == NULL &&
|
||||
list_empty(&bo->ddestroy) && atomic_read(&bo->usage) == 0) {
|
||||
|
|
@ -1838,8 +1838,8 @@ out_err_unlocked:
|
|||
EXPORT_SYMBOL(drm_buffer_object_create);
|
||||
|
||||
|
||||
static int drm_bo_add_user_object(struct drm_file *file_priv,
|
||||
struct drm_buffer_object *bo, int shareable)
|
||||
int drm_bo_add_user_object(struct drm_file *file_priv,
|
||||
struct drm_buffer_object *bo, int shareable)
|
||||
{
|
||||
struct drm_device *dev = file_priv->minor->dev;
|
||||
int ret;
|
||||
|
|
@ -1858,6 +1858,7 @@ out:
|
|||
mutex_unlock(&dev->struct_mutex);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_bo_add_user_object);
|
||||
|
||||
int drm_bo_create_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
|
|
@ -2705,7 +2706,7 @@ void drm_bo_unmap_virtual(struct drm_buffer_object *bo)
|
|||
* Remove any associated vm mapping on the drm device node that
|
||||
* would have been created for a drm_bo_type_device buffer
|
||||
*/
|
||||
static void drm_bo_takedown_vm_locked(struct drm_buffer_object *bo)
|
||||
void drm_bo_takedown_vm_locked(struct drm_buffer_object *bo)
|
||||
{
|
||||
struct drm_map_list *list;
|
||||
drm_local_map_t *map;
|
||||
|
|
@ -2734,6 +2735,7 @@ static void drm_bo_takedown_vm_locked(struct drm_buffer_object *bo)
|
|||
list->user_token = 0ULL;
|
||||
drm_bo_usage_deref_locked(&bo);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_bo_takedown_vm_locked);
|
||||
|
||||
/**
|
||||
* drm_bo_setup_vm_locked:
|
||||
|
|
|
|||
|
|
@ -781,19 +781,17 @@ EXPORT_SYMBOL(pci_get_bus_and_slot);
|
|||
#endif
|
||||
|
||||
#if defined(DRM_KMAP_ATOMIC_PROT_PFN)
|
||||
#define drm_kmap_get_fixmap_pte(vaddr) \
|
||||
pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), vaddr), (vaddr)), (vaddr))
|
||||
|
||||
void *kmap_atomic_prot_pfn(unsigned long pfn, enum km_type type,
|
||||
pgprot_t protection)
|
||||
{
|
||||
enum fixed_addresses idx;
|
||||
unsigned long vaddr;
|
||||
static pte_t *km_pte;
|
||||
int level;
|
||||
static int initialized = 0;
|
||||
|
||||
if (unlikely(!initialized)) {
|
||||
km_pte = drm_kmap_get_fixmap_pte(__fix_to_virt(FIX_KMAP_BEGIN));
|
||||
km_pte = lookup_address(__fix_to_virt(FIX_KMAP_BEGIN), &level);
|
||||
initialized = 1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -122,24 +122,31 @@ char *drm_get_subconnector_name(int val)
|
|||
return "unknown";
|
||||
}
|
||||
|
||||
struct drm_conn_prop_enum_list {
|
||||
int type;
|
||||
char *name;
|
||||
int count;
|
||||
};
|
||||
|
||||
/*
|
||||
* Connector and encoder types.
|
||||
*/
|
||||
static struct drm_prop_enum_list drm_connector_enum_list[] =
|
||||
{ { DRM_MODE_CONNECTOR_Unknown, "Unknown" },
|
||||
{ DRM_MODE_CONNECTOR_VGA, "VGA" },
|
||||
{ DRM_MODE_CONNECTOR_DVII, "DVI-I" },
|
||||
{ DRM_MODE_CONNECTOR_DVID, "DVI-D" },
|
||||
{ DRM_MODE_CONNECTOR_DVIA, "DVI-A" },
|
||||
{ DRM_MODE_CONNECTOR_Composite, "Composite" },
|
||||
{ DRM_MODE_CONNECTOR_SVIDEO, "SVIDEO" },
|
||||
{ DRM_MODE_CONNECTOR_LVDS, "LVDS" },
|
||||
{ DRM_MODE_CONNECTOR_Component, "Component" },
|
||||
{ DRM_MODE_CONNECTOR_9PinDIN, "9-pin DIN" },
|
||||
{ DRM_MODE_CONNECTOR_DisplayPort, "DisplayPort" },
|
||||
{ DRM_MODE_CONNECTOR_HDMIA, "HDMI Type A" },
|
||||
{ DRM_MODE_CONNECTOR_HDMIB, "HDMI Type B" },
|
||||
static struct drm_conn_prop_enum_list drm_connector_enum_list[] =
|
||||
{ { DRM_MODE_CONNECTOR_Unknown, "Unknown", 0 },
|
||||
{ DRM_MODE_CONNECTOR_VGA, "VGA", 0 },
|
||||
{ DRM_MODE_CONNECTOR_DVII, "DVI-I", 0 },
|
||||
{ DRM_MODE_CONNECTOR_DVID, "DVI-D", 0 },
|
||||
{ DRM_MODE_CONNECTOR_DVIA, "DVI-A", 0 },
|
||||
{ DRM_MODE_CONNECTOR_Composite, "Composite", 0 },
|
||||
{ DRM_MODE_CONNECTOR_SVIDEO, "SVIDEO", 0 },
|
||||
{ DRM_MODE_CONNECTOR_LVDS, "LVDS", 0 },
|
||||
{ DRM_MODE_CONNECTOR_Component, "Component", 0 },
|
||||
{ DRM_MODE_CONNECTOR_9PinDIN, "9-pin DIN", 0 },
|
||||
{ DRM_MODE_CONNECTOR_DisplayPort, "DisplayPort", 0 },
|
||||
{ DRM_MODE_CONNECTOR_HDMIA, "HDMI Type A", 0 },
|
||||
{ DRM_MODE_CONNECTOR_HDMIB, "HDMI Type B", 0 },
|
||||
};
|
||||
|
||||
static struct drm_prop_enum_list drm_encoder_enum_list[] =
|
||||
{ { DRM_MODE_ENCODER_NONE, "None" },
|
||||
{ DRM_MODE_ENCODER_DAC, "DAC" },
|
||||
|
|
@ -226,7 +233,7 @@ static void drm_mode_object_put(struct drm_device *dev, struct drm_mode_object *
|
|||
idr_remove(&dev->mode_config.crtc_idr, object->id);
|
||||
}
|
||||
|
||||
static void *drm_mode_object_find(struct drm_device *dev, uint32_t id, uint32_t type)
|
||||
void *drm_mode_object_find(struct drm_device *dev, uint32_t id, uint32_t type)
|
||||
{
|
||||
struct drm_mode_object *obj;
|
||||
|
||||
|
|
@ -236,6 +243,7 @@ static void *drm_mode_object_find(struct drm_device *dev, uint32_t id, uint32_t
|
|||
|
||||
return obj;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_mode_object_find);
|
||||
|
||||
/**
|
||||
* drm_crtc_from_fb - find the CRTC structure associated with an fb
|
||||
|
|
@ -419,7 +427,7 @@ void drm_connector_init(struct drm_device *dev,
|
|||
connector->funcs = funcs;
|
||||
drm_mode_object_get(dev, &connector->base, DRM_MODE_OBJECT_CONNECTOR);
|
||||
connector->connector_type = connector_type;
|
||||
connector->connector_type_id = 1; /* TODO */
|
||||
connector->connector_type_id = ++drm_connector_enum_list[connector_type].count; /* TODO */
|
||||
INIT_LIST_HEAD(&connector->user_modes);
|
||||
INIT_LIST_HEAD(&connector->probed_modes);
|
||||
INIT_LIST_HEAD(&connector->modes);
|
||||
|
|
@ -756,6 +764,9 @@ int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *group)
|
|||
total_objects += dev->mode_config.num_connector;
|
||||
total_objects += dev->mode_config.num_encoder;
|
||||
|
||||
if (total_objects == 0)
|
||||
return -EINVAL;
|
||||
|
||||
group->id_list = kzalloc(total_objects * sizeof(uint32_t), GFP_KERNEL);
|
||||
if (!group->id_list)
|
||||
return -ENOMEM;
|
||||
|
|
@ -771,9 +782,10 @@ int drm_mode_group_init_legacy_group(struct drm_device *dev, struct drm_mode_gro
|
|||
struct drm_crtc *crtc;
|
||||
struct drm_encoder *encoder;
|
||||
struct drm_connector *connector;
|
||||
int ret;
|
||||
|
||||
if (drm_mode_group_init(dev, group))
|
||||
return -ENOMEM;
|
||||
if ((ret = drm_mode_group_init(dev, group)))
|
||||
return ret;
|
||||
|
||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
|
||||
group->id_list[group->num_crtcs++] = crtc->base.id;
|
||||
|
|
|
|||
|
|
@ -664,6 +664,7 @@ extern void drm_mode_connector_detach_encoder(struct drm_connector *connector,
|
|||
struct drm_encoder *encoder);
|
||||
extern bool drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
|
||||
int gamma_size);
|
||||
extern void *drm_mode_object_find(struct drm_device *dev, uint32_t id, uint32_t type);
|
||||
/* IOCTLs */
|
||||
extern int drm_mode_getresources(struct drm_device *dev,
|
||||
void *data, struct drm_file *file_priv);
|
||||
|
|
|
|||
|
|
@ -500,7 +500,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
|
|||
|
||||
crtc_funcs = set->crtc->helper_private;
|
||||
|
||||
DRM_DEBUG("crtc: %p fb: %p connectors: %p num_connectors: %i (x, y) (%i, %i)\n", set->crtc, set->fb, set->connectors, set->num_connectors, set->x, set->y);
|
||||
DRM_DEBUG("crtc: %p %d fb: %p connectors: %p num_connectors: %i (x, y) (%i, %i)\n", set->crtc, set->crtc->base.id, set->fb, set->connectors, set->num_connectors, set->x, set->y);
|
||||
|
||||
dev = set->crtc->dev;
|
||||
|
||||
|
|
|
|||
|
|
@ -54,6 +54,8 @@ struct drm_encoder_helper_funcs {
|
|||
void (*mode_set)(struct drm_encoder *encoder,
|
||||
struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode);
|
||||
/* detect for DAC style encoders */
|
||||
enum drm_connector_status (*detect)(struct drm_encoder *encoder, struct drm_connector *connector);
|
||||
};
|
||||
|
||||
struct drm_connector_helper_funcs {
|
||||
|
|
|
|||
|
|
@ -100,7 +100,6 @@ drm_gem_object_alloc(struct drm_device *dev, size_t size)
|
|||
kfree(obj);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
kref_init(&obj->refcount);
|
||||
kref_init(&obj->handlecount);
|
||||
obj->size = size;
|
||||
|
|
|
|||
|
|
@ -546,6 +546,7 @@ void drm_mode_connector_list_update(struct drm_connector *connector)
|
|||
struct drm_display_mode *mode;
|
||||
struct drm_display_mode *pmode, *pt;
|
||||
int found_it;
|
||||
|
||||
list_for_each_entry_safe(pmode, pt, &connector->probed_modes,
|
||||
head) {
|
||||
found_it = 0;
|
||||
|
|
|
|||
|
|
@ -680,6 +680,8 @@ extern int drm_bo_pci_offset(struct drm_device *dev,
|
|||
unsigned long *bus_size);
|
||||
extern int drm_mem_reg_is_pci(struct drm_device *dev, struct drm_bo_mem_reg *mem);
|
||||
|
||||
extern int drm_bo_add_user_object(struct drm_file *file_priv,
|
||||
struct drm_buffer_object *bo, int shareable);
|
||||
extern void drm_bo_usage_deref_locked(struct drm_buffer_object **bo);
|
||||
extern void drm_bo_usage_deref_unlocked(struct drm_buffer_object **bo);
|
||||
extern void drm_putback_buffer_objects(struct drm_device *dev);
|
||||
|
|
@ -718,6 +720,8 @@ extern int drm_bo_do_validate(struct drm_buffer_object *bo,
|
|||
uint32_t fence_class,
|
||||
struct drm_bo_info_rep *rep);
|
||||
extern int drm_bo_evict_cached(struct drm_buffer_object *bo);
|
||||
|
||||
extern void drm_bo_takedown_vm_locked(struct drm_buffer_object *bo);
|
||||
/*
|
||||
* Buffer object memory move- and map helpers.
|
||||
* drm_bo_move.c
|
||||
|
|
|
|||
|
|
@ -544,14 +544,14 @@ static void intelfb_on(struct fb_info *info)
|
|||
if (crtc->base.id == par->crtc_ids[i])
|
||||
break;
|
||||
|
||||
crtc_funcs->dpms(crtc, DPMSModeOn);
|
||||
crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
|
||||
|
||||
/* Found a CRTC on this fb, now find encoders */
|
||||
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
|
||||
if (encoder->crtc == crtc) {
|
||||
struct drm_encoder_helper_funcs *encoder_funcs;
|
||||
encoder_funcs = encoder->helper_private;
|
||||
encoder_funcs->dpms(encoder, DPMSModeOn);
|
||||
encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -584,7 +584,7 @@ static void intelfb_off(struct fb_info *info, int dpms_mode)
|
|||
encoder_funcs->dpms(encoder, dpms_mode);
|
||||
}
|
||||
}
|
||||
if (dpms_mode == DPMSModeOff)
|
||||
if (dpms_mode == DRM_MODE_DPMS_OFF)
|
||||
crtc_funcs->dpms(crtc, dpms_mode);
|
||||
}
|
||||
}
|
||||
|
|
@ -596,16 +596,16 @@ int intelfb_blank(int blank, struct fb_info *info)
|
|||
intelfb_on(info);
|
||||
break;
|
||||
case FB_BLANK_NORMAL:
|
||||
intelfb_off(info, DPMSModeStandby);
|
||||
intelfb_off(info, DRM_MODE_DPMS_STANDBY);
|
||||
break;
|
||||
case FB_BLANK_HSYNC_SUSPEND:
|
||||
intelfb_off(info, DPMSModeStandby);
|
||||
intelfb_off(info, DRM_MODE_DPMS_STANDBY);
|
||||
break;
|
||||
case FB_BLANK_VSYNC_SUSPEND:
|
||||
intelfb_off(info, DPMSModeSuspend);
|
||||
intelfb_off(info, DRM_MODE_DPMS_SUSPEND);
|
||||
break;
|
||||
case FB_BLANK_POWERDOWN:
|
||||
intelfb_off(info, DPMSModeOff);
|
||||
intelfb_off(info, DRM_MODE_DPMS_OFF);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
|
|
|
|||
361
linux-core/radeon_atombios.c
Normal file
361
linux-core/radeon_atombios.c
Normal file
|
|
@ -0,0 +1,361 @@
|
|||
/*
|
||||
* Copyright 2007-8 Advanced Micro Devices, Inc.
|
||||
* Copyright 2008 Red Hat Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: Dave Airlie
|
||||
* Alex Deucher
|
||||
*/
|
||||
#include "drmP.h"
|
||||
#include "radeon_drm.h"
|
||||
#include "radeon_drv.h"
|
||||
|
||||
#include "atom.h"
|
||||
#include "atom-bits.h"
|
||||
|
||||
|
||||
union atom_supported_devices {
|
||||
struct _ATOM_SUPPORTED_DEVICES_INFO info;
|
||||
struct _ATOM_SUPPORTED_DEVICES_INFO_2 info_2;
|
||||
struct _ATOM_SUPPORTED_DEVICES_INFO_2d1 info_2d1;
|
||||
};
|
||||
|
||||
static inline struct radeon_i2c_bus_rec radeon_lookup_gpio_for_ddc(struct drm_device *dev, uint8_t id)
|
||||
{
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct atom_context *ctx = dev_priv->mode_info.atom_context;
|
||||
ATOM_GPIO_I2C_ASSIGMENT gpio;
|
||||
struct radeon_i2c_bus_rec i2c;
|
||||
int index = GetIndexIntoMasterTable(DATA, GPIO_I2C_Info);
|
||||
struct _ATOM_GPIO_I2C_INFO *i2c_info;
|
||||
uint16_t data_offset;
|
||||
|
||||
memset(&i2c, 0, sizeof(struct radeon_i2c_bus_rec));
|
||||
i2c.valid = false;
|
||||
|
||||
atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset);
|
||||
|
||||
i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset);
|
||||
|
||||
gpio = i2c_info->asGPIO_Info[id];
|
||||
|
||||
i2c.mask_clk_reg = le16_to_cpu(gpio.usClkMaskRegisterIndex) * 4;
|
||||
i2c.mask_data_reg = le16_to_cpu(gpio.usDataMaskRegisterIndex) * 4;
|
||||
i2c.put_clk_reg = le16_to_cpu(gpio.usClkEnRegisterIndex) * 4;
|
||||
i2c.put_data_reg = le16_to_cpu(gpio.usDataEnRegisterIndex) * 4;
|
||||
i2c.get_clk_reg = le16_to_cpu(gpio.usClkY_RegisterIndex) * 4;
|
||||
i2c.get_data_reg = le16_to_cpu(gpio.usDataY_RegisterIndex) * 4;
|
||||
i2c.mask_clk_mask = (1 << gpio.ucClkMaskShift);
|
||||
i2c.mask_data_mask = (1 << gpio.ucDataMaskShift);
|
||||
i2c.put_clk_mask = (1 << gpio.ucClkEnShift);
|
||||
i2c.put_data_mask = (1 << gpio.ucDataEnShift);
|
||||
i2c.get_clk_mask = (1 << gpio.ucClkY_Shift);
|
||||
i2c.get_data_mask = (1 << gpio.ucDataY_Shift);
|
||||
i2c.valid = true;
|
||||
|
||||
return i2c;
|
||||
}
|
||||
|
||||
static void radeon_atom_apply_quirks(struct drm_device *dev, int index)
|
||||
{
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct radeon_mode_info *mode_info = &dev_priv->mode_info;
|
||||
|
||||
if ((dev->pdev->device == 0x791e) &&
|
||||
(dev->pdev->subsystem_vendor == 0x1043) &&
|
||||
(dev->pdev->subsystem_device == 0x826d)) {
|
||||
if ((mode_info->bios_connector[index].connector_type == CONNECTOR_HDMI_TYPE_A) &&
|
||||
(mode_info->bios_connector[index].tmds_type == TMDS_LVTMA)) {
|
||||
mode_info->bios_connector[index].connector_type = CONNECTOR_DVI_D;
|
||||
}
|
||||
}
|
||||
|
||||
if ((dev->pdev->device == 0x5653) &&
|
||||
(dev->pdev->subsystem_vendor == 0x1462) &&
|
||||
(dev->pdev->subsystem_device == 0x0291)) {
|
||||
if (mode_info->bios_connector[index].connector_type == CONNECTOR_LVDS) {
|
||||
mode_info->bios_connector[index].ddc_i2c.valid = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool radeon_get_atom_connector_info_from_bios_connector_table(struct drm_device *dev)
|
||||
{
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct radeon_mode_info *mode_info = &dev_priv->mode_info;
|
||||
struct atom_context *ctx = mode_info->atom_context;
|
||||
int index = GetIndexIntoMasterTable(DATA, SupportedDevicesInfo);
|
||||
uint16_t size, data_offset;
|
||||
uint8_t frev, crev;
|
||||
uint16_t device_support;
|
||||
|
||||
union atom_supported_devices *supported_devices;
|
||||
int i,j;
|
||||
atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset);
|
||||
|
||||
supported_devices = (union atom_supported_devices *)(ctx->bios + data_offset);
|
||||
|
||||
device_support = le16_to_cpu(supported_devices->info.usDeviceSupport);
|
||||
|
||||
for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
|
||||
|
||||
ATOM_CONNECTOR_INFO_I2C ci = supported_devices->info.asConnInfo[i];
|
||||
|
||||
if (!(device_support & (1 << i))) {
|
||||
mode_info->bios_connector[i].valid = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i == ATOM_DEVICE_CV_INDEX) {
|
||||
DRM_DEBUG("Skipping Component Video\n");
|
||||
mode_info->bios_connector[i].valid = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i == ATOM_DEVICE_TV1_INDEX) {
|
||||
DRM_DEBUG("Skipping TV Out\n");
|
||||
mode_info->bios_connector[i].valid = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
mode_info->bios_connector[i].valid = true;
|
||||
mode_info->bios_connector[i].output_id = ci.sucI2cId.sbfAccess.bfI2C_LineMux;
|
||||
mode_info->bios_connector[i].devices = 1 << i;
|
||||
mode_info->bios_connector[i].connector_type = ci.sucConnectorInfo.sbfAccess.bfConnectorType;
|
||||
|
||||
if (mode_info->bios_connector[i].connector_type == CONNECTOR_NONE) {
|
||||
mode_info->bios_connector[i].valid = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
mode_info->bios_connector[i].dac_type = ci.sucConnectorInfo.sbfAccess.bfAssociatedDAC;
|
||||
|
||||
if ((i == ATOM_DEVICE_TV1_INDEX) ||
|
||||
(i == ATOM_DEVICE_TV2_INDEX) ||
|
||||
(i == ATOM_DEVICE_TV1_INDEX))
|
||||
mode_info->bios_connector[i].ddc_i2c.valid = false;
|
||||
else if ((dev_priv->chip_family == CHIP_RS600) ||
|
||||
(dev_priv->chip_family == CHIP_RS690) ||
|
||||
(dev_priv->chip_family == CHIP_RS740)) {
|
||||
if ((i == ATOM_DEVICE_DFP2_INDEX) || (i == ATOM_DEVICE_DFP3_INDEX))
|
||||
mode_info->bios_connector[i].ddc_i2c =
|
||||
radeon_lookup_gpio_for_ddc(dev, ci.sucI2cId.sbfAccess.bfI2C_LineMux + 1);
|
||||
else
|
||||
mode_info->bios_connector[i].ddc_i2c =
|
||||
radeon_lookup_gpio_for_ddc(dev, ci.sucI2cId.sbfAccess.bfI2C_LineMux);
|
||||
} else
|
||||
mode_info->bios_connector[i].ddc_i2c =
|
||||
radeon_lookup_gpio_for_ddc(dev, ci.sucI2cId.sbfAccess.bfI2C_LineMux);
|
||||
|
||||
if (i == ATOM_DEVICE_DFP1_INDEX)
|
||||
mode_info->bios_connector[i].tmds_type = TMDS_INT;
|
||||
else if (i == ATOM_DEVICE_DFP2_INDEX) {
|
||||
if ((dev_priv->chip_family == CHIP_RS600) ||
|
||||
(dev_priv->chip_family == CHIP_RS690) ||
|
||||
(dev_priv->chip_family == CHIP_RS740))
|
||||
mode_info->bios_connector[i].tmds_type = TMDS_DDIA;
|
||||
else
|
||||
mode_info->bios_connector[i].tmds_type = TMDS_EXT;
|
||||
} else if (i == ATOM_DEVICE_DFP3_INDEX)
|
||||
mode_info->bios_connector[i].tmds_type = TMDS_LVTMA;
|
||||
else
|
||||
mode_info->bios_connector[i].tmds_type = TMDS_NONE;
|
||||
|
||||
/* Always set the connector type to VGA for CRT1/CRT2. if they are
|
||||
* shared with a DVI port, we'll pick up the DVI connector below when we
|
||||
* merge the outputs
|
||||
*/
|
||||
if ((i == ATOM_DEVICE_CRT1_INDEX || i == ATOM_DEVICE_CRT2_INDEX) &&
|
||||
(mode_info->bios_connector[i].connector_type == CONNECTOR_DVI_I ||
|
||||
mode_info->bios_connector[i].connector_type == CONNECTOR_DVI_D ||
|
||||
mode_info->bios_connector[i].connector_type == CONNECTOR_DVI_A)) {
|
||||
mode_info->bios_connector[i].connector_type = CONNECTOR_VGA;
|
||||
}
|
||||
|
||||
if (crev > 1) {
|
||||
ATOM_CONNECTOR_INC_SRC_BITMAP isb = supported_devices->info_2.asIntSrcInfo[i];
|
||||
|
||||
switch(isb.ucIntSrcBitmap) {
|
||||
case 0x4:
|
||||
mode_info->bios_connector[i].hpd_mask = 0x1;
|
||||
break;
|
||||
case 0xa:
|
||||
mode_info->bios_connector[i].hpd_mask = 0x100;
|
||||
break;
|
||||
default:
|
||||
mode_info->bios_connector[i].hpd_mask = 0;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
mode_info->bios_connector[i].hpd_mask = 0;
|
||||
}
|
||||
|
||||
radeon_atom_apply_quirks(dev, i);
|
||||
}
|
||||
|
||||
/* CRTs/DFPs may share a port */
|
||||
for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
|
||||
if (!mode_info->bios_connector[i].valid)
|
||||
continue;
|
||||
|
||||
for (j = 0; j < ATOM_MAX_SUPPORTED_DEVICE; j++) {
|
||||
if (mode_info->bios_connector[j].valid && (i != j)) {
|
||||
if (mode_info->bios_connector[i].output_id ==
|
||||
mode_info->bios_connector[j].output_id) {
|
||||
if (((i == ATOM_DEVICE_DFP1_INDEX) ||
|
||||
(i == ATOM_DEVICE_DFP2_INDEX) ||
|
||||
(i == ATOM_DEVICE_DFP3_INDEX)) &&
|
||||
((j == ATOM_DEVICE_CRT1_INDEX) ||
|
||||
(j == ATOM_DEVICE_CRT2_INDEX))) {
|
||||
mode_info->bios_connector[i].dac_type = mode_info->bios_connector[j].dac_type;
|
||||
mode_info->bios_connector[i].devices |= mode_info->bios_connector[j].devices;
|
||||
mode_info->bios_connector[i].hpd_mask = mode_info->bios_connector[j].hpd_mask;
|
||||
mode_info->bios_connector[j].valid = false;
|
||||
} else if (((j == ATOM_DEVICE_DFP1_INDEX) ||
|
||||
(j == ATOM_DEVICE_DFP2_INDEX) ||
|
||||
(j == ATOM_DEVICE_DFP3_INDEX)) &&
|
||||
((i == ATOM_DEVICE_CRT1_INDEX) ||
|
||||
(i == ATOM_DEVICE_CRT2_INDEX))) {
|
||||
mode_info->bios_connector[j].dac_type = mode_info->bios_connector[i].dac_type;
|
||||
mode_info->bios_connector[j].devices |= mode_info->bios_connector[i].devices;
|
||||
mode_info->bios_connector[j].hpd_mask = mode_info->bios_connector[i].hpd_mask;
|
||||
mode_info->bios_connector[i].valid = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DRM_DEBUG("BIOS Connector table\n");
|
||||
for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
|
||||
if (!mode_info->bios_connector[i].valid)
|
||||
continue;
|
||||
|
||||
DRM_DEBUG("Port %d: ddc_type 0x%x, dac_type %d, tmds_type %d, connector type %d, hpd_mask %d\n",
|
||||
i, mode_info->bios_connector[i].ddc_i2c.mask_clk_reg,
|
||||
mode_info->bios_connector[i].dac_type,
|
||||
mode_info->bios_connector[i].tmds_type,
|
||||
mode_info->bios_connector[i].connector_type,
|
||||
mode_info->bios_connector[i].hpd_mask);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
union firmware_info {
|
||||
ATOM_FIRMWARE_INFO info;
|
||||
ATOM_FIRMWARE_INFO_V1_2 info_12;
|
||||
ATOM_FIRMWARE_INFO_V1_3 info_13;
|
||||
ATOM_FIRMWARE_INFO_V1_4 info_14;
|
||||
};
|
||||
|
||||
bool radeon_atom_get_clock_info(struct drm_device *dev)
|
||||
{
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct radeon_mode_info *mode_info = &dev_priv->mode_info;
|
||||
int index = GetIndexIntoMasterTable(DATA, FirmwareInfo);
|
||||
union firmware_info *firmware_info;
|
||||
uint8_t frev, crev;
|
||||
struct radeon_pll *pll = &mode_info->pll;
|
||||
uint16_t data_offset;
|
||||
|
||||
atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset);
|
||||
|
||||
firmware_info = (union firmware_info *)(mode_info->atom_context->bios + data_offset);
|
||||
|
||||
pll->reference_freq = le16_to_cpu(firmware_info->info.usReferenceClock);
|
||||
pll->reference_div = 0;
|
||||
|
||||
pll->pll_out_min = le16_to_cpu(firmware_info->info.usMinPixelClockPLL_Output);
|
||||
pll->pll_out_max = le32_to_cpu(firmware_info->info.ulMaxPixelClockPLL_Output);
|
||||
|
||||
if (pll->pll_out_min == 0) {
|
||||
if (radeon_is_avivo(dev_priv))
|
||||
pll->pll_out_min = 64800;
|
||||
else
|
||||
pll->pll_out_min = 20000;
|
||||
}
|
||||
|
||||
pll->pll_in_min = le16_to_cpu(firmware_info->info.usMinPixelClockPLL_Input);
|
||||
pll->pll_in_max = le16_to_cpu(firmware_info->info.usMaxPixelClockPLL_Input);
|
||||
|
||||
pll->xclk = le16_to_cpu(firmware_info->info.usMaxPixelClock);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
union lvds_info {
|
||||
struct _ATOM_LVDS_INFO info;
|
||||
struct _ATOM_LVDS_INFO_V12 info_12;
|
||||
};
|
||||
|
||||
void radeon_get_lvds_info(struct radeon_encoder *encoder)
|
||||
{
|
||||
struct drm_device *dev = encoder->base.dev;
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct radeon_mode_info *mode_info = &dev_priv->mode_info;
|
||||
int index = GetIndexIntoMasterTable(DATA, LVDS_Info);
|
||||
uint16_t data_offset;
|
||||
union lvds_info *lvds_info;
|
||||
uint8_t frev, crev;
|
||||
|
||||
atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset);
|
||||
|
||||
lvds_info = (union lvds_info *)(mode_info->atom_context->bios + data_offset);
|
||||
|
||||
encoder->dotclock = le16_to_cpu(lvds_info->info.sLCDTiming.usPixClk) * 10;
|
||||
encoder->panel_xres = le16_to_cpu(lvds_info->info.sLCDTiming.usHActive);
|
||||
encoder->panel_yres = le16_to_cpu(lvds_info->info.sLCDTiming.usVActive);
|
||||
encoder->hblank = le16_to_cpu(lvds_info->info.sLCDTiming.usHBlanking_Time);
|
||||
encoder->hoverplus = le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncOffset);
|
||||
encoder->hsync_width = le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncWidth);
|
||||
|
||||
encoder->vblank = le16_to_cpu(lvds_info->info.sLCDTiming.usVBlanking_Time);
|
||||
encoder->hoverplus = le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncOffset);
|
||||
encoder->hsync_width = le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncWidth);
|
||||
encoder->panel_pwr_delay = le16_to_cpu(lvds_info->info.usOffDelayInMs);
|
||||
}
|
||||
|
||||
void radeon_atom_dyn_clk_setup(struct drm_device *dev, int enable)
|
||||
{
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct radeon_mode_info *mode_info = &dev_priv->mode_info;
|
||||
struct atom_context *ctx = mode_info->atom_context;
|
||||
DYNAMIC_CLOCK_GATING_PS_ALLOCATION args;
|
||||
int index = GetIndexIntoMasterTable(COMMAND, DynamicClockGating);
|
||||
|
||||
args.ucEnable = enable;
|
||||
|
||||
atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
|
||||
}
|
||||
|
||||
void radeon_atom_static_pwrmgt_setup(struct drm_device *dev, int enable)
|
||||
{
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct radeon_mode_info *mode_info = &dev_priv->mode_info;
|
||||
struct atom_context *ctx = mode_info->atom_context;
|
||||
ENABLE_ASIC_STATIC_PWR_MGT_PS_ALLOCATION args;
|
||||
int index = GetIndexIntoMasterTable(COMMAND, EnableASIC_StaticPwrMgt);
|
||||
|
||||
args.ucEnable = enable;
|
||||
|
||||
atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
|
||||
}
|
||||
|
||||
266
linux-core/radeon_buffer.c
Normal file
266
linux-core/radeon_buffer.c
Normal file
|
|
@ -0,0 +1,266 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Dave Airlie
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
* USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
*
|
||||
**************************************************************************/
|
||||
/*
|
||||
* Authors: Dave Airlie <airlied@linux.ie>
|
||||
*/
|
||||
|
||||
#include "drmP.h"
|
||||
#include "radeon_drm.h"
|
||||
#include "radeon_drv.h"
|
||||
|
||||
struct drm_ttm_backend *radeon_create_ttm_backend_entry(struct drm_device * dev)
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
|
||||
if(dev_priv->flags & RADEON_IS_AGP)
|
||||
return drm_agp_init_ttm(dev);
|
||||
else
|
||||
return ati_pcigart_init_ttm(dev, &dev_priv->gart_info, radeon_gart_flush);
|
||||
}
|
||||
|
||||
int radeon_fence_types(struct drm_buffer_object *bo, uint32_t * class, uint32_t * type)
|
||||
{
|
||||
*class = 0;
|
||||
*type = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int radeon_invalidate_caches(struct drm_device * dev, uint64_t flags)
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
RING_LOCALS;
|
||||
|
||||
BEGIN_RING(4);
|
||||
RADEON_FLUSH_CACHE();
|
||||
RADEON_FLUSH_ZCACHE();
|
||||
ADVANCE_RING();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int radeon_init_mem_type(struct drm_device * dev, uint32_t type,
|
||||
struct drm_mem_type_manager * man)
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
|
||||
switch (type) {
|
||||
case DRM_BO_MEM_LOCAL:
|
||||
man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE |
|
||||
_DRM_FLAG_MEMTYPE_CACHED;
|
||||
man->drm_bus_maptype = 0;
|
||||
break;
|
||||
case DRM_BO_MEM_VRAM:
|
||||
man->flags = _DRM_FLAG_MEMTYPE_FIXED | _DRM_FLAG_MEMTYPE_MAPPABLE | _DRM_FLAG_NEEDS_IOREMAP;
|
||||
man->io_addr = NULL;
|
||||
man->drm_bus_maptype = _DRM_FRAME_BUFFER;
|
||||
man->io_offset = drm_get_resource_start(dev, 0);
|
||||
man->io_size = drm_get_resource_len(dev, 0);
|
||||
break;
|
||||
case DRM_BO_MEM_TT:
|
||||
if (dev_priv->flags & RADEON_IS_AGP) {
|
||||
if (!(drm_core_has_AGP(dev) && dev->agp)) {
|
||||
DRM_ERROR("AGP is not enabled for memory type %u\n",
|
||||
(unsigned)type);
|
||||
return -EINVAL;
|
||||
}
|
||||
man->io_offset = dev->agp->agp_info.aper_base;
|
||||
man->io_size = dev->agp->agp_info.aper_size * 1024 * 1024;
|
||||
man->io_addr = NULL;
|
||||
man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE |
|
||||
_DRM_FLAG_MEMTYPE_CSELECT | _DRM_FLAG_NEEDS_IOREMAP;
|
||||
man->drm_bus_maptype = _DRM_AGP;
|
||||
} else {
|
||||
man->io_offset = dev_priv->gart_vm_start;
|
||||
man->io_size = dev_priv->gart_size;
|
||||
man->io_addr = NULL;
|
||||
man->flags = _DRM_FLAG_MEMTYPE_CSELECT | _DRM_FLAG_MEMTYPE_MAPPABLE | _DRM_FLAG_MEMTYPE_CMA;
|
||||
man->drm_bus_maptype = _DRM_SCATTER_GATHER;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("Unsupported memory type %u\n", (unsigned)type);
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void radeon_emit_copy_blit(struct drm_device * dev,
|
||||
uint32_t src_offset,
|
||||
uint32_t dst_offset,
|
||||
uint32_t pages, int direction)
|
||||
{
|
||||
uint32_t cur_pages;
|
||||
uint32_t stride = PAGE_SIZE;
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
uint32_t format, height;
|
||||
RING_LOCALS;
|
||||
|
||||
if (!dev_priv)
|
||||
return;
|
||||
|
||||
/* 32-bit copy format */
|
||||
format = RADEON_COLOR_FORMAT_ARGB8888;
|
||||
|
||||
/* radeon limited to 16k stride */
|
||||
stride &= 0x3fff;
|
||||
while(pages > 0) {
|
||||
cur_pages = pages;
|
||||
if (cur_pages > 2048)
|
||||
cur_pages = 2048;
|
||||
pages -= cur_pages;
|
||||
|
||||
/* needs verification */
|
||||
BEGIN_RING(7);
|
||||
OUT_RING(CP_PACKET3(RADEON_CNTL_BITBLT_MULTI, 5));
|
||||
OUT_RING(RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
|
||||
RADEON_GMC_DST_PITCH_OFFSET_CNTL |
|
||||
RADEON_GMC_BRUSH_NONE |
|
||||
(format << 8) |
|
||||
RADEON_GMC_SRC_DATATYPE_COLOR |
|
||||
RADEON_ROP3_S |
|
||||
RADEON_DP_SRC_SOURCE_MEMORY |
|
||||
RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS);
|
||||
if (direction) {
|
||||
OUT_RING((stride << 22) | (src_offset >> 10));
|
||||
OUT_RING((stride << 22) | (dst_offset >> 10));
|
||||
} else {
|
||||
OUT_RING((stride << 22) | (dst_offset >> 10));
|
||||
OUT_RING((stride << 22) | (src_offset >> 10));
|
||||
}
|
||||
OUT_RING(0);
|
||||
OUT_RING(pages); /* x - y */
|
||||
OUT_RING((stride << 16) | cur_pages);
|
||||
ADVANCE_RING();
|
||||
}
|
||||
|
||||
BEGIN_RING(2);
|
||||
RADEON_WAIT_UNTIL_2D_IDLE();
|
||||
ADVANCE_RING();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static int radeon_move_blit(struct drm_buffer_object * bo,
|
||||
int evict, int no_wait, struct drm_bo_mem_reg *new_mem)
|
||||
{
|
||||
struct drm_bo_mem_reg *old_mem = &bo->mem;
|
||||
int dir = 0;
|
||||
|
||||
if ((old_mem->mem_type == new_mem->mem_type) &&
|
||||
(new_mem->mm_node->start <
|
||||
old_mem->mm_node->start + old_mem->mm_node->size)) {
|
||||
dir = 1;
|
||||
}
|
||||
|
||||
radeon_emit_copy_blit(bo->dev,
|
||||
old_mem->mm_node->start << PAGE_SHIFT,
|
||||
new_mem->mm_node->start << PAGE_SHIFT,
|
||||
new_mem->num_pages, dir);
|
||||
|
||||
|
||||
return drm_bo_move_accel_cleanup(bo, evict, no_wait, 0,
|
||||
DRM_FENCE_TYPE_EXE, 0,
|
||||
new_mem);
|
||||
}
|
||||
|
||||
static int radeon_move_flip(struct drm_buffer_object * bo,
|
||||
int evict, int no_wait, struct drm_bo_mem_reg * new_mem)
|
||||
{
|
||||
struct drm_device *dev = bo->dev;
|
||||
struct drm_bo_mem_reg tmp_mem;
|
||||
int ret;
|
||||
|
||||
tmp_mem = *new_mem;
|
||||
tmp_mem.mm_node = NULL;
|
||||
// tmp_mem.mask = DRM_BO_FLAG_MEM_TT |
|
||||
// DRM_BO_FLAG_CACHED | DRM_BO_FLAG_FORCE_CACHING;
|
||||
|
||||
ret = drm_bo_mem_space(bo, &tmp_mem, no_wait);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = drm_ttm_bind(bo->ttm, &tmp_mem);
|
||||
if (ret)
|
||||
goto out_cleanup;
|
||||
|
||||
ret = radeon_move_blit(bo, 1, no_wait, &tmp_mem);
|
||||
if (ret)
|
||||
goto out_cleanup;
|
||||
|
||||
ret = drm_bo_move_ttm(bo, evict, no_wait, new_mem);
|
||||
out_cleanup:
|
||||
if (tmp_mem.mm_node) {
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
if (tmp_mem.mm_node != bo->pinned_node)
|
||||
drm_memrange_put_block(tmp_mem.mm_node);
|
||||
tmp_mem.mm_node = NULL;
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int radeon_move(struct drm_buffer_object * bo,
|
||||
int evict, int no_wait, struct drm_bo_mem_reg * new_mem)
|
||||
{
|
||||
struct drm_bo_mem_reg *old_mem = &bo->mem;
|
||||
|
||||
return drm_bo_move_memcpy(bo, evict, no_wait, new_mem);
|
||||
#if 0
|
||||
DRM_DEBUG("\n");
|
||||
if (old_mem->mem_type == DRM_BO_MEM_LOCAL) {
|
||||
return drm_bo_move_memcpy(bo, evict, no_wait, new_mem);
|
||||
} else if (new_mem->mem_type == DRM_BO_MEM_LOCAL) {
|
||||
if (radeon_move_flip(bo, evict, no_wait, new_mem))
|
||||
return drm_bo_move_memcpy(bo, evict, no_wait, new_mem);
|
||||
} else {
|
||||
if (radeon_move_blit(bo, evict, no_wait, new_mem))
|
||||
return drm_bo_move_memcpy(bo, evict, no_wait, new_mem);
|
||||
}
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* i915_evict_flags:
|
||||
*
|
||||
* @bo: the buffer object to be evicted
|
||||
*
|
||||
* Return the bo flags for a buffer which is not mapped to the hardware.
|
||||
* These will be placed in proposed_flags so that when the move is
|
||||
* finished, they'll end up in bo->mem.flags
|
||||
*/
|
||||
uint64_t radeon_evict_flags(struct drm_buffer_object *bo)
|
||||
{
|
||||
switch (bo->mem.mem_type) {
|
||||
case DRM_BO_MEM_LOCAL:
|
||||
case DRM_BO_MEM_TT:
|
||||
return DRM_BO_FLAG_MEM_LOCAL;
|
||||
default:
|
||||
return DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_CACHED;
|
||||
}
|
||||
}
|
||||
381
linux-core/radeon_combios.c
Normal file
381
linux-core/radeon_combios.c
Normal file
|
|
@ -0,0 +1,381 @@
|
|||
/*
|
||||
* Copyright 2004 ATI Technologies Inc., Markham, Ontario
|
||||
* Copyright 2007-8 Advanced Micro Devices, Inc.
|
||||
* Copyright 2008 Red Hat Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: Dave Airlie
|
||||
* Alex Deucher
|
||||
*/
|
||||
#include "drmP.h"
|
||||
#include "radeon_drm.h"
|
||||
#include "radeon_drv.h"
|
||||
|
||||
/* old legacy ATI BIOS routines */
|
||||
|
||||
enum radeon_combios_ddc
|
||||
{
|
||||
DDC_NONE_DETECTED,
|
||||
DDC_MONID,
|
||||
DDC_DVI,
|
||||
DDC_VGA,
|
||||
DDC_CRT2,
|
||||
DDC_LCD,
|
||||
DDC_GPIO,
|
||||
};
|
||||
|
||||
enum radeon_combios_connector
|
||||
{
|
||||
CONNECTOR_NONE_LEGACY,
|
||||
CONNECTOR_PROPRIETARY_LEGACY,
|
||||
CONNECTOR_CRT_LEGACY,
|
||||
CONNECTOR_DVI_I_LEGACY,
|
||||
CONNECTOR_DVI_D_LEGACY,
|
||||
CONNECTOR_CTV_LEGACY,
|
||||
CONNECTOR_STV_LEGACY,
|
||||
CONNECTOR_UNSUPPORTED_LEGACY
|
||||
};
|
||||
|
||||
struct radeon_i2c_bus_rec combios_setup_i2c_bus(int ddc_line)
|
||||
{
|
||||
struct radeon_i2c_bus_rec i2c;
|
||||
|
||||
i2c.mask_clk_mask = RADEON_GPIO_EN_1 | RADEON_GPIO_Y_1;
|
||||
i2c.mask_data_mask = RADEON_GPIO_EN_0 | RADEON_GPIO_Y_0;
|
||||
i2c.put_clk_mask = RADEON_GPIO_EN_1;
|
||||
i2c.put_data_mask = RADEON_GPIO_EN_0;
|
||||
i2c.get_clk_mask = RADEON_GPIO_Y_1;
|
||||
i2c.get_data_mask = RADEON_GPIO_Y_0;
|
||||
if ((ddc_line == RADEON_LCD_GPIO_MASK) ||
|
||||
(ddc_line == RADEON_MDGPIO_EN_REG)) {
|
||||
i2c.mask_clk_reg = ddc_line;
|
||||
i2c.mask_data_reg = ddc_line;
|
||||
i2c.put_clk_reg = ddc_line;
|
||||
i2c.put_data_reg = ddc_line;
|
||||
i2c.get_clk_reg = ddc_line + 4;
|
||||
i2c.get_data_reg = ddc_line + 4;
|
||||
} else {
|
||||
i2c.mask_clk_reg = ddc_line;
|
||||
i2c.mask_data_reg = ddc_line;
|
||||
i2c.put_clk_reg = ddc_line;
|
||||
i2c.put_data_reg = ddc_line;
|
||||
i2c.get_clk_reg = ddc_line;
|
||||
i2c.get_data_reg = ddc_line;
|
||||
}
|
||||
|
||||
if (ddc_line)
|
||||
i2c.valid = true;
|
||||
else
|
||||
i2c.valid = false;
|
||||
|
||||
return i2c;
|
||||
}
|
||||
|
||||
bool radeon_combios_get_clock_info(struct drm_device *dev)
|
||||
{
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct radeon_mode_info *mode_info = &dev_priv->mode_info;
|
||||
uint16_t pll_info_block;
|
||||
struct radeon_pll *pll = &mode_info->pll;
|
||||
int rev;
|
||||
|
||||
pll_info_block = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x30);
|
||||
rev = radeon_bios8(dev_priv, pll_info_block);
|
||||
|
||||
pll->reference_freq = radeon_bios16(dev_priv, pll_info_block + 0xe);
|
||||
pll->reference_div = radeon_bios16(dev_priv, pll_info_block + 0x10);
|
||||
pll->pll_out_min = radeon_bios32(dev_priv, pll_info_block + 0x12);
|
||||
pll->pll_out_max = radeon_bios32(dev_priv, pll_info_block + 0x16);
|
||||
|
||||
if (rev > 9) {
|
||||
pll->pll_in_min = radeon_bios32(dev_priv, pll_info_block + 0x36);
|
||||
pll->pll_in_max = radeon_bios32(dev_priv, pll_info_block + 0x3a);
|
||||
} else {
|
||||
pll->pll_in_min = 40;
|
||||
pll->pll_in_max = 500;
|
||||
}
|
||||
|
||||
pll->xclk = radeon_bios16(dev_priv, pll_info_block + 0x08);
|
||||
|
||||
// sclk/mclk use fixed point
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool radeon_combios_get_lvds_info(struct radeon_encoder *encoder)
|
||||
{
|
||||
struct drm_device *dev = encoder->base.dev;
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
uint16_t tmp;
|
||||
char stmp[30];
|
||||
int tmp0;
|
||||
int i;
|
||||
|
||||
tmp = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x40);
|
||||
if (!tmp) {
|
||||
DRM_INFO("No panel info found in BIOS\n");
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
for (i = 0; i < 24; i++)
|
||||
stmp[i] = radeon_bios8(dev_priv, tmp + i + 1);
|
||||
stmp[24] = 0;
|
||||
|
||||
DRM_INFO("Panel ID String: %s\n", stmp);
|
||||
|
||||
encoder->panel_xres = radeon_bios16(dev_priv, tmp + 25);
|
||||
encoder->panel_yres = radeon_bios16(dev_priv, tmp + 27);
|
||||
|
||||
DRM_INFO("Panel Size %dx%d\n", encoder->panel_xres, encoder->panel_yres);
|
||||
|
||||
encoder->panel_pwr_delay = radeon_bios16(dev_priv, tmp + 44);
|
||||
if (encoder->panel_pwr_delay > 2000 || encoder->panel_pwr_delay < 0)
|
||||
encoder->panel_pwr_delay = 2000;
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
tmp0 = radeon_bios16(dev_priv, tmp + 64 + i * 2);
|
||||
if (tmp0 == 0) break;
|
||||
|
||||
if ((radeon_bios16(dev_priv, tmp0) == encoder->panel_xres) &&
|
||||
(radeon_bios16(dev_priv, tmp0 + 2) == encoder->panel_yres)) {
|
||||
encoder->hblank = (radeon_bios16(dev_priv, tmp0 + 17) -
|
||||
radeon_bios16(dev_priv, tmp0 + 19)) * 8;
|
||||
encoder->hoverplus = (radeon_bios16(dev_priv, tmp0 + 21) -
|
||||
radeon_bios16(dev_priv, tmp0 + 19) - 1) * 8;
|
||||
encoder->hsync_width = radeon_bios8(dev_priv, tmp0 + 23) * 8;
|
||||
|
||||
encoder->vblank = (radeon_bios16(dev_priv, tmp0 + 24) -
|
||||
radeon_bios16(dev_priv, tmp0 + 26));
|
||||
encoder->voverplus = ((radeon_bios16(dev_priv, tmp0 + 28) & 0x7fff) -
|
||||
radeon_bios16(dev_priv, tmp0 + 26));
|
||||
encoder->vsync_width = ((radeon_bios16(dev_priv, tmp0 + 28) & 0xf800) >> 11);
|
||||
encoder->dotclock = radeon_bios16(dev_priv, tmp0 + 9) * 10;
|
||||
encoder->flags = 0;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void radeon_apply_legacy_quirks(struct drm_device *dev, int bios_index)
|
||||
{
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct radeon_mode_info *mode_info = &dev_priv->mode_info;
|
||||
|
||||
/* on XPRESS chips, CRT2_DDC and MONID_DCC both use the
|
||||
* MONID gpio, but use different pins.
|
||||
* CRT2_DDC uses the standard pinout, MONID_DDC uses
|
||||
* something else.
|
||||
*/
|
||||
if ((dev_priv->chip_family == CHIP_RS400 ||
|
||||
dev_priv->chip_family == CHIP_RS480) &&
|
||||
mode_info->bios_connector[bios_index].connector_type == CONNECTOR_VGA &&
|
||||
mode_info->bios_connector[bios_index].ddc_i2c.mask_clk_reg == RADEON_GPIO_CRT2_DDC) {
|
||||
mode_info->bios_connector[bios_index].ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_MONID);
|
||||
}
|
||||
|
||||
/* XPRESS desktop chips seem to have a proprietary connector listed for
|
||||
* DVI-D, try and do the right thing here.
|
||||
*/
|
||||
if ((dev_priv->flags & RADEON_IS_MOBILITY) &&
|
||||
(mode_info->bios_connector[bios_index].connector_type == CONNECTOR_LVDS)) {
|
||||
DRM_INFO("proprietary connector found. assuming DVI-D\n");
|
||||
mode_info->bios_connector[bios_index].dac_type = DAC_NONE;
|
||||
mode_info->bios_connector[bios_index].tmds_type = TMDS_EXT;
|
||||
mode_info->bios_connector[bios_index].connector_type = CONNECTOR_DVI_D;
|
||||
}
|
||||
|
||||
/* Certain IBM chipset RN50s have a BIOS reporting two VGAs,
|
||||
one with VGA DDC and one with CRT2 DDC. - kill the CRT2 DDC one */
|
||||
if (dev->pdev->device == 0x515e &&
|
||||
dev->pdev->subsystem_vendor == 0x1014) {
|
||||
if (mode_info->bios_connector[bios_index].connector_type == CONNECTOR_VGA &&
|
||||
mode_info->bios_connector[bios_index].ddc_i2c.mask_clk_reg == RADEON_GPIO_CRT2_DDC) {
|
||||
mode_info->bios_connector[bios_index].valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Some RV100 cards with 2 VGA ports show up with DVI+VGA */
|
||||
if (dev->pdev->device == 0x5159 &&
|
||||
dev->pdev->subsystem_vendor == 0x1002 &&
|
||||
dev->pdev->subsystem_device == 0x013a) {
|
||||
if (mode_info->bios_connector[bios_index].connector_type == CONNECTOR_DVI_I)
|
||||
mode_info->bios_connector[bios_index].connector_type = CONNECTOR_VGA;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
|
||||
{
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct radeon_mode_info *mode_info = &dev_priv->mode_info;
|
||||
uint32_t offset, entry;
|
||||
uint16_t tmp0, tmp1, tmp;
|
||||
enum radeon_combios_ddc ddctype;
|
||||
enum radeon_combios_connector connector_type;
|
||||
int i;
|
||||
|
||||
DRM_DEBUG("\n");
|
||||
offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x50);
|
||||
if (offset) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
entry = offset + 2 + i * 2;
|
||||
|
||||
if (!radeon_bios16(dev_priv, entry))
|
||||
break;
|
||||
|
||||
mode_info->bios_connector[i].valid = true;
|
||||
|
||||
tmp = radeon_bios16(dev_priv, entry);
|
||||
|
||||
connector_type = (tmp >> 12) & 0xf;
|
||||
mode_info->bios_connector[i].connector_type = connector_type;
|
||||
|
||||
switch(connector_type) {
|
||||
case CONNECTOR_PROPRIETARY_LEGACY:
|
||||
mode_info->bios_connector[i].connector_type = CONNECTOR_LVDS;
|
||||
break;
|
||||
case CONNECTOR_CRT_LEGACY:
|
||||
mode_info->bios_connector[i].connector_type = CONNECTOR_VGA;
|
||||
break;
|
||||
case CONNECTOR_DVI_I_LEGACY:
|
||||
mode_info->bios_connector[i].connector_type = CONNECTOR_DVI_I;
|
||||
break;
|
||||
case CONNECTOR_DVI_D_LEGACY:
|
||||
mode_info->bios_connector[i].connector_type = CONNECTOR_DVI_D;
|
||||
break;
|
||||
case CONNECTOR_CTV_LEGACY:
|
||||
mode_info->bios_connector[i].connector_type = CONNECTOR_CTV;
|
||||
break;
|
||||
case CONNECTOR_STV_LEGACY:
|
||||
mode_info->bios_connector[i].connector_type = CONNECTOR_STV;
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("Unknown connector type: %d\n", connector_type);
|
||||
mode_info->bios_connector[i].valid = false;
|
||||
break;
|
||||
}
|
||||
|
||||
mode_info->bios_connector[i].ddc_i2c.valid = false;
|
||||
|
||||
ddctype = (tmp >> 8) & 0xf;
|
||||
switch (ddctype) {
|
||||
case DDC_MONID:
|
||||
mode_info->bios_connector[i].ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_MONID);
|
||||
break;
|
||||
case DDC_DVI:
|
||||
mode_info->bios_connector[i].ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
|
||||
break;
|
||||
case DDC_VGA:
|
||||
mode_info->bios_connector[i].ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
|
||||
break;
|
||||
case DDC_CRT2:
|
||||
mode_info->bios_connector[i].ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (tmp & 0x1)
|
||||
mode_info->bios_connector[i].dac_type = DAC_TVDAC;
|
||||
else
|
||||
mode_info->bios_connector[i].dac_type = DAC_PRIMARY;
|
||||
|
||||
if ((dev_priv->chip_family == CHIP_RS300) ||
|
||||
(dev_priv->chip_family == CHIP_RS400) ||
|
||||
(dev_priv->chip_family == CHIP_RS480))
|
||||
mode_info->bios_connector[i].dac_type = DAC_TVDAC;
|
||||
|
||||
if ((tmp >> 4) & 0x1)
|
||||
mode_info->bios_connector[i].tmds_type = TMDS_EXT;
|
||||
else
|
||||
mode_info->bios_connector[i].tmds_type = TMDS_INT;
|
||||
|
||||
radeon_apply_legacy_quirks(dev, i);
|
||||
}
|
||||
} else {
|
||||
DRM_INFO("no connector table found in BIOS\n");
|
||||
offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x34);
|
||||
if (offset) {
|
||||
DRM_DEBUG("Found DFP table, assuming DVI connector\n");
|
||||
|
||||
mode_info->bios_connector[0].valid = true;
|
||||
mode_info->bios_connector[0].connector_type = CONNECTOR_DVI_I;
|
||||
mode_info->bios_connector[0].dac_type = DAC_PRIMARY;
|
||||
mode_info->bios_connector[0].tmds_type = TMDS_INT;
|
||||
mode_info->bios_connector[0].ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
|
||||
} else {
|
||||
DRM_DEBUG("No table found\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (dev_priv->flags & RADEON_IS_MOBILITY) {
|
||||
offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x40);
|
||||
if (offset) {
|
||||
mode_info->bios_connector[4].valid = true;
|
||||
mode_info->bios_connector[4].connector_type = CONNECTOR_LVDS;
|
||||
mode_info->bios_connector[4].dac_type = DAC_NONE;
|
||||
mode_info->bios_connector[4].tmds_type = TMDS_NONE;
|
||||
mode_info->bios_connector[4].ddc_i2c.valid = false;
|
||||
|
||||
tmp = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x42);
|
||||
if (tmp) {
|
||||
tmp0 = radeon_bios16(dev_priv, tmp + 0x15);
|
||||
if (tmp0) {
|
||||
tmp1 = radeon_bios8(dev_priv, tmp0 + 2) & 0x07;
|
||||
if (tmp1) {
|
||||
ddctype = tmp1;
|
||||
|
||||
switch(ddctype) {
|
||||
case DDC_MONID:
|
||||
case DDC_DVI:
|
||||
case DDC_CRT2:
|
||||
case DDC_LCD:
|
||||
case DDC_GPIO:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
DRM_DEBUG("LCD DDC Info Table found!\n");
|
||||
}
|
||||
}
|
||||
} else
|
||||
mode_info->bios_connector[4].ddc_i2c.valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
DRM_DEBUG("BIOS Connector table\n");
|
||||
for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
|
||||
if (!mode_info->bios_connector[i].valid)
|
||||
continue;
|
||||
|
||||
DRM_DEBUG("Port %d: ddc_type 0x%x, dac_type %d, tmds_type %d, connector type %d, hpd_mask %d\n",
|
||||
i, mode_info->bios_connector[i].ddc_i2c.mask_clk_reg,
|
||||
mode_info->bios_connector[i].dac_type,
|
||||
mode_info->bios_connector[i].tmds_type,
|
||||
mode_info->bios_connector[i].connector_type,
|
||||
mode_info->bios_connector[i].hpd_mask);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
344
linux-core/radeon_connectors.c
Normal file
344
linux-core/radeon_connectors.c
Normal file
|
|
@ -0,0 +1,344 @@
|
|||
/*
|
||||
* Copyright 2007-8 Advanced Micro Devices, Inc.
|
||||
* Copyright 2008 Red Hat Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: Dave Airlie
|
||||
* Alex Deucher
|
||||
*/
|
||||
#include "drmP.h"
|
||||
#include "drm_edid.h"
|
||||
#include "drm_crtc_helper.h"
|
||||
#include "radeon_drm.h"
|
||||
#include "radeon_drv.h"
|
||||
|
||||
static int radeon_lvds_get_modes(struct drm_connector *connector)
|
||||
{
|
||||
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
|
||||
struct drm_encoder *lvds_encoder;
|
||||
int ret = 0;
|
||||
struct edid *edid;
|
||||
|
||||
avivo_i2c_do_lock(radeon_connector, 1);
|
||||
edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
|
||||
avivo_i2c_do_lock(radeon_connector, 0);
|
||||
if (edid) {
|
||||
drm_mode_connector_update_edid_property(&radeon_connector->base, edid);
|
||||
ret = drm_add_edid_modes(&radeon_connector->base, edid);
|
||||
kfree(edid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
lvds_encoder = radeon_best_single_encoder(connector);
|
||||
|
||||
if (!lvds_encoder)
|
||||
return ret;
|
||||
|
||||
radeon_encoder_update_panel_size(lvds_encoder, connector);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int radeon_lvds_mode_valid(struct drm_connector *connector,
|
||||
struct drm_display_mode *mode)
|
||||
{
|
||||
|
||||
return MODE_OK;
|
||||
}
|
||||
|
||||
static enum drm_connector_status radeon_lvds_detect(struct drm_connector *connector)
|
||||
{
|
||||
return connector_status_connected;
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct drm_encoder *radeon_best_single_encoder(struct drm_connector *connector)
|
||||
{
|
||||
int enc_id = connector->encoder_ids[0];
|
||||
struct drm_mode_object *obj;
|
||||
struct drm_encoder *encoder;
|
||||
|
||||
/* pick the encoder ids */
|
||||
if (enc_id) {
|
||||
obj = drm_mode_object_find(connector->dev, enc_id, DRM_MODE_OBJECT_ENCODER);
|
||||
if (!obj)
|
||||
return NULL;
|
||||
encoder = obj_to_encoder(obj);
|
||||
return encoder;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void radeon_connector_destroy(struct drm_connector *connector)
|
||||
{
|
||||
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
|
||||
|
||||
if (radeon_connector->ddc_bus)
|
||||
radeon_i2c_destroy(radeon_connector->ddc_bus);
|
||||
drm_sysfs_connector_remove(connector);
|
||||
drm_connector_cleanup(connector);
|
||||
kfree(connector);
|
||||
}
|
||||
|
||||
struct drm_connector_helper_funcs radeon_lvds_connector_helper_funcs = {
|
||||
.get_modes = radeon_lvds_get_modes,
|
||||
.mode_valid = radeon_lvds_mode_valid,
|
||||
.best_encoder = radeon_best_single_encoder,
|
||||
};
|
||||
|
||||
struct drm_connector_funcs radeon_lvds_connector_funcs = {
|
||||
.detect = radeon_lvds_detect,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.destroy = radeon_connector_destroy,
|
||||
};
|
||||
|
||||
static int radeon_atom_vga_get_modes(struct drm_connector *connector)
|
||||
{
|
||||
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
|
||||
int ret;
|
||||
|
||||
ret = radeon_ddc_get_modes(radeon_connector);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int radeon_atom_vga_mode_valid(struct drm_connector *connector,
|
||||
struct drm_display_mode *mode)
|
||||
{
|
||||
|
||||
return MODE_OK;
|
||||
}
|
||||
|
||||
static enum drm_connector_status radeon_atom_vga_detect(struct drm_connector *connector)
|
||||
{
|
||||
struct edid *edid;
|
||||
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
|
||||
struct drm_encoder *encoder;
|
||||
struct drm_encoder_helper_funcs *encoder_funcs;
|
||||
|
||||
avivo_i2c_do_lock(radeon_connector, 1);
|
||||
edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
|
||||
avivo_i2c_do_lock(radeon_connector, 0);
|
||||
if (edid) {
|
||||
kfree(edid);
|
||||
return connector_status_connected;
|
||||
}
|
||||
|
||||
/* if EDID fails to a load detect */
|
||||
encoder = radeon_best_single_encoder(connector);
|
||||
if (!encoder)
|
||||
return connector_status_disconnected;
|
||||
|
||||
encoder_funcs = encoder->helper_private;
|
||||
return encoder_funcs->detect(encoder, connector);
|
||||
}
|
||||
|
||||
struct drm_connector_helper_funcs radeon_atom_vga_connector_helper_funcs = {
|
||||
.get_modes = radeon_atom_vga_get_modes,
|
||||
.mode_valid = radeon_atom_vga_mode_valid,
|
||||
.best_encoder = radeon_best_single_encoder,
|
||||
};
|
||||
|
||||
struct drm_connector_funcs radeon_atom_vga_connector_funcs = {
|
||||
.detect = radeon_atom_vga_detect,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.destroy = radeon_connector_destroy,
|
||||
};
|
||||
|
||||
|
||||
static enum drm_connector_status radeon_atom_dvi_detect(struct drm_connector *connector)
|
||||
{
|
||||
struct edid *edid;
|
||||
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
|
||||
struct drm_encoder *encoder;
|
||||
struct drm_encoder_helper_funcs *encoder_funcs;
|
||||
struct drm_mode_object *obj;
|
||||
int i;
|
||||
enum drm_connector_status ret;
|
||||
|
||||
avivo_i2c_do_lock(radeon_connector, 1);
|
||||
edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
|
||||
avivo_i2c_do_lock(radeon_connector, 0);
|
||||
if (edid) {
|
||||
/* if the monitor is digital - set the bits */
|
||||
if (edid->digital)
|
||||
radeon_connector->use_digital = 1;
|
||||
else
|
||||
radeon_connector->use_digital = 0;
|
||||
|
||||
kfree(edid);
|
||||
return connector_status_connected;
|
||||
}
|
||||
|
||||
for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
|
||||
if (connector->encoder_ids[i] == 0)
|
||||
break;
|
||||
|
||||
obj = drm_mode_object_find(connector->dev, connector->encoder_ids[i], DRM_MODE_OBJECT_ENCODER);
|
||||
if (!obj)
|
||||
continue;
|
||||
|
||||
encoder = obj_to_encoder(obj);
|
||||
|
||||
encoder_funcs = encoder->helper_private;
|
||||
if (encoder_funcs->detect) {
|
||||
ret = encoder_funcs->detect(encoder, connector);
|
||||
if (ret == connector_status_connected) {
|
||||
radeon_connector->use_digital = 0;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
return connector_status_disconnected;
|
||||
}
|
||||
|
||||
/* okay need to be smart in here about which encoder to pick */
|
||||
struct drm_encoder *radeon_atom_dvi_encoder(struct drm_connector *connector)
|
||||
{
|
||||
int enc_id = connector->encoder_ids[0];
|
||||
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
|
||||
struct drm_mode_object *obj;
|
||||
struct drm_encoder *encoder;
|
||||
int i;
|
||||
for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
|
||||
if (connector->encoder_ids[i] == 0)
|
||||
break;
|
||||
|
||||
obj = drm_mode_object_find(connector->dev, connector->encoder_ids[i], DRM_MODE_OBJECT_ENCODER);
|
||||
if (!obj)
|
||||
continue;
|
||||
|
||||
encoder = obj_to_encoder(obj);
|
||||
|
||||
if (radeon_connector->use_digital) {
|
||||
if (encoder->encoder_type == DRM_MODE_ENCODER_TMDS)
|
||||
return encoder;
|
||||
} else {
|
||||
if (encoder->encoder_type == DRM_MODE_ENCODER_DAC ||
|
||||
encoder->encoder_type == DRM_MODE_ENCODER_TVDAC)
|
||||
return encoder;
|
||||
}
|
||||
}
|
||||
|
||||
/* see if we have a default encoder TODO */
|
||||
|
||||
/* then check use digitial */
|
||||
/* pick the first one */
|
||||
if (enc_id) {
|
||||
obj = drm_mode_object_find(connector->dev, enc_id, DRM_MODE_OBJECT_ENCODER);
|
||||
if (!obj)
|
||||
return NULL;
|
||||
encoder = obj_to_encoder(obj);
|
||||
return encoder;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct drm_connector_helper_funcs radeon_atom_dvi_connector_helper_funcs = {
|
||||
.get_modes = radeon_atom_vga_get_modes,
|
||||
.mode_valid = radeon_atom_vga_mode_valid,
|
||||
.best_encoder = radeon_atom_dvi_encoder,
|
||||
};
|
||||
|
||||
struct drm_connector_funcs radeon_atom_dvi_connector_funcs = {
|
||||
.detect = radeon_atom_dvi_detect,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.destroy = radeon_connector_destroy,
|
||||
};
|
||||
|
||||
|
||||
static struct connector_funcs {
|
||||
int conn_id;
|
||||
struct drm_connector_funcs *connector_funcs;
|
||||
struct drm_connector_helper_funcs *helper_funcs;
|
||||
int conn_type;
|
||||
char *i2c_id;
|
||||
} connector_fns[] = {
|
||||
{ CONNECTOR_NONE, NULL, NULL, DRM_MODE_CONNECTOR_Unknown },
|
||||
{ CONNECTOR_VGA, &radeon_atom_vga_connector_funcs, &radeon_atom_vga_connector_helper_funcs, DRM_MODE_CONNECTOR_VGA , "VGA"},
|
||||
{ CONNECTOR_LVDS, &radeon_lvds_connector_funcs, &radeon_lvds_connector_helper_funcs, DRM_MODE_CONNECTOR_LVDS, "LVDS" },
|
||||
{ CONNECTOR_DVI_A, &radeon_atom_vga_connector_funcs, &radeon_atom_vga_connector_helper_funcs, DRM_MODE_CONNECTOR_DVIA, "DVI" },
|
||||
{ CONNECTOR_DVI_I, &radeon_atom_dvi_connector_funcs, &radeon_atom_dvi_connector_helper_funcs, DRM_MODE_CONNECTOR_DVII, "DVI" },
|
||||
|
||||
#if 0
|
||||
{ CONNECTOR_DVI_D, radeon_vga_connector_funcs, radeon_vga_connector_helper_funcs, DRM_MODE_CONNECTOR_VGA },
|
||||
|
||||
{ CONNECTOR_STV, radeon_vga_connector_funcs, radeon_vga_connector_helper_funcs, DRM_MODE_CONNECTOR_VGA },
|
||||
{ CONNECTOR_CTV, radeon_vga_connector_funcs, radeon_vga_connector_helper_funcs, DRM_MODE_CONNECTOR_VGA },
|
||||
{ CONNECTOR_DIGITAL, radeon_vga_connector_funcs, radeon_vga_connector_helper_funcs, DRM_MODE_CONNECTOR_VGA },
|
||||
{ CONNECTOR_SCART, radeon_vga_connector_funcs, radeon_vga_connector_helper_funcs, DRM_MODE_CONNECTOR_VGA },
|
||||
|
||||
{ CONNECTOR_HDMI_TYPE_A, radeon_vga_connector_funcs, radeon_vga_connector_helper_funcs, DRM_MODE_CONNECTOR_VGA },
|
||||
{ CONNECTOR_HDMI_TYPE_B, radeon_vga_connector_funcs, radeon_vga_connector_helper_funcs, DRM_MODE_CONNECTOR_VGA },
|
||||
{ CONNECTOR_HDMI_TYPE_B, radeon_vga_connector_funcs, radeon_vga_connector_helper_funcs, DRM_MODE_CONNECTOR_VGA },
|
||||
{ CONNECTOR_HDMI_TYPE_B, radeon_vga_connector_funcs, radeon_vga_connector_helper_funcs, DRM_MODE_CONNECTOR_VGA },
|
||||
{ CONNECTOR_DIN, radeon_vga_connector_funcs, radeon_vga_connector_helper_funcs, DRM_MODE_CONNECTOR_VGA },
|
||||
{ CONNECTOR_DISPLAY_PORT, radeon_vga_connector_funcs, radeon_vga_connector_helper_funcs, DRM_MODE_CONNECTOR_VGA },
|
||||
#endif
|
||||
};
|
||||
|
||||
struct drm_connector *radeon_connector_add(struct drm_device *dev, int bios_index)
|
||||
{
|
||||
struct radeon_connector *radeon_connector;
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct radeon_mode_info *mode_info = &dev_priv->mode_info;
|
||||
struct drm_connector *connector;
|
||||
int table_idx;
|
||||
|
||||
for (table_idx = 0; table_idx < ARRAY_SIZE(connector_fns); table_idx++) {
|
||||
if (connector_fns[table_idx].conn_id == mode_info->bios_connector[bios_index].connector_type)
|
||||
break;
|
||||
}
|
||||
|
||||
if (table_idx == ARRAY_SIZE(connector_fns))
|
||||
return NULL;
|
||||
|
||||
radeon_connector = kzalloc(sizeof(struct radeon_connector), GFP_KERNEL);
|
||||
if (!radeon_connector) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
connector = &radeon_connector->base;
|
||||
|
||||
drm_connector_init(dev, &radeon_connector->base, connector_fns[table_idx].connector_funcs,
|
||||
connector_fns[table_idx].conn_type);
|
||||
|
||||
drm_connector_helper_add(&radeon_connector->base, connector_fns[table_idx].helper_funcs);
|
||||
|
||||
if (mode_info->bios_connector[bios_index].ddc_i2c.valid) {
|
||||
radeon_connector->ddc_bus = radeon_i2c_create(dev, &mode_info->bios_connector[bios_index].ddc_i2c,
|
||||
connector_fns[table_idx].i2c_id);
|
||||
if (!radeon_connector->ddc_bus)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
drm_sysfs_connector_add(connector);
|
||||
return connector;
|
||||
|
||||
|
||||
failed:
|
||||
if (radeon_connector->ddc_bus)
|
||||
radeon_i2c_destroy(radeon_connector->ddc_bus);
|
||||
drm_connector_cleanup(connector);
|
||||
kfree(connector);
|
||||
return NULL;
|
||||
}
|
||||
725
linux-core/radeon_display.c
Normal file
725
linux-core/radeon_display.c
Normal file
|
|
@ -0,0 +1,725 @@
|
|||
/*
|
||||
* Copyright 2007-8 Advanced Micro Devices, Inc.
|
||||
* Copyright 2008 Red Hat Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: Dave Airlie
|
||||
* Alex Deucher
|
||||
*/
|
||||
#include "drmP.h"
|
||||
#include "radeon_drm.h"
|
||||
#include "radeon_drv.h"
|
||||
|
||||
#include "atom.h"
|
||||
#include <asm/div64.h>
|
||||
|
||||
#include "drm_crtc_helper.h"
|
||||
|
||||
#define CURSOR_WIDTH 64
|
||||
#define CURSOR_HEIGHT 64
|
||||
|
||||
int radeon_ddc_dump(struct drm_connector *connector);
|
||||
|
||||
|
||||
|
||||
static void avivo_crtc_load_lut(struct drm_crtc *crtc)
|
||||
{
|
||||
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
int i;
|
||||
|
||||
DRM_DEBUG("%d\n", radeon_crtc->crtc_id);
|
||||
RADEON_WRITE(AVIVO_DC_LUTA_CONTROL + radeon_crtc->crtc_offset, 0);
|
||||
|
||||
RADEON_WRITE(AVIVO_DC_LUTA_BLACK_OFFSET_BLUE + radeon_crtc->crtc_offset, 0);
|
||||
RADEON_WRITE(AVIVO_DC_LUTA_BLACK_OFFSET_GREEN + radeon_crtc->crtc_offset, 0);
|
||||
RADEON_WRITE(AVIVO_DC_LUTA_BLACK_OFFSET_RED + radeon_crtc->crtc_offset, 0);
|
||||
|
||||
RADEON_WRITE(AVIVO_DC_LUTA_WHITE_OFFSET_BLUE + radeon_crtc->crtc_offset, 0xffff);
|
||||
RADEON_WRITE(AVIVO_DC_LUTA_WHITE_OFFSET_GREEN + radeon_crtc->crtc_offset, 0xffff);
|
||||
RADEON_WRITE(AVIVO_DC_LUTA_WHITE_OFFSET_RED + radeon_crtc->crtc_offset, 0xffff);
|
||||
|
||||
RADEON_WRITE(AVIVO_DC_LUT_RW_SELECT, radeon_crtc->crtc_id);
|
||||
RADEON_WRITE(AVIVO_DC_LUT_RW_MODE, 0);
|
||||
RADEON_WRITE(AVIVO_DC_LUT_WRITE_EN_MASK, 0x0000003f);
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
|
||||
RADEON_WRITE8(AVIVO_DC_LUT_RW_INDEX, i);
|
||||
RADEON_WRITE(AVIVO_DC_LUT_30_COLOR,
|
||||
(radeon_crtc->lut_r[i] << 22) |
|
||||
(radeon_crtc->lut_g[i] << 12) |
|
||||
(radeon_crtc->lut_b[i] << 2));
|
||||
}
|
||||
|
||||
RADEON_WRITE(AVIVO_D1GRPH_LUT_SEL + radeon_crtc->crtc_offset, radeon_crtc->crtc_id);
|
||||
}
|
||||
|
||||
|
||||
void radeon_crtc_load_lut(struct drm_crtc *crtc)
|
||||
{
|
||||
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
u32 temp;
|
||||
int i;
|
||||
if (!crtc->enabled)
|
||||
return;
|
||||
|
||||
|
||||
if (radeon_is_avivo(dev_priv)) {
|
||||
avivo_crtc_load_lut(crtc);
|
||||
return;
|
||||
}
|
||||
|
||||
temp = RADEON_READ(RADEON_DAC_CNTL2);
|
||||
if (radeon_crtc->crtc_id == 0)
|
||||
temp &= (uint32_t)~RADEON_DAC2_PALETTE_ACC_CTL;
|
||||
else
|
||||
temp |= RADEON_DAC2_PALETTE_ACC_CTL;
|
||||
RADEON_WRITE(RADEON_DAC_CNTL2, temp);
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
// OUTPAL(i, radeon_crtc->lut_r[i], radeon_crtc->lut_g[i], radeon_crtc->lut_b[i]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** Sets the color ramps on behalf of RandR */
|
||||
void radeon_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
|
||||
u16 blue, int regno)
|
||||
{
|
||||
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
|
||||
|
||||
if (regno==0)
|
||||
DRM_DEBUG("gamma set %d\n", radeon_crtc->crtc_id);
|
||||
radeon_crtc->lut_r[regno] = red >> 8;
|
||||
radeon_crtc->lut_g[regno] = green >> 8;
|
||||
radeon_crtc->lut_b[regno] = blue >> 8;
|
||||
}
|
||||
|
||||
void radeon_crtc_dpms(struct drm_crtc *crtc, int mode)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
static bool radeon_crtc_mode_fixup(struct drm_crtc *crtc,
|
||||
struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static void radeon_crtc_mode_set(struct drm_crtc *crtc,
|
||||
struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode,
|
||||
int x, int y)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y)
|
||||
{
|
||||
}
|
||||
|
||||
static void radeon_crtc_prepare(struct drm_crtc *crtc)
|
||||
{
|
||||
}
|
||||
|
||||
static void radeon_crtc_commit(struct drm_crtc *crtc)
|
||||
{
|
||||
}
|
||||
|
||||
static void avivo_lock_cursor(struct drm_crtc *crtc, bool lock)
|
||||
{
|
||||
struct drm_radeon_private *dev_priv = crtc->dev->dev_private;
|
||||
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
|
||||
|
||||
uint32_t tmp;
|
||||
|
||||
tmp = RADEON_READ(AVIVO_D1CUR_UPDATE + radeon_crtc->crtc_offset);
|
||||
if (lock)
|
||||
tmp |= AVIVO_D1CURSOR_UPDATE_LOCK;
|
||||
else
|
||||
tmp &= ~AVIVO_D1CURSOR_UPDATE_LOCK;
|
||||
|
||||
RADEON_WRITE(AVIVO_D1CUR_UPDATE + radeon_crtc->crtc_offset, tmp);
|
||||
}
|
||||
|
||||
static int radeon_crtc_cursor_set(struct drm_crtc *crtc,
|
||||
struct drm_file *file_priv,
|
||||
uint32_t handle,
|
||||
uint32_t width,
|
||||
uint32_t height)
|
||||
{
|
||||
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
|
||||
struct drm_radeon_private *dev_priv = crtc->dev->dev_private;
|
||||
struct drm_gem_object *obj;
|
||||
struct drm_radeon_gem_object *obj_priv;
|
||||
|
||||
if (!handle) {
|
||||
RADEON_WRITE(AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset, 0);
|
||||
return 0;
|
||||
/* turn off cursor */
|
||||
}
|
||||
|
||||
obj = drm_gem_object_lookup(crtc->dev, file_priv, handle);
|
||||
if (!obj) {
|
||||
DRM_ERROR("Cannot find cursor object %x for crtc %d\n", handle, radeon_crtc->crtc_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
obj_priv = obj->driver_private;
|
||||
|
||||
RADEON_WRITE(AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset, 0);
|
||||
if (radeon_is_avivo(dev_priv)) {
|
||||
RADEON_WRITE(AVIVO_D1CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
|
||||
dev_priv->fb_location + obj_priv->bo->offset);
|
||||
RADEON_WRITE(AVIVO_D1CUR_SIZE + radeon_crtc->crtc_offset,
|
||||
(CURSOR_WIDTH - 1) << 16 | (CURSOR_HEIGHT - 1));
|
||||
RADEON_WRITE(AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset,
|
||||
AVIVO_D1CURSOR_EN | (AVIVO_D1CURSOR_MODE_24BPP << AVIVO_D1CURSOR_MODE_SHIFT));
|
||||
}
|
||||
|
||||
mutex_lock(&crtc->dev->struct_mutex);
|
||||
drm_gem_object_unreference(obj);
|
||||
mutex_unlock(&crtc->dev->struct_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int radeon_crtc_cursor_move(struct drm_crtc *crtc,
|
||||
int x, int y)
|
||||
{
|
||||
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
|
||||
struct drm_radeon_private *dev_priv = crtc->dev->dev_private;
|
||||
int xorigin = 0, yorigin = 0;
|
||||
|
||||
if (x < 0) xorigin = -x+1;
|
||||
if (y < 0) yorigin = -x+1;
|
||||
if (xorigin >= CURSOR_WIDTH) xorigin = CURSOR_WIDTH - 1;
|
||||
if (yorigin >= CURSOR_WIDTH) yorigin = CURSOR_WIDTH - 1;
|
||||
|
||||
if (crtc->mode.flags & DRM_MODE_FLAG_INTERLACE)
|
||||
y /= 2;
|
||||
else if (crtc->mode.flags & DRM_MODE_FLAG_DBLSCAN)
|
||||
y *= 2;
|
||||
|
||||
if (radeon_is_avivo(dev_priv)) {
|
||||
avivo_lock_cursor(crtc, true);
|
||||
|
||||
RADEON_WRITE(AVIVO_D1CUR_POSITION + radeon_crtc->crtc_offset,
|
||||
((xorigin ? 0: x) << 16) |
|
||||
(yorigin ? 0 : y));
|
||||
RADEON_WRITE(AVIVO_D1CUR_HOT_SPOT + radeon_crtc->crtc_offset, (xorigin << 16) | yorigin);
|
||||
avivo_lock_cursor(crtc, false);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void radeon_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
|
||||
u16 *blue, uint32_t size)
|
||||
{
|
||||
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
|
||||
int i;
|
||||
|
||||
if (size != 256)
|
||||
return;
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
radeon_crtc->lut_r[i] = red[i] >> 8;
|
||||
radeon_crtc->lut_g[i] = green[i] >> 8;
|
||||
radeon_crtc->lut_b[i] = blue[i] >> 8;
|
||||
}
|
||||
|
||||
radeon_crtc_load_lut(crtc);
|
||||
}
|
||||
|
||||
static void radeon_crtc_destroy(struct drm_crtc *crtc)
|
||||
{
|
||||
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
|
||||
|
||||
drm_crtc_cleanup(crtc);
|
||||
kfree(radeon_crtc);
|
||||
}
|
||||
|
||||
static const struct drm_crtc_helper_funcs radeon_helper_funcs = {
|
||||
.dpms = radeon_crtc_dpms,
|
||||
.mode_fixup = radeon_crtc_mode_fixup,
|
||||
.mode_set = radeon_crtc_mode_set,
|
||||
.mode_set_base = radeon_crtc_set_base,
|
||||
.prepare = radeon_crtc_prepare,
|
||||
.commit = radeon_crtc_commit,
|
||||
};
|
||||
|
||||
static const struct drm_crtc_funcs radeon_crtc_funcs = {
|
||||
.cursor_set = radeon_crtc_cursor_set,
|
||||
.cursor_move = radeon_crtc_cursor_move,
|
||||
.gamma_set = radeon_crtc_gamma_set,
|
||||
.set_config = drm_crtc_helper_set_config,
|
||||
.destroy = radeon_crtc_destroy,
|
||||
};
|
||||
|
||||
static void radeon_crtc_init(struct drm_device *dev, int index)
|
||||
{
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct radeon_crtc *radeon_crtc;
|
||||
int i;
|
||||
|
||||
radeon_crtc = kzalloc(sizeof(struct radeon_crtc) + (RADEONFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL);
|
||||
// radeon_crtc = kzalloc(sizeof(struct radeon_crtc), GFP_KERNEL);
|
||||
if (radeon_crtc == NULL)
|
||||
return;
|
||||
|
||||
drm_crtc_init(dev, &radeon_crtc->base, &radeon_crtc_funcs);
|
||||
|
||||
drm_mode_crtc_set_gamma_size(&radeon_crtc->base, 256);
|
||||
radeon_crtc->crtc_id = index;
|
||||
|
||||
radeon_crtc->mode_set.crtc = &radeon_crtc->base;
|
||||
radeon_crtc->mode_set.connectors = (struct drm_connector **)(radeon_crtc + 1);
|
||||
radeon_crtc->mode_set.num_connectors = 0;
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
radeon_crtc->lut_r[i] = i;
|
||||
radeon_crtc->lut_g[i] = i;
|
||||
radeon_crtc->lut_b[i] = i;
|
||||
}
|
||||
|
||||
if (dev_priv->is_atom_bios && dev_priv->chip_family > CHIP_RS690)
|
||||
radeon_atombios_init_crtc(dev, radeon_crtc);
|
||||
else
|
||||
drm_crtc_helper_add(&radeon_crtc->base, &radeon_helper_funcs);
|
||||
}
|
||||
|
||||
bool radeon_legacy_setup_enc_conn(struct drm_device *dev)
|
||||
{
|
||||
|
||||
radeon_get_legacy_connector_info_from_bios(dev);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool radeon_setup_enc_conn(struct drm_device *dev)
|
||||
{
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct radeon_mode_info *mode_info = &dev_priv->mode_info;
|
||||
/* do all the mac and stuff */
|
||||
struct drm_connector *connector;
|
||||
struct drm_encoder *encoder;
|
||||
int i;
|
||||
|
||||
if (dev_priv->is_atom_bios)
|
||||
radeon_get_atom_connector_info_from_bios_connector_table(dev);
|
||||
else
|
||||
radeon_get_legacy_connector_info_from_bios(dev);
|
||||
|
||||
for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
|
||||
if (!mode_info->bios_connector[i].valid)
|
||||
continue;
|
||||
|
||||
/* add a connector for this */
|
||||
if (mode_info->bios_connector[i].connector_type == CONNECTOR_NONE)
|
||||
continue;
|
||||
|
||||
connector = radeon_connector_add(dev, i);
|
||||
if (!connector)
|
||||
continue;
|
||||
|
||||
encoder = NULL;
|
||||
/* if we find an LVDS connector */
|
||||
if (mode_info->bios_connector[i].connector_type == CONNECTOR_LVDS) {
|
||||
if (radeon_is_avivo(dev_priv))
|
||||
encoder = radeon_encoder_lvtma_add(dev, i);
|
||||
else
|
||||
encoder = radeon_encoder_legacy_lvds_add(dev, i);
|
||||
if (encoder)
|
||||
drm_mode_connector_attach_encoder(connector, encoder);
|
||||
}
|
||||
|
||||
/* DAC on DVI or VGA */
|
||||
if ((mode_info->bios_connector[i].connector_type == CONNECTOR_DVI_I) ||
|
||||
(mode_info->bios_connector[i].connector_type == CONNECTOR_DVI_A) ||
|
||||
(mode_info->bios_connector[i].connector_type == CONNECTOR_VGA)) {
|
||||
if (radeon_is_avivo(dev_priv))
|
||||
encoder = radeon_encoder_atom_dac_add(dev, i, mode_info->bios_connector[i].dac_type, 0);
|
||||
if (encoder)
|
||||
drm_mode_connector_attach_encoder(connector, encoder);
|
||||
}
|
||||
|
||||
/* TMDS on DVI */
|
||||
if ((mode_info->bios_connector[i].connector_type == CONNECTOR_DVI_I) ||
|
||||
(mode_info->bios_connector[i].connector_type == CONNECTOR_DVI_D)) {
|
||||
if (radeon_is_avivo(dev_priv))
|
||||
encoder = radeon_encoder_atom_tmds_add(dev, i, mode_info->bios_connector[i].dac_type);
|
||||
if (encoder)
|
||||
drm_mode_connector_attach_encoder(connector, encoder);
|
||||
}
|
||||
|
||||
/* TVDAC on DIN */
|
||||
if (mode_info->bios_connector[i].connector_type == CONNECTOR_DIN) {
|
||||
if (radeon_is_avivo(dev_priv))
|
||||
encoder = radeon_encoder_atom_dac_add(dev, i, mode_info->bios_connector[i].dac_type, 1);
|
||||
if (encoder)
|
||||
drm_mode_connector_attach_encoder(connector, encoder);
|
||||
}
|
||||
}
|
||||
|
||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head)
|
||||
radeon_ddc_dump(connector);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void avivo_i2c_do_lock(struct radeon_connector *radeon_connector, int lock_state)
|
||||
{
|
||||
struct drm_radeon_private *dev_priv = radeon_connector->base.dev->dev_private;
|
||||
uint32_t temp;
|
||||
struct radeon_i2c_bus_rec *rec = &radeon_connector->ddc_bus->rec;
|
||||
|
||||
temp = RADEON_READ(rec->mask_clk_reg);
|
||||
if (lock_state)
|
||||
temp |= rec->put_clk_mask;
|
||||
else
|
||||
temp &= ~rec->put_clk_mask;
|
||||
RADEON_WRITE(rec->mask_clk_reg, temp);
|
||||
temp = RADEON_READ(rec->mask_clk_reg);
|
||||
|
||||
temp = RADEON_READ(rec->mask_data_reg);
|
||||
if (lock_state)
|
||||
temp |= rec->put_data_mask;
|
||||
else
|
||||
temp &= ~rec->put_data_mask;
|
||||
RADEON_WRITE(rec->mask_data_reg, temp);
|
||||
temp = RADEON_READ(rec->mask_data_reg);
|
||||
}
|
||||
|
||||
int radeon_ddc_get_modes(struct radeon_connector *radeon_connector)
|
||||
{
|
||||
struct drm_radeon_private *dev_priv = radeon_connector->base.dev->dev_private;
|
||||
struct edid *edid;
|
||||
int ret = 0;
|
||||
|
||||
if (!radeon_connector->ddc_bus)
|
||||
return -1;
|
||||
|
||||
if (radeon_is_avivo(dev_priv))
|
||||
avivo_i2c_do_lock(radeon_connector, 1);
|
||||
edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
|
||||
if (radeon_is_avivo(dev_priv))
|
||||
avivo_i2c_do_lock(radeon_connector, 0);
|
||||
if (edid) {
|
||||
drm_mode_connector_update_edid_property(&radeon_connector->base, edid);
|
||||
ret = drm_add_edid_modes(&radeon_connector->base, edid);
|
||||
kfree(edid);
|
||||
return ret;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int radeon_ddc_dump(struct drm_connector *connector)
|
||||
{
|
||||
struct edid *edid;
|
||||
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
|
||||
int ret = 0;
|
||||
|
||||
if (!radeon_connector->ddc_bus)
|
||||
return -1;
|
||||
edid = drm_get_edid(connector, &radeon_connector->ddc_bus->adapter);
|
||||
if (edid) {
|
||||
kfree(edid);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline uint32_t radeon_div(uint64_t n, uint32_t d)
|
||||
{
|
||||
uint64_t x, y, result;
|
||||
uint64_t mod;
|
||||
|
||||
n += d / 2;
|
||||
|
||||
mod = do_div(n, d);
|
||||
return n;
|
||||
}
|
||||
|
||||
void radeon_compute_pll(struct radeon_pll *pll,
|
||||
uint64_t freq,
|
||||
uint32_t *dot_clock_p,
|
||||
uint32_t *fb_div_p,
|
||||
uint32_t *ref_div_p,
|
||||
uint32_t *post_div_p,
|
||||
int flags)
|
||||
{
|
||||
uint32_t min_ref_div = pll->min_ref_div;
|
||||
uint32_t max_ref_div = pll->max_ref_div;
|
||||
uint32_t best_vco = pll->best_vco;
|
||||
uint32_t best_post_div = 1;
|
||||
uint32_t best_ref_div = 1;
|
||||
uint32_t best_feedback_div = 1;
|
||||
uint32_t best_freq = -1;
|
||||
uint32_t best_error = 0xffffffff;
|
||||
uint32_t best_vco_diff = 1;
|
||||
uint32_t post_div;
|
||||
|
||||
DRM_DEBUG("PLL freq %llu\n", freq);
|
||||
freq = freq * 1000;
|
||||
|
||||
if (flags & RADEON_PLL_USE_REF_DIV)
|
||||
min_ref_div = max_ref_div = pll->reference_div;
|
||||
else {
|
||||
while (min_ref_div < max_ref_div-1) {
|
||||
uint32_t mid=(min_ref_div+max_ref_div)/2;
|
||||
uint32_t pll_in = pll->reference_freq / mid;
|
||||
if (pll_in < pll->pll_in_min)
|
||||
max_ref_div = mid;
|
||||
else if (pll_in > pll->pll_in_max)
|
||||
min_ref_div = mid;
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (post_div = pll->min_post_div; post_div <= pll->max_post_div; ++post_div) {
|
||||
uint32_t ref_div;
|
||||
|
||||
if ((flags & RADEON_PLL_NO_ODD_POST_DIV) && (post_div & 1))
|
||||
continue;
|
||||
|
||||
/* legacy radeons only have a few post_divs */
|
||||
if (flags & RADEON_PLL_LEGACY) {
|
||||
if ((post_div == 5) ||
|
||||
(post_div == 7) ||
|
||||
(post_div == 9) ||
|
||||
(post_div == 10) ||
|
||||
(post_div == 11))
|
||||
continue;
|
||||
}
|
||||
|
||||
for (ref_div = min_ref_div; ref_div <= max_ref_div; ++ref_div) {
|
||||
uint32_t feedback_div, current_freq, error, vco_diff;
|
||||
uint32_t pll_in = pll->reference_freq / ref_div;
|
||||
uint32_t min_feed_div = pll->min_feedback_div;
|
||||
uint32_t max_feed_div = pll->max_feedback_div+1;
|
||||
|
||||
if (pll_in < pll->pll_in_min || pll_in > pll->pll_in_max)
|
||||
continue;
|
||||
|
||||
while (min_feed_div < max_feed_div) {
|
||||
uint32_t vco;
|
||||
feedback_div = (min_feed_div+max_feed_div)/2;
|
||||
|
||||
vco = radeon_div((uint64_t)pll->reference_freq * feedback_div,
|
||||
ref_div);
|
||||
|
||||
if (vco < pll->pll_out_min) {
|
||||
min_feed_div = feedback_div+1;
|
||||
continue;
|
||||
} else if(vco > pll->pll_out_max) {
|
||||
max_feed_div = feedback_div;
|
||||
continue;
|
||||
}
|
||||
|
||||
current_freq = radeon_div((uint64_t)pll->reference_freq * 10000 * feedback_div,
|
||||
ref_div * post_div);
|
||||
|
||||
error = abs(current_freq - freq);
|
||||
vco_diff = abs(vco - best_vco);
|
||||
|
||||
if ((best_vco == 0 && error < best_error) ||
|
||||
(best_vco != 0 &&
|
||||
(error < best_error - 100 ||
|
||||
(abs(error - best_error) < 100 && vco_diff < best_vco_diff )))) {
|
||||
best_post_div = post_div;
|
||||
best_ref_div = ref_div;
|
||||
best_feedback_div = feedback_div;
|
||||
best_freq = current_freq;
|
||||
best_error = error;
|
||||
best_vco_diff = vco_diff;
|
||||
} else if (current_freq == freq) {
|
||||
if (best_freq == -1) {
|
||||
best_post_div = post_div;
|
||||
best_ref_div = ref_div;
|
||||
best_feedback_div = feedback_div;
|
||||
best_freq = current_freq;
|
||||
best_error = error;
|
||||
best_vco_diff = vco_diff;
|
||||
} else if ((flags & RADEON_PLL_PREFER_LOW_REF_DIV) && (ref_div < best_ref_div)) {
|
||||
best_post_div = post_div;
|
||||
best_ref_div = ref_div;
|
||||
best_feedback_div = feedback_div;
|
||||
best_freq = current_freq;
|
||||
best_error = error;
|
||||
best_vco_diff = vco_diff;
|
||||
}
|
||||
}
|
||||
|
||||
if (current_freq < freq)
|
||||
min_feed_div = feedback_div+1;
|
||||
else
|
||||
max_feed_div = feedback_div;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*dot_clock_p = best_freq / 10000;
|
||||
*fb_div_p = best_feedback_div;
|
||||
*ref_div_p = best_ref_div;
|
||||
*post_div_p = best_post_div;
|
||||
}
|
||||
|
||||
void radeon_get_clock_info(struct drm_device *dev)
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
struct radeon_pll *pll = &dev_priv->mode_info.pll;
|
||||
int ret;
|
||||
|
||||
if (dev_priv->is_atom_bios)
|
||||
ret = radeon_atom_get_clock_info(dev);
|
||||
else
|
||||
ret = radeon_combios_get_clock_info(dev);
|
||||
|
||||
if (ret) {
|
||||
|
||||
if (pll->reference_div < 2) pll->reference_div = 12;
|
||||
} else {
|
||||
// TODO FALLBACK
|
||||
}
|
||||
|
||||
if (radeon_is_avivo(dev_priv)) {
|
||||
pll->min_post_div = 2;
|
||||
pll->max_post_div = 0x7f;
|
||||
} else {
|
||||
pll->min_post_div = 1;
|
||||
pll->max_post_div = 12; // 16 on crtc 0??
|
||||
}
|
||||
|
||||
pll->min_ref_div = 2;
|
||||
pll->max_ref_div = 0x3ff;
|
||||
pll->min_feedback_div = 4;
|
||||
pll->max_feedback_div = 0x7ff;
|
||||
pll->best_vco = 0;
|
||||
|
||||
}
|
||||
|
||||
static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb)
|
||||
{
|
||||
struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb);
|
||||
struct drm_device *dev = fb->dev;
|
||||
|
||||
if (fb->fbdev)
|
||||
radeonfb_remove(dev, fb);
|
||||
|
||||
drm_framebuffer_cleanup(fb);
|
||||
kfree(radeon_fb);
|
||||
}
|
||||
|
||||
static const struct drm_framebuffer_funcs radeon_fb_funcs = {
|
||||
.destroy = radeon_user_framebuffer_destroy,
|
||||
};
|
||||
|
||||
struct drm_framebuffer *radeon_user_framebuffer_create(struct drm_device *dev,
|
||||
struct drm_file *filp,
|
||||
struct drm_mode_fb_cmd *mode_cmd)
|
||||
{
|
||||
|
||||
struct radeon_framebuffer *radeon_fb;
|
||||
|
||||
radeon_fb = kzalloc(sizeof(*radeon_fb), GFP_KERNEL);
|
||||
if (!radeon_fb)
|
||||
return NULL;
|
||||
|
||||
drm_framebuffer_init(dev, &radeon_fb->base, &radeon_fb_funcs);
|
||||
drm_helper_mode_fill_fb_struct(&radeon_fb->base, mode_cmd);
|
||||
|
||||
if (filp) {
|
||||
radeon_fb->obj = drm_gem_object_lookup(dev, filp,
|
||||
mode_cmd->handle);
|
||||
if (!radeon_fb->obj) {
|
||||
kfree(radeon_fb);
|
||||
return NULL;
|
||||
}
|
||||
drm_gem_object_unreference(radeon_fb->obj);
|
||||
}
|
||||
return &radeon_fb->base;
|
||||
}
|
||||
|
||||
static const struct drm_mode_config_funcs radeon_mode_funcs = {
|
||||
.fb_create = radeon_user_framebuffer_create,
|
||||
.fb_changed = radeonfb_probe,
|
||||
};
|
||||
|
||||
|
||||
int radeon_modeset_init(struct drm_device *dev)
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
static struct card_info card;
|
||||
size_t size;
|
||||
int num_crtc = 2, i;
|
||||
int ret;
|
||||
|
||||
drm_mode_config_init(dev);
|
||||
|
||||
dev->mode_config.funcs = (void *)&radeon_mode_funcs;
|
||||
|
||||
if (radeon_is_avivo(dev_priv)) {
|
||||
dev->mode_config.max_width = 8192;
|
||||
dev->mode_config.max_height = 8192;
|
||||
} else {
|
||||
dev->mode_config.max_width = 4096;
|
||||
dev->mode_config.max_height = 4096;
|
||||
}
|
||||
|
||||
dev->mode_config.fb_base = dev_priv->fb_aper_offset;
|
||||
|
||||
/* allocate crtcs - TODO single crtc */
|
||||
for (i = 0; i < num_crtc; i++) {
|
||||
radeon_crtc_init(dev, i);
|
||||
}
|
||||
|
||||
/* okay we should have all the bios connectors */
|
||||
|
||||
ret = radeon_setup_enc_conn(dev);
|
||||
|
||||
if (!ret)
|
||||
return ret;
|
||||
|
||||
drm_helper_initial_config(dev, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int radeon_load_modeset_init(struct drm_device *dev)
|
||||
{
|
||||
int ret;
|
||||
ret = radeon_modeset_init(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void radeon_modeset_cleanup(struct drm_device *dev)
|
||||
{
|
||||
drm_mode_config_cleanup(dev);
|
||||
}
|
||||
|
||||
|
|
@ -37,10 +37,17 @@
|
|||
#include "drm_pciids.h"
|
||||
|
||||
int radeon_no_wb;
|
||||
int radeon_dynclks = 1;
|
||||
|
||||
MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers\n");
|
||||
module_param_named(no_wb, radeon_no_wb, int, 0444);
|
||||
|
||||
unsigned int radeon_modeset = 0;
|
||||
module_param_named(modeset, radeon_modeset, int, 0400);
|
||||
|
||||
MODULE_PARM_DESC(dynclks, "Disable/Enable dynamic clocks");
|
||||
module_param_named(dynclks, radeon_dynclks, int, 0444);
|
||||
|
||||
static int dri_library_name(struct drm_device * dev, char * buf)
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
|
|
@ -56,11 +63,29 @@ static struct pci_device_id pciidlist[] = {
|
|||
radeon_PCI_IDS
|
||||
};
|
||||
|
||||
extern struct drm_fence_driver radeon_fence_driver;
|
||||
|
||||
static uint32_t radeon_mem_prios[] = {DRM_BO_MEM_VRAM, DRM_BO_MEM_TT, DRM_BO_MEM_LOCAL};
|
||||
static uint32_t radeon_busy_prios[] = {DRM_BO_MEM_TT, DRM_BO_MEM_VRAM, DRM_BO_MEM_LOCAL};
|
||||
|
||||
static struct drm_bo_driver radeon_bo_driver = {
|
||||
.mem_type_prio = radeon_mem_prios,
|
||||
.mem_busy_prio = radeon_busy_prios,
|
||||
.num_mem_type_prio = sizeof(radeon_mem_prios)/sizeof(uint32_t),
|
||||
.num_mem_busy_prio = sizeof(radeon_busy_prios)/sizeof(uint32_t),
|
||||
.create_ttm_backend_entry = radeon_create_ttm_backend_entry,
|
||||
.fence_type = radeon_fence_types,
|
||||
.invalidate_caches = radeon_invalidate_caches,
|
||||
.init_mem_type = radeon_init_mem_type,
|
||||
.move = radeon_move,
|
||||
.evict_flags = radeon_evict_flags,
|
||||
};
|
||||
|
||||
static int probe(struct pci_dev *pdev, const struct pci_device_id *ent);
|
||||
static struct drm_driver driver = {
|
||||
.driver_features =
|
||||
DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG |
|
||||
DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED,
|
||||
DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED | DRIVER_GEM,
|
||||
.dev_priv_size = sizeof(drm_radeon_buf_priv_t),
|
||||
.load = radeon_driver_load,
|
||||
.firstopen = radeon_driver_firstopen,
|
||||
|
|
@ -81,7 +106,11 @@ static struct drm_driver driver = {
|
|||
.get_map_ofs = drm_core_get_map_ofs,
|
||||
.get_reg_ofs = drm_core_get_reg_ofs,
|
||||
.ioctls = radeon_ioctls,
|
||||
.gem_init_object = radeon_gem_init_object,
|
||||
.gem_free_object = radeon_gem_free_object,
|
||||
.dma_ioctl = radeon_cp_buffers,
|
||||
.master_create = radeon_master_create,
|
||||
.master_destroy = radeon_master_destroy,
|
||||
.fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = drm_open,
|
||||
|
|
@ -101,6 +130,9 @@ static struct drm_driver driver = {
|
|||
.remove = __devexit_p(drm_cleanup_pci),
|
||||
},
|
||||
|
||||
.fence_driver = &radeon_fence_driver,
|
||||
.bo_driver = &radeon_bo_driver,
|
||||
|
||||
.name = DRIVER_NAME,
|
||||
.desc = DRIVER_DESC,
|
||||
.date = DRIVER_DATE,
|
||||
|
|
@ -117,6 +149,10 @@ static int probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
static int __init radeon_init(void)
|
||||
{
|
||||
driver.num_ioctls = radeon_max_ioctl;
|
||||
|
||||
if (radeon_modeset == 1)
|
||||
driver.driver_features |= DRIVER_MODESET;
|
||||
|
||||
return drm_init(&driver, pciidlist);
|
||||
}
|
||||
|
||||
|
|
|
|||
962
linux-core/radeon_encoders.c
Normal file
962
linux-core/radeon_encoders.c
Normal file
|
|
@ -0,0 +1,962 @@
|
|||
/*
|
||||
* Copyright 2007-8 Advanced Micro Devices, Inc.
|
||||
* Copyright 2008 Red Hat Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: Dave Airlie
|
||||
* Alex Deucher
|
||||
*/
|
||||
#include "drmP.h"
|
||||
#include "drm_crtc_helper.h"
|
||||
#include "radeon_drm.h"
|
||||
#include "radeon_drv.h"
|
||||
|
||||
extern int atom_debug;
|
||||
|
||||
static void radeon_rmx_mode_fixup(struct drm_encoder *encoder,
|
||||
struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode)
|
||||
{
|
||||
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
|
||||
if (mode->hdisplay < radeon_encoder->panel_xres ||
|
||||
mode->vdisplay < radeon_encoder->panel_yres) {
|
||||
radeon_encoder->flags |= RADEON_USE_RMX;
|
||||
adjusted_mode->hdisplay = radeon_encoder->panel_xres;
|
||||
adjusted_mode->vdisplay = radeon_encoder->panel_yres;
|
||||
adjusted_mode->htotal = radeon_encoder->panel_xres + radeon_encoder->hblank;
|
||||
adjusted_mode->hsync_start = radeon_encoder->panel_xres + radeon_encoder->hoverplus;
|
||||
adjusted_mode->hsync_end = adjusted_mode->hsync_start + radeon_encoder->hsync_width;
|
||||
adjusted_mode->vtotal = radeon_encoder->panel_yres + radeon_encoder->vblank;
|
||||
adjusted_mode->vsync_start = radeon_encoder->panel_yres + radeon_encoder->voverplus;
|
||||
adjusted_mode->vsync_end = adjusted_mode->vsync_start + radeon_encoder->vsync_width;
|
||||
/* update crtc values */
|
||||
drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
|
||||
/* adjust crtc values */
|
||||
adjusted_mode->crtc_hdisplay = radeon_encoder->panel_xres;
|
||||
adjusted_mode->crtc_vdisplay = radeon_encoder->panel_yres;
|
||||
adjusted_mode->crtc_htotal = adjusted_mode->crtc_hdisplay + radeon_encoder->hblank;
|
||||
adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hdisplay + radeon_encoder->hoverplus;
|
||||
adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + radeon_encoder->hsync_width;
|
||||
adjusted_mode->crtc_vtotal = adjusted_mode->crtc_vdisplay + radeon_encoder->vblank;
|
||||
adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + radeon_encoder->voverplus;
|
||||
adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + radeon_encoder->vsync_width;
|
||||
} else {
|
||||
adjusted_mode->htotal = radeon_encoder->panel_xres + radeon_encoder->hblank;
|
||||
adjusted_mode->hsync_start = radeon_encoder->panel_xres + radeon_encoder->hoverplus;
|
||||
adjusted_mode->hsync_end = adjusted_mode->hsync_start + radeon_encoder->hsync_width;
|
||||
adjusted_mode->vtotal = radeon_encoder->panel_yres + radeon_encoder->vblank;
|
||||
adjusted_mode->vsync_start = radeon_encoder->panel_yres + radeon_encoder->voverplus;
|
||||
adjusted_mode->vsync_end = adjusted_mode->vsync_start + radeon_encoder->vsync_width;
|
||||
/* update crtc values */
|
||||
drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
|
||||
/* adjust crtc values */
|
||||
adjusted_mode->crtc_htotal = adjusted_mode->crtc_hdisplay + radeon_encoder->hblank;
|
||||
adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hdisplay + radeon_encoder->hoverplus;
|
||||
adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + radeon_encoder->hsync_width;
|
||||
adjusted_mode->crtc_vtotal = adjusted_mode->crtc_vdisplay + radeon_encoder->vblank;
|
||||
adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + radeon_encoder->voverplus;
|
||||
adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + radeon_encoder->vsync_width;
|
||||
}
|
||||
adjusted_mode->clock = radeon_encoder->dotclock;
|
||||
adjusted_mode->flags = radeon_encoder->flags;
|
||||
}
|
||||
|
||||
|
||||
static int atom_dac_find_atom_type(struct radeon_encoder *radeon_encoder, struct drm_connector *connector)
|
||||
{
|
||||
struct drm_device *dev = radeon_encoder->base.dev;
|
||||
struct drm_connector *connector_find;
|
||||
int atom_type = -1;
|
||||
|
||||
if (!connector) {
|
||||
list_for_each_entry(connector_find, &dev->mode_config.connector_list, head) {
|
||||
if (connector_find->encoder == &radeon_encoder->base)
|
||||
connector = connector_find;
|
||||
}
|
||||
}
|
||||
if (connector) {
|
||||
/* look for the encoder in the connector list -
|
||||
check if we the DAC is enabled on a VGA or STV/CTV or CV connector */
|
||||
/* work out the ATOM_DEVICE bits */
|
||||
switch (connector->connector_type) {
|
||||
case CONNECTOR_VGA:
|
||||
case CONNECTOR_DVI_I:
|
||||
case CONNECTOR_DVI_A:
|
||||
if (radeon_encoder->atom_device & ATOM_DEVICE_CRT1_SUPPORT)
|
||||
atom_type = ATOM_DEVICE_CRT1_INDEX;
|
||||
else if (radeon_encoder->atom_device & ATOM_DEVICE_CRT2_SUPPORT)
|
||||
atom_type = ATOM_DEVICE_CRT2_INDEX;
|
||||
break;
|
||||
case CONNECTOR_STV:
|
||||
case CONNECTOR_CTV:
|
||||
if (radeon_encoder->atom_device & ATOM_DEVICE_TV1_SUPPORT)
|
||||
atom_type = ATOM_DEVICE_TV1_INDEX;
|
||||
break;
|
||||
case CONNECTOR_DIN:
|
||||
if (radeon_encoder->atom_device & ATOM_DEVICE_TV1_SUPPORT)
|
||||
atom_type = ATOM_DEVICE_TV1_INDEX;
|
||||
if (radeon_encoder->atom_device & ATOM_DEVICE_CV_SUPPORT)
|
||||
atom_type = ATOM_DEVICE_CV_INDEX;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return atom_type;
|
||||
}
|
||||
|
||||
/* LVTMA encoder for LVDS usage */
|
||||
static void atombios_display_device_control(struct drm_encoder *encoder, int index, uint8_t state)
|
||||
{
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args;
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
args.ucAction = state;
|
||||
|
||||
atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
|
||||
}
|
||||
|
||||
|
||||
static void atombios_scaler_setup(struct drm_encoder *encoder, struct drm_display_mode *mode)
|
||||
{
|
||||
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
|
||||
ENABLE_SCALER_PS_ALLOCATION args;
|
||||
int index = GetIndexIntoMasterTable(COMMAND, EnableScaler);
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
args.ucScaler = radeon_crtc->crtc_id;
|
||||
|
||||
if (radeon_encoder->flags & RADEON_USE_RMX) {
|
||||
if (radeon_encoder->rmx_type == RMX_FULL)
|
||||
args.ucEnable = ATOM_SCALER_EXPANSION;
|
||||
else if (radeon_encoder->rmx_type == RMX_CENTER)
|
||||
args.ucEnable = ATOM_SCALER_CENTER;
|
||||
} else
|
||||
args.ucEnable = ATOM_SCALER_DISABLE;
|
||||
|
||||
atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
|
||||
}
|
||||
|
||||
void atombios_set_crtc_source(struct drm_encoder *encoder, int source)
|
||||
{
|
||||
int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source);
|
||||
struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
|
||||
struct drm_radeon_private *dev_priv = encoder->dev->dev_private;
|
||||
uint8_t frev, crev;
|
||||
SELECT_CRTC_SOURCE_PS_ALLOCATION crtc_src_param;
|
||||
SELECT_CRTC_SOURCE_PARAMETERS_V2 crtc_src_param2;
|
||||
uint32_t *param = NULL;
|
||||
|
||||
atom_parse_cmd_header(dev_priv->mode_info.atom_context, index, &frev, &crev);
|
||||
switch (frev) {
|
||||
case 1: {
|
||||
switch (crev) {
|
||||
case 0:
|
||||
case 1:
|
||||
default:
|
||||
memset(&crtc_src_param, 0, sizeof(crtc_src_param));
|
||||
crtc_src_param.ucCRTC = radeon_crtc->crtc_id;
|
||||
crtc_src_param.ucDevice = source;
|
||||
param = (uint32_t *)&crtc_src_param;
|
||||
break;
|
||||
case 2:
|
||||
memset(&crtc_src_param2, 0, sizeof(crtc_src_param2));
|
||||
crtc_src_param2.ucCRTC = radeon_crtc->crtc_id;
|
||||
crtc_src_param2.ucEncoderID = source;
|
||||
switch (source) {
|
||||
case ATOM_DEVICE_CRT1_INDEX:
|
||||
case ATOM_DEVICE_CRT2_INDEX:
|
||||
crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_CRT;
|
||||
break;
|
||||
case ATOM_DEVICE_DFP1_INDEX:
|
||||
case ATOM_DEVICE_DFP2_INDEX:
|
||||
case ATOM_DEVICE_DFP3_INDEX:
|
||||
crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_DVI;
|
||||
// TODO ENCODER MODE
|
||||
break;
|
||||
case ATOM_DEVICE_LCD1_INDEX:
|
||||
crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_LVDS;
|
||||
break;
|
||||
case ATOM_DEVICE_TV1_INDEX:
|
||||
crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_TV;
|
||||
break;
|
||||
case ATOM_DEVICE_CV_INDEX:
|
||||
crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_CV;
|
||||
break;
|
||||
}
|
||||
param = (uint32_t *)&crtc_src_param2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)param);
|
||||
|
||||
}
|
||||
|
||||
static void radeon_dfp_disable_dither(struct drm_encoder *encoder, int device)
|
||||
{
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
|
||||
switch (device) {
|
||||
case ATOM_DEVICE_DFP1_INDEX:
|
||||
RADEON_WRITE(AVIVO_TMDSA_BIT_DEPTH_CONTROL, 0); /* TMDSA */
|
||||
break;
|
||||
case ATOM_DEVICE_DFP2_INDEX:
|
||||
if ((dev_priv->chip_family == CHIP_RS600) ||
|
||||
(dev_priv->chip_family == CHIP_RS690) ||
|
||||
(dev_priv->chip_family == CHIP_RS740))
|
||||
RADEON_WRITE(AVIVO_DDIA_BIT_DEPTH_CONTROL, 0); /* DDIA */
|
||||
else
|
||||
RADEON_WRITE(AVIVO_DVOA_BIT_DEPTH_CONTROL, 0); /* DVO */
|
||||
break;
|
||||
/*case ATOM_DEVICE_LCD1_INDEX:*/ /* LVDS panels need dither enabled */
|
||||
case ATOM_DEVICE_DFP3_INDEX:
|
||||
RADEON_WRITE(AVIVO_LVTMA_BIT_DEPTH_CONTROL, 0); /* LVTMA */
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void radeon_lvtma_mode_set(struct drm_encoder *encoder,
|
||||
struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode)
|
||||
{
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
LVDS_ENCODER_CONTROL_PS_ALLOCATION args;
|
||||
int index = GetIndexIntoMasterTable(COMMAND, LVDSEncoderControl);
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
atombios_scaler_setup(encoder, mode);
|
||||
atombios_set_crtc_source(encoder, ATOM_DEVICE_LCD1_INDEX);
|
||||
|
||||
args.ucAction = 1;
|
||||
if (adjusted_mode->clock > 165000)
|
||||
args.ucMisc = 1;
|
||||
else
|
||||
args.ucMisc = 0;
|
||||
args.usPixelClock = cpu_to_le16(adjusted_mode->clock / 10);
|
||||
|
||||
printk("executing set LVDS encoder\n");
|
||||
atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
|
||||
}
|
||||
|
||||
|
||||
static void radeon_lvtma_dpms(struct drm_encoder *encoder, int mode)
|
||||
{
|
||||
struct drm_device *dev = encoder->dev;
|
||||
int index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl);
|
||||
|
||||
switch(mode) {
|
||||
case DRM_MODE_DPMS_ON:
|
||||
atombios_display_device_control(encoder, index, ATOM_ENABLE);
|
||||
break;
|
||||
case DRM_MODE_DPMS_STANDBY:
|
||||
case DRM_MODE_DPMS_SUSPEND:
|
||||
case DRM_MODE_DPMS_OFF:
|
||||
atombios_display_device_control(encoder, index, ATOM_DISABLE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static bool radeon_lvtma_mode_fixup(struct drm_encoder *encoder,
|
||||
struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode)
|
||||
{
|
||||
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
|
||||
|
||||
radeon_encoder->flags &= ~RADEON_USE_RMX;
|
||||
|
||||
if (radeon_encoder->rmx_type != RMX_OFF)
|
||||
radeon_rmx_mode_fixup(encoder, mode, adjusted_mode);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void radeon_lvtma_prepare(struct drm_encoder *encoder)
|
||||
{
|
||||
radeon_lvtma_dpms(encoder, DRM_MODE_DPMS_OFF);
|
||||
}
|
||||
|
||||
static void radeon_lvtma_commit(struct drm_encoder *encoder)
|
||||
{
|
||||
radeon_lvtma_dpms(encoder, DRM_MODE_DPMS_ON);
|
||||
}
|
||||
|
||||
static const struct drm_encoder_helper_funcs radeon_atom_lvtma_helper_funcs = {
|
||||
.dpms = radeon_lvtma_dpms,
|
||||
.mode_fixup = radeon_lvtma_mode_fixup,
|
||||
.prepare = radeon_lvtma_prepare,
|
||||
.mode_set = radeon_lvtma_mode_set,
|
||||
.commit = radeon_lvtma_commit,
|
||||
};
|
||||
|
||||
static void radeon_enc_destroy(struct drm_encoder *encoder)
|
||||
{
|
||||
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
|
||||
drm_encoder_cleanup(encoder);
|
||||
kfree(radeon_encoder);
|
||||
}
|
||||
|
||||
static const struct drm_encoder_funcs radeon_atom_lvtma_enc_funcs = {
|
||||
.destroy = radeon_enc_destroy,
|
||||
};
|
||||
|
||||
struct drm_encoder *radeon_encoder_lvtma_add(struct drm_device *dev, int bios_index)
|
||||
{
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct radeon_mode_info *mode_info = &dev_priv->mode_info;
|
||||
struct radeon_encoder *radeon_encoder;
|
||||
struct drm_encoder *encoder;
|
||||
radeon_encoder = kzalloc(sizeof(struct radeon_encoder), GFP_KERNEL);
|
||||
if (!radeon_encoder) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
encoder = &radeon_encoder->base;
|
||||
|
||||
encoder->possible_crtcs = 0x3;
|
||||
encoder->possible_clones = 0;
|
||||
drm_encoder_init(dev, encoder, &radeon_atom_lvtma_enc_funcs,
|
||||
DRM_MODE_ENCODER_LVDS);
|
||||
|
||||
drm_encoder_helper_add(encoder, &radeon_atom_lvtma_helper_funcs);
|
||||
radeon_encoder->atom_device = mode_info->bios_connector[bios_index].devices;
|
||||
|
||||
/* TODO get the LVDS info from the BIOS for panel size etc. */
|
||||
/* get the lvds info from the bios */
|
||||
radeon_get_lvds_info(radeon_encoder);
|
||||
|
||||
/* LVDS gets default RMX full scaling */
|
||||
radeon_encoder->rmx_type = RMX_FULL;
|
||||
|
||||
return encoder;
|
||||
}
|
||||
|
||||
static void radeon_atom_dac_dpms(struct drm_encoder *encoder, int mode)
|
||||
{
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
|
||||
int atom_type = -1;
|
||||
int index;
|
||||
|
||||
atom_type = atom_dac_find_atom_type(radeon_encoder, NULL);
|
||||
if (atom_type == -1)
|
||||
return;
|
||||
|
||||
switch(atom_type) {
|
||||
case ATOM_DEVICE_CRT1_INDEX:
|
||||
index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl);
|
||||
break;
|
||||
case ATOM_DEVICE_CRT2_INDEX:
|
||||
index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl);
|
||||
break;
|
||||
case ATOM_DEVICE_TV1_INDEX:
|
||||
index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl);
|
||||
break;
|
||||
case ATOM_DEVICE_CV_INDEX:
|
||||
index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
switch(mode) {
|
||||
case DRM_MODE_DPMS_ON:
|
||||
atombios_display_device_control(encoder, index, ATOM_ENABLE);
|
||||
break;
|
||||
case DRM_MODE_DPMS_STANDBY:
|
||||
case DRM_MODE_DPMS_SUSPEND:
|
||||
case DRM_MODE_DPMS_OFF:
|
||||
atombios_display_device_control(encoder, index, ATOM_DISABLE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static bool radeon_atom_dac_mode_fixup(struct drm_encoder *encoder,
|
||||
struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static void radeon_atom_dac_prepare(struct drm_encoder *encoder)
|
||||
{
|
||||
radeon_atom_dac_dpms(encoder, DRM_MODE_DPMS_OFF);
|
||||
}
|
||||
|
||||
static void radeon_atom_dac_commit(struct drm_encoder *encoder)
|
||||
{
|
||||
radeon_atom_dac_dpms(encoder, DRM_MODE_DPMS_ON);
|
||||
}
|
||||
|
||||
static int atombios_dac_setup(struct drm_encoder *encoder,
|
||||
struct drm_display_mode *mode,
|
||||
int atom_type)
|
||||
{
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
|
||||
DAC_ENCODER_CONTROL_PS_ALLOCATION args;
|
||||
int id = (radeon_encoder->type.dac == DAC_TVDAC);
|
||||
int index;
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
if (id == 0)
|
||||
index = GetIndexIntoMasterTable(COMMAND, DAC1EncoderControl);
|
||||
else
|
||||
index = GetIndexIntoMasterTable(COMMAND, DAC2EncoderControl);
|
||||
|
||||
args.ucAction = 1;
|
||||
args.usPixelClock = cpu_to_le16(mode->clock / 10);
|
||||
if ((atom_type == ATOM_DEVICE_CRT1_INDEX) ||
|
||||
(atom_type == ATOM_DEVICE_CRT2_INDEX))
|
||||
args.ucDacStandard = id ? ATOM_DAC2_PS2 : ATOM_DAC1_PS2;
|
||||
else if (atom_type == ATOM_DEVICE_CV_INDEX)
|
||||
args.ucDacStandard = id ? ATOM_DAC2_CV : ATOM_DAC1_CV;
|
||||
else if (atom_type == ATOM_DEVICE_TV1_INDEX)
|
||||
args.ucDacStandard = id ? ATOM_DAC2_NTSC : ATOM_DAC1_NTSC;
|
||||
/* TODO PAL */
|
||||
atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int atombios_tv1_setup(struct drm_encoder *encoder,
|
||||
struct drm_display_mode *mode,
|
||||
int atom_type)
|
||||
{
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
|
||||
TV_ENCODER_CONTROL_PS_ALLOCATION args;
|
||||
int index = GetIndexIntoMasterTable(COMMAND, TVEncoderControl);
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
args.sTVEncoder.ucAction = 1;
|
||||
if (atom_type == ATOM_DEVICE_CV_INDEX)
|
||||
args.sTVEncoder.ucTvStandard = ATOM_TV_CV;
|
||||
else {
|
||||
// TODO PAL
|
||||
args.sTVEncoder.ucTvStandard = ATOM_TV_NTSC;
|
||||
}
|
||||
|
||||
args.sTVEncoder.usPixelClock = cpu_to_le16(mode->clock / 10);
|
||||
|
||||
atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void radeon_atom_dac_mode_set(struct drm_encoder *encoder,
|
||||
struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode)
|
||||
{
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
|
||||
int atom_type = -1;
|
||||
|
||||
atom_type = atom_dac_find_atom_type(radeon_encoder, NULL);
|
||||
if (atom_type == -1)
|
||||
return;
|
||||
|
||||
atombios_scaler_setup(encoder, mode);
|
||||
atombios_set_crtc_source(encoder, atom_type);
|
||||
|
||||
atombios_dac_setup(encoder, adjusted_mode, atom_type);
|
||||
if ((atom_type == ATOM_DEVICE_TV1_INDEX) ||
|
||||
(atom_type == ATOM_DEVICE_CV_INDEX))
|
||||
atombios_tv1_setup(encoder, adjusted_mode, atom_type);
|
||||
|
||||
}
|
||||
|
||||
static bool atom_dac_load_detect(struct drm_encoder *encoder, int atom_devices)
|
||||
{
|
||||
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
DAC_LOAD_DETECTION_PS_ALLOCATION args;
|
||||
int index = GetIndexIntoMasterTable(COMMAND, DAC_LoadDetection);
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
args.sDacload.ucMisc = 0;
|
||||
args.sDacload.ucDacType = (radeon_encoder->type.dac == DAC_PRIMARY) ? ATOM_DAC_A : ATOM_DAC_B;
|
||||
|
||||
if (atom_devices & ATOM_DEVICE_CRT1_SUPPORT)
|
||||
args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT1_SUPPORT);
|
||||
else if (atom_devices & ATOM_DEVICE_CRT2_SUPPORT)
|
||||
args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT2_SUPPORT);
|
||||
else if (atom_devices & ATOM_DEVICE_CV_SUPPORT) {
|
||||
args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CV_SUPPORT);
|
||||
if (radeon_is_dce3(dev_priv))
|
||||
args.sDacload.ucMisc = 1;
|
||||
} else if (atom_devices & ATOM_DEVICE_TV1_SUPPORT) {
|
||||
args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_TV1_SUPPORT);
|
||||
if (radeon_is_dce3(dev_priv))
|
||||
args.sDacload.ucMisc = 1;
|
||||
} else
|
||||
return false;
|
||||
|
||||
DRM_DEBUG("writing %x %x\n", args.sDacload.usDeviceID, args.sDacload.ucDacType);
|
||||
atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
|
||||
return true;
|
||||
}
|
||||
|
||||
static enum drm_connector_status radeon_atom_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector)
|
||||
{
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
|
||||
int atom_type = -1;
|
||||
uint32_t bios_0_scratch;
|
||||
|
||||
atom_type = atom_dac_find_atom_type(radeon_encoder, connector);
|
||||
if (atom_type == -1) {
|
||||
DRM_DEBUG("exit after find \n");
|
||||
return connector_status_unknown;
|
||||
}
|
||||
|
||||
if(!atom_dac_load_detect(encoder, (1 << atom_type))) {
|
||||
DRM_DEBUG("detect returned false \n");
|
||||
return connector_status_unknown;
|
||||
}
|
||||
|
||||
|
||||
if (dev_priv->chip_family >= CHIP_R600)
|
||||
bios_0_scratch = RADEON_READ(R600_BIOS_0_SCRATCH);
|
||||
else
|
||||
bios_0_scratch = RADEON_READ(RADEON_BIOS_0_SCRATCH);
|
||||
|
||||
DRM_DEBUG("Bios 0 scratch %x\n", bios_0_scratch);
|
||||
if (radeon_encoder->atom_device & ATOM_DEVICE_CRT1_SUPPORT) {
|
||||
if (bios_0_scratch & ATOM_S0_CRT1_MASK)
|
||||
return connector_status_connected;
|
||||
} else if (radeon_encoder->atom_device & ATOM_DEVICE_CRT2_SUPPORT) {
|
||||
if (bios_0_scratch & ATOM_S0_CRT2_MASK)
|
||||
return connector_status_connected;
|
||||
} else if (radeon_encoder->atom_device & ATOM_DEVICE_CV_SUPPORT) {
|
||||
if (bios_0_scratch & (ATOM_S0_CV_MASK|ATOM_S0_CV_MASK_A))
|
||||
return connector_status_connected;
|
||||
} else if (radeon_encoder->atom_device & ATOM_DEVICE_TV1_SUPPORT) {
|
||||
if (bios_0_scratch & (ATOM_S0_TV1_COMPOSITE | ATOM_S0_TV1_COMPOSITE_A))
|
||||
return connector_status_connected; // CTV
|
||||
else if (bios_0_scratch & (ATOM_S0_TV1_SVIDEO | ATOM_S0_TV1_SVIDEO_A))
|
||||
return connector_status_connected; // STV
|
||||
}
|
||||
return connector_status_disconnected;
|
||||
}
|
||||
|
||||
static const struct drm_encoder_helper_funcs radeon_atom_dac_helper_funcs = {
|
||||
.dpms = radeon_atom_dac_dpms,
|
||||
.mode_fixup = radeon_atom_dac_mode_fixup,
|
||||
.prepare = radeon_atom_dac_prepare,
|
||||
.mode_set = radeon_atom_dac_mode_set,
|
||||
.commit = radeon_atom_dac_commit,
|
||||
.detect = radeon_atom_dac_detect,
|
||||
};
|
||||
|
||||
static const struct drm_encoder_funcs radeon_atom_dac_enc_funcs = {
|
||||
. destroy = radeon_enc_destroy,
|
||||
};
|
||||
|
||||
|
||||
static void atombios_tmds1_setup(struct drm_encoder *encoder,
|
||||
struct drm_display_mode *mode)
|
||||
{
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
|
||||
TMDS1_ENCODER_CONTROL_PS_ALLOCATION args;
|
||||
int index = GetIndexIntoMasterTable(COMMAND, TMDS1EncoderControl);
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
args.ucAction = 1;
|
||||
if (mode->clock > 165000)
|
||||
args.ucMisc = 1;
|
||||
else
|
||||
args.ucMisc = 0;
|
||||
|
||||
args.usPixelClock = cpu_to_le16(mode->clock / 10);
|
||||
|
||||
atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
|
||||
}
|
||||
|
||||
static void atombios_tmds2_setup(struct drm_encoder *encoder,
|
||||
struct drm_display_mode *mode)
|
||||
{
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
|
||||
TMDS2_ENCODER_CONTROL_PS_ALLOCATION args;
|
||||
int index = GetIndexIntoMasterTable(COMMAND, TMDS2EncoderControl);
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
args.ucAction = 1;
|
||||
if (mode->clock > 165000)
|
||||
args.ucMisc = 1;
|
||||
else
|
||||
args.ucMisc = 0;
|
||||
|
||||
args.usPixelClock = cpu_to_le16(mode->clock / 10);
|
||||
|
||||
atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
|
||||
}
|
||||
|
||||
|
||||
static void atombios_ext_tmds_setup(struct drm_encoder *encoder,
|
||||
struct drm_display_mode *mode)
|
||||
{
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
|
||||
ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION args;
|
||||
int index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl);
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
args.sXTmdsEncoder.ucEnable = 1;
|
||||
|
||||
if (mode->clock > 165000)
|
||||
args.sXTmdsEncoder.ucMisc = 1;
|
||||
else
|
||||
args.sXTmdsEncoder.ucMisc = 0;
|
||||
|
||||
// TODO 6-bit DAC
|
||||
// args.usPixelClock = cpu_to_le16(mode->clock / 10);
|
||||
|
||||
atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
|
||||
}
|
||||
|
||||
static void atombios_dig1_setup(struct drm_encoder *encoder,
|
||||
struct drm_display_mode *mode)
|
||||
{
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
DIG_ENCODER_CONTROL_PS_ALLOCATION args;
|
||||
int index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
|
||||
|
||||
args.ucAction = 1;
|
||||
args.usPixelClock = mode->clock / 10;
|
||||
args.ucConfig = ATOM_ENCODER_CONFIG_TRANSMITTER1;
|
||||
|
||||
// TODO coherent mode
|
||||
// if (encoder->coherent_mode)
|
||||
// args.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT;
|
||||
|
||||
if (mode->clock > 165000) {
|
||||
args.ucConfig |= ATOM_ENCODER_CONFIG_LINKA_B;
|
||||
args.ucLaneNum = 8;
|
||||
} else {
|
||||
args.ucConfig |= ATOM_ENCODER_CONFIG_LINKA;
|
||||
args.ucLaneNum = 4;
|
||||
}
|
||||
|
||||
// TODO Encoder MODE
|
||||
atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
|
||||
}
|
||||
|
||||
static void atombios_ddia_setup(struct drm_encoder *encoder,
|
||||
struct drm_display_mode *mode)
|
||||
{
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
DVO_ENCODER_CONTROL_PS_ALLOCATION args;
|
||||
int index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl);
|
||||
|
||||
args.sDVOEncoder.ucAction = ATOM_ENABLE;
|
||||
args.sDVOEncoder.usPixelClock = mode->clock / 10;
|
||||
|
||||
if (mode->clock > 165000)
|
||||
args.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute = PANEL_ENCODER_MISC_DUAL;
|
||||
else
|
||||
args.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute = 0;
|
||||
|
||||
atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
|
||||
}
|
||||
|
||||
struct drm_encoder *radeon_encoder_atom_dac_add(struct drm_device *dev, int bios_index, int dac_type, int with_tv)
|
||||
{
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct radeon_mode_info *mode_info = &dev_priv->mode_info;
|
||||
struct radeon_encoder *radeon_encoder = NULL;
|
||||
struct drm_encoder *encoder;
|
||||
int type = with_tv ? DRM_MODE_ENCODER_TVDAC : DRM_MODE_ENCODER_DAC;
|
||||
int found = 0;
|
||||
int digital_enc_mask = ~(ATOM_DEVICE_DFP1_SUPPORT | ATOM_DEVICE_DFP2_SUPPORT | ATOM_DEVICE_DFP3_SUPPORT |
|
||||
ATOM_DEVICE_LCD1_SUPPORT);
|
||||
/* we may already have added this encoder */
|
||||
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
|
||||
if (encoder->encoder_type != DRM_MODE_ENCODER_DAC ||
|
||||
encoder->encoder_type != DRM_MODE_ENCODER_TVDAC)
|
||||
continue;
|
||||
|
||||
radeon_encoder = to_radeon_encoder(encoder);
|
||||
if (radeon_encoder->type.dac == dac_type) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
/* upgrade to a TV controlling DAC */
|
||||
if (type == DRM_MODE_ENCODER_TVDAC)
|
||||
encoder->encoder_type = type;
|
||||
radeon_encoder->atom_device |= mode_info->bios_connector[bios_index].devices;
|
||||
radeon_encoder->atom_device &= digital_enc_mask;
|
||||
return encoder;
|
||||
}
|
||||
|
||||
radeon_encoder = kzalloc(sizeof(struct radeon_encoder), GFP_KERNEL);
|
||||
if (!radeon_encoder) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
encoder = &radeon_encoder->base;
|
||||
|
||||
encoder->possible_crtcs = 0x3;
|
||||
encoder->possible_clones = 0;
|
||||
drm_encoder_init(dev, encoder, &radeon_atom_dac_enc_funcs,
|
||||
type);
|
||||
|
||||
drm_encoder_helper_add(encoder, &radeon_atom_dac_helper_funcs);
|
||||
radeon_encoder->type.dac = dac_type;
|
||||
radeon_encoder->atom_device = mode_info->bios_connector[bios_index].devices;
|
||||
|
||||
/* mask off any digital encoders */
|
||||
radeon_encoder->atom_device &= digital_enc_mask;
|
||||
return encoder;
|
||||
}
|
||||
|
||||
static void radeon_atom_tmds_dpms(struct drm_encoder *encoder, int mode)
|
||||
{
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
|
||||
int atom_type = -1;
|
||||
int index = -1;
|
||||
|
||||
if (radeon_encoder->atom_device & ATOM_DEVICE_DFP1_SUPPORT)
|
||||
atom_type = ATOM_DEVICE_DFP1_INDEX;
|
||||
if (radeon_encoder->atom_device & ATOM_DEVICE_DFP2_SUPPORT)
|
||||
atom_type = ATOM_DEVICE_DFP2_INDEX;
|
||||
if (radeon_encoder->atom_device & ATOM_DEVICE_DFP3_SUPPORT)
|
||||
atom_type = ATOM_DEVICE_DFP3_INDEX;
|
||||
|
||||
if (atom_type == -1)
|
||||
return;
|
||||
|
||||
switch(atom_type) {
|
||||
case ATOM_DEVICE_DFP1_INDEX:
|
||||
index = GetIndexIntoMasterTable(COMMAND, TMDSAOutputControl);
|
||||
break;
|
||||
case ATOM_DEVICE_DFP2_INDEX:
|
||||
index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl);
|
||||
break;
|
||||
case ATOM_DEVICE_DFP3_INDEX:
|
||||
index = GetIndexIntoMasterTable(COMMAND, LVTMAOutputControl);
|
||||
break;
|
||||
}
|
||||
|
||||
if (index == -1)
|
||||
return;
|
||||
|
||||
switch(mode) {
|
||||
case DRM_MODE_DPMS_ON:
|
||||
atombios_display_device_control(encoder, index, ATOM_ENABLE);
|
||||
break;
|
||||
case DRM_MODE_DPMS_STANDBY:
|
||||
case DRM_MODE_DPMS_SUSPEND:
|
||||
case DRM_MODE_DPMS_OFF:
|
||||
atombios_display_device_control(encoder, index, ATOM_DISABLE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static bool radeon_atom_tmds_mode_fixup(struct drm_encoder *encoder,
|
||||
struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static void radeon_atom_tmds_mode_set(struct drm_encoder *encoder,
|
||||
struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode)
|
||||
{
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
|
||||
int atom_type;
|
||||
|
||||
if (radeon_encoder->atom_device & ATOM_DEVICE_DFP1_SUPPORT)
|
||||
atom_type = ATOM_DEVICE_DFP1_INDEX;
|
||||
if (radeon_encoder->atom_device & ATOM_DEVICE_DFP2_SUPPORT)
|
||||
atom_type = ATOM_DEVICE_DFP2_INDEX;
|
||||
if (radeon_encoder->atom_device & ATOM_DEVICE_DFP3_SUPPORT)
|
||||
atom_type = ATOM_DEVICE_DFP3_INDEX;
|
||||
|
||||
atombios_scaler_setup(encoder, mode);
|
||||
atombios_set_crtc_source(encoder, atom_type);
|
||||
|
||||
if (atom_type == ATOM_DEVICE_DFP1_INDEX)
|
||||
atombios_tmds1_setup(encoder, adjusted_mode);
|
||||
if (atom_type == ATOM_DEVICE_DFP2_INDEX) {
|
||||
if ((dev_priv->chip_family == CHIP_RS600) ||
|
||||
(dev_priv->chip_family == CHIP_RS690) ||
|
||||
(dev_priv->chip_family == CHIP_RS740))
|
||||
atombios_ddia_setup(encoder, adjusted_mode);
|
||||
else
|
||||
atombios_ext_tmds_setup(encoder, adjusted_mode);
|
||||
}
|
||||
if (atom_type == ATOM_DEVICE_DFP3_INDEX)
|
||||
atombios_tmds2_setup(encoder, adjusted_mode);
|
||||
radeon_dfp_disable_dither(encoder, atom_type);
|
||||
|
||||
|
||||
}
|
||||
|
||||
static void radeon_atom_tmds_prepare(struct drm_encoder *encoder)
|
||||
{
|
||||
radeon_atom_tmds_dpms(encoder, DRM_MODE_DPMS_OFF);
|
||||
}
|
||||
|
||||
static void radeon_atom_tmds_commit(struct drm_encoder *encoder)
|
||||
{
|
||||
radeon_atom_tmds_dpms(encoder, DRM_MODE_DPMS_ON);
|
||||
}
|
||||
|
||||
static const struct drm_encoder_helper_funcs radeon_atom_tmds_helper_funcs = {
|
||||
.dpms = radeon_atom_tmds_dpms,
|
||||
.mode_fixup = radeon_atom_tmds_mode_fixup,
|
||||
.prepare = radeon_atom_tmds_prepare,
|
||||
.mode_set = radeon_atom_tmds_mode_set,
|
||||
.commit = radeon_atom_tmds_commit,
|
||||
/* no detect for TMDS */
|
||||
};
|
||||
|
||||
static const struct drm_encoder_funcs radeon_atom_tmds_enc_funcs = {
|
||||
. destroy = radeon_enc_destroy,
|
||||
};
|
||||
|
||||
struct drm_encoder *radeon_encoder_atom_tmds_add(struct drm_device *dev, int bios_index, int tmds_type)
|
||||
{
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct radeon_mode_info *mode_info = &dev_priv->mode_info;
|
||||
struct radeon_encoder *radeon_encoder = NULL;
|
||||
struct drm_encoder *encoder;
|
||||
int analog_enc_mask = ~(ATOM_DEVICE_CRT1_SUPPORT | ATOM_DEVICE_CRT2_SUPPORT);
|
||||
|
||||
radeon_encoder = kzalloc(sizeof(struct radeon_encoder), GFP_KERNEL);
|
||||
if (!radeon_encoder) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
encoder = &radeon_encoder->base;
|
||||
|
||||
encoder->possible_crtcs = 0x3;
|
||||
encoder->possible_clones = 0;
|
||||
drm_encoder_init(dev, encoder, &radeon_atom_tmds_enc_funcs,
|
||||
DRM_MODE_ENCODER_TMDS);
|
||||
|
||||
drm_encoder_helper_add(encoder, &radeon_atom_tmds_helper_funcs);
|
||||
|
||||
radeon_encoder->atom_device = mode_info->bios_connector[bios_index].devices;
|
||||
|
||||
/* mask off any analog encoders */
|
||||
radeon_encoder->atom_device &= analog_enc_mask;
|
||||
return encoder;
|
||||
}
|
||||
|
||||
static void radeon_legacy_lvds_dpms(struct drm_encoder *encoder, int mode)
|
||||
{
|
||||
struct drm_device *dev = encoder->dev;
|
||||
}
|
||||
|
||||
static void radeon_legacy_lvds_prepare(struct drm_encoder *encoder)
|
||||
{
|
||||
radeon_legacy_lvds_dpms(encoder, DRM_MODE_DPMS_OFF);
|
||||
}
|
||||
|
||||
static void radeon_legacy_lvds_commit(struct drm_encoder *encoder)
|
||||
{
|
||||
radeon_legacy_lvds_dpms(encoder, DRM_MODE_DPMS_ON);
|
||||
}
|
||||
|
||||
static void radeon_legacy_lvds_mode_set(struct drm_encoder *encoder,
|
||||
struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
static const struct drm_encoder_helper_funcs radeon_legacy_lvds_helper_funcs = {
|
||||
.dpms = radeon_legacy_lvds_dpms,
|
||||
.mode_fixup = radeon_lvtma_mode_fixup,
|
||||
.prepare = radeon_legacy_lvds_prepare,
|
||||
.mode_set = radeon_legacy_lvds_mode_set,
|
||||
.commit = radeon_legacy_lvds_commit,
|
||||
};
|
||||
|
||||
|
||||
static const struct drm_encoder_funcs radeon_legacy_lvds_enc_funcs = {
|
||||
.destroy = radeon_enc_destroy,
|
||||
};
|
||||
|
||||
struct drm_encoder *radeon_encoder_legacy_lvds_add(struct drm_device *dev, int bios_index)
|
||||
{
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct radeon_mode_info *mode_info = &dev_priv->mode_info;
|
||||
struct radeon_encoder *radeon_encoder;
|
||||
struct drm_encoder *encoder;
|
||||
radeon_encoder = kzalloc(sizeof(struct radeon_encoder), GFP_KERNEL);
|
||||
if (!radeon_encoder) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
encoder = &radeon_encoder->base;
|
||||
|
||||
encoder->possible_crtcs = 0x3;
|
||||
encoder->possible_clones = 0;
|
||||
drm_encoder_init(dev, encoder, &radeon_legacy_lvds_enc_funcs,
|
||||
DRM_MODE_ENCODER_LVDS);
|
||||
|
||||
drm_encoder_helper_add(encoder, &radeon_legacy_lvds_helper_funcs);
|
||||
|
||||
/* TODO get the LVDS info from the BIOS for panel size etc. */
|
||||
/* get the lvds info from the bios */
|
||||
radeon_combios_get_lvds_info(radeon_encoder);
|
||||
|
||||
/* LVDS gets default RMX full scaling */
|
||||
radeon_encoder->rmx_type = RMX_FULL;
|
||||
|
||||
return encoder;
|
||||
}
|
||||
1163
linux-core/radeon_fb.c
Normal file
1163
linux-core/radeon_fb.c
Normal file
File diff suppressed because it is too large
Load diff
96
linux-core/radeon_fence.c
Normal file
96
linux-core/radeon_fence.c
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
* USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
*
|
||||
**************************************************************************/
|
||||
/*
|
||||
* Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
|
||||
*/
|
||||
|
||||
#include "drmP.h"
|
||||
#include "drm.h"
|
||||
#include "radeon_drm.h"
|
||||
#include "radeon_drv.h"
|
||||
|
||||
int radeon_fence_emit_sequence(struct drm_device *dev, uint32_t class,
|
||||
uint32_t flags, uint32_t *sequence,
|
||||
uint32_t *native_type)
|
||||
{
|
||||
struct drm_radeon_private *dev_priv = (struct drm_radeon_private *) dev->dev_private;
|
||||
RING_LOCALS;
|
||||
|
||||
if (!dev_priv)
|
||||
return -EINVAL;
|
||||
|
||||
radeon_emit_irq(dev);
|
||||
*sequence = (uint32_t) dev_priv->counter;
|
||||
*native_type = DRM_FENCE_TYPE_EXE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void radeon_fence_poll(struct drm_device *dev, uint32_t fence_class,
|
||||
uint32_t waiting_types)
|
||||
{
|
||||
struct drm_radeon_private *dev_priv = (struct drm_radeon_private *) dev->dev_private;
|
||||
uint32_t sequence;
|
||||
if (waiting_types & DRM_FENCE_TYPE_EXE) {
|
||||
|
||||
sequence = READ_BREADCRUMB(dev_priv);
|
||||
|
||||
drm_fence_handler(dev, 0, sequence,
|
||||
DRM_FENCE_TYPE_EXE, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void radeon_fence_handler(struct drm_device * dev)
|
||||
{
|
||||
struct drm_fence_manager *fm = &dev->fm;
|
||||
struct drm_fence_class_manager *fc = &fm->fence_class[0];
|
||||
|
||||
write_lock(&fm->lock);
|
||||
radeon_fence_poll(dev, 0, fc->waiting_types);
|
||||
write_unlock(&fm->lock);
|
||||
}
|
||||
|
||||
int radeon_fence_has_irq(struct drm_device *dev, uint32_t class, uint32_t flags)
|
||||
{
|
||||
/*
|
||||
* We have an irq that tells us when we have a new breadcrumb.
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
struct drm_fence_driver radeon_fence_driver = {
|
||||
.num_classes = 1,
|
||||
.wrap_diff = (1U << (BREADCRUMB_BITS -1)),
|
||||
.flush_diff = (1U << (BREADCRUMB_BITS - 2)),
|
||||
.sequence_mask = BREADCRUMB_MASK,
|
||||
.emit = radeon_fence_emit_sequence,
|
||||
.has_irq = radeon_fence_has_irq,
|
||||
.poll = radeon_fence_poll,
|
||||
};
|
||||
|
||||
687
linux-core/radeon_gem.c
Normal file
687
linux-core/radeon_gem.c
Normal file
|
|
@ -0,0 +1,687 @@
|
|||
/*
|
||||
* Copyright 2008 Red Hat Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Author: Dave Airlie
|
||||
*/
|
||||
#include "drmP.h"
|
||||
#include "drm.h"
|
||||
|
||||
#include "radeon_drm.h"
|
||||
#include "radeon_drv.h"
|
||||
|
||||
int radeon_gem_init_object(struct drm_gem_object *obj)
|
||||
{
|
||||
struct drm_radeon_gem_object *obj_priv;
|
||||
|
||||
obj_priv = drm_calloc(1, sizeof(*obj_priv), DRM_MEM_DRIVER);
|
||||
if (!obj_priv) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
obj->driver_private = obj_priv;
|
||||
obj_priv->obj = obj;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void radeon_gem_free_object(struct drm_gem_object *obj)
|
||||
{
|
||||
|
||||
struct drm_radeon_gem_object *obj_priv = obj->driver_private;
|
||||
|
||||
/* tear down the buffer object - gem holds struct mutex */
|
||||
drm_bo_takedown_vm_locked(obj_priv->bo);
|
||||
drm_bo_usage_deref_locked(&obj_priv->bo);
|
||||
drm_free(obj->driver_private, 1, DRM_MEM_DRIVER);
|
||||
}
|
||||
|
||||
int radeon_gem_info_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct drm_radeon_gem_info *args = data;
|
||||
|
||||
args->vram_start = dev_priv->mm.vram_offset;
|
||||
args->vram_size = dev_priv->mm.vram_size;
|
||||
args->vram_visible = dev_priv->mm.vram_visible;
|
||||
|
||||
args->gart_start = dev_priv->mm.gart_start;
|
||||
args->gart_size = dev_priv->mm.gart_size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct drm_gem_object *radeon_gem_object_alloc(struct drm_device *dev, int size, int alignment,
|
||||
int initial_domain)
|
||||
{
|
||||
struct drm_gem_object *obj;
|
||||
struct drm_radeon_gem_object *obj_priv;
|
||||
int ret;
|
||||
uint32_t flags;
|
||||
|
||||
DRM_DEBUG("size 0x%x, alignment %d, initial_domain %d\n", size, alignment, initial_domain);
|
||||
obj = drm_gem_object_alloc(dev, size);
|
||||
if (!obj)
|
||||
return NULL;;
|
||||
|
||||
obj_priv = obj->driver_private;
|
||||
if (initial_domain == RADEON_GEM_DOMAIN_VRAM)
|
||||
flags = DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MAPPABLE;
|
||||
else
|
||||
flags = DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_MAPPABLE;
|
||||
|
||||
flags |= DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_EXE;
|
||||
/* create a TTM BO */
|
||||
ret = drm_buffer_object_create(dev,
|
||||
size, drm_bo_type_device,
|
||||
flags, 0, alignment,
|
||||
0, &obj_priv->bo);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
return obj;
|
||||
fail:
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int radeon_gem_create_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
struct drm_radeon_gem_create *args = data;
|
||||
struct drm_radeon_gem_object *obj_priv;
|
||||
struct drm_gem_object *obj;
|
||||
int ret = 0;
|
||||
uint32_t flags;
|
||||
int handle;
|
||||
|
||||
/* create a gem object to contain this object in */
|
||||
args->size = roundup(args->size, PAGE_SIZE);
|
||||
|
||||
obj = radeon_gem_object_alloc(dev, args->size, args->alignment, args->initial_domain);
|
||||
if (!obj)
|
||||
return -EINVAL;
|
||||
|
||||
obj_priv = obj->driver_private;
|
||||
DRM_DEBUG("obj is %p bo is %p, %d\n", obj, obj_priv->bo, obj_priv->bo->num_pages);
|
||||
ret = drm_gem_handle_create(file_priv, obj, &handle);
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
drm_gem_object_handle_unreference(obj);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
args->handle = handle;
|
||||
|
||||
return 0;
|
||||
fail:
|
||||
drm_gem_object_unreference(obj);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
/* transition the BO to a domain - just validate the BO into a certain domain */
|
||||
struct drm_radeon_gem_set_domain *args = data;
|
||||
struct drm_gem_object *obj;
|
||||
struct drm_radeon_gem_object *obj_priv;
|
||||
int ret;
|
||||
/* for now if someone requests domain CPU - just make sure the buffer is finished with */
|
||||
|
||||
/* just do a BO wait for now */
|
||||
obj = drm_gem_object_lookup(dev, file_priv, args->handle);
|
||||
if (obj == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
obj_priv = obj->driver_private;
|
||||
|
||||
mutex_lock(&obj_priv->bo->mutex);
|
||||
ret = drm_bo_wait(obj_priv->bo, 0, 1, 0, 0);
|
||||
mutex_unlock(&obj_priv->bo->mutex);
|
||||
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
drm_gem_object_unreference(obj);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int radeon_gem_pread_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
int radeon_gem_pwrite_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
int radeon_gem_mmap_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
struct drm_radeon_gem_mmap *args = data;
|
||||
struct drm_gem_object *obj;
|
||||
struct drm_radeon_gem_object *obj_priv;
|
||||
loff_t offset;
|
||||
unsigned long addr;
|
||||
|
||||
obj = drm_gem_object_lookup(dev, file_priv, args->handle);
|
||||
if (obj == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
offset = args->offset;
|
||||
|
||||
DRM_DEBUG("got here %p\n", obj);
|
||||
obj_priv = obj->driver_private;
|
||||
|
||||
DRM_DEBUG("got here %p %p %lld %ld\n", obj, obj_priv->bo, args->size, obj_priv->bo->num_pages);
|
||||
if (!obj_priv->bo) {
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
drm_gem_object_unreference(obj);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
down_write(¤t->mm->mmap_sem);
|
||||
addr = do_mmap_pgoff(file_priv->filp, 0, args->size,
|
||||
PROT_READ | PROT_WRITE, MAP_SHARED,
|
||||
obj_priv->bo->map_list.hash.key);
|
||||
up_write(¤t->mm->mmap_sem);
|
||||
|
||||
DRM_DEBUG("got here %p\n", obj);
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
drm_gem_object_unreference(obj);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
if (IS_ERR((void *)addr))
|
||||
return addr;
|
||||
|
||||
args->addr_ptr = (uint64_t) addr;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int radeon_gem_pin_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
struct drm_radeon_gem_pin *args = data;
|
||||
struct drm_gem_object *obj;
|
||||
struct drm_radeon_gem_object *obj_priv;
|
||||
int ret;
|
||||
|
||||
obj = drm_gem_object_lookup(dev, file_priv, args->handle);
|
||||
if (obj == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
obj_priv = obj->driver_private;
|
||||
|
||||
DRM_DEBUG("got here %p %p %d\n", obj, obj_priv->bo, atomic_read(&obj_priv->bo->usage));
|
||||
/* validate into a pin with no fence */
|
||||
|
||||
ret = drm_bo_do_validate(obj_priv->bo, 0, DRM_BO_FLAG_NO_EVICT,
|
||||
DRM_BO_HINT_DONT_FENCE,
|
||||
0, NULL);
|
||||
|
||||
args->offset = obj_priv->bo->offset;
|
||||
DRM_DEBUG("got here %p %p\n", obj, obj_priv->bo);
|
||||
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
drm_gem_object_unreference(obj);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int radeon_gem_unpin_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
struct drm_radeon_gem_unpin *args = data;
|
||||
struct drm_gem_object *obj;
|
||||
struct drm_radeon_gem_object *obj_priv;
|
||||
int ret;
|
||||
|
||||
obj = drm_gem_object_lookup(dev, file_priv, args->handle);
|
||||
if (obj == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
obj_priv = obj->driver_private;
|
||||
|
||||
/* validate into a pin with no fence */
|
||||
|
||||
ret = drm_bo_do_validate(obj_priv->bo, DRM_BO_FLAG_NO_EVICT, DRM_BO_FLAG_NO_EVICT,
|
||||
DRM_BO_HINT_DONT_FENCE,
|
||||
0, NULL);
|
||||
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
drm_gem_object_unreference(obj);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int radeon_gem_busy(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int radeon_gem_execbuffer(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
return -ENOSYS;
|
||||
|
||||
|
||||
}
|
||||
|
||||
int radeon_gem_indirect_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
struct drm_radeon_gem_indirect *args = data;
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct drm_gem_object *obj;
|
||||
struct drm_radeon_gem_object *obj_priv;
|
||||
uint32_t start, end;
|
||||
int ret;
|
||||
RING_LOCALS;
|
||||
|
||||
obj = drm_gem_object_lookup(dev, file_priv, args->handle);
|
||||
if (obj == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
obj_priv = obj->driver_private;
|
||||
|
||||
DRM_DEBUG("got here %p %d\n", obj, args->used);
|
||||
//RING_SPACE_TEST_WITH_RETURN(dev_priv);
|
||||
//VB_AGE_TEST_WITH_RETURN(dev_priv);
|
||||
|
||||
ret = drm_bo_do_validate(obj_priv->bo, 0, DRM_BO_FLAG_NO_EVICT,
|
||||
0 , 0, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Wait for the 3D stream to idle before the indirect buffer
|
||||
* containing 2D acceleration commands is processed.
|
||||
*/
|
||||
BEGIN_RING(2);
|
||||
|
||||
RADEON_WAIT_UNTIL_3D_IDLE();
|
||||
|
||||
ADVANCE_RING();
|
||||
|
||||
start = 0;
|
||||
end = args->used;
|
||||
|
||||
if (start != end) {
|
||||
int offset = (dev_priv->gart_vm_start +
|
||||
+ obj_priv->bo->offset + start);
|
||||
int dwords = (end - start + 3) / sizeof(u32);
|
||||
|
||||
#if 0
|
||||
/* Indirect buffer data must be an even number of
|
||||
* dwords, so if we've been given an odd number we must
|
||||
* pad the data with a Type-2 CP packet.
|
||||
*/
|
||||
if (dwords & 1) {
|
||||
u32 *data = (u32 *)
|
||||
((char *)dev->agp_buffer_map->handle
|
||||
+ buf->offset + start);
|
||||
data[dwords++] = RADEON_CP_PACKET2;
|
||||
}
|
||||
#endif
|
||||
/* Fire off the indirect buffer */
|
||||
BEGIN_RING(3);
|
||||
|
||||
OUT_RING(CP_PACKET0(RADEON_CP_IB_BASE, 1));
|
||||
OUT_RING(offset);
|
||||
OUT_RING(dwords);
|
||||
|
||||
ADVANCE_RING();
|
||||
}
|
||||
|
||||
COMMIT_RING();
|
||||
|
||||
/* we need to fence the buffer */
|
||||
ret = drm_fence_buffer_objects(dev, NULL, 0, NULL, &obj_priv->fence);
|
||||
if (ret) {
|
||||
|
||||
drm_putback_buffer_objects(dev);
|
||||
ret = 0;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* dereference he fence object */
|
||||
drm_fence_usage_deref_unlocked(&obj_priv->fence);
|
||||
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
drm_gem_object_unreference(obj);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
ret = 0;
|
||||
fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Depending on card genertation, chipset bugs, etc... the amount of vram
|
||||
* accessible to the CPU can vary. This function is our best shot at figuring
|
||||
* it out. Returns a value in KB.
|
||||
*/
|
||||
static uint32_t radeon_get_accessible_vram(struct drm_device *dev)
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
uint32_t aper_size;
|
||||
u8 byte;
|
||||
|
||||
if (dev_priv->chip_family >= CHIP_R600)
|
||||
aper_size = RADEON_READ(R600_CONFIG_APER_SIZE) / 1024;
|
||||
else
|
||||
aper_size = RADEON_READ(RADEON_CONFIG_APER_SIZE) / 1024;
|
||||
|
||||
/* Set HDP_APER_CNTL only on cards that are known not to be broken,
|
||||
* that is has the 2nd generation multifunction PCI interface
|
||||
*/
|
||||
if (dev_priv->chip_family == CHIP_RV280 ||
|
||||
dev_priv->chip_family == CHIP_RV350 ||
|
||||
dev_priv->chip_family == CHIP_RV380 ||
|
||||
dev_priv->chip_family == CHIP_R420 ||
|
||||
dev_priv->chip_family == CHIP_RV410 ||
|
||||
dev_priv->chip_family >= CHIP_RS600) {
|
||||
uint32_t temp = RADEON_READ(RADEON_HOST_PATH_CNTL);
|
||||
temp |= RADEON_HDP_APER_CNTL;
|
||||
RADEON_WRITE(RADEON_HOST_PATH_CNTL, temp);
|
||||
return aper_size * 2;
|
||||
}
|
||||
|
||||
/* Older cards have all sorts of funny issues to deal with. First
|
||||
* check if it's a multifunction card by reading the PCI config
|
||||
* header type... Limit those to one aperture size
|
||||
*/
|
||||
pci_read_config_byte(dev->pdev, 0xe, &byte);
|
||||
if (byte & 0x80)
|
||||
return aper_size;
|
||||
|
||||
/* Single function older card. We read HDP_APER_CNTL to see how the BIOS
|
||||
* have set it up. We don't write this as it's broken on some ASICs but
|
||||
* we expect the BIOS to have done the right thing (might be too optimistic...)
|
||||
*/
|
||||
if (RADEON_READ(RADEON_HOST_PATH_CNTL) & RADEON_HDP_APER_CNTL)
|
||||
return aper_size * 2;
|
||||
|
||||
return aper_size;
|
||||
}
|
||||
|
||||
/* code from the DDX - do memory sizing */
|
||||
void radeon_vram_setup(struct drm_device *dev)
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
uint32_t vram;
|
||||
uint32_t accessible, bar_size;
|
||||
|
||||
if ((dev_priv->chip_family <= CHIP_RV515) && (dev_priv->flags & RADEON_IS_IGP)) {
|
||||
uint32_t tom = RADEON_READ(RADEON_NB_TOM);
|
||||
|
||||
vram = (((tom >> 16) - (tom & 0xffff) + 1) << 6);
|
||||
RADEON_WRITE(RADEON_CONFIG_MEMSIZE, vram * 1024);
|
||||
} else {
|
||||
if (dev_priv->chip_family >= CHIP_R600)
|
||||
vram = RADEON_READ(R600_CONFIG_MEMSIZE) / 1024;
|
||||
else {
|
||||
vram = RADEON_READ(RADEON_CONFIG_MEMSIZE) / 1024;
|
||||
|
||||
/* Some production boards of m6 will return 0 if it's 8 MB */
|
||||
if (vram == 0) {
|
||||
vram = 8192;
|
||||
RADEON_WRITE(RADEON_CONFIG_MEMSIZE, 0x800000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
accessible = radeon_get_accessible_vram(dev);
|
||||
|
||||
bar_size = drm_get_resource_len(dev, 0) / 1024;
|
||||
if (bar_size == 0)
|
||||
bar_size = 0x20000;
|
||||
if (accessible > bar_size)
|
||||
accessible = bar_size;
|
||||
|
||||
DRM_INFO("Detected VRAM RAM=%dK, accessible=%uK, BAR=%uK\n",
|
||||
vram, accessible, bar_size);
|
||||
|
||||
dev_priv->mm.vram_offset = dev_priv->fb_aper_offset;
|
||||
dev_priv->mm.vram_size = vram * 1024;
|
||||
dev_priv->mm.vram_visible = accessible * 1024;
|
||||
|
||||
|
||||
}
|
||||
|
||||
static int radeon_gart_init(struct drm_device *dev)
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
int ret;
|
||||
u32 base = 0;
|
||||
|
||||
/* setup a 32MB GART */
|
||||
dev_priv->gart_size = dev_priv->mm.gart_size;
|
||||
|
||||
#if __OS_HAS_AGP
|
||||
/* setup VRAM vs GART here */
|
||||
if (dev_priv->flags & RADEON_IS_AGP) {
|
||||
base = dev->agp->base;
|
||||
if ((base + dev_priv->gart_size - 1) >= dev_priv->fb_location &&
|
||||
base < (dev_priv->fb_location + dev_priv->fb_size - 1)) {
|
||||
DRM_INFO("Can't use agp base @0x%08xlx, won't fit\n",
|
||||
dev->agp->base);
|
||||
base = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (base == 0) {
|
||||
base = dev_priv->fb_location + dev_priv->fb_size;
|
||||
if (base < dev_priv->fb_location ||
|
||||
((base + dev_priv->gart_size) & 0xfffffffful) < base)
|
||||
base = dev_priv->fb_location
|
||||
- dev_priv->gart_size;
|
||||
}
|
||||
/* start on the card */
|
||||
dev_priv->gart_vm_start = base & 0xffc00000u;
|
||||
if (dev_priv->gart_vm_start != base)
|
||||
DRM_INFO("GART aligned down from 0x%08x to 0x%08x\n",
|
||||
base, dev_priv->gart_vm_start);
|
||||
|
||||
/* if on PCIE we need to allocate an fb object for the PCIE GART table */
|
||||
if (dev_priv->flags & RADEON_IS_PCIE) {
|
||||
ret = drm_buffer_object_create(dev, RADEON_PCIGART_TABLE_SIZE,
|
||||
drm_bo_type_kernel,
|
||||
DRM_BO_FLAG_READ | DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MAPPABLE | DRM_BO_FLAG_NO_EVICT,
|
||||
0, 1, 0, &dev_priv->mm.pcie_table);
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
|
||||
DRM_DEBUG("pcie table bo created %p, %x\n", dev_priv->mm.pcie_table, dev_priv->mm.pcie_table->offset);
|
||||
ret = drm_bo_kmap(dev_priv->mm.pcie_table, 0, RADEON_PCIGART_TABLE_SIZE >> PAGE_SHIFT,
|
||||
&dev_priv->mm.pcie_table_map);
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
|
||||
dev_priv->pcigart_offset_set = 2;
|
||||
dev_priv->gart_info.bus_addr = dev_priv->fb_location + dev_priv->mm.pcie_table->offset;
|
||||
dev_priv->gart_info.addr = dev_priv->mm.pcie_table_map.virtual;
|
||||
dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCIE;
|
||||
dev_priv->gart_info.gart_table_location = DRM_ATI_GART_FB;
|
||||
memset(dev_priv->gart_info.addr, 0, RADEON_PCIGART_TABLE_SIZE);
|
||||
} else if (!(dev_priv->flags & RADEON_IS_AGP)) {
|
||||
/* allocate PCI GART table */
|
||||
dev_priv->gart_info.table_mask = DMA_BIT_MASK(32);
|
||||
ret = drm_ati_alloc_pcigart_table(dev, &dev_priv->gart_info);
|
||||
if (ret) {
|
||||
DRM_ERROR("cannot allocate PCI GART page!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dev_priv->gart_info.gart_table_location = DRM_ATI_GART_MAIN;
|
||||
if (dev_priv->flags & RADEON_IS_IGPGART)
|
||||
dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_IGP;
|
||||
else
|
||||
dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI;
|
||||
dev_priv->gart_info.addr = NULL;
|
||||
dev_priv->gart_info.bus_addr = 0;
|
||||
}
|
||||
|
||||
/* gart values setup - start the GART */
|
||||
if (dev_priv->flags & RADEON_IS_AGP) {
|
||||
radeon_set_pcigart(dev_priv, 0);
|
||||
} else {
|
||||
radeon_set_pcigart(dev_priv, 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int radeon_alloc_gart_objects(struct drm_device *dev)
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
int ret;
|
||||
|
||||
ret = drm_buffer_object_create(dev, RADEON_DEFAULT_RING_SIZE,
|
||||
drm_bo_type_kernel,
|
||||
DRM_BO_FLAG_READ | DRM_BO_FLAG_MEM_TT |
|
||||
DRM_BO_FLAG_MAPPABLE | DRM_BO_FLAG_NO_EVICT,
|
||||
0, 1, 0, &dev_priv->mm.ring);
|
||||
if (ret) {
|
||||
DRM_ERROR("failed to allocate ring\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = drm_bo_kmap(dev_priv->mm.ring, 0, RADEON_DEFAULT_RING_SIZE >> PAGE_SHIFT,
|
||||
&dev_priv->mm.ring_map);
|
||||
if (ret) {
|
||||
DRM_ERROR("failed to map ring\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = drm_buffer_object_create(dev, PAGE_SIZE,
|
||||
drm_bo_type_kernel,
|
||||
DRM_BO_FLAG_WRITE |DRM_BO_FLAG_READ | DRM_BO_FLAG_MEM_TT |
|
||||
DRM_BO_FLAG_MAPPABLE | DRM_BO_FLAG_NO_EVICT,
|
||||
0, 1, 0, &dev_priv->mm.ring_read_ptr);
|
||||
if (ret) {
|
||||
DRM_ERROR("failed to allocate ring read\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = drm_bo_kmap(dev_priv->mm.ring_read_ptr, 0,
|
||||
PAGE_SIZE >> PAGE_SHIFT,
|
||||
&dev_priv->mm.ring_read_ptr_map);
|
||||
if (ret) {
|
||||
DRM_ERROR("failed to map ring read\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
DRM_DEBUG("Ring ptr %p mapped at %d %p, read ptr %p maped at %d %p\n",
|
||||
dev_priv->mm.ring, dev_priv->mm.ring->offset, dev_priv->mm.ring_map.virtual,
|
||||
dev_priv->mm.ring_read_ptr, dev_priv->mm.ring_read_ptr->offset, dev_priv->mm.ring_read_ptr_map.virtual);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
/* init memory manager - start with all of VRAM and a 32MB GART aperture for now */
|
||||
int radeon_gem_mm_init(struct drm_device *dev)
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
int ret;
|
||||
|
||||
/* size the mappable VRAM memory for now */
|
||||
radeon_vram_setup(dev);
|
||||
|
||||
drm_bo_init_mm(dev, DRM_BO_MEM_VRAM, 0, /*dev_priv->mm.vram_offset >> PAGE_SHIFT,*/
|
||||
(dev_priv->mm.vram_visible) >> PAGE_SHIFT,
|
||||
0);
|
||||
|
||||
|
||||
dev_priv->mm.gart_size = (32 * 1024 * 1024);
|
||||
dev_priv->mm.gart_start = 0;
|
||||
ret = radeon_gart_init(dev);
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
|
||||
drm_bo_init_mm(dev, DRM_BO_MEM_TT, 0,
|
||||
dev_priv->mm.gart_size >> PAGE_SHIFT,
|
||||
0);
|
||||
|
||||
/* need to allocate some objects in the GART */
|
||||
/* ring + ring read ptr */
|
||||
ret = radeon_alloc_gart_objects(dev);
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void radeon_gem_mm_fini(struct drm_device *dev)
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
|
||||
if (dev_priv->mm.ring_read_ptr) {
|
||||
drm_bo_kunmap(&dev_priv->mm.ring_read_ptr_map);
|
||||
drm_bo_usage_deref_locked(&dev_priv->mm.ring_read_ptr);
|
||||
}
|
||||
|
||||
if (dev_priv->mm.ring) {
|
||||
drm_bo_kunmap(&dev_priv->mm.ring_map);
|
||||
drm_bo_usage_deref_locked(&dev_priv->mm.ring);
|
||||
}
|
||||
|
||||
if (drm_bo_clean_mm(dev, DRM_BO_MEM_TT, 1)) {
|
||||
DRM_DEBUG("delaying takedown of TTM memory\n");
|
||||
}
|
||||
|
||||
if (dev_priv->flags & RADEON_IS_PCIE) {
|
||||
if (dev_priv->mm.pcie_table) {
|
||||
drm_bo_kunmap(&dev_priv->mm.pcie_table_map);
|
||||
drm_bo_usage_deref_locked(&dev_priv->mm.pcie_table);
|
||||
}
|
||||
}
|
||||
|
||||
if (drm_bo_clean_mm(dev, DRM_BO_MEM_VRAM, 1)) {
|
||||
DRM_DEBUG("delaying takedown of TTM memory\n");
|
||||
}
|
||||
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
}
|
||||
|
||||
int radeon_gem_object_pin(struct drm_gem_object *obj,
|
||||
uint32_t alignment)
|
||||
{
|
||||
struct drm_radeon_gem_object *obj_priv;
|
||||
int ret;
|
||||
|
||||
obj_priv = obj->driver_private;
|
||||
|
||||
ret = drm_bo_do_validate(obj_priv->bo, 0, DRM_BO_FLAG_NO_EVICT,
|
||||
DRM_BO_HINT_DONT_FENCE, 0, NULL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
131
linux-core/radeon_i2c.c
Normal file
131
linux-core/radeon_i2c.c
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* Copyright 2007-8 Advanced Micro Devices, Inc.
|
||||
* Copyright 2008 Red Hat Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: Dave Airlie
|
||||
* Alex Deucher
|
||||
*/
|
||||
#include "drmP.h"
|
||||
#include "radeon_drm.h"
|
||||
#include "radeon_drv.h"
|
||||
|
||||
|
||||
static int get_clock(void *i2c_priv)
|
||||
{
|
||||
struct radeon_i2c_chan *i2c = i2c_priv;
|
||||
struct drm_radeon_private *dev_priv = i2c->dev->dev_private;
|
||||
struct radeon_i2c_bus_rec *rec = &i2c->rec;
|
||||
uint32_t val;
|
||||
|
||||
val = RADEON_READ(rec->get_clk_reg);
|
||||
val &= rec->get_clk_mask;
|
||||
|
||||
return (val != 0);
|
||||
}
|
||||
|
||||
|
||||
static int get_data(void *i2c_priv)
|
||||
{
|
||||
struct radeon_i2c_chan *i2c = i2c_priv;
|
||||
struct drm_radeon_private *dev_priv = i2c->dev->dev_private;
|
||||
struct radeon_i2c_bus_rec *rec = &i2c->rec;
|
||||
uint32_t val;
|
||||
|
||||
val = RADEON_READ(rec->get_data_reg);
|
||||
val &= rec->get_data_mask;
|
||||
return (val != 0);
|
||||
}
|
||||
|
||||
static void set_clock(void *i2c_priv, int clock)
|
||||
{
|
||||
struct radeon_i2c_chan *i2c = i2c_priv;
|
||||
struct drm_radeon_private *dev_priv = i2c->dev->dev_private;
|
||||
struct radeon_i2c_bus_rec *rec = &i2c->rec;
|
||||
uint32_t val;
|
||||
|
||||
val = RADEON_READ(rec->put_clk_reg) & (uint32_t)~(rec->put_clk_mask);
|
||||
val |= clock ? 0 : rec->put_clk_mask;
|
||||
RADEON_WRITE(rec->put_clk_reg, val);
|
||||
}
|
||||
|
||||
static void set_data(void *i2c_priv, int data)
|
||||
{
|
||||
struct radeon_i2c_chan *i2c = i2c_priv;
|
||||
struct drm_radeon_private *dev_priv = i2c->dev->dev_private;
|
||||
struct radeon_i2c_bus_rec *rec = &i2c->rec;
|
||||
uint32_t val;
|
||||
|
||||
val = RADEON_READ(rec->put_data_reg) & (uint32_t)~(rec->put_data_mask);
|
||||
val |= data ? 0 : rec->put_data_mask;
|
||||
RADEON_WRITE(rec->put_data_reg, val);
|
||||
}
|
||||
|
||||
struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
|
||||
struct radeon_i2c_bus_rec *rec,
|
||||
const char *name)
|
||||
{
|
||||
struct radeon_i2c_chan *i2c;
|
||||
int ret;
|
||||
|
||||
i2c = drm_calloc(1, sizeof(struct radeon_i2c_chan), DRM_MEM_DRIVER);
|
||||
if (i2c == NULL)
|
||||
return NULL;
|
||||
|
||||
i2c->adapter.owner = THIS_MODULE;
|
||||
i2c->adapter.id = I2C_HW_B_RADEON;
|
||||
i2c->adapter.algo_data = &i2c->algo;
|
||||
i2c->dev = dev;
|
||||
i2c->algo.setsda = set_data;
|
||||
i2c->algo.setscl = set_clock;
|
||||
i2c->algo.getsda = get_data;
|
||||
i2c->algo.getscl = get_clock;
|
||||
i2c->algo.udelay = 20;
|
||||
i2c->algo.timeout = usecs_to_jiffies(2200);
|
||||
i2c->algo.data = i2c;
|
||||
i2c->rec = *rec;
|
||||
i2c_set_adapdata(&i2c->adapter, i2c);
|
||||
|
||||
ret = i2c_bit_add_bus(&i2c->adapter);
|
||||
if (ret) {
|
||||
DRM_INFO("Failed to register i2c %s\n", name);
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
return i2c;
|
||||
out_free:
|
||||
drm_free(i2c, sizeof(struct radeon_i2c_chan), DRM_MEM_DRIVER);
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
void radeon_i2c_destroy(struct radeon_i2c_chan *i2c)
|
||||
{
|
||||
if (!i2c)
|
||||
return;
|
||||
|
||||
i2c_del_adapter(&i2c->adapter);
|
||||
drm_free(i2c, sizeof(struct radeon_i2c_chan), DRM_MEM_DRIVER);
|
||||
}
|
||||
|
||||
struct drm_encoder *radeon_best_encoder(struct drm_connector *connector)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
255
linux-core/radeon_mode.h
Normal file
255
linux-core/radeon_mode.h
Normal file
|
|
@ -0,0 +1,255 @@
|
|||
/*
|
||||
* Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
|
||||
* VA Linux Systems Inc., Fremont, California.
|
||||
* Copyright 2008 Red Hat Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Original Authors:
|
||||
* Kevin E. Martin, Rickard E. Faith, Alan Hourihane
|
||||
*
|
||||
* Kernel port Author: Dave Airlie
|
||||
*/
|
||||
|
||||
#ifndef RADEON_MODE_H
|
||||
#define RADEON_MODE_H
|
||||
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c-id.h>
|
||||
#include <linux/i2c-algo-bit.h>
|
||||
|
||||
#define to_radeon_crtc(x) container_of(x, struct radeon_crtc, base)
|
||||
#define to_radeon_connector(x) container_of(x, struct radeon_connector, base)
|
||||
#define to_radeon_encoder(x) container_of(x, struct radeon_encoder, base)
|
||||
#define to_radeon_framebuffer(x) container_of(x, struct radeon_framebuffer, base)
|
||||
|
||||
enum radeon_connector_type {
|
||||
CONNECTOR_NONE,
|
||||
CONNECTOR_VGA,
|
||||
CONNECTOR_DVI_I,
|
||||
CONNECTOR_DVI_D,
|
||||
CONNECTOR_DVI_A,
|
||||
CONNECTOR_STV,
|
||||
CONNECTOR_CTV,
|
||||
CONNECTOR_LVDS,
|
||||
CONNECTOR_DIGITAL,
|
||||
CONNECTOR_SCART,
|
||||
CONNECTOR_HDMI_TYPE_A,
|
||||
CONNECTOR_HDMI_TYPE_B,
|
||||
CONNECTOR_0XC,
|
||||
CONNECTOR_0XD,
|
||||
CONNECTOR_DIN,
|
||||
CONNECTOR_DISPLAY_PORT,
|
||||
CONNECTOR_UNSUPPORTED
|
||||
};
|
||||
|
||||
enum radeon_dac_type {
|
||||
DAC_NONE = 0,
|
||||
DAC_PRIMARY = 1,
|
||||
DAC_TVDAC = 2,
|
||||
DAC_EXT = 3
|
||||
};
|
||||
|
||||
enum radeon_tmds_type {
|
||||
TMDS_NONE = 0,
|
||||
TMDS_INT = 1,
|
||||
TMDS_EXT = 2,
|
||||
TMDS_LVTMA = 3,
|
||||
TMDS_DDIA = 4,
|
||||
TMDS_UNIPHY = 5
|
||||
};
|
||||
|
||||
enum radeon_dvi_type {
|
||||
DVI_AUTO,
|
||||
DVI_DIGITAL,
|
||||
DVI_ANALOG
|
||||
};
|
||||
|
||||
enum radeon_rmx_type {
|
||||
RMX_OFF,
|
||||
RMX_FULL,
|
||||
RMX_CENTER,
|
||||
};
|
||||
|
||||
struct radeon_i2c_bus_rec {
|
||||
bool valid;
|
||||
uint32_t mask_clk_reg;
|
||||
uint32_t mask_data_reg;
|
||||
uint32_t put_clk_reg;
|
||||
uint32_t put_data_reg;
|
||||
uint32_t get_clk_reg;
|
||||
uint32_t get_data_reg;
|
||||
uint32_t mask_clk_mask;
|
||||
uint32_t mask_data_mask;
|
||||
uint32_t put_clk_mask;
|
||||
uint32_t put_data_mask;
|
||||
uint32_t get_clk_mask;
|
||||
uint32_t get_data_mask;
|
||||
};
|
||||
|
||||
struct radeon_bios_connector {
|
||||
enum radeon_dac_type dac_type;
|
||||
enum radeon_tmds_type tmds_type;
|
||||
enum radeon_connector_type connector_type;
|
||||
bool valid;
|
||||
int output_id;
|
||||
int devices;
|
||||
int hpd_mask;
|
||||
struct radeon_i2c_bus_rec ddc_i2c;
|
||||
int igp_lane_info;
|
||||
};
|
||||
|
||||
#define RADEON_MAX_BIOS_CONNECTOR 16
|
||||
|
||||
#define RADEON_PLL_USE_BIOS_DIVS (1 << 0)
|
||||
#define RADEON_PLL_NO_ODD_POST_DIV (1 << 1)
|
||||
#define RADEON_PLL_USE_REF_DIV (1 << 2)
|
||||
#define RADEON_PLL_LEGACY (1 << 3)
|
||||
#define RADEON_PLL_PREFER_LOW_REF_DIV (1 << 4)
|
||||
|
||||
struct radeon_pll {
|
||||
uint16_t reference_freq;
|
||||
uint16_t reference_div;
|
||||
uint32_t pll_in_min;
|
||||
uint32_t pll_in_max;
|
||||
uint32_t pll_out_min;
|
||||
uint32_t pll_out_max;
|
||||
uint16_t xclk;
|
||||
|
||||
uint32_t min_ref_div;
|
||||
uint32_t max_ref_div;
|
||||
uint32_t min_post_div;
|
||||
uint32_t max_post_div;
|
||||
uint32_t min_feedback_div;
|
||||
uint32_t max_feedback_div;
|
||||
uint32_t best_vco;
|
||||
};
|
||||
|
||||
struct radeon_mode_info {
|
||||
struct atom_context *atom_context;
|
||||
struct radeon_bios_connector bios_connector[RADEON_MAX_BIOS_CONNECTOR];
|
||||
struct radeon_pll pll;
|
||||
};
|
||||
|
||||
struct radeon_crtc {
|
||||
struct drm_crtc base;
|
||||
int crtc_id;
|
||||
u8 lut_r[256], lut_g[256], lut_b[256];
|
||||
bool enabled;
|
||||
bool can_tile;
|
||||
uint32_t crtc_offset;
|
||||
struct radeon_framebuffer *fbdev_fb;
|
||||
struct drm_mode_set mode_set;
|
||||
};
|
||||
|
||||
struct radeon_i2c_chan {
|
||||
struct drm_device *dev;
|
||||
struct i2c_adapter adapter;
|
||||
struct i2c_algo_bit_data algo;
|
||||
struct radeon_i2c_bus_rec rec;
|
||||
};
|
||||
|
||||
|
||||
#define RADEON_USE_RMX 1
|
||||
|
||||
struct radeon_encoder {
|
||||
struct drm_encoder base;
|
||||
uint32_t encoder_mode;
|
||||
uint32_t flags;
|
||||
enum radeon_rmx_type rmx_type;
|
||||
union {
|
||||
enum radeon_dac_type dac;
|
||||
enum radeon_tmds_type tmds;
|
||||
} type;
|
||||
int atom_device; /* atom devices */
|
||||
uint32_t panel_xres, panel_yres;
|
||||
uint32_t hoverplus, hsync_width;
|
||||
uint32_t hblank;
|
||||
uint32_t voverplus, vsync_width;
|
||||
uint32_t vblank;
|
||||
uint32_t panel_pwr_delay;
|
||||
uint32_t dotclock;
|
||||
};
|
||||
|
||||
struct radeon_connector {
|
||||
struct drm_connector base;
|
||||
struct radeon_i2c_chan *ddc_bus;
|
||||
int use_digital;
|
||||
|
||||
};
|
||||
|
||||
struct radeon_framebuffer {
|
||||
struct drm_framebuffer base;
|
||||
struct drm_gem_object *obj;
|
||||
struct drm_bo_kmap_obj kmap_obj;
|
||||
};
|
||||
|
||||
extern struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
|
||||
struct radeon_i2c_bus_rec *rec,
|
||||
const char *name);
|
||||
extern void radeon_i2c_destroy(struct radeon_i2c_chan *i2c);
|
||||
extern int radeon_ddc_get_modes(struct radeon_connector *radeon_connector);
|
||||
extern struct drm_connector *radeon_connector_add(struct drm_device *dev, int bios_index);
|
||||
|
||||
extern struct drm_encoder *radeon_best_encoder(struct drm_connector *connector);
|
||||
|
||||
extern void radeon_compute_pll(struct radeon_pll *pll,
|
||||
uint64_t freq,
|
||||
uint32_t *dot_clock_p,
|
||||
uint32_t *fb_div_p,
|
||||
uint32_t *ref_div_p,
|
||||
uint32_t *post_div_p,
|
||||
int flags);
|
||||
|
||||
struct drm_encoder *radeon_encoder_lvtma_add(struct drm_device *dev, int bios_index);
|
||||
struct drm_encoder *radeon_encoder_atom_dac_add(struct drm_device *dev, int bios_index, int dac_id, int with_tv);
|
||||
struct drm_encoder *radeon_encoder_atom_tmds_add(struct drm_device *dev, int bios_index, int tmds_type);
|
||||
struct drm_encoder *radeon_encoder_legacy_lvds_add(struct drm_device *dev, int bios_index);
|
||||
|
||||
extern void radeon_crtc_load_lut(struct drm_crtc *crtc);
|
||||
extern void atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y);
|
||||
extern void atombios_crtc_mode_set(struct drm_crtc *crtc,
|
||||
struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode,
|
||||
int x, int y);
|
||||
extern void atombios_crtc_dpms(struct drm_crtc *crtc, int mode);
|
||||
extern bool radeon_atom_get_clock_info(struct drm_device *dev);
|
||||
extern bool radeon_combios_get_clock_info(struct drm_device *dev);
|
||||
extern void radeon_get_lvds_info(struct radeon_encoder *encoder);
|
||||
extern bool radeon_combios_get_lvds_info(struct radeon_encoder *encoder);
|
||||
extern void radeon_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
|
||||
u16 blue, int regno);
|
||||
struct drm_framebuffer *radeon_user_framebuffer_create(struct drm_device *dev,
|
||||
struct drm_file *filp,
|
||||
struct drm_mode_fb_cmd *mode_cmd);
|
||||
|
||||
int radeonfb_probe(struct drm_device *dev);
|
||||
|
||||
int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb);
|
||||
bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev);
|
||||
void radeon_atombios_init_crtc(struct drm_device *dev,
|
||||
struct radeon_crtc *radeon_crtc);
|
||||
void avivo_i2c_do_lock(struct radeon_connector *radeon_connector, int lock_state);
|
||||
|
||||
void radeon_atom_static_pwrmgt_setup(struct drm_device *dev, int enable);
|
||||
void radeon_atom_dyn_clk_setup(struct drm_device *dev, int enable);
|
||||
void radeon_get_clock_info(struct drm_device *dev);
|
||||
extern bool radeon_get_atom_connector_info_from_bios_connector_table(struct drm_device *dev);
|
||||
|
||||
#endif
|
||||
5276
linux-core/radeon_reg.h
Normal file
5276
linux-core/radeon_reg.h
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -236,7 +236,7 @@ enum drm_map_type {
|
|||
_DRM_AGP = 3, /**< AGP/GART */
|
||||
_DRM_SCATTER_GATHER = 4, /**< Scatter/gather memory for PCI DMA */
|
||||
_DRM_CONSISTENT = 5, /**< Consistent memory for PCI DMA */
|
||||
_DRM_TTM = 6
|
||||
_DRM_TTM = 6,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -732,12 +732,12 @@ static __inline__ void r300_pacify(drm_radeon_private_t *dev_priv)
|
|||
* The actual age emit is done by r300_do_cp_cmdbuf, which is why you must
|
||||
* be careful about how this function is called.
|
||||
*/
|
||||
static void r300_discard_buffer(struct drm_device * dev, struct drm_buf * buf)
|
||||
static void r300_discard_buffer(struct drm_device * dev, struct drm_master *master, struct drm_buf * buf)
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
drm_radeon_buf_priv_t *buf_priv = buf->dev_private;
|
||||
struct drm_radeon_master_private *master_priv = master->driver_priv;
|
||||
|
||||
buf_priv->age = ++dev_priv->sarea_priv->last_dispatch;
|
||||
buf_priv->age = ++master_priv->sarea_priv->last_dispatch;
|
||||
buf->pending = 1;
|
||||
buf->used = 0;
|
||||
}
|
||||
|
|
@ -898,6 +898,7 @@ int r300_do_cp_cmdbuf(struct drm_device *dev,
|
|||
drm_radeon_kcmd_buffer_t *cmdbuf)
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv;
|
||||
struct drm_device_dma *dma = dev->dma;
|
||||
struct drm_buf *buf = NULL;
|
||||
int emit_dispatch_age = 0;
|
||||
|
|
@ -1005,7 +1006,7 @@ int r300_do_cp_cmdbuf(struct drm_device *dev,
|
|||
}
|
||||
|
||||
emit_dispatch_age = 1;
|
||||
r300_discard_buffer(dev, buf);
|
||||
r300_discard_buffer(dev, file_priv->master, buf);
|
||||
break;
|
||||
|
||||
case R300_CMD_WAIT:
|
||||
|
|
@ -1060,7 +1061,7 @@ int r300_do_cp_cmdbuf(struct drm_device *dev,
|
|||
|
||||
/* Emit the vertex buffer age */
|
||||
BEGIN_RING(2);
|
||||
RADEON_DISPATCH_AGE(dev_priv->sarea_priv->last_dispatch);
|
||||
RADEON_DISPATCH_AGE(master_priv->sarea_priv->last_dispatch);
|
||||
ADVANCE_RING();
|
||||
}
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -457,12 +457,6 @@ typedef struct {
|
|||
unsigned int last_fence;
|
||||
} drm_radeon_sarea_t;
|
||||
|
||||
/* The only fence class we support */
|
||||
#define DRM_RADEON_FENCE_CLASS_ACCEL 0
|
||||
/* Fence type that guarantees read-write flush */
|
||||
#define DRM_RADEON_FENCE_TYPE_RW 2
|
||||
/* cache flushes programmed just before the fence */
|
||||
#define DRM_RADEON_FENCE_FLAG_FLUSHED 0x01000000
|
||||
|
||||
/* WARNING: If you change any of these defines, make sure to change the
|
||||
* defines in the Xserver file (xf86drmRadeon.h)
|
||||
|
|
@ -502,6 +496,17 @@ typedef struct {
|
|||
#define DRM_RADEON_SURF_ALLOC 0x1a
|
||||
#define DRM_RADEON_SURF_FREE 0x1b
|
||||
|
||||
#define DRM_RADEON_GEM_INFO 0x1c
|
||||
#define DRM_RADEON_GEM_CREATE 0x1d
|
||||
#define DRM_RADEON_GEM_MMAP 0x1e
|
||||
#define DRM_RADEON_GEM_PIN 0x1f
|
||||
#define DRM_RADEON_GEM_UNPIN 0x20
|
||||
#define DRM_RADEON_GEM_PREAD 0x21
|
||||
#define DRM_RADEON_GEM_PWRITE 0x22
|
||||
#define DRM_RADEON_GEM_SET_DOMAIN 0x23
|
||||
#define DRM_RADEON_GEM_INDIRECT 0x24 // temporary for X server
|
||||
|
||||
|
||||
#define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CP_INIT, drm_radeon_init_t)
|
||||
#define DRM_IOCTL_RADEON_CP_START DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_CP_START)
|
||||
#define DRM_IOCTL_RADEON_CP_STOP DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CP_STOP, drm_radeon_cp_stop_t)
|
||||
|
|
@ -530,6 +535,18 @@ typedef struct {
|
|||
#define DRM_IOCTL_RADEON_SURF_ALLOC DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SURF_ALLOC, drm_radeon_surface_alloc_t)
|
||||
#define DRM_IOCTL_RADEON_SURF_FREE DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SURF_FREE, drm_radeon_surface_free_t)
|
||||
|
||||
#define DRM_IOCTL_RADEON_GEM_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_INFO, struct drm_radeon_gem_info)
|
||||
#define DRM_IOCTL_RADEON_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_CREATE, struct drm_radeon_gem_create)
|
||||
#define DRM_IOCTL_RADEON_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_MMAP, struct drm_radeon_gem_mmap)
|
||||
#define DRM_IOCTL_RADEON_GEM_PIN DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_PIN, struct drm_radeon_gem_pin)
|
||||
#define DRM_IOCTL_RADEON_GEM_UNPIN DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_UNPIN, struct drm_radeon_gem_unpin)
|
||||
#define DRM_IOCTL_RADEON_GEM_PREAD DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_PREAD, struct drm_radeon_gem_pread)
|
||||
#define DRM_IOCTL_RADEON_GEM_PWRITE DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_PWRITE, struct drm_radeon_gem_pwrite)
|
||||
#define DRM_IOCTL_RADEON_GEM_SET_DOMAIN DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_SET_DOMAIN, struct drm_radeon_gem_set_domain)
|
||||
#define DRM_IOCTL_RADEON_GEM_INDIRECT DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_INDIRECT, struct drm_radeon_gem_indirect)
|
||||
|
||||
|
||||
|
||||
typedef struct drm_radeon_init {
|
||||
enum {
|
||||
RADEON_INIT_CP = 0x01,
|
||||
|
|
@ -756,4 +773,92 @@ typedef struct drm_radeon_surface_free {
|
|||
#define DRM_RADEON_VBLANK_CRTC1 1
|
||||
#define DRM_RADEON_VBLANK_CRTC2 2
|
||||
|
||||
#define RADEON_GEM_DOMAIN_CPU 0x1
|
||||
#define RADEON_GEM_DOMAIN_VRAM 0x2
|
||||
#define RADEON_GEM_DOMAIN_2D 0x4
|
||||
#define RADEON_GEM_DOMAIN_3D 0x8
|
||||
#define RADEON_GEM_DOMAIN_TEXTURE 0x10
|
||||
#define RADEON_GEM_DOMAIN_GPU 0x20 // for vertex buffers
|
||||
|
||||
/* return to userspace start/size of gtt and vram apertures */
|
||||
struct drm_radeon_gem_info {
|
||||
uint64_t gart_start;
|
||||
uint64_t gart_size;
|
||||
uint64_t vram_start;
|
||||
uint64_t vram_size;
|
||||
uint64_t vram_visible;
|
||||
};
|
||||
|
||||
struct drm_radeon_gem_create {
|
||||
uint64_t size;
|
||||
uint64_t alignment;
|
||||
uint32_t handle;
|
||||
uint32_t initial_domain; // to allow VRAM to be created
|
||||
uint32_t no_backing_store; // for VRAM objects - select whether they need backing store
|
||||
// pretty much front/back/depth don't need it - other things do
|
||||
};
|
||||
|
||||
struct drm_radeon_gem_mmap {
|
||||
uint32_t handle;
|
||||
uint32_t pad;
|
||||
uint64_t offset;
|
||||
uint64_t size;
|
||||
uint64_t addr_ptr;
|
||||
};
|
||||
|
||||
struct drm_radeon_gem_set_domain {
|
||||
uint32_t handle;
|
||||
uint32_t read_domains;
|
||||
uint32_t write_domain;
|
||||
};
|
||||
|
||||
struct drm_radeon_gem_exec_buffer {
|
||||
};
|
||||
|
||||
struct drm_radeon_gem_pin {
|
||||
uint32_t handle;
|
||||
uint32_t pad;
|
||||
uint64_t alignment;
|
||||
uint64_t offset;
|
||||
};
|
||||
|
||||
struct drm_radeon_gem_unpin {
|
||||
uint32_t handle;
|
||||
uint32_t pad;
|
||||
};
|
||||
|
||||
struct drm_radeon_gem_busy {
|
||||
uint32_t handle;
|
||||
uint32_t busy;
|
||||
};
|
||||
|
||||
struct drm_radeon_gem_pread {
|
||||
/** Handle for the object being read. */
|
||||
uint32_t handle;
|
||||
uint32_t pad;
|
||||
/** Offset into the object to read from */
|
||||
uint64_t offset;
|
||||
/** Length of data to read */
|
||||
uint64_t size;
|
||||
/** Pointer to write the data into. */
|
||||
uint64_t data_ptr; /* void *, but pointers are not 32/64 compatible */
|
||||
};
|
||||
|
||||
struct drm_radeon_gem_pwrite {
|
||||
/** Handle for the object being written to. */
|
||||
uint32_t handle;
|
||||
uint32_t pad;
|
||||
/** Offset into the object to write to */
|
||||
uint64_t offset;
|
||||
/** Length of data to write */
|
||||
uint64_t size;
|
||||
/** Pointer to read the data from. */
|
||||
uint64_t data_ptr; /* void *, but pointers are not 32/64 compatible */
|
||||
};
|
||||
|
||||
struct drm_radeon_gem_indirect {
|
||||
uint32_t handle;
|
||||
uint32_t used;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#ifndef __RADEON_DRV_H__
|
||||
#define __RADEON_DRV_H__
|
||||
|
||||
#include "atom.h"
|
||||
/* General customization:
|
||||
*/
|
||||
|
||||
|
|
@ -96,13 +97,13 @@
|
|||
* 1.25- Add support for r200 vertex programs (R200_EMIT_VAP_PVS_CNTL,
|
||||
* new packet type)
|
||||
* 1.26- Add support for variable size PCI(E) gart aperture
|
||||
* 1.27- Add support for IGP GART
|
||||
* 1.27- Add support for IGPGART
|
||||
* 1.28- Add support for VBL on CRTC2
|
||||
* 1.29- R500 3D cmd buffer support
|
||||
*/
|
||||
|
||||
#define DRIVER_MAJOR 1
|
||||
#define DRIVER_MINOR 29
|
||||
#define DRIVER_MINOR 30
|
||||
#define DRIVER_PATCHLEVEL 0
|
||||
|
||||
/*
|
||||
|
|
@ -124,23 +125,29 @@ enum radeon_family {
|
|||
CHIP_RV380,
|
||||
CHIP_R420,
|
||||
CHIP_RV410,
|
||||
CHIP_RS400,
|
||||
CHIP_RS480,
|
||||
CHIP_RS600,
|
||||
CHIP_RS690,
|
||||
CHIP_RS740,
|
||||
CHIP_RV515,
|
||||
CHIP_R520,
|
||||
CHIP_RV530,
|
||||
CHIP_RV560,
|
||||
CHIP_RV570,
|
||||
CHIP_R580,
|
||||
CHIP_R600,
|
||||
CHIP_R630,
|
||||
CHIP_RV610,
|
||||
CHIP_RV630,
|
||||
CHIP_RV670,
|
||||
CHIP_RV620,
|
||||
CHIP_RV635,
|
||||
CHIP_RS780,
|
||||
CHIP_RV770,
|
||||
CHIP_LAST,
|
||||
};
|
||||
|
||||
enum radeon_cp_microcode_version {
|
||||
UCODE_R100,
|
||||
UCODE_R200,
|
||||
UCODE_R300,
|
||||
};
|
||||
|
||||
/*
|
||||
* Chip flags
|
||||
*/
|
||||
|
|
@ -158,9 +165,42 @@ enum radeon_chip_flags {
|
|||
RADEON_IS_IGPGART = 0x01000000UL,
|
||||
};
|
||||
|
||||
/*
|
||||
* Errata workarounds
|
||||
*/
|
||||
enum radeon_pll_errata {
|
||||
CHIP_ERRATA_R300_CG = 0x00000001,
|
||||
CHIP_ERRATA_PLL_DUMMYREADS = 0x00000002,
|
||||
CHIP_ERRATA_PLL_DELAY = 0x00000004
|
||||
};
|
||||
|
||||
enum radeon_ext_tmds_chip {
|
||||
RADEON_DVOCHIP_NONE,
|
||||
RADEON_SIL_164,
|
||||
RADEON_SIL_1178
|
||||
};
|
||||
|
||||
#if defined(__powerpc__)
|
||||
enum radeon_mac_model {
|
||||
RADEON_MAC_NONE,
|
||||
RADEON_MAC_IBOOK,
|
||||
RADEON_MAC_POWERBOOK_EXTERNAL,
|
||||
RADEON_MAC_POWERBOOK_INTERNAL,
|
||||
RADEON_MAC_POWERBOOK_VGA,
|
||||
RADEON_MAC_MINI_EXTERNAL,
|
||||
RADEON_MAC_MINI_INTERNAL,
|
||||
RADEON_MAC_IMAC_G5_ISIGHT
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
#define GET_RING_HEAD(dev_priv) (dev_priv->writeback_works ? \
|
||||
DRM_READ32( (dev_priv)->ring_rptr, 0 ) : RADEON_READ(RADEON_CP_RB_RPTR))
|
||||
#define SET_RING_HEAD(dev_priv,val) DRM_WRITE32( (dev_priv)->ring_rptr, 0, (val) )
|
||||
(dev_priv->mm.ring_read_ptr ? readl(dev_priv->mm.ring_read_ptr_map.virtual + 0) : DRM_READ32((dev_priv)->ring_rptr, 0 )) : \
|
||||
RADEON_READ(RADEON_CP_RB_RPTR))
|
||||
|
||||
#define SET_RING_HEAD(dev_priv,val) (dev_priv->mm.ring_read_ptr ? \
|
||||
writel((val), dev_priv->mm.ring_read_ptr_map.virtual) : \
|
||||
DRM_WRITE32((dev_priv)->ring_rptr, 0, (val)))
|
||||
|
||||
typedef struct drm_radeon_freelist {
|
||||
unsigned int age;
|
||||
|
|
@ -221,13 +261,35 @@ struct radeon_virt_surface {
|
|||
struct drm_file *file_priv;
|
||||
};
|
||||
|
||||
struct radeon_mm_info {
|
||||
uint64_t vram_offset; // Offset into GPU space
|
||||
uint64_t vram_size;
|
||||
uint64_t vram_visible;
|
||||
|
||||
uint64_t gart_start;
|
||||
uint64_t gart_size;
|
||||
|
||||
struct drm_buffer_object *pcie_table;
|
||||
struct drm_bo_kmap_obj pcie_table_map;
|
||||
|
||||
struct drm_buffer_object *ring;
|
||||
struct drm_bo_kmap_obj ring_map;
|
||||
|
||||
struct drm_buffer_object *ring_read_ptr;
|
||||
struct drm_bo_kmap_obj ring_read_ptr_map;
|
||||
};
|
||||
|
||||
#include "radeon_mode.h"
|
||||
|
||||
struct drm_radeon_master_private {
|
||||
drm_local_map_t *sarea;
|
||||
drm_radeon_sarea_t *sarea_priv;
|
||||
};
|
||||
|
||||
typedef struct drm_radeon_private {
|
||||
|
||||
drm_radeon_ring_buffer_t ring;
|
||||
drm_radeon_sarea_t *sarea_priv;
|
||||
|
||||
u32 fb_location;
|
||||
u32 fb_size;
|
||||
int new_memmap;
|
||||
|
||||
int gart_size;
|
||||
|
|
@ -245,8 +307,6 @@ typedef struct drm_radeon_private {
|
|||
|
||||
int usec_timeout;
|
||||
|
||||
int microcode_version;
|
||||
|
||||
struct {
|
||||
u32 boxes;
|
||||
int freelist_timeouts;
|
||||
|
|
@ -282,8 +342,6 @@ typedef struct drm_radeon_private {
|
|||
unsigned long buffers_offset;
|
||||
unsigned long gart_textures_offset;
|
||||
|
||||
drm_local_map_t *sarea;
|
||||
drm_local_map_t *mmio;
|
||||
drm_local_map_t *cp_ring;
|
||||
drm_local_map_t *ring_rptr;
|
||||
drm_local_map_t *gart_textures;
|
||||
|
|
@ -292,8 +350,8 @@ typedef struct drm_radeon_private {
|
|||
struct mem_block *fb_heap;
|
||||
|
||||
/* SW interrupt */
|
||||
int counter;
|
||||
wait_queue_head_t swi_queue;
|
||||
atomic_t swi_emitted;
|
||||
int vblank_crtc;
|
||||
uint32_t irq_enable_reg;
|
||||
int irq_enabled;
|
||||
|
|
@ -302,9 +360,6 @@ typedef struct drm_radeon_private {
|
|||
struct radeon_surface surfaces[RADEON_MAX_SURFACES];
|
||||
struct radeon_virt_surface virt_surfaces[2 * RADEON_MAX_SURFACES];
|
||||
|
||||
unsigned long pcigart_offset;
|
||||
unsigned int pcigart_offset_set;
|
||||
struct drm_ati_pcigart_info gart_info;
|
||||
|
||||
u32 scratch_ages[5];
|
||||
|
||||
|
|
@ -316,6 +371,28 @@ typedef struct drm_radeon_private {
|
|||
unsigned long fb_aper_offset;
|
||||
|
||||
int num_gb_pipes;
|
||||
|
||||
struct radeon_mm_info mm;
|
||||
drm_local_map_t *mmio;
|
||||
|
||||
uint32_t chip_family;
|
||||
|
||||
unsigned long pcigart_offset;
|
||||
unsigned int pcigart_offset_set;
|
||||
struct drm_ati_pcigart_info gart_info;
|
||||
|
||||
struct radeon_mode_info mode_info;
|
||||
|
||||
uint8_t *bios; /* copy of the BIOS image */
|
||||
bool is_atom_bios;
|
||||
uint16_t bios_header_start;
|
||||
u32 fb_location;
|
||||
u32 fb_size;
|
||||
bool is_ddr;
|
||||
u32 ram_width;
|
||||
|
||||
enum radeon_pll_errata pll_errata;
|
||||
|
||||
} drm_radeon_private_t;
|
||||
|
||||
typedef struct drm_radeon_buf_priv {
|
||||
|
|
@ -330,6 +407,7 @@ typedef struct drm_radeon_kcmd_buffer {
|
|||
} drm_radeon_kcmd_buffer_t;
|
||||
|
||||
extern int radeon_no_wb;
|
||||
extern int radeon_dynclks;
|
||||
extern struct drm_ioctl_desc radeon_ioctls[];
|
||||
extern int radeon_max_ioctl;
|
||||
|
||||
|
|
@ -417,9 +495,14 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev,
|
|||
#define RADEON_BOX_WAIT_IDLE 0x8
|
||||
#define RADEON_BOX_TEXTURE_LOAD 0x10
|
||||
|
||||
#define R600_CONFIG_MEMSIZE 0x5428
|
||||
#define R600_CONFIG_APER_SIZE 0x5430
|
||||
/* Register definitions, register access macros and drmAddMap constants
|
||||
* for Radeon kernel driver.
|
||||
*/
|
||||
|
||||
#include "radeon_reg.h"
|
||||
|
||||
#define RADEON_AGP_COMMAND 0x0f60
|
||||
#define RADEON_AGP_COMMAND_PCI_CONFIG 0x0060 /* offset in PCI config */
|
||||
# define RADEON_AGP_ENABLE (1<<8)
|
||||
|
|
@ -522,16 +605,6 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev,
|
|||
#define R520_MC_IND_WR_EN (1 << 24)
|
||||
#define R520_MC_IND_DATA 0x74
|
||||
|
||||
#define RV515_MC_FB_LOCATION 0x01
|
||||
#define RV515_MC_AGP_LOCATION 0x02
|
||||
#define RV515_MC_AGP_BASE 0x03
|
||||
#define RV515_MC_AGP_BASE_2 0x04
|
||||
|
||||
#define R520_MC_FB_LOCATION 0x04
|
||||
#define R520_MC_AGP_LOCATION 0x05
|
||||
#define R520_MC_AGP_BASE 0x06
|
||||
#define R520_MC_AGP_BASE_2 0x07
|
||||
|
||||
#define RADEON_MPP_TB_CONFIG 0x01c0
|
||||
#define RADEON_MEM_CNTL 0x0140
|
||||
#define RADEON_MEM_SDRAM_MODE_REG 0x0158
|
||||
|
|
@ -601,9 +674,11 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev,
|
|||
|
||||
#define RADEON_SCRATCHOFF( x ) (RADEON_SCRATCH_REG_OFFSET + 4*(x))
|
||||
|
||||
#define GET_SCRATCH( x ) (dev_priv->writeback_works \
|
||||
? DRM_READ32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(x) ) \
|
||||
: RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x) ) )
|
||||
#define GET_SCRATCH( x ) (dev_priv->writeback_works ? \
|
||||
(dev_priv->mm.ring_read_ptr ? \
|
||||
readl(dev_priv->mm.ring_read_ptr_map.virtual + RADEON_SCRATCHOFF(0)) : \
|
||||
DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(x))) : \
|
||||
RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x)))
|
||||
|
||||
#define RADEON_CRTC_CRNT_FRAME 0x0214
|
||||
#define RADEON_CRTC2_CRNT_FRAME 0x0314
|
||||
|
|
@ -628,11 +703,11 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev,
|
|||
# define RADEON_SW_INT_FIRE (1 << 26)
|
||||
# define R500_DISPLAY_INT_STATUS (1 << 0)
|
||||
|
||||
#define RADEON_HOST_PATH_CNTL 0x0130
|
||||
# define RADEON_HDP_SOFT_RESET (1 << 26)
|
||||
# define RADEON_HDP_APER_CNTL (1 << 23)
|
||||
|
||||
#define RADEON_HOST_PATH_CNTL 0x0130
|
||||
# define RADEON_HDP_SOFT_RESET (1 << 26)
|
||||
# define RADEON_HDP_WC_TIMEOUT_MASK (7 << 28)
|
||||
# define RADEON_HDP_WC_TIMEOUT_28BCLK (7 << 28)
|
||||
#define RADEON_NB_TOM 0x15c
|
||||
|
||||
#define RADEON_ISYNC_CNTL 0x1724
|
||||
# define RADEON_ISYNC_ANY2D_IDLE3D (1 << 0)
|
||||
|
|
@ -703,11 +778,6 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev,
|
|||
# define R300_ZC_FREE (1 << 1)
|
||||
# define R300_ZC_FLUSH_ALL 0x3
|
||||
# define R300_ZC_BUSY (1 << 31)
|
||||
#define RADEON_RB3D_DSTCACHE_CTLSTAT 0x325c
|
||||
# define RADEON_RB3D_DC_FLUSH (3 << 0)
|
||||
# define RADEON_RB3D_DC_FREE (3 << 2)
|
||||
# define RADEON_RB3D_DC_FLUSH_ALL 0xf
|
||||
# define RADEON_RB3D_DC_BUSY (1 << 31)
|
||||
#define R300_RB3D_DSTCACHE_CTLSTAT 0x4e4c
|
||||
# define R300_RB3D_DC_FINISH (1 << 4)
|
||||
#define RADEON_RB3D_ZSTENCILCNTL 0x1c2c
|
||||
|
|
@ -981,27 +1051,6 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev,
|
|||
#define RADEON_NUM_VERTICES_SHIFT 16
|
||||
|
||||
#define RADEON_COLOR_FORMAT_CI8 2
|
||||
#define RADEON_COLOR_FORMAT_ARGB1555 3
|
||||
#define RADEON_COLOR_FORMAT_RGB565 4
|
||||
#define RADEON_COLOR_FORMAT_ARGB8888 6
|
||||
#define RADEON_COLOR_FORMAT_RGB332 7
|
||||
#define RADEON_COLOR_FORMAT_RGB8 9
|
||||
#define RADEON_COLOR_FORMAT_ARGB4444 15
|
||||
|
||||
#define RADEON_TXFORMAT_I8 0
|
||||
#define RADEON_TXFORMAT_AI88 1
|
||||
#define RADEON_TXFORMAT_RGB332 2
|
||||
#define RADEON_TXFORMAT_ARGB1555 3
|
||||
#define RADEON_TXFORMAT_RGB565 4
|
||||
#define RADEON_TXFORMAT_ARGB4444 5
|
||||
#define RADEON_TXFORMAT_ARGB8888 6
|
||||
#define RADEON_TXFORMAT_RGBA8888 7
|
||||
#define RADEON_TXFORMAT_Y8 8
|
||||
#define RADEON_TXFORMAT_VYUY422 10
|
||||
#define RADEON_TXFORMAT_YVYU422 11
|
||||
#define RADEON_TXFORMAT_DXT1 12
|
||||
#define RADEON_TXFORMAT_DXT23 14
|
||||
#define RADEON_TXFORMAT_DXT45 15
|
||||
|
||||
#define R200_PP_TXCBLEND_0 0x2f00
|
||||
#define R200_PP_TXCBLEND_1 0x2f10
|
||||
|
|
@ -1187,18 +1236,16 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev,
|
|||
#define RADEON_RING_HIGH_MARK 128
|
||||
|
||||
#define RADEON_PCIGART_TABLE_SIZE (32*1024)
|
||||
#define RADEON_DEFAULT_RING_SIZE (1024*1024)
|
||||
#define RADEON_DEFAULT_CP_TIMEOUT 100000 /* usecs */
|
||||
|
||||
#define RADEON_READ(reg) DRM_READ32( dev_priv->mmio, (reg) )
|
||||
#define RADEON_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) )
|
||||
#define RADEON_READ8(reg) DRM_READ8( dev_priv->mmio, (reg) )
|
||||
#define RADEON_WRITE8(reg,val) DRM_WRITE8( dev_priv->mmio, (reg), (val) )
|
||||
|
||||
#define RADEON_WRITE_PLL( addr, val ) \
|
||||
do { \
|
||||
RADEON_WRITE8( RADEON_CLOCK_CNTL_INDEX, \
|
||||
((addr) & 0x1f) | RADEON_PLL_WR_EN ); \
|
||||
RADEON_WRITE( RADEON_CLOCK_CNTL_DATA, (val) ); \
|
||||
} while (0)
|
||||
extern int RADEON_READ_PLL(struct drm_radeon_private *dev_priv, int addr);
|
||||
extern void RADEON_WRITE_PLL(struct drm_radeon_private *dev_priv, int addr, uint32_t data);
|
||||
|
||||
#define RADEON_WRITE_PCIE( addr, val ) \
|
||||
do { \
|
||||
|
|
@ -1311,7 +1358,7 @@ do { \
|
|||
OUT_RING( CP_PACKET0( RADEON_RB3D_ZCACHE_CTLSTAT, 0 ) ); \
|
||||
OUT_RING( RADEON_RB3D_ZC_FLUSH_ALL ); \
|
||||
} else { \
|
||||
OUT_RING( CP_PACKET0( R300_RB3D_DSTCACHE_CTLSTAT, 0 ) ); \
|
||||
OUT_RING( CP_PACKET0( R300_RB3D_ZCACHE_CTLSTAT, 0 ) ); \
|
||||
OUT_RING( R300_ZC_FLUSH_ALL ); \
|
||||
} \
|
||||
} while (0)
|
||||
|
|
@ -1333,7 +1380,8 @@ do { \
|
|||
|
||||
#define VB_AGE_TEST_WITH_RETURN( dev_priv ) \
|
||||
do { \
|
||||
drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; \
|
||||
struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv; \
|
||||
drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv; \
|
||||
if ( sarea_priv->last_dispatch >= RADEON_MAX_VB_AGE ) { \
|
||||
int __ret = radeon_do_cp_idle( dev_priv ); \
|
||||
if ( __ret ) return __ret; \
|
||||
|
|
@ -1439,4 +1487,110 @@ do { \
|
|||
write &= mask; \
|
||||
} while (0)
|
||||
|
||||
/* radeon GEM->TTM munger */
|
||||
struct drm_radeon_gem_object {
|
||||
/* wrap a TTM bo */
|
||||
struct drm_buffer_object *bo;
|
||||
struct drm_fence_object *fence;
|
||||
struct drm_gem_object *obj;
|
||||
|
||||
};
|
||||
|
||||
extern int radeon_gem_info_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv);
|
||||
|
||||
extern int radeon_gem_create_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv);
|
||||
|
||||
extern int radeon_gem_pwrite_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv);
|
||||
|
||||
extern int radeon_gem_mmap_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv);
|
||||
extern int radeon_gem_pread_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv);
|
||||
|
||||
extern void radeon_fence_handler(struct drm_device *dev);
|
||||
extern int radeon_fence_emit_sequence(struct drm_device *dev, uint32_t class,
|
||||
uint32_t flags, uint32_t *sequence,
|
||||
uint32_t *native_type);
|
||||
extern void radeon_poke_flush(struct drm_device *dev, uint32_t class);
|
||||
extern int radeon_fence_has_irq(struct drm_device *dev, uint32_t class, uint32_t flags);
|
||||
|
||||
/* radeon_buffer.c */
|
||||
extern struct drm_ttm_backend *radeon_create_ttm_backend_entry(struct drm_device *dev);
|
||||
extern int radeon_fence_types(struct drm_buffer_object *bo, uint32_t *class, uint32_t *type);
|
||||
extern int radeon_invalidate_caches(struct drm_device *dev, uint64_t buffer_flags);
|
||||
extern int radeon_init_mem_type(struct drm_device * dev, uint32_t type,
|
||||
struct drm_mem_type_manager * man);
|
||||
extern int radeon_move(struct drm_buffer_object * bo,
|
||||
int evict, int no_wait, struct drm_bo_mem_reg * new_mem);
|
||||
|
||||
extern void radeon_gart_flush(struct drm_device *dev);
|
||||
extern uint64_t radeon_evict_flags(struct drm_buffer_object *bo);
|
||||
|
||||
#define BREADCRUMB_BITS 31
|
||||
#define BREADCRUMB_MASK ((1U << BREADCRUMB_BITS) - 1)
|
||||
|
||||
/* Breadcrumb - swi irq */
|
||||
#define READ_BREADCRUMB(dev_priv) RADEON_READ(RADEON_LAST_SWI_REG)
|
||||
|
||||
static inline int radeon_update_breadcrumb(struct drm_device *dev)
|
||||
{
|
||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||
struct drm_radeon_master_private *master_priv;
|
||||
|
||||
++dev_priv->counter;
|
||||
if (dev_priv->counter > BREADCRUMB_MASK)
|
||||
dev_priv->counter = 1;
|
||||
|
||||
if (dev->primary->master) {
|
||||
master_priv = dev->primary->master->driver_priv;
|
||||
|
||||
if (master_priv->sarea_priv)
|
||||
master_priv->sarea_priv->last_fence = dev_priv->counter;
|
||||
}
|
||||
return dev_priv->counter;
|
||||
}
|
||||
|
||||
#define radeon_is_avivo(dev_priv) ((dev_priv->chip_family >= CHIP_RS600))
|
||||
|
||||
#define radeon_is_dce3(dev_priv) ((dev_priv->chip_family >= CHIP_RV620))
|
||||
|
||||
#define radeon_bios8(dev_priv, v) (dev_priv->bios[v])
|
||||
#define radeon_bios16(dev_priv, v) (dev_priv->bios[v] | (dev_priv->bios[(v) + 1] << 8))
|
||||
#define radeon_bios32(dev_priv, v) ((dev_priv->bios[v]) | \
|
||||
(dev_priv->bios[(v) + 1] << 8) | \
|
||||
(dev_priv->bios[(v) + 2] << 16) | \
|
||||
(dev_priv->bios[(v) + 3] << 24))
|
||||
|
||||
extern int radeon_emit_irq(struct drm_device * dev);
|
||||
|
||||
extern void radeon_gem_free_object(struct drm_gem_object *obj);
|
||||
extern int radeon_gem_init_object(struct drm_gem_object *obj);
|
||||
extern int radeon_gem_mm_init(struct drm_device *dev);
|
||||
extern void radeon_gem_mm_fini(struct drm_device *dev);
|
||||
extern int radeon_gem_pin_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv);
|
||||
extern int radeon_gem_unpin_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv);
|
||||
int radeon_gem_object_pin(struct drm_gem_object *obj,
|
||||
uint32_t alignment);
|
||||
int radeon_gem_indirect_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv);
|
||||
int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv);
|
||||
struct drm_gem_object *radeon_gem_object_alloc(struct drm_device *dev, int size, int alignment,
|
||||
int initial_domain);
|
||||
int radeon_modeset_init(struct drm_device *dev);
|
||||
void radeon_modeset_cleanup(struct drm_device *dev);
|
||||
extern u32 radeon_read_mc_reg(drm_radeon_private_t *dev_priv, int addr);
|
||||
extern void radeon_write_mc_reg(drm_radeon_private_t *dev_priv, u32 addr, u32 val);
|
||||
|
||||
extern void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on);
|
||||
#define RADEONFB_CONN_LIMIT 4
|
||||
|
||||
extern int radeon_master_create(struct drm_device *dev, struct drm_master *master);
|
||||
extern void radeon_master_destroy(struct drm_device *dev, struct drm_master *master);
|
||||
extern void radeon_cp_dispatch_flip(struct drm_device * dev, struct drm_master *master);
|
||||
#endif /* __RADEON_DRV_H__ */
|
||||
|
|
|
|||
|
|
@ -198,8 +198,10 @@ irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS)
|
|||
stat &= dev_priv->irq_enable_reg;
|
||||
|
||||
/* SW interrupt */
|
||||
if (stat & RADEON_SW_INT_TEST)
|
||||
if (stat & RADEON_SW_INT_TEST) {
|
||||
DRM_WAKEUP(&dev_priv->swi_queue);
|
||||
radeon_fence_handler(dev);
|
||||
}
|
||||
|
||||
/* VBLANK interrupt */
|
||||
if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) {
|
||||
|
|
@ -216,14 +218,13 @@ irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS)
|
|||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int radeon_emit_irq(struct drm_device * dev)
|
||||
int radeon_emit_irq(struct drm_device * dev)
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
unsigned int ret;
|
||||
RING_LOCALS;
|
||||
|
||||
atomic_inc(&dev_priv->swi_emitted);
|
||||
ret = atomic_read(&dev_priv->swi_emitted);
|
||||
ret = radeon_update_breadcrumb(dev);
|
||||
|
||||
BEGIN_RING(4);
|
||||
OUT_RING_REG(RADEON_LAST_SWI_REG, ret);
|
||||
|
|
@ -240,13 +241,13 @@ static int radeon_wait_irq(struct drm_device * dev, int swi_nr)
|
|||
(drm_radeon_private_t *) dev->dev_private;
|
||||
int ret = 0;
|
||||
|
||||
if (RADEON_READ(RADEON_LAST_SWI_REG) >= swi_nr)
|
||||
if (READ_BREADCRUMB(dev_priv) >= swi_nr)
|
||||
return 0;
|
||||
|
||||
dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
|
||||
|
||||
DRM_WAIT_ON(ret, dev_priv->swi_queue, 3 * DRM_HZ,
|
||||
RADEON_READ(RADEON_LAST_SWI_REG) >= swi_nr);
|
||||
READ_BREADCRUMB(dev_priv) >= swi_nr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -349,7 +350,6 @@ int radeon_driver_irq_postinstall(struct drm_device * dev)
|
|||
(drm_radeon_private_t *) dev->dev_private;
|
||||
int ret;
|
||||
|
||||
atomic_set(&dev_priv->swi_emitted, 0);
|
||||
DRM_INIT_WAITQUEUE(&dev_priv->swi_queue);
|
||||
|
||||
ret = drm_vblank_init(dev, 2);
|
||||
|
|
|
|||
|
|
@ -305,8 +305,9 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t *
|
|||
case RADEON_CP_3D_DRAW_INDX_2:
|
||||
case RADEON_3D_CLEAR_HIZ:
|
||||
/* safe but r200 only */
|
||||
if (dev_priv->microcode_version != UCODE_R200) {
|
||||
DRM_ERROR("Invalid 3d packet for r100-class chip\n");
|
||||
if ((dev_priv->chip_family < CHIP_R200) ||
|
||||
(dev_priv->chip_family > CHIP_RV280)) {
|
||||
DRM_ERROR("Invalid 3d packet for non r200-class chip\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
|
|
@ -359,8 +360,8 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t *
|
|||
break;
|
||||
|
||||
case RADEON_3D_RNDR_GEN_INDX_PRIM:
|
||||
if (dev_priv->microcode_version != UCODE_R100) {
|
||||
DRM_ERROR("Invalid 3d packet for r200-class chip\n");
|
||||
if (dev_priv->chip_family > CHIP_RS200) {
|
||||
DRM_ERROR("Invalid 3d packet for non-r100-class chip\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (radeon_check_and_fixup_offset(dev_priv, file_priv, &cmd[1])) {
|
||||
|
|
@ -370,8 +371,10 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t *
|
|||
break;
|
||||
|
||||
case RADEON_CP_INDX_BUFFER:
|
||||
if (dev_priv->microcode_version != UCODE_R200) {
|
||||
DRM_ERROR("Invalid 3d packet for r100-class chip\n");
|
||||
/* safe but r200 only */
|
||||
if ((dev_priv->chip_family < CHIP_R200) ||
|
||||
(dev_priv->chip_family > CHIP_RV280)) {
|
||||
DRM_ERROR("Invalid 3d packet for non-r200-class chip\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if ((cmd[1] & 0x8000ffff) != 0x80000810) {
|
||||
|
|
@ -742,13 +745,14 @@ static struct {
|
|||
*/
|
||||
|
||||
static void radeon_clear_box(drm_radeon_private_t * dev_priv,
|
||||
struct drm_radeon_master_private *master_priv,
|
||||
int x, int y, int w, int h, int r, int g, int b)
|
||||
{
|
||||
u32 color;
|
||||
RING_LOCALS;
|
||||
|
||||
x += dev_priv->sarea_priv->boxes[0].x1;
|
||||
y += dev_priv->sarea_priv->boxes[0].y1;
|
||||
x += master_priv->sarea_priv->boxes[0].x1;
|
||||
y += master_priv->sarea_priv->boxes[0].y1;
|
||||
|
||||
switch (dev_priv->color_fmt) {
|
||||
case RADEON_COLOR_FORMAT_RGB565:
|
||||
|
|
@ -776,7 +780,7 @@ static void radeon_clear_box(drm_radeon_private_t * dev_priv,
|
|||
RADEON_GMC_SRC_DATATYPE_COLOR |
|
||||
RADEON_ROP3_P | RADEON_GMC_CLR_CMP_CNTL_DIS);
|
||||
|
||||
if (dev_priv->sarea_priv->pfCurrentPage == 1) {
|
||||
if (master_priv->sarea_priv->pfCurrentPage == 1) {
|
||||
OUT_RING(dev_priv->front_pitch_offset);
|
||||
} else {
|
||||
OUT_RING(dev_priv->back_pitch_offset);
|
||||
|
|
@ -790,7 +794,7 @@ static void radeon_clear_box(drm_radeon_private_t * dev_priv,
|
|||
ADVANCE_RING();
|
||||
}
|
||||
|
||||
static void radeon_cp_performance_boxes(drm_radeon_private_t * dev_priv)
|
||||
static void radeon_cp_performance_boxes(drm_radeon_private_t * dev_priv, struct drm_radeon_master_private *master_priv)
|
||||
{
|
||||
/* Collapse various things into a wait flag -- trying to
|
||||
* guess if userspase slept -- better just to have them tell us.
|
||||
|
|
@ -807,12 +811,12 @@ static void radeon_cp_performance_boxes(drm_radeon_private_t * dev_priv)
|
|||
/* Purple box for page flipping
|
||||
*/
|
||||
if (dev_priv->stats.boxes & RADEON_BOX_FLIP)
|
||||
radeon_clear_box(dev_priv, 4, 4, 8, 8, 255, 0, 255);
|
||||
radeon_clear_box(dev_priv, master_priv, 4, 4, 8, 8, 255, 0, 255);
|
||||
|
||||
/* Red box if we have to wait for idle at any point
|
||||
*/
|
||||
if (dev_priv->stats.boxes & RADEON_BOX_WAIT_IDLE)
|
||||
radeon_clear_box(dev_priv, 16, 4, 8, 8, 255, 0, 0);
|
||||
radeon_clear_box(dev_priv, master_priv, 16, 4, 8, 8, 255, 0, 0);
|
||||
|
||||
/* Blue box: lost context?
|
||||
*/
|
||||
|
|
@ -820,12 +824,12 @@ static void radeon_cp_performance_boxes(drm_radeon_private_t * dev_priv)
|
|||
/* Yellow box for texture swaps
|
||||
*/
|
||||
if (dev_priv->stats.boxes & RADEON_BOX_TEXTURE_LOAD)
|
||||
radeon_clear_box(dev_priv, 40, 4, 8, 8, 255, 255, 0);
|
||||
radeon_clear_box(dev_priv, master_priv, 40, 4, 8, 8, 255, 255, 0);
|
||||
|
||||
/* Green box if hardware never idles (as far as we can tell)
|
||||
*/
|
||||
if (!(dev_priv->stats.boxes & RADEON_BOX_DMA_IDLE))
|
||||
radeon_clear_box(dev_priv, 64, 4, 8, 8, 0, 255, 0);
|
||||
radeon_clear_box(dev_priv, master_priv, 64, 4, 8, 8, 0, 255, 0);
|
||||
|
||||
/* Draw bars indicating number of buffers allocated
|
||||
* (not a great measure, easily confused)
|
||||
|
|
@ -834,7 +838,7 @@ static void radeon_cp_performance_boxes(drm_radeon_private_t * dev_priv)
|
|||
if (dev_priv->stats.requested_bufs > 100)
|
||||
dev_priv->stats.requested_bufs = 100;
|
||||
|
||||
radeon_clear_box(dev_priv, 4, 16,
|
||||
radeon_clear_box(dev_priv, master_priv, 4, 16,
|
||||
dev_priv->stats.requested_bufs, 4,
|
||||
196, 128, 128);
|
||||
}
|
||||
|
|
@ -848,11 +852,13 @@ static void radeon_cp_performance_boxes(drm_radeon_private_t * dev_priv)
|
|||
*/
|
||||
|
||||
static void radeon_cp_dispatch_clear(struct drm_device * dev,
|
||||
struct drm_master *master,
|
||||
drm_radeon_clear_t * clear,
|
||||
drm_radeon_clear_rect_t * depth_boxes)
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
struct drm_radeon_master_private *master_priv = master->driver_priv;
|
||||
drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv;
|
||||
drm_radeon_depth_clear_t *depth_clear = &dev_priv->depth_clear;
|
||||
int nbox = sarea_priv->nbox;
|
||||
struct drm_clip_rect *pbox = sarea_priv->boxes;
|
||||
|
|
@ -864,7 +870,7 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev,
|
|||
|
||||
dev_priv->stats.clears++;
|
||||
|
||||
if (dev_priv->sarea_priv->pfCurrentPage == 1) {
|
||||
if (sarea_priv->pfCurrentPage == 1) {
|
||||
unsigned int tmp = flags;
|
||||
|
||||
flags &= ~(RADEON_FRONT | RADEON_BACK);
|
||||
|
|
@ -890,7 +896,7 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev,
|
|||
|
||||
/* Make sure we restore the 3D state next time.
|
||||
*/
|
||||
dev_priv->sarea_priv->ctx_owner = 0;
|
||||
sarea_priv->ctx_owner = 0;
|
||||
|
||||
for (i = 0; i < nbox; i++) {
|
||||
int x = pbox[i].x1;
|
||||
|
|
@ -967,7 +973,7 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev,
|
|||
/* Make sure we restore the 3D state next time.
|
||||
* we haven't touched any "normal" state - still need this?
|
||||
*/
|
||||
dev_priv->sarea_priv->ctx_owner = 0;
|
||||
sarea_priv->ctx_owner = 0;
|
||||
|
||||
if ((dev_priv->flags & RADEON_HAS_HIERZ)
|
||||
&& (flags & RADEON_USE_HIERZ)) {
|
||||
|
|
@ -1015,7 +1021,7 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev,
|
|||
int tileoffset, nrtilesx, nrtilesy, j;
|
||||
/* it looks like r200 needs rv-style clears, at least if hierz is not enabled? */
|
||||
if ((dev_priv->flags & RADEON_HAS_HIERZ)
|
||||
&& !(dev_priv->microcode_version == UCODE_R200)) {
|
||||
&& (dev_priv->chip_family < CHIP_R200)) {
|
||||
/* FIXME : figure this out for r200 (when hierz is enabled). Or
|
||||
maybe r200 actually doesn't need to put the low-res z value into
|
||||
the tile cache like r100, but just needs to clear the hi-level z-buffer?
|
||||
|
|
@ -1044,7 +1050,8 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev,
|
|||
ADVANCE_RING();
|
||||
tileoffset += depthpixperline >> 6;
|
||||
}
|
||||
} else if (dev_priv->microcode_version == UCODE_R200) {
|
||||
} else if ((dev_priv->chip_family >= CHIP_R200) &&
|
||||
(dev_priv->chip_family <= CHIP_RV280)) {
|
||||
/* works for rv250. */
|
||||
/* find first macro tile (8x2 4x4 z-pixels on rv250) */
|
||||
tileoffset =
|
||||
|
|
@ -1099,7 +1106,8 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev,
|
|||
|
||||
/* TODO don't always clear all hi-level z tiles */
|
||||
if ((dev_priv->flags & RADEON_HAS_HIERZ)
|
||||
&& (dev_priv->microcode_version == UCODE_R200)
|
||||
&& ((dev_priv->chip_family >= CHIP_R200) &&
|
||||
(dev_priv->chip_family <= CHIP_RV280))
|
||||
&& (flags & RADEON_USE_HIERZ))
|
||||
/* r100 and cards without hierarchical z-buffer have no high-level z-buffer */
|
||||
/* FIXME : the mask supposedly contains low-res z values. So can't set
|
||||
|
|
@ -1119,8 +1127,9 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev,
|
|||
* rendering a quad into just those buffers. Thus, we have to
|
||||
* make sure the 3D engine is configured correctly.
|
||||
*/
|
||||
else if ((dev_priv->microcode_version == UCODE_R200) &&
|
||||
(flags & (RADEON_DEPTH | RADEON_STENCIL))) {
|
||||
else if ((dev_priv->chip_family >= CHIP_R200) &&
|
||||
(dev_priv->chip_family <= CHIP_RV280) &&
|
||||
(flags & (RADEON_DEPTH | RADEON_STENCIL))) {
|
||||
|
||||
int tempPP_CNTL;
|
||||
int tempRE_CNTL;
|
||||
|
|
@ -1214,7 +1223,7 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev,
|
|||
|
||||
/* Make sure we restore the 3D state next time.
|
||||
*/
|
||||
dev_priv->sarea_priv->ctx_owner = 0;
|
||||
sarea_priv->ctx_owner = 0;
|
||||
|
||||
for (i = 0; i < nbox; i++) {
|
||||
|
||||
|
|
@ -1285,7 +1294,7 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev,
|
|||
|
||||
/* Make sure we restore the 3D state next time.
|
||||
*/
|
||||
dev_priv->sarea_priv->ctx_owner = 0;
|
||||
sarea_priv->ctx_owner = 0;
|
||||
|
||||
for (i = 0; i < nbox; i++) {
|
||||
|
||||
|
|
@ -1328,20 +1337,21 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev,
|
|||
* wait on this value before performing the clear ioctl. We
|
||||
* need this because the card's so damned fast...
|
||||
*/
|
||||
dev_priv->sarea_priv->last_clear++;
|
||||
sarea_priv->last_clear++;
|
||||
|
||||
BEGIN_RING(4);
|
||||
|
||||
RADEON_CLEAR_AGE(dev_priv->sarea_priv->last_clear);
|
||||
RADEON_CLEAR_AGE(sarea_priv->last_clear);
|
||||
RADEON_WAIT_UNTIL_IDLE();
|
||||
|
||||
ADVANCE_RING();
|
||||
}
|
||||
|
||||
static void radeon_cp_dispatch_swap(struct drm_device * dev)
|
||||
static void radeon_cp_dispatch_swap(struct drm_device * dev, struct drm_master *master)
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
struct drm_radeon_master_private *master_priv = master->driver_priv;
|
||||
drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv;
|
||||
int nbox = sarea_priv->nbox;
|
||||
struct drm_clip_rect *pbox = sarea_priv->boxes;
|
||||
int i;
|
||||
|
|
@ -1351,7 +1361,7 @@ static void radeon_cp_dispatch_swap(struct drm_device * dev)
|
|||
/* Do some trivial performance monitoring...
|
||||
*/
|
||||
if (dev_priv->do_boxes)
|
||||
radeon_cp_performance_boxes(dev_priv);
|
||||
radeon_cp_performance_boxes(dev_priv, master_priv);
|
||||
|
||||
/* Wait for the 3D stream to idle before dispatching the bitblt.
|
||||
* This will prevent data corruption between the two streams.
|
||||
|
|
@ -1385,7 +1395,7 @@ static void radeon_cp_dispatch_swap(struct drm_device * dev)
|
|||
/* Make this work even if front & back are flipped:
|
||||
*/
|
||||
OUT_RING(CP_PACKET0(RADEON_SRC_PITCH_OFFSET, 1));
|
||||
if (dev_priv->sarea_priv->pfCurrentPage == 0) {
|
||||
if (sarea_priv->pfCurrentPage == 0) {
|
||||
OUT_RING(dev_priv->back_pitch_offset);
|
||||
OUT_RING(dev_priv->front_pitch_offset);
|
||||
} else {
|
||||
|
|
@ -1405,31 +1415,32 @@ static void radeon_cp_dispatch_swap(struct drm_device * dev)
|
|||
* throttle the framerate by waiting for this value before
|
||||
* performing the swapbuffer ioctl.
|
||||
*/
|
||||
dev_priv->sarea_priv->last_frame++;
|
||||
sarea_priv->last_frame++;
|
||||
|
||||
BEGIN_RING(4);
|
||||
|
||||
RADEON_FRAME_AGE(dev_priv->sarea_priv->last_frame);
|
||||
RADEON_FRAME_AGE(sarea_priv->last_frame);
|
||||
RADEON_WAIT_UNTIL_2D_IDLE();
|
||||
|
||||
ADVANCE_RING();
|
||||
}
|
||||
|
||||
static void radeon_cp_dispatch_flip(struct drm_device * dev)
|
||||
void radeon_cp_dispatch_flip(struct drm_device * dev, struct drm_master *master)
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
struct drm_sarea *sarea = (struct drm_sarea *) dev_priv->sarea->handle;
|
||||
int offset = (dev_priv->sarea_priv->pfCurrentPage == 1)
|
||||
struct drm_radeon_master_private *master_priv = master->driver_priv;
|
||||
struct drm_sarea *sarea = (struct drm_sarea *) master_priv->sarea->handle;
|
||||
int offset = (master_priv->sarea_priv->pfCurrentPage == 1)
|
||||
? dev_priv->front_offset : dev_priv->back_offset;
|
||||
RING_LOCALS;
|
||||
DRM_DEBUG("pfCurrentPage=%d\n",
|
||||
dev_priv->sarea_priv->pfCurrentPage);
|
||||
master_priv->sarea_priv->pfCurrentPage);
|
||||
|
||||
/* Do some trivial performance monitoring...
|
||||
*/
|
||||
if (dev_priv->do_boxes) {
|
||||
dev_priv->stats.boxes |= RADEON_BOX_FLIP;
|
||||
radeon_cp_performance_boxes(dev_priv);
|
||||
radeon_cp_performance_boxes(dev_priv, master_priv);
|
||||
}
|
||||
|
||||
/* Update the frame offsets for both CRTCs
|
||||
|
|
@ -1441,7 +1452,7 @@ static void radeon_cp_dispatch_flip(struct drm_device * dev)
|
|||
((sarea->frame.y * dev_priv->front_pitch +
|
||||
sarea->frame.x * (dev_priv->color_fmt - 2)) & ~7)
|
||||
+ offset);
|
||||
OUT_RING_REG(RADEON_CRTC2_OFFSET, dev_priv->sarea_priv->crtc2_base
|
||||
OUT_RING_REG(RADEON_CRTC2_OFFSET, master_priv->sarea_priv->crtc2_base
|
||||
+ offset);
|
||||
|
||||
ADVANCE_RING();
|
||||
|
|
@ -1450,13 +1461,13 @@ static void radeon_cp_dispatch_flip(struct drm_device * dev)
|
|||
* throttle the framerate by waiting for this value before
|
||||
* performing the swapbuffer ioctl.
|
||||
*/
|
||||
dev_priv->sarea_priv->last_frame++;
|
||||
dev_priv->sarea_priv->pfCurrentPage =
|
||||
1 - dev_priv->sarea_priv->pfCurrentPage;
|
||||
master_priv->sarea_priv->last_frame++;
|
||||
master_priv->sarea_priv->pfCurrentPage =
|
||||
1 - master_priv->sarea_priv->pfCurrentPage;
|
||||
|
||||
BEGIN_RING(2);
|
||||
|
||||
RADEON_FRAME_AGE(dev_priv->sarea_priv->last_frame);
|
||||
RADEON_FRAME_AGE(master_priv->sarea_priv->last_frame);
|
||||
|
||||
ADVANCE_RING();
|
||||
}
|
||||
|
|
@ -1494,11 +1505,13 @@ typedef struct {
|
|||
} drm_radeon_tcl_prim_t;
|
||||
|
||||
static void radeon_cp_dispatch_vertex(struct drm_device * dev,
|
||||
struct drm_file *file_priv,
|
||||
struct drm_buf * buf,
|
||||
drm_radeon_tcl_prim_t * prim)
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv;
|
||||
drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv;
|
||||
int offset = dev_priv->gart_buffers_offset + buf->offset + prim->start;
|
||||
int numverts = (int)prim->numverts;
|
||||
int nbox = sarea_priv->nbox;
|
||||
|
|
@ -1539,13 +1552,14 @@ static void radeon_cp_dispatch_vertex(struct drm_device * dev,
|
|||
} while (i < nbox);
|
||||
}
|
||||
|
||||
static void radeon_cp_discard_buffer(struct drm_device * dev, struct drm_buf * buf)
|
||||
static void radeon_cp_discard_buffer(struct drm_device * dev, struct drm_master *master, struct drm_buf * buf)
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
struct drm_radeon_master_private *master_priv = master->driver_priv;
|
||||
drm_radeon_buf_priv_t *buf_priv = buf->dev_private;
|
||||
RING_LOCALS;
|
||||
|
||||
buf_priv->age = ++dev_priv->sarea_priv->last_dispatch;
|
||||
buf_priv->age = ++master_priv->sarea_priv->last_dispatch;
|
||||
|
||||
/* Emit the vertex buffer age */
|
||||
BEGIN_RING(2);
|
||||
|
|
@ -1590,12 +1604,14 @@ static void radeon_cp_dispatch_indirect(struct drm_device * dev,
|
|||
}
|
||||
}
|
||||
|
||||
static void radeon_cp_dispatch_indices(struct drm_device * dev,
|
||||
static void radeon_cp_dispatch_indices(struct drm_device *dev,
|
||||
struct drm_master *master,
|
||||
struct drm_buf * elt_buf,
|
||||
drm_radeon_tcl_prim_t * prim)
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
struct drm_radeon_master_private *master_priv = master->driver_priv;
|
||||
drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv;
|
||||
int offset = dev_priv->gart_buffers_offset + prim->offset;
|
||||
u32 *data;
|
||||
int dwords;
|
||||
|
|
@ -1870,7 +1886,7 @@ static int radeon_cp_dispatch_texture(struct drm_device * dev,
|
|||
ADVANCE_RING();
|
||||
COMMIT_RING();
|
||||
|
||||
radeon_cp_discard_buffer(dev, buf);
|
||||
radeon_cp_discard_buffer(dev, file_priv->master, buf);
|
||||
|
||||
/* Update the input parameters for next time */
|
||||
image->y += height;
|
||||
|
|
@ -2120,7 +2136,8 @@ static int radeon_surface_free(struct drm_device *dev, void *data, struct drm_fi
|
|||
static int radeon_cp_clear(struct drm_device *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv;
|
||||
drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv;
|
||||
drm_radeon_clear_t *clear = data;
|
||||
drm_radeon_clear_rect_t depth_boxes[RADEON_NR_SAREA_CLIPRECTS];
|
||||
DRM_DEBUG("\n");
|
||||
|
|
@ -2136,7 +2153,7 @@ static int radeon_cp_clear(struct drm_device *dev, void *data, struct drm_file *
|
|||
sarea_priv->nbox * sizeof(depth_boxes[0])))
|
||||
return -EFAULT;
|
||||
|
||||
radeon_cp_dispatch_clear(dev, clear, depth_boxes);
|
||||
radeon_cp_dispatch_clear(dev, file_priv->master, clear, depth_boxes);
|
||||
|
||||
COMMIT_RING();
|
||||
return 0;
|
||||
|
|
@ -2144,9 +2161,10 @@ static int radeon_cp_clear(struct drm_device *dev, void *data, struct drm_file *
|
|||
|
||||
/* Not sure why this isn't set all the time:
|
||||
*/
|
||||
static int radeon_do_init_pageflip(struct drm_device * dev)
|
||||
static int radeon_do_init_pageflip(struct drm_device * dev, struct drm_master *master)
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
struct drm_radeon_master_private *master_priv = master->driver_priv;
|
||||
RING_LOCALS;
|
||||
|
||||
DRM_DEBUG("\n");
|
||||
|
|
@ -2163,8 +2181,8 @@ static int radeon_do_init_pageflip(struct drm_device * dev)
|
|||
|
||||
dev_priv->page_flipping = 1;
|
||||
|
||||
if (dev_priv->sarea_priv->pfCurrentPage != 1)
|
||||
dev_priv->sarea_priv->pfCurrentPage = 0;
|
||||
if (master_priv->sarea_priv->pfCurrentPage != 1)
|
||||
master_priv->sarea_priv->pfCurrentPage = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -2182,9 +2200,9 @@ static int radeon_cp_flip(struct drm_device *dev, void *data, struct drm_file *f
|
|||
RING_SPACE_TEST_WITH_RETURN(dev_priv);
|
||||
|
||||
if (!dev_priv->page_flipping)
|
||||
radeon_do_init_pageflip(dev);
|
||||
radeon_do_init_pageflip(dev, file_priv->master);
|
||||
|
||||
radeon_cp_dispatch_flip(dev);
|
||||
radeon_cp_dispatch_flip(dev, file_priv->master);
|
||||
|
||||
COMMIT_RING();
|
||||
return 0;
|
||||
|
|
@ -2193,7 +2211,9 @@ static int radeon_cp_flip(struct drm_device *dev, void *data, struct drm_file *f
|
|||
static int radeon_cp_swap(struct drm_device *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv;
|
||||
drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv;
|
||||
|
||||
DRM_DEBUG("\n");
|
||||
|
||||
LOCK_TEST_WITH_RETURN(dev, file_priv);
|
||||
|
|
@ -2203,8 +2223,8 @@ static int radeon_cp_swap(struct drm_device *dev, void *data, struct drm_file *f
|
|||
if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS)
|
||||
sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS;
|
||||
|
||||
radeon_cp_dispatch_swap(dev);
|
||||
dev_priv->sarea_priv->ctx_owner = 0;
|
||||
radeon_cp_dispatch_swap(dev, file_priv->master);
|
||||
sarea_priv->ctx_owner = 0;
|
||||
|
||||
COMMIT_RING();
|
||||
return 0;
|
||||
|
|
@ -2213,6 +2233,7 @@ static int radeon_cp_swap(struct drm_device *dev, void *data, struct drm_file *f
|
|||
static int radeon_cp_vertex(struct drm_device *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv;
|
||||
drm_radeon_sarea_t *sarea_priv;
|
||||
struct drm_device_dma *dma = dev->dma;
|
||||
struct drm_buf *buf;
|
||||
|
|
@ -2226,7 +2247,7 @@ static int radeon_cp_vertex(struct drm_device *dev, void *data, struct drm_file
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
sarea_priv = dev_priv->sarea_priv;
|
||||
sarea_priv = master_priv->sarea_priv;
|
||||
|
||||
DRM_DEBUG("pid=%d index=%d count=%d discard=%d\n",
|
||||
DRM_CURRENTPID, vertex->idx, vertex->count, vertex->discard);
|
||||
|
|
@ -2280,13 +2301,13 @@ static int radeon_cp_vertex(struct drm_device *dev, void *data, struct drm_file
|
|||
prim.finish = vertex->count; /* unused */
|
||||
prim.prim = vertex->prim;
|
||||
prim.numverts = vertex->count;
|
||||
prim.vc_format = dev_priv->sarea_priv->vc_format;
|
||||
prim.vc_format = sarea_priv->vc_format;
|
||||
|
||||
radeon_cp_dispatch_vertex(dev, buf, &prim);
|
||||
radeon_cp_dispatch_vertex(dev, file_priv, buf, &prim);
|
||||
}
|
||||
|
||||
if (vertex->discard) {
|
||||
radeon_cp_discard_buffer(dev, buf);
|
||||
radeon_cp_discard_buffer(dev, file_priv->master, buf);
|
||||
}
|
||||
|
||||
COMMIT_RING();
|
||||
|
|
@ -2296,6 +2317,7 @@ static int radeon_cp_vertex(struct drm_device *dev, void *data, struct drm_file
|
|||
static int radeon_cp_indices(struct drm_device *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv;
|
||||
drm_radeon_sarea_t *sarea_priv;
|
||||
struct drm_device_dma *dma = dev->dma;
|
||||
struct drm_buf *buf;
|
||||
|
|
@ -2309,7 +2331,7 @@ static int radeon_cp_indices(struct drm_device *dev, void *data, struct drm_file
|
|||
DRM_ERROR("called with no initialization\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
sarea_priv = dev_priv->sarea_priv;
|
||||
sarea_priv = master_priv->sarea_priv;
|
||||
|
||||
DRM_DEBUG("pid=%d index=%d start=%d end=%d discard=%d\n",
|
||||
DRM_CURRENTPID, elts->idx, elts->start, elts->end,
|
||||
|
|
@ -2376,11 +2398,11 @@ static int radeon_cp_indices(struct drm_device *dev, void *data, struct drm_file
|
|||
prim.prim = elts->prim;
|
||||
prim.offset = 0; /* offset from start of dma buffers */
|
||||
prim.numverts = RADEON_MAX_VB_VERTS; /* duh */
|
||||
prim.vc_format = dev_priv->sarea_priv->vc_format;
|
||||
prim.vc_format = sarea_priv->vc_format;
|
||||
|
||||
radeon_cp_dispatch_indices(dev, buf, &prim);
|
||||
radeon_cp_dispatch_indices(dev, file_priv->master, buf, &prim);
|
||||
if (elts->discard) {
|
||||
radeon_cp_discard_buffer(dev, buf);
|
||||
radeon_cp_discard_buffer(dev, file_priv->master, buf);
|
||||
}
|
||||
|
||||
COMMIT_RING();
|
||||
|
|
@ -2496,7 +2518,7 @@ static int radeon_cp_indirect(struct drm_device *dev, void *data, struct drm_fil
|
|||
*/
|
||||
radeon_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end);
|
||||
if (indirect->discard) {
|
||||
radeon_cp_discard_buffer(dev, buf);
|
||||
radeon_cp_discard_buffer(dev, file_priv->master, buf);
|
||||
}
|
||||
|
||||
COMMIT_RING();
|
||||
|
|
@ -2506,6 +2528,7 @@ static int radeon_cp_indirect(struct drm_device *dev, void *data, struct drm_fil
|
|||
static int radeon_cp_vertex2(struct drm_device *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv;
|
||||
drm_radeon_sarea_t *sarea_priv;
|
||||
struct drm_device_dma *dma = dev->dma;
|
||||
struct drm_buf *buf;
|
||||
|
|
@ -2520,7 +2543,7 @@ static int radeon_cp_vertex2(struct drm_device *dev, void *data, struct drm_file
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
sarea_priv = dev_priv->sarea_priv;
|
||||
sarea_priv = master_priv->sarea_priv;
|
||||
|
||||
DRM_DEBUG("pid=%d index=%d discard=%d\n",
|
||||
DRM_CURRENTPID, vertex->idx, vertex->discard);
|
||||
|
|
@ -2582,12 +2605,12 @@ static int radeon_cp_vertex2(struct drm_device *dev, void *data, struct drm_file
|
|||
tclprim.offset = prim.numverts * 64;
|
||||
tclprim.numverts = RADEON_MAX_VB_VERTS; /* duh */
|
||||
|
||||
radeon_cp_dispatch_indices(dev, buf, &tclprim);
|
||||
radeon_cp_dispatch_indices(dev, file_priv->master, buf, &tclprim);
|
||||
} else {
|
||||
tclprim.numverts = prim.numverts;
|
||||
tclprim.offset = 0; /* not used */
|
||||
|
||||
radeon_cp_dispatch_vertex(dev, buf, &tclprim);
|
||||
radeon_cp_dispatch_vertex(dev, file_priv, buf, &tclprim);
|
||||
}
|
||||
|
||||
if (sarea_priv->nbox == 1)
|
||||
|
|
@ -2595,7 +2618,7 @@ static int radeon_cp_vertex2(struct drm_device *dev, void *data, struct drm_file
|
|||
}
|
||||
|
||||
if (vertex->discard) {
|
||||
radeon_cp_discard_buffer(dev, buf);
|
||||
radeon_cp_discard_buffer(dev, file_priv->master, buf);
|
||||
}
|
||||
|
||||
COMMIT_RING();
|
||||
|
|
@ -2889,7 +2912,7 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data, struct drm_file
|
|||
|
||||
orig_nbox = cmdbuf->nbox;
|
||||
|
||||
if (dev_priv->microcode_version == UCODE_R300) {
|
||||
if (dev_priv->chip_family >= CHIP_R300) {
|
||||
int temp;
|
||||
temp = r300_do_cp_cmdbuf(dev, file_priv, cmdbuf);
|
||||
|
||||
|
|
@ -2949,7 +2972,7 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data, struct drm_file
|
|||
goto err;
|
||||
}
|
||||
|
||||
radeon_cp_discard_buffer(dev, buf);
|
||||
radeon_cp_discard_buffer(dev, file_priv->master, buf);
|
||||
break;
|
||||
|
||||
case RADEON_CMD_PACKET3:
|
||||
|
|
@ -3110,6 +3133,7 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil
|
|||
static int radeon_cp_setparam(struct drm_device *dev, void *data, struct drm_file *file_priv)
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv;
|
||||
drm_radeon_setparam_t *sp = data;
|
||||
struct drm_radeon_driver_file_fields *radeon_priv;
|
||||
|
||||
|
|
@ -3129,14 +3153,14 @@ static int radeon_cp_setparam(struct drm_device *dev, void *data, struct drm_fil
|
|||
DRM_DEBUG("color tiling disabled\n");
|
||||
dev_priv->front_pitch_offset &= ~RADEON_DST_TILE_MACRO;
|
||||
dev_priv->back_pitch_offset &= ~RADEON_DST_TILE_MACRO;
|
||||
if (dev_priv->sarea_priv)
|
||||
dev_priv->sarea_priv->tiling_enabled = 0;
|
||||
if (master_priv->sarea_priv)
|
||||
master_priv->sarea_priv->tiling_enabled = 0;
|
||||
} else if (sp->value == 1) {
|
||||
DRM_DEBUG("color tiling enabled\n");
|
||||
dev_priv->front_pitch_offset |= RADEON_DST_TILE_MACRO;
|
||||
dev_priv->back_pitch_offset |= RADEON_DST_TILE_MACRO;
|
||||
if (dev_priv->sarea_priv)
|
||||
dev_priv->sarea_priv->tiling_enabled = 1;
|
||||
if (master_priv->sarea_priv)
|
||||
master_priv->sarea_priv->tiling_enabled = 1;
|
||||
}
|
||||
break;
|
||||
case RADEON_SETPARAM_PCIGART_LOCATION:
|
||||
|
|
@ -3183,14 +3207,6 @@ void radeon_driver_preclose(struct drm_device *dev,
|
|||
|
||||
void radeon_driver_lastclose(struct drm_device *dev)
|
||||
{
|
||||
if (dev->dev_private) {
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
|
||||
if (dev_priv->sarea_priv &&
|
||||
dev_priv->sarea_priv->pfCurrentPage != 0)
|
||||
radeon_cp_dispatch_flip(dev);
|
||||
}
|
||||
|
||||
radeon_do_release(dev);
|
||||
}
|
||||
|
||||
|
|
@ -3251,7 +3267,18 @@ struct drm_ioctl_desc radeon_ioctls[] = {
|
|||
DRM_IOCTL_DEF(DRM_RADEON_IRQ_WAIT, radeon_irq_wait, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_RADEON_SETPARAM, radeon_cp_setparam, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_RADEON_SURF_ALLOC, radeon_surface_alloc, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_RADEON_SURF_FREE, radeon_surface_free, DRM_AUTH)
|
||||
DRM_IOCTL_DEF(DRM_RADEON_SURF_FREE, radeon_surface_free, DRM_AUTH),
|
||||
|
||||
DRM_IOCTL_DEF(DRM_RADEON_GEM_INFO, radeon_gem_info_ioctl, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_RADEON_GEM_CREATE, radeon_gem_create_ioctl, DRM_AUTH),
|
||||
|
||||
DRM_IOCTL_DEF(DRM_RADEON_GEM_MMAP, radeon_gem_mmap_ioctl, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_RADEON_GEM_PIN, radeon_gem_pin_ioctl, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_RADEON_GEM_UNPIN, radeon_gem_unpin_ioctl, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_RADEON_GEM_PREAD, radeon_gem_pread_ioctl, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_RADEON_GEM_PWRITE, radeon_gem_pwrite_ioctl, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_RADEON_GEM_SET_DOMAIN, radeon_gem_set_domain_ioctl, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_RADEON_GEM_INDIRECT, radeon_gem_indirect_ioctl, DRM_AUTH),
|
||||
};
|
||||
|
||||
int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue