Merge branch 'drm-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6
* 'drm-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6: drm/radeon/kms: Fix oops after radeon_cs_parser_init() failure. drm/radeon/kms: move radeon KMS on/off switch out of staging. drm/radeon/kms: Bailout of blit if error happen & protect with mutex V3 drm/vmwgfx: Don't send bad flags to the host drm/vmwgfx: Request SVGA version 2 and bail if not found drm/vmwgfx: Correctly detect 3D drm/ttm: remove unnecessary save_flags and ttm_flag_masked in ttm_bo_util.c drm/kms: Remove incorrect comment in struct drm_mode_modeinfo drm/ttm: remove padding from ttm_ref_object on 64bit builds drm/radeon/kms: release agp on error. drm/kms/radeon/agp: Move the check of the aper_size after drm_acp_acquire and drm_agp_info drm/kms/radeon/agp: Fix warning, format ‘%d’ expects type ‘int’, but argument 4 has type ‘size_t’ drm/ttm: Avoid conflicting reserve_memtype during ttm_tt_set_page_caching. drm/kms/radeon: pick digitial encoders smarter. (v3) drm/radeon/kms: use active device to pick connector for encoder drm/radeon/kms: fix incorrect logic in DP vs eDP connector checking.
This commit is contained in:
commit
9ce929078a
21 changed files with 245 additions and 165 deletions
|
@ -66,6 +66,8 @@ config DRM_RADEON
|
||||||
|
|
||||||
If M is selected, the module will be called radeon.
|
If M is selected, the module will be called radeon.
|
||||||
|
|
||||||
|
source "drivers/gpu/drm/radeon/Kconfig"
|
||||||
|
|
||||||
config DRM_I810
|
config DRM_I810
|
||||||
tristate "Intel I810"
|
tristate "Intel I810"
|
||||||
depends on DRM && AGP && AGP_INTEL
|
depends on DRM && AGP && AGP_INTEL
|
||||||
|
|
|
@ -468,7 +468,7 @@ void radeon_dp_set_link_config(struct drm_connector *connector,
|
||||||
struct radeon_connector *radeon_connector;
|
struct radeon_connector *radeon_connector;
|
||||||
struct radeon_connector_atom_dig *dig_connector;
|
struct radeon_connector_atom_dig *dig_connector;
|
||||||
|
|
||||||
if ((connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort) ||
|
if ((connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort) &&
|
||||||
(connector->connector_type != DRM_MODE_CONNECTOR_eDP))
|
(connector->connector_type != DRM_MODE_CONNECTOR_eDP))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -583,7 +583,7 @@ void dp_link_train(struct drm_encoder *encoder,
|
||||||
u8 train_set[4];
|
u8 train_set[4];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if ((connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort) ||
|
if ((connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort) &&
|
||||||
(connector->connector_type != DRM_MODE_CONNECTOR_eDP))
|
(connector->connector_type != DRM_MODE_CONNECTOR_eDP))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -596,21 +596,14 @@ void dp_link_train(struct drm_encoder *encoder,
|
||||||
return;
|
return;
|
||||||
dig_connector = radeon_connector->con_priv;
|
dig_connector = radeon_connector->con_priv;
|
||||||
|
|
||||||
if (ASIC_IS_DCE32(rdev)) {
|
if (dig->dig_encoder)
|
||||||
if (dig->dig_block)
|
enc_id |= ATOM_DP_CONFIG_DIG2_ENCODER;
|
||||||
enc_id |= ATOM_DP_CONFIG_DIG2_ENCODER;
|
else
|
||||||
else
|
enc_id |= ATOM_DP_CONFIG_DIG1_ENCODER;
|
||||||
enc_id |= ATOM_DP_CONFIG_DIG1_ENCODER;
|
if (dig_connector->linkb)
|
||||||
if (dig_connector->linkb)
|
enc_id |= ATOM_DP_CONFIG_LINK_B;
|
||||||
enc_id |= ATOM_DP_CONFIG_LINK_B;
|
else
|
||||||
else
|
enc_id |= ATOM_DP_CONFIG_LINK_A;
|
||||||
enc_id |= ATOM_DP_CONFIG_LINK_A;
|
|
||||||
} else {
|
|
||||||
if (dig_connector->linkb)
|
|
||||||
enc_id |= ATOM_DP_CONFIG_DIG2_ENCODER | ATOM_DP_CONFIG_LINK_B;
|
|
||||||
else
|
|
||||||
enc_id |= ATOM_DP_CONFIG_DIG1_ENCODER | ATOM_DP_CONFIG_LINK_A;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(link_configuration, 0, DP_LINK_CONFIGURATION_SIZE);
|
memset(link_configuration, 0, DP_LINK_CONFIGURATION_SIZE);
|
||||||
if (dig_connector->dp_clock == 270000)
|
if (dig_connector->dp_clock == 270000)
|
||||||
|
|
|
@ -1788,23 +1788,24 @@ void r600_fence_ring_emit(struct radeon_device *rdev,
|
||||||
radeon_ring_write(rdev, RB_INT_STAT);
|
radeon_ring_write(rdev, RB_INT_STAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
int r600_copy_dma(struct radeon_device *rdev,
|
|
||||||
uint64_t src_offset,
|
|
||||||
uint64_t dst_offset,
|
|
||||||
unsigned num_pages,
|
|
||||||
struct radeon_fence *fence)
|
|
||||||
{
|
|
||||||
/* FIXME: implement */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int r600_copy_blit(struct radeon_device *rdev,
|
int r600_copy_blit(struct radeon_device *rdev,
|
||||||
uint64_t src_offset, uint64_t dst_offset,
|
uint64_t src_offset, uint64_t dst_offset,
|
||||||
unsigned num_pages, struct radeon_fence *fence)
|
unsigned num_pages, struct radeon_fence *fence)
|
||||||
{
|
{
|
||||||
r600_blit_prepare_copy(rdev, num_pages * RADEON_GPU_PAGE_SIZE);
|
int r;
|
||||||
|
|
||||||
|
mutex_lock(&rdev->r600_blit.mutex);
|
||||||
|
rdev->r600_blit.vb_ib = NULL;
|
||||||
|
r = r600_blit_prepare_copy(rdev, num_pages * RADEON_GPU_PAGE_SIZE);
|
||||||
|
if (r) {
|
||||||
|
if (rdev->r600_blit.vb_ib)
|
||||||
|
radeon_ib_free(rdev, &rdev->r600_blit.vb_ib);
|
||||||
|
mutex_unlock(&rdev->r600_blit.mutex);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
r600_kms_blit_copy(rdev, src_offset, dst_offset, num_pages * RADEON_GPU_PAGE_SIZE);
|
r600_kms_blit_copy(rdev, src_offset, dst_offset, num_pages * RADEON_GPU_PAGE_SIZE);
|
||||||
r600_blit_done_copy(rdev, fence);
|
r600_blit_done_copy(rdev, fence);
|
||||||
|
mutex_unlock(&rdev->r600_blit.mutex);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1860,26 +1861,19 @@ int r600_startup(struct radeon_device *rdev)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
r600_gpu_init(rdev);
|
r600_gpu_init(rdev);
|
||||||
|
/* pin copy shader into vram */
|
||||||
if (!rdev->r600_blit.shader_obj) {
|
if (rdev->r600_blit.shader_obj) {
|
||||||
r = r600_blit_init(rdev);
|
r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
|
||||||
|
if (unlikely(r != 0))
|
||||||
|
return r;
|
||||||
|
r = radeon_bo_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM,
|
||||||
|
&rdev->r600_blit.shader_gpu_addr);
|
||||||
|
radeon_bo_unreserve(rdev->r600_blit.shader_obj);
|
||||||
if (r) {
|
if (r) {
|
||||||
DRM_ERROR("radeon: failed blitter (%d).\n", r);
|
dev_err(rdev->dev, "(%d) pin blit object failed\n", r);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
|
|
||||||
if (unlikely(r != 0))
|
|
||||||
return r;
|
|
||||||
r = radeon_bo_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM,
|
|
||||||
&rdev->r600_blit.shader_gpu_addr);
|
|
||||||
radeon_bo_unreserve(rdev->r600_blit.shader_obj);
|
|
||||||
if (r) {
|
|
||||||
dev_err(rdev->dev, "(%d) pin blit object failed\n", r);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Enable IRQ */
|
/* Enable IRQ */
|
||||||
r = r600_irq_init(rdev);
|
r = r600_irq_init(rdev);
|
||||||
if (r) {
|
if (r) {
|
||||||
|
@ -2051,6 +2045,12 @@ int r600_init(struct radeon_device *rdev)
|
||||||
r = r600_pcie_gart_init(rdev);
|
r = r600_pcie_gart_init(rdev);
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
|
r = r600_blit_init(rdev);
|
||||||
|
if (r) {
|
||||||
|
r600_blit_fini(rdev);
|
||||||
|
rdev->asic->copy = NULL;
|
||||||
|
dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r);
|
||||||
|
}
|
||||||
|
|
||||||
rdev->accel_working = true;
|
rdev->accel_working = true;
|
||||||
r = r600_startup(rdev);
|
r = r600_startup(rdev);
|
||||||
|
|
|
@ -449,6 +449,7 @@ int r600_blit_init(struct radeon_device *rdev)
|
||||||
u32 packet2s[16];
|
u32 packet2s[16];
|
||||||
int num_packet2s = 0;
|
int num_packet2s = 0;
|
||||||
|
|
||||||
|
mutex_init(&rdev->r600_blit.mutex);
|
||||||
rdev->r600_blit.state_offset = 0;
|
rdev->r600_blit.state_offset = 0;
|
||||||
|
|
||||||
if (rdev->family >= CHIP_RV770)
|
if (rdev->family >= CHIP_RV770)
|
||||||
|
@ -557,7 +558,8 @@ int r600_blit_prepare_copy(struct radeon_device *rdev, int size_bytes)
|
||||||
int dwords_per_loop = 76, num_loops;
|
int dwords_per_loop = 76, num_loops;
|
||||||
|
|
||||||
r = r600_vb_ib_get(rdev);
|
r = r600_vb_ib_get(rdev);
|
||||||
WARN_ON(r);
|
if (r)
|
||||||
|
return r;
|
||||||
|
|
||||||
/* set_render_target emits 2 extra dwords on rv6xx */
|
/* set_render_target emits 2 extra dwords on rv6xx */
|
||||||
if (rdev->family > CHIP_R600 && rdev->family < CHIP_RV770)
|
if (rdev->family > CHIP_R600 && rdev->family < CHIP_RV770)
|
||||||
|
@ -583,7 +585,8 @@ int r600_blit_prepare_copy(struct radeon_device *rdev, int size_bytes)
|
||||||
ring_size += 5; /* done copy */
|
ring_size += 5; /* done copy */
|
||||||
ring_size += 7; /* fence emit for done copy */
|
ring_size += 7; /* fence emit for done copy */
|
||||||
r = radeon_ring_lock(rdev, ring_size);
|
r = radeon_ring_lock(rdev, ring_size);
|
||||||
WARN_ON(r);
|
if (r)
|
||||||
|
return r;
|
||||||
|
|
||||||
set_default_state(rdev); /* 14 */
|
set_default_state(rdev); /* 14 */
|
||||||
set_shaders(rdev); /* 26 */
|
set_shaders(rdev); /* 26 */
|
||||||
|
|
|
@ -416,6 +416,7 @@ struct r600_ih {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct r600_blit {
|
struct r600_blit {
|
||||||
|
struct mutex mutex;
|
||||||
struct radeon_bo *shader_obj;
|
struct radeon_bo *shader_obj;
|
||||||
u64 shader_gpu_addr;
|
u64 shader_gpu_addr;
|
||||||
u32 vs_offset, ps_offset;
|
u32 vs_offset, ps_offset;
|
||||||
|
|
|
@ -133,13 +133,6 @@ int radeon_agp_init(struct radeon_device *rdev)
|
||||||
bool is_v3;
|
bool is_v3;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (rdev->ddev->agp->agp_info.aper_size < 32) {
|
|
||||||
dev_warn(rdev->dev, "AGP aperture to small (%dM) "
|
|
||||||
"need at least 32M, disabling AGP\n",
|
|
||||||
rdev->ddev->agp->agp_info.aper_size);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Acquire AGP. */
|
/* Acquire AGP. */
|
||||||
if (!rdev->ddev->agp->acquired) {
|
if (!rdev->ddev->agp->acquired) {
|
||||||
ret = drm_agp_acquire(rdev->ddev);
|
ret = drm_agp_acquire(rdev->ddev);
|
||||||
|
@ -151,9 +144,19 @@ int radeon_agp_init(struct radeon_device *rdev)
|
||||||
|
|
||||||
ret = drm_agp_info(rdev->ddev, &info);
|
ret = drm_agp_info(rdev->ddev, &info);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
drm_agp_release(rdev->ddev);
|
||||||
DRM_ERROR("Unable to get AGP info: %d\n", ret);
|
DRM_ERROR("Unable to get AGP info: %d\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rdev->ddev->agp->agp_info.aper_size < 32) {
|
||||||
|
drm_agp_release(rdev->ddev);
|
||||||
|
dev_warn(rdev->dev, "AGP aperture too small (%zuM) "
|
||||||
|
"need at least 32M, disabling AGP\n",
|
||||||
|
rdev->ddev->agp->agp_info.aper_size);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
mode.mode = info.mode;
|
mode.mode = info.mode;
|
||||||
agp_status = (RREG32(RADEON_AGP_STATUS) | RADEON_AGPv3_MODE) & mode.mode;
|
agp_status = (RREG32(RADEON_AGP_STATUS) | RADEON_AGPv3_MODE) & mode.mode;
|
||||||
is_v3 = !!(agp_status & RADEON_AGPv3_MODE);
|
is_v3 = !!(agp_status & RADEON_AGPv3_MODE);
|
||||||
|
@ -228,6 +231,7 @@ int radeon_agp_init(struct radeon_device *rdev)
|
||||||
ret = drm_agp_enable(rdev->ddev, mode);
|
ret = drm_agp_enable(rdev->ddev, mode);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
DRM_ERROR("Unable to enable AGP (mode = 0x%lx)\n", mode.mode);
|
DRM_ERROR("Unable to enable AGP (mode = 0x%lx)\n", mode.mode);
|
||||||
|
drm_agp_release(rdev->ddev);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -189,7 +189,7 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
if (error) {
|
if (error && parser->ib) {
|
||||||
radeon_bo_list_unvalidate(&parser->validated,
|
radeon_bo_list_unvalidate(&parser->validated,
|
||||||
parser->ib->fence);
|
parser->ib->fence);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -156,6 +156,26 @@ radeon_get_encoder_id(struct drm_device *dev, uint32_t supported_device, uint8_t
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool radeon_encoder_is_digital(struct drm_encoder *encoder)
|
||||||
|
{
|
||||||
|
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
|
||||||
|
switch (radeon_encoder->encoder_id) {
|
||||||
|
case ENCODER_OBJECT_ID_INTERNAL_LVDS:
|
||||||
|
case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
|
||||||
|
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
|
||||||
|
case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
|
||||||
|
case ENCODER_OBJECT_ID_INTERNAL_DVO1:
|
||||||
|
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
|
||||||
|
case ENCODER_OBJECT_ID_INTERNAL_DDI:
|
||||||
|
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
|
||||||
|
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
|
||||||
|
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
|
||||||
|
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
void
|
void
|
||||||
radeon_link_encoder_connector(struct drm_device *dev)
|
radeon_link_encoder_connector(struct drm_device *dev)
|
||||||
{
|
{
|
||||||
|
@ -202,7 +222,7 @@ radeon_get_connector_for_encoder(struct drm_encoder *encoder)
|
||||||
|
|
||||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
||||||
radeon_connector = to_radeon_connector(connector);
|
radeon_connector = to_radeon_connector(connector);
|
||||||
if (radeon_encoder->devices & radeon_connector->devices)
|
if (radeon_encoder->active_device & radeon_connector->devices)
|
||||||
return connector;
|
return connector;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -676,31 +696,11 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action)
|
||||||
|
|
||||||
memset(&args, 0, sizeof(args));
|
memset(&args, 0, sizeof(args));
|
||||||
|
|
||||||
if (ASIC_IS_DCE32(rdev)) {
|
if (dig->dig_encoder)
|
||||||
if (dig->dig_block)
|
index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl);
|
||||||
index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl);
|
else
|
||||||
else
|
index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
|
||||||
index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
|
num = dig->dig_encoder + 1;
|
||||||
num = dig->dig_block + 1;
|
|
||||||
} else {
|
|
||||||
switch (radeon_encoder->encoder_id) {
|
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
|
|
||||||
/* XXX doesn't really matter which dig encoder we pick as long as it's
|
|
||||||
* not already in use
|
|
||||||
*/
|
|
||||||
if (dig_connector->linkb)
|
|
||||||
index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl);
|
|
||||||
else
|
|
||||||
index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
|
|
||||||
num = 1;
|
|
||||||
break;
|
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
|
|
||||||
/* Only dig2 encoder can drive LVTMA */
|
|
||||||
index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl);
|
|
||||||
num = 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev);
|
atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev);
|
||||||
|
|
||||||
|
@ -822,7 +822,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
|
||||||
args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
|
args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
|
||||||
}
|
}
|
||||||
if (ASIC_IS_DCE32(rdev)) {
|
if (ASIC_IS_DCE32(rdev)) {
|
||||||
if (dig->dig_block)
|
if (dig->dig_encoder == 1)
|
||||||
args.v2.acConfig.ucEncoderSel = 1;
|
args.v2.acConfig.ucEncoderSel = 1;
|
||||||
if (dig_connector->linkb)
|
if (dig_connector->linkb)
|
||||||
args.v2.acConfig.ucLinkSel = 1;
|
args.v2.acConfig.ucLinkSel = 1;
|
||||||
|
@ -849,17 +849,16 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
|
||||||
args.v2.acConfig.fCoherentMode = 1;
|
args.v2.acConfig.fCoherentMode = 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL;
|
args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL;
|
||||||
|
|
||||||
|
if (dig->dig_encoder)
|
||||||
|
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER;
|
||||||
|
else
|
||||||
|
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER;
|
||||||
|
|
||||||
switch (radeon_encoder->encoder_id) {
|
switch (radeon_encoder->encoder_id) {
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
|
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
|
||||||
/* XXX doesn't really matter which dig encoder we pick as long as it's
|
|
||||||
* not already in use
|
|
||||||
*/
|
|
||||||
if (dig_connector->linkb)
|
|
||||||
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER;
|
|
||||||
else
|
|
||||||
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER;
|
|
||||||
if (rdev->flags & RADEON_IS_IGP) {
|
if (rdev->flags & RADEON_IS_IGP) {
|
||||||
if (radeon_encoder->pixel_clock > 165000) {
|
if (radeon_encoder->pixel_clock > 165000) {
|
||||||
if (dig_connector->igp_lane_info & 0x3)
|
if (dig_connector->igp_lane_info & 0x3)
|
||||||
|
@ -878,10 +877,6 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
|
|
||||||
/* Only dig2 encoder can drive LVTMA */
|
|
||||||
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (radeon_encoder->pixel_clock > 165000)
|
if (radeon_encoder->pixel_clock > 165000)
|
||||||
|
@ -1046,6 +1041,7 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder)
|
||||||
union crtc_sourc_param args;
|
union crtc_sourc_param args;
|
||||||
int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source);
|
int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source);
|
||||||
uint8_t frev, crev;
|
uint8_t frev, crev;
|
||||||
|
struct radeon_encoder_atom_dig *dig;
|
||||||
|
|
||||||
memset(&args, 0, sizeof(args));
|
memset(&args, 0, sizeof(args));
|
||||||
|
|
||||||
|
@ -1109,40 +1105,16 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder)
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
|
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
|
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
|
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
|
||||||
if (ASIC_IS_DCE32(rdev)) {
|
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
|
||||||
if (radeon_crtc->crtc_id)
|
dig = radeon_encoder->enc_priv;
|
||||||
args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
|
if (dig->dig_encoder)
|
||||||
else
|
args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
|
||||||
args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;
|
else
|
||||||
} else {
|
args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;
|
||||||
struct drm_connector *connector;
|
|
||||||
struct radeon_connector *radeon_connector;
|
|
||||||
struct radeon_connector_atom_dig *dig_connector;
|
|
||||||
|
|
||||||
connector = radeon_get_connector_for_encoder(encoder);
|
|
||||||
if (!connector)
|
|
||||||
return;
|
|
||||||
radeon_connector = to_radeon_connector(connector);
|
|
||||||
if (!radeon_connector->con_priv)
|
|
||||||
return;
|
|
||||||
dig_connector = radeon_connector->con_priv;
|
|
||||||
|
|
||||||
/* XXX doesn't really matter which dig encoder we pick as long as it's
|
|
||||||
* not already in use
|
|
||||||
*/
|
|
||||||
if (dig_connector->linkb)
|
|
||||||
args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
|
|
||||||
else
|
|
||||||
args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
|
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
|
||||||
args.v2.ucEncoderID = ASIC_INT_DVO_ENCODER_ID;
|
args.v2.ucEncoderID = ASIC_INT_DVO_ENCODER_ID;
|
||||||
break;
|
break;
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
|
|
||||||
/* Only dig2 encoder can drive LVTMA */
|
|
||||||
args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
|
|
||||||
break;
|
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
|
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
|
||||||
if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
|
if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
|
||||||
args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
|
args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
|
||||||
|
@ -1202,6 +1174,47 @@ atombios_apply_encoder_quirks(struct drm_encoder *encoder,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder)
|
||||||
|
{
|
||||||
|
struct drm_device *dev = encoder->dev;
|
||||||
|
struct radeon_device *rdev = dev->dev_private;
|
||||||
|
struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
|
||||||
|
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
|
||||||
|
struct drm_encoder *test_encoder;
|
||||||
|
struct radeon_encoder_atom_dig *dig;
|
||||||
|
uint32_t dig_enc_in_use = 0;
|
||||||
|
/* on DCE32 and encoder can driver any block so just crtc id */
|
||||||
|
if (ASIC_IS_DCE32(rdev)) {
|
||||||
|
return radeon_crtc->crtc_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* on DCE3 - LVTMA can only be driven by DIGB */
|
||||||
|
list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) {
|
||||||
|
struct radeon_encoder *radeon_test_encoder;
|
||||||
|
|
||||||
|
if (encoder == test_encoder)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!radeon_encoder_is_digital(test_encoder))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
radeon_test_encoder = to_radeon_encoder(test_encoder);
|
||||||
|
dig = radeon_test_encoder->enc_priv;
|
||||||
|
|
||||||
|
if (dig->dig_encoder >= 0)
|
||||||
|
dig_enc_in_use |= (1 << dig->dig_encoder);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA) {
|
||||||
|
if (dig_enc_in_use & 0x2)
|
||||||
|
DRM_ERROR("LVDS required digital encoder 2 but it was in use - stealing\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (!(dig_enc_in_use & 1))
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
|
radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
|
||||||
struct drm_display_mode *mode,
|
struct drm_display_mode *mode,
|
||||||
|
@ -1214,12 +1227,9 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
|
||||||
|
|
||||||
if (radeon_encoder->active_device &
|
if (radeon_encoder->active_device &
|
||||||
(ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) {
|
(ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) {
|
||||||
if (radeon_encoder->enc_priv) {
|
struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
|
||||||
struct radeon_encoder_atom_dig *dig;
|
if (dig)
|
||||||
|
dig->dig_encoder = radeon_atom_pick_dig_encoder(encoder);
|
||||||
dig = radeon_encoder->enc_priv;
|
|
||||||
dig->dig_block = radeon_crtc->crtc_id;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
radeon_encoder->pixel_clock = adjusted_mode->clock;
|
radeon_encoder->pixel_clock = adjusted_mode->clock;
|
||||||
|
|
||||||
|
@ -1379,7 +1389,13 @@ static void radeon_atom_encoder_commit(struct drm_encoder *encoder)
|
||||||
static void radeon_atom_encoder_disable(struct drm_encoder *encoder)
|
static void radeon_atom_encoder_disable(struct drm_encoder *encoder)
|
||||||
{
|
{
|
||||||
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
|
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
|
||||||
|
struct radeon_encoder_atom_dig *dig;
|
||||||
radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
|
radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
|
||||||
|
|
||||||
|
if (radeon_encoder_is_digital(encoder)) {
|
||||||
|
dig = radeon_encoder->enc_priv;
|
||||||
|
dig->dig_encoder = -1;
|
||||||
|
}
|
||||||
radeon_encoder->active_device = 0;
|
radeon_encoder->active_device = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1436,6 +1452,7 @@ radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder)
|
||||||
|
|
||||||
/* coherent mode by default */
|
/* coherent mode by default */
|
||||||
dig->coherent_mode = true;
|
dig->coherent_mode = true;
|
||||||
|
dig->dig_encoder = -1;
|
||||||
|
|
||||||
return dig;
|
return dig;
|
||||||
}
|
}
|
||||||
|
|
|
@ -299,7 +299,7 @@ struct radeon_atom_ss {
|
||||||
struct radeon_encoder_atom_dig {
|
struct radeon_encoder_atom_dig {
|
||||||
/* atom dig */
|
/* atom dig */
|
||||||
bool coherent_mode;
|
bool coherent_mode;
|
||||||
int dig_block;
|
int dig_encoder; /* -1 disabled, 0 DIGA, 1 DIGB */
|
||||||
/* atom lvds */
|
/* atom lvds */
|
||||||
uint32_t lvds_misc;
|
uint32_t lvds_misc;
|
||||||
uint16_t panel_pwr_delay;
|
uint16_t panel_pwr_delay;
|
||||||
|
|
|
@ -887,26 +887,19 @@ static int rv770_startup(struct radeon_device *rdev)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
rv770_gpu_init(rdev);
|
rv770_gpu_init(rdev);
|
||||||
|
/* pin copy shader into vram */
|
||||||
if (!rdev->r600_blit.shader_obj) {
|
if (rdev->r600_blit.shader_obj) {
|
||||||
r = r600_blit_init(rdev);
|
r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
|
||||||
|
if (unlikely(r != 0))
|
||||||
|
return r;
|
||||||
|
r = radeon_bo_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM,
|
||||||
|
&rdev->r600_blit.shader_gpu_addr);
|
||||||
|
radeon_bo_unreserve(rdev->r600_blit.shader_obj);
|
||||||
if (r) {
|
if (r) {
|
||||||
DRM_ERROR("radeon: failed blitter (%d).\n", r);
|
DRM_ERROR("failed to pin blit object %d\n", r);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
|
|
||||||
if (unlikely(r != 0))
|
|
||||||
return r;
|
|
||||||
r = radeon_bo_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM,
|
|
||||||
&rdev->r600_blit.shader_gpu_addr);
|
|
||||||
radeon_bo_unreserve(rdev->r600_blit.shader_obj);
|
|
||||||
if (r) {
|
|
||||||
DRM_ERROR("failed to pin blit object %d\n", r);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Enable IRQ */
|
/* Enable IRQ */
|
||||||
r = r600_irq_init(rdev);
|
r = r600_irq_init(rdev);
|
||||||
if (r) {
|
if (r) {
|
||||||
|
@ -1062,6 +1055,12 @@ int rv770_init(struct radeon_device *rdev)
|
||||||
r = r600_pcie_gart_init(rdev);
|
r = r600_pcie_gart_init(rdev);
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
|
r = r600_blit_init(rdev);
|
||||||
|
if (r) {
|
||||||
|
r600_blit_fini(rdev);
|
||||||
|
rdev->asic->copy = NULL;
|
||||||
|
dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r);
|
||||||
|
}
|
||||||
|
|
||||||
rdev->accel_working = true;
|
rdev->accel_working = true;
|
||||||
r = rv770_startup(rdev);
|
r = rv770_startup(rdev);
|
||||||
|
|
|
@ -53,7 +53,6 @@ int ttm_bo_move_ttm(struct ttm_buffer_object *bo,
|
||||||
{
|
{
|
||||||
struct ttm_tt *ttm = bo->ttm;
|
struct ttm_tt *ttm = bo->ttm;
|
||||||
struct ttm_mem_reg *old_mem = &bo->mem;
|
struct ttm_mem_reg *old_mem = &bo->mem;
|
||||||
uint32_t save_flags = old_mem->placement;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (old_mem->mem_type != TTM_PL_SYSTEM) {
|
if (old_mem->mem_type != TTM_PL_SYSTEM) {
|
||||||
|
@ -62,7 +61,6 @@ int ttm_bo_move_ttm(struct ttm_buffer_object *bo,
|
||||||
ttm_flag_masked(&old_mem->placement, TTM_PL_FLAG_SYSTEM,
|
ttm_flag_masked(&old_mem->placement, TTM_PL_FLAG_SYSTEM,
|
||||||
TTM_PL_MASK_MEM);
|
TTM_PL_MASK_MEM);
|
||||||
old_mem->mem_type = TTM_PL_SYSTEM;
|
old_mem->mem_type = TTM_PL_SYSTEM;
|
||||||
save_flags = old_mem->placement;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = ttm_tt_set_placement_caching(ttm, new_mem->placement);
|
ret = ttm_tt_set_placement_caching(ttm, new_mem->placement);
|
||||||
|
@ -77,7 +75,7 @@ int ttm_bo_move_ttm(struct ttm_buffer_object *bo,
|
||||||
|
|
||||||
*old_mem = *new_mem;
|
*old_mem = *new_mem;
|
||||||
new_mem->mm_node = NULL;
|
new_mem->mm_node = NULL;
|
||||||
ttm_flag_masked(&save_flags, new_mem->placement, TTM_PL_MASK_MEMTYPE);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(ttm_bo_move_ttm);
|
EXPORT_SYMBOL(ttm_bo_move_ttm);
|
||||||
|
@ -219,7 +217,6 @@ int ttm_bo_move_memcpy(struct ttm_buffer_object *bo,
|
||||||
void *old_iomap;
|
void *old_iomap;
|
||||||
void *new_iomap;
|
void *new_iomap;
|
||||||
int ret;
|
int ret;
|
||||||
uint32_t save_flags = old_mem->placement;
|
|
||||||
unsigned long i;
|
unsigned long i;
|
||||||
unsigned long page;
|
unsigned long page;
|
||||||
unsigned long add = 0;
|
unsigned long add = 0;
|
||||||
|
@ -270,7 +267,6 @@ out2:
|
||||||
|
|
||||||
*old_mem = *new_mem;
|
*old_mem = *new_mem;
|
||||||
new_mem->mm_node = NULL;
|
new_mem->mm_node = NULL;
|
||||||
ttm_flag_masked(&save_flags, new_mem->placement, TTM_PL_MASK_MEMTYPE);
|
|
||||||
|
|
||||||
if ((man->flags & TTM_MEMTYPE_FLAG_FIXED) && (ttm != NULL)) {
|
if ((man->flags & TTM_MEMTYPE_FLAG_FIXED) && (ttm != NULL)) {
|
||||||
ttm_tt_unbind(ttm);
|
ttm_tt_unbind(ttm);
|
||||||
|
@ -537,7 +533,6 @@ int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo,
|
||||||
struct ttm_mem_type_manager *man = &bdev->man[new_mem->mem_type];
|
struct ttm_mem_type_manager *man = &bdev->man[new_mem->mem_type];
|
||||||
struct ttm_mem_reg *old_mem = &bo->mem;
|
struct ttm_mem_reg *old_mem = &bo->mem;
|
||||||
int ret;
|
int ret;
|
||||||
uint32_t save_flags = old_mem->placement;
|
|
||||||
struct ttm_buffer_object *ghost_obj;
|
struct ttm_buffer_object *ghost_obj;
|
||||||
void *tmp_obj = NULL;
|
void *tmp_obj = NULL;
|
||||||
|
|
||||||
|
@ -598,7 +593,7 @@ int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo,
|
||||||
|
|
||||||
*old_mem = *new_mem;
|
*old_mem = *new_mem;
|
||||||
new_mem->mm_node = NULL;
|
new_mem->mm_node = NULL;
|
||||||
ttm_flag_masked(&save_flags, new_mem->placement, TTM_PL_MASK_MEMTYPE);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(ttm_bo_move_accel_cleanup);
|
EXPORT_SYMBOL(ttm_bo_move_accel_cleanup);
|
||||||
|
|
|
@ -109,8 +109,8 @@ struct ttm_ref_object {
|
||||||
struct drm_hash_item hash;
|
struct drm_hash_item hash;
|
||||||
struct list_head head;
|
struct list_head head;
|
||||||
struct kref kref;
|
struct kref kref;
|
||||||
struct ttm_base_object *obj;
|
|
||||||
enum ttm_ref_type ref_type;
|
enum ttm_ref_type ref_type;
|
||||||
|
struct ttm_base_object *obj;
|
||||||
struct ttm_object_file *tfile;
|
struct ttm_object_file *tfile;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -198,17 +198,26 @@ EXPORT_SYMBOL(ttm_tt_populate);
|
||||||
static inline int ttm_tt_set_page_caching(struct page *p,
|
static inline int ttm_tt_set_page_caching(struct page *p,
|
||||||
enum ttm_caching_state c_state)
|
enum ttm_caching_state c_state)
|
||||||
{
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
if (PageHighMem(p))
|
if (PageHighMem(p))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
switch (c_state) {
|
if (get_page_memtype(p) != -1) {
|
||||||
case tt_cached:
|
/* p isn't in the default caching state, set it to
|
||||||
return set_pages_wb(p, 1);
|
* writeback first to free its current memtype. */
|
||||||
case tt_wc:
|
|
||||||
return set_memory_wc((unsigned long) page_address(p), 1);
|
ret = set_pages_wb(p, 1);
|
||||||
default:
|
if (ret)
|
||||||
return set_pages_uc(p, 1);
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (c_state == tt_wc)
|
||||||
|
ret = set_memory_wc((unsigned long) page_address(p), 1);
|
||||||
|
else if (c_state == tt_uncached)
|
||||||
|
ret = set_pages_uc(p, 1);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
#else /* CONFIG_X86 */
|
#else /* CONFIG_X86 */
|
||||||
static inline int ttm_tt_set_page_caching(struct page *p,
|
static inline int ttm_tt_set_page_caching(struct page *p,
|
||||||
|
|
|
@ -209,6 +209,7 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
|
||||||
{
|
{
|
||||||
struct vmw_private *dev_priv;
|
struct vmw_private *dev_priv;
|
||||||
int ret;
|
int ret;
|
||||||
|
uint32_t svga_id;
|
||||||
|
|
||||||
dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL);
|
dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL);
|
||||||
if (unlikely(dev_priv == NULL)) {
|
if (unlikely(dev_priv == NULL)) {
|
||||||
|
@ -239,6 +240,16 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
|
||||||
dev_priv->mmio_start = pci_resource_start(dev->pdev, 2);
|
dev_priv->mmio_start = pci_resource_start(dev->pdev, 2);
|
||||||
|
|
||||||
mutex_lock(&dev_priv->hw_mutex);
|
mutex_lock(&dev_priv->hw_mutex);
|
||||||
|
|
||||||
|
vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2);
|
||||||
|
svga_id = vmw_read(dev_priv, SVGA_REG_ID);
|
||||||
|
if (svga_id != SVGA_ID_2) {
|
||||||
|
ret = -ENOSYS;
|
||||||
|
DRM_ERROR("Unsuported SVGA ID 0x%x\n", svga_id);
|
||||||
|
mutex_unlock(&dev_priv->hw_mutex);
|
||||||
|
goto out_err0;
|
||||||
|
}
|
||||||
|
|
||||||
dev_priv->capabilities = vmw_read(dev_priv, SVGA_REG_CAPABILITIES);
|
dev_priv->capabilities = vmw_read(dev_priv, SVGA_REG_CAPABILITIES);
|
||||||
|
|
||||||
if (dev_priv->capabilities & SVGA_CAP_GMR) {
|
if (dev_priv->capabilities & SVGA_CAP_GMR) {
|
||||||
|
@ -357,6 +368,8 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
|
||||||
dev_priv->pm_nb.notifier_call = vmwgfx_pm_notifier;
|
dev_priv->pm_nb.notifier_call = vmwgfx_pm_notifier;
|
||||||
register_pm_notifier(&dev_priv->pm_nb);
|
register_pm_notifier(&dev_priv->pm_nb);
|
||||||
|
|
||||||
|
DRM_INFO("%s", vmw_fifo_have_3d(dev_priv) ? "Have 3D\n" : "No 3D\n");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_no_device:
|
out_no_device:
|
||||||
|
|
|
@ -96,6 +96,8 @@ struct vmw_surface {
|
||||||
struct drm_vmw_size *sizes;
|
struct drm_vmw_size *sizes;
|
||||||
uint32_t num_sizes;
|
uint32_t num_sizes;
|
||||||
|
|
||||||
|
bool scanout;
|
||||||
|
|
||||||
/* TODO so far just a extra pointer */
|
/* TODO so far just a extra pointer */
|
||||||
struct vmw_cursor_snooper snooper;
|
struct vmw_cursor_snooper snooper;
|
||||||
};
|
};
|
||||||
|
@ -389,6 +391,7 @@ extern int vmw_fifo_send_fence(struct vmw_private *dev_priv,
|
||||||
uint32_t *sequence);
|
uint32_t *sequence);
|
||||||
extern void vmw_fifo_ping_host(struct vmw_private *dev_priv, uint32_t reason);
|
extern void vmw_fifo_ping_host(struct vmw_private *dev_priv, uint32_t reason);
|
||||||
extern int vmw_fifo_mmap(struct file *filp, struct vm_area_struct *vma);
|
extern int vmw_fifo_mmap(struct file *filp, struct vm_area_struct *vma);
|
||||||
|
extern bool vmw_fifo_have_3d(struct vmw_private *dev_priv);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TTM glue - vmwgfx_ttm_glue.c
|
* TTM glue - vmwgfx_ttm_glue.c
|
||||||
|
|
|
@ -29,6 +29,25 @@
|
||||||
#include "drmP.h"
|
#include "drmP.h"
|
||||||
#include "ttm/ttm_placement.h"
|
#include "ttm/ttm_placement.h"
|
||||||
|
|
||||||
|
bool vmw_fifo_have_3d(struct vmw_private *dev_priv)
|
||||||
|
{
|
||||||
|
__le32 __iomem *fifo_mem = dev_priv->mmio_virt;
|
||||||
|
uint32_t fifo_min, hwversion;
|
||||||
|
|
||||||
|
fifo_min = ioread32(fifo_mem + SVGA_FIFO_MIN);
|
||||||
|
if (fifo_min <= SVGA_FIFO_3D_HWVERSION * sizeof(unsigned int))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
hwversion = ioread32(fifo_mem + SVGA_FIFO_3D_HWVERSION);
|
||||||
|
if (hwversion == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (hwversion < SVGA3D_HWVERSION_WS65_B1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int vmw_fifo_init(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo)
|
int vmw_fifo_init(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo)
|
||||||
{
|
{
|
||||||
__le32 __iomem *fifo_mem = dev_priv->mmio_virt;
|
__le32 __iomem *fifo_mem = dev_priv->mmio_virt;
|
||||||
|
|
|
@ -43,7 +43,7 @@ int vmw_getparam_ioctl(struct drm_device *dev, void *data,
|
||||||
param->value = vmw_overlay_num_free_overlays(dev_priv);
|
param->value = vmw_overlay_num_free_overlays(dev_priv);
|
||||||
break;
|
break;
|
||||||
case DRM_VMW_PARAM_3D:
|
case DRM_VMW_PARAM_3D:
|
||||||
param->value = dev_priv->capabilities & SVGA_CAP_3D ? 1 : 0;
|
param->value = vmw_fifo_have_3d(dev_priv) ? 1 : 0;
|
||||||
break;
|
break;
|
||||||
case DRM_VMW_PARAM_FIFO_OFFSET:
|
case DRM_VMW_PARAM_FIFO_OFFSET:
|
||||||
param->value = dev_priv->mmio_start;
|
param->value = dev_priv->mmio_start;
|
||||||
|
|
|
@ -707,6 +707,9 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
|
||||||
if (ret)
|
if (ret)
|
||||||
goto try_dmabuf;
|
goto try_dmabuf;
|
||||||
|
|
||||||
|
if (!surface->scanout)
|
||||||
|
goto err_not_scanout;
|
||||||
|
|
||||||
ret = vmw_kms_new_framebuffer_surface(dev_priv, surface, &vfb,
|
ret = vmw_kms_new_framebuffer_surface(dev_priv, surface, &vfb,
|
||||||
mode_cmd->width, mode_cmd->height);
|
mode_cmd->width, mode_cmd->height);
|
||||||
|
|
||||||
|
@ -740,6 +743,13 @@ try_dmabuf:
|
||||||
}
|
}
|
||||||
|
|
||||||
return &vfb->base;
|
return &vfb->base;
|
||||||
|
|
||||||
|
err_not_scanout:
|
||||||
|
DRM_ERROR("surface not marked as scanout\n");
|
||||||
|
/* vmw_user_surface_lookup takes one ref */
|
||||||
|
vmw_surface_unreference(&surface);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vmw_kms_fb_changed(struct drm_device *dev)
|
static int vmw_kms_fb_changed(struct drm_device *dev)
|
||||||
|
|
|
@ -35,6 +35,11 @@
|
||||||
#define VMW_RES_SURFACE ttm_driver_type1
|
#define VMW_RES_SURFACE ttm_driver_type1
|
||||||
#define VMW_RES_STREAM ttm_driver_type2
|
#define VMW_RES_STREAM ttm_driver_type2
|
||||||
|
|
||||||
|
/* XXX: This isn't a real hardware flag, but just a hack for kernel to
|
||||||
|
* know about primary surfaces. Find a better way to accomplish this.
|
||||||
|
*/
|
||||||
|
#define SVGA3D_SURFACE_HINT_SCANOUT (1 << 9)
|
||||||
|
|
||||||
struct vmw_user_context {
|
struct vmw_user_context {
|
||||||
struct ttm_base_object base;
|
struct ttm_base_object base;
|
||||||
struct vmw_resource res;
|
struct vmw_resource res;
|
||||||
|
@ -599,8 +604,17 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data,
|
||||||
if (unlikely(ret != 0))
|
if (unlikely(ret != 0))
|
||||||
goto out_err1;
|
goto out_err1;
|
||||||
|
|
||||||
|
if (srf->flags & SVGA3D_SURFACE_HINT_SCANOUT) {
|
||||||
|
/* we should not send this flag down to hardware since
|
||||||
|
* its not a official one
|
||||||
|
*/
|
||||||
|
srf->flags &= ~SVGA3D_SURFACE_HINT_SCANOUT;
|
||||||
|
srf->scanout = true;
|
||||||
|
} else {
|
||||||
|
srf->scanout = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (srf->flags & (1 << 9) &&
|
if (srf->scanout &&
|
||||||
srf->num_sizes == 1 &&
|
srf->num_sizes == 1 &&
|
||||||
srf->sizes[0].width == 64 &&
|
srf->sizes[0].width == 64 &&
|
||||||
srf->sizes[0].height == 64 &&
|
srf->sizes[0].height == 64 &&
|
||||||
|
|
|
@ -99,8 +99,6 @@ source "drivers/staging/line6/Kconfig"
|
||||||
|
|
||||||
source "drivers/gpu/drm/vmwgfx/Kconfig"
|
source "drivers/gpu/drm/vmwgfx/Kconfig"
|
||||||
|
|
||||||
source "drivers/gpu/drm/radeon/Kconfig"
|
|
||||||
|
|
||||||
source "drivers/gpu/drm/nouveau/Kconfig"
|
source "drivers/gpu/drm/nouveau/Kconfig"
|
||||||
|
|
||||||
source "drivers/staging/octeon/Kconfig"
|
source "drivers/staging/octeon/Kconfig"
|
||||||
|
|
|
@ -85,7 +85,7 @@ struct drm_mode_modeinfo {
|
||||||
__u16 hdisplay, hsync_start, hsync_end, htotal, hskew;
|
__u16 hdisplay, hsync_start, hsync_end, htotal, hskew;
|
||||||
__u16 vdisplay, vsync_start, vsync_end, vtotal, vscan;
|
__u16 vdisplay, vsync_start, vsync_end, vtotal, vscan;
|
||||||
|
|
||||||
__u32 vrefresh; /* vertical refresh * 1000 */
|
__u32 vrefresh;
|
||||||
|
|
||||||
__u32 flags;
|
__u32 flags;
|
||||||
__u32 type;
|
__u32 type;
|
||||||
|
|
Loading…
Add table
Reference in a new issue