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.main
parent
31da9492a4
commit
df9871064e
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
File diff suppressed because it is too large
Load Diff
|
@ -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
|
File diff suppressed because it is too large
Load Diff
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -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,
|
||||
};
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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
|
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…
Reference in New Issue