mirror of
https://github.com/torvalds/linux.git
synced 2024-11-15 08:31:55 +00:00
Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux
Pull drm fixes from Dave Airlie: "gma500 build fix + some regression fixes for nouveau/radeon" * 'drm-fixes' of git://people.freedesktop.org/~airlied/linux: drm/radeon: Only warn if the intra-domain offset actually exceeds the limit. drm/radeon/kms: add htile support to the cs checker v3 drm/radeon/kms/atom: force bpc to 8 for now drm/nouveau/i2c: fix thinko/regression on really old chipsets drm/nouveau: default to 8bpc for non-LVDS panels if EDID isn't useful drm/nouveau: fix thinko causing init to fail on cards without accel gma500: medfield: fix build without CONFIG_BACKLIGHT_CLASS_DEVICE
This commit is contained in:
commit
516e779770
@ -244,7 +244,6 @@ static int mdfld_dsi_connector_set_property(struct drm_connector *connector,
|
||||
uint64_t value)
|
||||
{
|
||||
struct drm_encoder *encoder = connector->encoder;
|
||||
struct backlight_device *psb_bd;
|
||||
|
||||
if (!strcmp(property->name, "scaling mode") && encoder) {
|
||||
struct psb_intel_crtc *psb_crtc =
|
||||
@ -301,11 +300,15 @@ static int mdfld_dsi_connector_set_property(struct drm_connector *connector,
|
||||
value))
|
||||
goto set_prop_error;
|
||||
else {
|
||||
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
|
||||
struct backlight_device *psb_bd;
|
||||
|
||||
psb_bd = mdfld_get_backlight_device();
|
||||
if (psb_bd) {
|
||||
psb_bd->props.brightness = value;
|
||||
mdfld_set_brightness(psb_bd);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
set_prop_done:
|
||||
|
@ -654,10 +654,13 @@ nouveau_connector_detect_depth(struct drm_connector *connector)
|
||||
if (nv_connector->edid && connector->display_info.bpc)
|
||||
return;
|
||||
|
||||
/* if not, we're out of options unless we're LVDS, default to 6bpc */
|
||||
connector->display_info.bpc = 6;
|
||||
if (nv_encoder->dcb->type != OUTPUT_LVDS)
|
||||
/* if not, we're out of options unless we're LVDS, default to 8bpc */
|
||||
if (nv_encoder->dcb->type != OUTPUT_LVDS) {
|
||||
connector->display_info.bpc = 8;
|
||||
return;
|
||||
}
|
||||
|
||||
connector->display_info.bpc = 6;
|
||||
|
||||
/* LVDS: panel straps */
|
||||
if (bios->fp_no_ddc) {
|
||||
|
@ -315,8 +315,8 @@ nouveau_i2c_init(struct drm_device *dev)
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
struct nvbios *bios = &dev_priv->vbios;
|
||||
struct nouveau_i2c_chan *port;
|
||||
u8 version = 0x00, entries, recordlen;
|
||||
u8 *i2c, *entry, legacy[2][4] = {};
|
||||
u8 version, entries, recordlen;
|
||||
int ret, i;
|
||||
|
||||
INIT_LIST_HEAD(&dev_priv->i2c_ports);
|
||||
@ -346,12 +346,12 @@ nouveau_i2c_init(struct drm_device *dev)
|
||||
if (i2c[7]) legacy[1][1] = i2c[7];
|
||||
}
|
||||
|
||||
if (i2c && version >= 0x30) {
|
||||
if (version >= 0x30) {
|
||||
entry = i2c[1] + i2c;
|
||||
entries = i2c[2];
|
||||
recordlen = i2c[3];
|
||||
} else
|
||||
if (i2c) {
|
||||
if (version) {
|
||||
entry = i2c;
|
||||
entries = 16;
|
||||
recordlen = 4;
|
||||
|
@ -852,7 +852,7 @@ nouveau_card_init(struct drm_device *dev)
|
||||
if (ret)
|
||||
goto out_pm;
|
||||
|
||||
if (!dev_priv->noaccel) {
|
||||
if (dev_priv->eng[NVOBJ_ENGINE_GR]) {
|
||||
ret = nouveau_card_channel_init(dev);
|
||||
if (ret)
|
||||
goto out_fence;
|
||||
|
@ -588,8 +588,8 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
|
||||
if (encoder->crtc == crtc) {
|
||||
radeon_encoder = to_radeon_encoder(encoder);
|
||||
connector = radeon_get_connector_for_encoder(encoder);
|
||||
if (connector && connector->display_info.bpc)
|
||||
bpc = connector->display_info.bpc;
|
||||
/* if (connector && connector->display_info.bpc)
|
||||
bpc = connector->display_info.bpc; */
|
||||
encoder_mode = atombios_get_encoder_mode(encoder);
|
||||
is_duallink = radeon_dig_monitor_is_duallink(encoder, mode->clock);
|
||||
if ((radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) ||
|
||||
@ -965,7 +965,9 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode
|
||||
struct radeon_connector_atom_dig *dig_connector =
|
||||
radeon_connector->con_priv;
|
||||
int dp_clock;
|
||||
bpc = connector->display_info.bpc;
|
||||
|
||||
/* if (connector->display_info.bpc)
|
||||
bpc = connector->display_info.bpc; */
|
||||
|
||||
switch (encoder_mode) {
|
||||
case ATOM_ENCODER_MODE_DP_MST:
|
||||
|
@ -405,10 +405,13 @@ static void dp_get_adjust_train(u8 link_status[DP_LINK_STATUS_SIZE],
|
||||
/* get bpc from the EDID */
|
||||
static int convert_bpc_to_bpp(int bpc)
|
||||
{
|
||||
#if 0
|
||||
if (bpc == 0)
|
||||
return 24;
|
||||
else
|
||||
return bpc * 3;
|
||||
#endif
|
||||
return 24;
|
||||
}
|
||||
|
||||
/* get the max pix clock supported by the link rate and lane num */
|
||||
|
@ -541,7 +541,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mo
|
||||
dp_clock = dig_connector->dp_clock;
|
||||
dp_lane_count = dig_connector->dp_lane_count;
|
||||
hpd_id = radeon_connector->hpd.hpd;
|
||||
bpc = connector->display_info.bpc;
|
||||
/* bpc = connector->display_info.bpc; */
|
||||
}
|
||||
|
||||
/* no dig encoder assigned */
|
||||
@ -1159,7 +1159,7 @@ atombios_external_encoder_setup(struct drm_encoder *encoder,
|
||||
dp_lane_count = dig_connector->dp_lane_count;
|
||||
connector_object_id =
|
||||
(radeon_connector->connector_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
|
||||
bpc = connector->display_info.bpc;
|
||||
/* bpc = connector->display_info.bpc; */
|
||||
}
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
|
@ -80,6 +80,9 @@ struct evergreen_cs_track {
|
||||
bool cb_dirty;
|
||||
bool db_dirty;
|
||||
bool streamout_dirty;
|
||||
u32 htile_offset;
|
||||
u32 htile_surface;
|
||||
struct radeon_bo *htile_bo;
|
||||
};
|
||||
|
||||
static u32 evergreen_cs_get_aray_mode(u32 tiling_flags)
|
||||
@ -144,6 +147,9 @@ static void evergreen_cs_track_init(struct evergreen_cs_track *track)
|
||||
track->db_s_read_bo = NULL;
|
||||
track->db_s_write_bo = NULL;
|
||||
track->db_dirty = true;
|
||||
track->htile_bo = NULL;
|
||||
track->htile_offset = 0xFFFFFFFF;
|
||||
track->htile_surface = 0;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
track->vgt_strmout_size[i] = 0;
|
||||
@ -444,6 +450,62 @@ static int evergreen_cs_track_validate_cb(struct radeon_cs_parser *p, unsigned i
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int evergreen_cs_track_validate_htile(struct radeon_cs_parser *p,
|
||||
unsigned nbx, unsigned nby)
|
||||
{
|
||||
struct evergreen_cs_track *track = p->track;
|
||||
unsigned long size;
|
||||
|
||||
if (track->htile_bo == NULL) {
|
||||
dev_warn(p->dev, "%s:%d htile enabled without htile surface 0x%08x\n",
|
||||
__func__, __LINE__, track->db_z_info);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (G_028ABC_LINEAR(track->htile_surface)) {
|
||||
/* pitch must be 16 htiles aligned == 16 * 8 pixel aligned */
|
||||
nbx = round_up(nbx, 16 * 8);
|
||||
/* height is npipes htiles aligned == npipes * 8 pixel aligned */
|
||||
nby = round_up(nby, track->npipes * 8);
|
||||
} else {
|
||||
switch (track->npipes) {
|
||||
case 8:
|
||||
nbx = round_up(nbx, 64 * 8);
|
||||
nby = round_up(nby, 64 * 8);
|
||||
break;
|
||||
case 4:
|
||||
nbx = round_up(nbx, 64 * 8);
|
||||
nby = round_up(nby, 32 * 8);
|
||||
break;
|
||||
case 2:
|
||||
nbx = round_up(nbx, 32 * 8);
|
||||
nby = round_up(nby, 32 * 8);
|
||||
break;
|
||||
case 1:
|
||||
nbx = round_up(nbx, 32 * 8);
|
||||
nby = round_up(nby, 16 * 8);
|
||||
break;
|
||||
default:
|
||||
dev_warn(p->dev, "%s:%d invalid num pipes %d\n",
|
||||
__func__, __LINE__, track->npipes);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
/* compute number of htile */
|
||||
nbx = nbx / 8;
|
||||
nby = nby / 8;
|
||||
size = nbx * nby * 4;
|
||||
size += track->htile_offset;
|
||||
|
||||
if (size > radeon_bo_size(track->htile_bo)) {
|
||||
dev_warn(p->dev, "%s:%d htile surface too small %ld for %ld (%d %d)\n",
|
||||
__func__, __LINE__, radeon_bo_size(track->htile_bo),
|
||||
size, nbx, nby);
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int evergreen_cs_track_validate_stencil(struct radeon_cs_parser *p)
|
||||
{
|
||||
struct evergreen_cs_track *track = p->track;
|
||||
@ -530,6 +592,14 @@ static int evergreen_cs_track_validate_stencil(struct radeon_cs_parser *p)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* hyperz */
|
||||
if (G_028040_TILE_SURFACE_ENABLE(track->db_z_info)) {
|
||||
r = evergreen_cs_track_validate_htile(p, surf.nbx, surf.nby);
|
||||
if (r) {
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -617,6 +687,14 @@ static int evergreen_cs_track_validate_depth(struct radeon_cs_parser *p)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* hyperz */
|
||||
if (G_028040_TILE_SURFACE_ENABLE(track->db_z_info)) {
|
||||
r = evergreen_cs_track_validate_htile(p, surf.nbx, surf.nby);
|
||||
if (r) {
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -850,7 +928,7 @@ static int evergreen_cs_track_check(struct radeon_cs_parser *p)
|
||||
return r;
|
||||
}
|
||||
/* Check depth buffer */
|
||||
if (G_028800_Z_WRITE_ENABLE(track->db_depth_control)) {
|
||||
if (G_028800_Z_ENABLE(track->db_depth_control)) {
|
||||
r = evergreen_cs_track_validate_depth(p);
|
||||
if (r)
|
||||
return r;
|
||||
@ -1616,6 +1694,23 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
|
||||
track->cb_color_bo[tmp] = reloc->robj;
|
||||
track->cb_dirty = true;
|
||||
break;
|
||||
case DB_HTILE_DATA_BASE:
|
||||
r = evergreen_cs_packet_next_reloc(p, &reloc);
|
||||
if (r) {
|
||||
dev_warn(p->dev, "bad SET_CONTEXT_REG "
|
||||
"0x%04X\n", reg);
|
||||
return -EINVAL;
|
||||
}
|
||||
track->htile_offset = radeon_get_ib_value(p, idx);
|
||||
ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
|
||||
track->htile_bo = reloc->robj;
|
||||
track->db_dirty = true;
|
||||
break;
|
||||
case DB_HTILE_SURFACE:
|
||||
/* 8x8 only */
|
||||
track->htile_surface = radeon_get_ib_value(p, idx);
|
||||
track->db_dirty = true;
|
||||
break;
|
||||
case CB_IMMED0_BASE:
|
||||
case CB_IMMED1_BASE:
|
||||
case CB_IMMED2_BASE:
|
||||
@ -1628,7 +1723,6 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
|
||||
case CB_IMMED9_BASE:
|
||||
case CB_IMMED10_BASE:
|
||||
case CB_IMMED11_BASE:
|
||||
case DB_HTILE_DATA_BASE:
|
||||
case SQ_PGM_START_FS:
|
||||
case SQ_PGM_START_ES:
|
||||
case SQ_PGM_START_VS:
|
||||
|
@ -991,6 +991,14 @@
|
||||
#define G_028008_SLICE_MAX(x) (((x) >> 13) & 0x7FF)
|
||||
#define C_028008_SLICE_MAX 0xFF001FFF
|
||||
#define DB_HTILE_DATA_BASE 0x28014
|
||||
#define DB_HTILE_SURFACE 0x28abc
|
||||
#define S_028ABC_HTILE_WIDTH(x) (((x) & 0x1) << 0)
|
||||
#define G_028ABC_HTILE_WIDTH(x) (((x) >> 0) & 0x1)
|
||||
#define C_028ABC_HTILE_WIDTH 0xFFFFFFFE
|
||||
#define S_028ABC_HTILE_HEIGHT(x) (((x) & 0x1) << 1)
|
||||
#define G_028ABC_HTILE_HEIGHT(x) (((x) >> 1) & 0x1)
|
||||
#define C_028ABC_HTILE_HEIGHT 0xFFFFFFFD
|
||||
#define G_028ABC_LINEAR(x) (((x) >> 2) & 0x1)
|
||||
#define DB_Z_INFO 0x28040
|
||||
# define Z_ARRAY_MODE(x) ((x) << 4)
|
||||
# define DB_TILE_SPLIT(x) (((x) & 0x7) << 8)
|
||||
|
@ -78,6 +78,9 @@ struct r600_cs_track {
|
||||
bool cb_dirty;
|
||||
bool db_dirty;
|
||||
bool streamout_dirty;
|
||||
struct radeon_bo *htile_bo;
|
||||
u64 htile_offset;
|
||||
u32 htile_surface;
|
||||
};
|
||||
|
||||
#define FMT_8_BIT(fmt, vc) [fmt] = { 1, 1, 1, vc, CHIP_R600 }
|
||||
@ -321,6 +324,9 @@ static void r600_cs_track_init(struct r600_cs_track *track)
|
||||
track->db_depth_size_idx = 0;
|
||||
track->db_depth_control = 0xFFFFFFFF;
|
||||
track->db_dirty = true;
|
||||
track->htile_bo = NULL;
|
||||
track->htile_offset = 0xFFFFFFFF;
|
||||
track->htile_surface = 0;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
track->vgt_strmout_size[i] = 0;
|
||||
@ -455,12 +461,256 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int r600_cs_track_validate_db(struct radeon_cs_parser *p)
|
||||
{
|
||||
struct r600_cs_track *track = p->track;
|
||||
u32 nviews, bpe, ntiles, size, slice_tile_max, tmp;
|
||||
u32 height_align, pitch_align, depth_align;
|
||||
u32 pitch = 8192;
|
||||
u32 height = 8192;
|
||||
u64 base_offset, base_align;
|
||||
struct array_mode_checker array_check;
|
||||
int array_mode;
|
||||
volatile u32 *ib = p->ib->ptr;
|
||||
|
||||
|
||||
if (track->db_bo == NULL) {
|
||||
dev_warn(p->dev, "z/stencil with no depth buffer\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
switch (G_028010_FORMAT(track->db_depth_info)) {
|
||||
case V_028010_DEPTH_16:
|
||||
bpe = 2;
|
||||
break;
|
||||
case V_028010_DEPTH_X8_24:
|
||||
case V_028010_DEPTH_8_24:
|
||||
case V_028010_DEPTH_X8_24_FLOAT:
|
||||
case V_028010_DEPTH_8_24_FLOAT:
|
||||
case V_028010_DEPTH_32_FLOAT:
|
||||
bpe = 4;
|
||||
break;
|
||||
case V_028010_DEPTH_X24_8_32_FLOAT:
|
||||
bpe = 8;
|
||||
break;
|
||||
default:
|
||||
dev_warn(p->dev, "z/stencil with invalid format %d\n", G_028010_FORMAT(track->db_depth_info));
|
||||
return -EINVAL;
|
||||
}
|
||||
if ((track->db_depth_size & 0xFFFFFC00) == 0xFFFFFC00) {
|
||||
if (!track->db_depth_size_idx) {
|
||||
dev_warn(p->dev, "z/stencil buffer size not set\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
tmp = radeon_bo_size(track->db_bo) - track->db_offset;
|
||||
tmp = (tmp / bpe) >> 6;
|
||||
if (!tmp) {
|
||||
dev_warn(p->dev, "z/stencil buffer too small (0x%08X %d %d %ld)\n",
|
||||
track->db_depth_size, bpe, track->db_offset,
|
||||
radeon_bo_size(track->db_bo));
|
||||
return -EINVAL;
|
||||
}
|
||||
ib[track->db_depth_size_idx] = S_028000_SLICE_TILE_MAX(tmp - 1) | (track->db_depth_size & 0x3FF);
|
||||
} else {
|
||||
size = radeon_bo_size(track->db_bo);
|
||||
/* pitch in pixels */
|
||||
pitch = (G_028000_PITCH_TILE_MAX(track->db_depth_size) + 1) * 8;
|
||||
slice_tile_max = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1;
|
||||
slice_tile_max *= 64;
|
||||
height = slice_tile_max / pitch;
|
||||
if (height > 8192)
|
||||
height = 8192;
|
||||
base_offset = track->db_bo_mc + track->db_offset;
|
||||
array_mode = G_028010_ARRAY_MODE(track->db_depth_info);
|
||||
array_check.array_mode = array_mode;
|
||||
array_check.group_size = track->group_size;
|
||||
array_check.nbanks = track->nbanks;
|
||||
array_check.npipes = track->npipes;
|
||||
array_check.nsamples = track->nsamples;
|
||||
array_check.blocksize = bpe;
|
||||
if (r600_get_array_mode_alignment(&array_check,
|
||||
&pitch_align, &height_align, &depth_align, &base_align)) {
|
||||
dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__,
|
||||
G_028010_ARRAY_MODE(track->db_depth_info),
|
||||
track->db_depth_info);
|
||||
return -EINVAL;
|
||||
}
|
||||
switch (array_mode) {
|
||||
case V_028010_ARRAY_1D_TILED_THIN1:
|
||||
/* don't break userspace */
|
||||
height &= ~0x7;
|
||||
break;
|
||||
case V_028010_ARRAY_2D_TILED_THIN1:
|
||||
break;
|
||||
default:
|
||||
dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__,
|
||||
G_028010_ARRAY_MODE(track->db_depth_info),
|
||||
track->db_depth_info);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!IS_ALIGNED(pitch, pitch_align)) {
|
||||
dev_warn(p->dev, "%s:%d db pitch (%d, 0x%x, %d) invalid\n",
|
||||
__func__, __LINE__, pitch, pitch_align, array_mode);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!IS_ALIGNED(height, height_align)) {
|
||||
dev_warn(p->dev, "%s:%d db height (%d, 0x%x, %d) invalid\n",
|
||||
__func__, __LINE__, height, height_align, array_mode);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!IS_ALIGNED(base_offset, base_align)) {
|
||||
dev_warn(p->dev, "%s offset 0x%llx, 0x%llx, %d not aligned\n", __func__,
|
||||
base_offset, base_align, array_mode);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ntiles = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1;
|
||||
nviews = G_028004_SLICE_MAX(track->db_depth_view) + 1;
|
||||
tmp = ntiles * bpe * 64 * nviews;
|
||||
if ((tmp + track->db_offset) > radeon_bo_size(track->db_bo)) {
|
||||
dev_warn(p->dev, "z/stencil buffer (%d) too small (0x%08X %d %d %d -> %u have %lu)\n",
|
||||
array_mode,
|
||||
track->db_depth_size, ntiles, nviews, bpe, tmp + track->db_offset,
|
||||
radeon_bo_size(track->db_bo));
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/* hyperz */
|
||||
if (G_028010_TILE_SURFACE_ENABLE(track->db_depth_info)) {
|
||||
unsigned long size;
|
||||
unsigned nbx, nby;
|
||||
|
||||
if (track->htile_bo == NULL) {
|
||||
dev_warn(p->dev, "%s:%d htile enabled without htile surface 0x%08x\n",
|
||||
__func__, __LINE__, track->db_depth_info);
|
||||
return -EINVAL;
|
||||
}
|
||||
if ((track->db_depth_size & 0xFFFFFC00) == 0xFFFFFC00) {
|
||||
dev_warn(p->dev, "%s:%d htile can't be enabled with bogus db_depth_size 0x%08x\n",
|
||||
__func__, __LINE__, track->db_depth_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
nbx = pitch;
|
||||
nby = height;
|
||||
if (G_028D24_LINEAR(track->htile_surface)) {
|
||||
/* nbx must be 16 htiles aligned == 16 * 8 pixel aligned */
|
||||
nbx = round_up(nbx, 16 * 8);
|
||||
/* nby is npipes htiles aligned == npipes * 8 pixel aligned */
|
||||
nby = round_up(nby, track->npipes * 8);
|
||||
} else {
|
||||
/* htile widht & nby (8 or 4) make 2 bits number */
|
||||
tmp = track->htile_surface & 3;
|
||||
/* align is htile align * 8, htile align vary according to
|
||||
* number of pipe and tile width and nby
|
||||
*/
|
||||
switch (track->npipes) {
|
||||
case 8:
|
||||
switch (tmp) {
|
||||
case 3: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/
|
||||
nbx = round_up(nbx, 64 * 8);
|
||||
nby = round_up(nby, 64 * 8);
|
||||
break;
|
||||
case 2: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 8*/
|
||||
case 1: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 4*/
|
||||
nbx = round_up(nbx, 64 * 8);
|
||||
nby = round_up(nby, 32 * 8);
|
||||
break;
|
||||
case 0: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 4*/
|
||||
nbx = round_up(nbx, 32 * 8);
|
||||
nby = round_up(nby, 32 * 8);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
switch (tmp) {
|
||||
case 3: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/
|
||||
nbx = round_up(nbx, 64 * 8);
|
||||
nby = round_up(nby, 32 * 8);
|
||||
break;
|
||||
case 2: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 8*/
|
||||
case 1: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 4*/
|
||||
nbx = round_up(nbx, 32 * 8);
|
||||
nby = round_up(nby, 32 * 8);
|
||||
break;
|
||||
case 0: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 4*/
|
||||
nbx = round_up(nbx, 32 * 8);
|
||||
nby = round_up(nby, 16 * 8);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
switch (tmp) {
|
||||
case 3: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/
|
||||
nbx = round_up(nbx, 32 * 8);
|
||||
nby = round_up(nby, 32 * 8);
|
||||
break;
|
||||
case 2: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 8*/
|
||||
case 1: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 4*/
|
||||
nbx = round_up(nbx, 32 * 8);
|
||||
nby = round_up(nby, 16 * 8);
|
||||
break;
|
||||
case 0: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 4*/
|
||||
nbx = round_up(nbx, 16 * 8);
|
||||
nby = round_up(nby, 16 * 8);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
switch (tmp) {
|
||||
case 3: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/
|
||||
nbx = round_up(nbx, 32 * 8);
|
||||
nby = round_up(nby, 16 * 8);
|
||||
break;
|
||||
case 2: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 8*/
|
||||
case 1: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 4*/
|
||||
nbx = round_up(nbx, 16 * 8);
|
||||
nby = round_up(nby, 16 * 8);
|
||||
break;
|
||||
case 0: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 4*/
|
||||
nbx = round_up(nbx, 16 * 8);
|
||||
nby = round_up(nby, 8 * 8);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
dev_warn(p->dev, "%s:%d invalid num pipes %d\n",
|
||||
__func__, __LINE__, track->npipes);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
/* compute number of htile */
|
||||
nbx = G_028D24_HTILE_WIDTH(track->htile_surface) ? nbx / 8 : nbx / 4;
|
||||
nby = G_028D24_HTILE_HEIGHT(track->htile_surface) ? nby / 8 : nby / 4;
|
||||
size = nbx * nby * 4;
|
||||
size += track->htile_offset;
|
||||
|
||||
if (size > radeon_bo_size(track->htile_bo)) {
|
||||
dev_warn(p->dev, "%s:%d htile surface too small %ld for %ld (%d %d)\n",
|
||||
__func__, __LINE__, radeon_bo_size(track->htile_bo),
|
||||
size, nbx, nby);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
track->db_dirty = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int r600_cs_track_check(struct radeon_cs_parser *p)
|
||||
{
|
||||
struct r600_cs_track *track = p->track;
|
||||
u32 tmp;
|
||||
int r, i;
|
||||
volatile u32 *ib = p->ib->ptr;
|
||||
|
||||
/* on legacy kernel we don't perform advanced check */
|
||||
if (p->rdev == NULL)
|
||||
@ -513,124 +763,14 @@ static int r600_cs_track_check(struct radeon_cs_parser *p)
|
||||
track->cb_dirty = false;
|
||||
}
|
||||
|
||||
if (track->db_dirty) {
|
||||
/* Check depth buffer */
|
||||
if (G_028800_STENCIL_ENABLE(track->db_depth_control) ||
|
||||
G_028800_Z_ENABLE(track->db_depth_control)) {
|
||||
u32 nviews, bpe, ntiles, size, slice_tile_max;
|
||||
u32 height, height_align, pitch, pitch_align, depth_align;
|
||||
u64 base_offset, base_align;
|
||||
struct array_mode_checker array_check;
|
||||
int array_mode;
|
||||
|
||||
if (track->db_bo == NULL) {
|
||||
dev_warn(p->dev, "z/stencil with no depth buffer\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (G_028010_TILE_SURFACE_ENABLE(track->db_depth_info)) {
|
||||
dev_warn(p->dev, "this kernel doesn't support z/stencil htile\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
switch (G_028010_FORMAT(track->db_depth_info)) {
|
||||
case V_028010_DEPTH_16:
|
||||
bpe = 2;
|
||||
break;
|
||||
case V_028010_DEPTH_X8_24:
|
||||
case V_028010_DEPTH_8_24:
|
||||
case V_028010_DEPTH_X8_24_FLOAT:
|
||||
case V_028010_DEPTH_8_24_FLOAT:
|
||||
case V_028010_DEPTH_32_FLOAT:
|
||||
bpe = 4;
|
||||
break;
|
||||
case V_028010_DEPTH_X24_8_32_FLOAT:
|
||||
bpe = 8;
|
||||
break;
|
||||
default:
|
||||
dev_warn(p->dev, "z/stencil with invalid format %d\n", G_028010_FORMAT(track->db_depth_info));
|
||||
return -EINVAL;
|
||||
}
|
||||
if ((track->db_depth_size & 0xFFFFFC00) == 0xFFFFFC00) {
|
||||
if (!track->db_depth_size_idx) {
|
||||
dev_warn(p->dev, "z/stencil buffer size not set\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
tmp = radeon_bo_size(track->db_bo) - track->db_offset;
|
||||
tmp = (tmp / bpe) >> 6;
|
||||
if (!tmp) {
|
||||
dev_warn(p->dev, "z/stencil buffer too small (0x%08X %d %d %ld)\n",
|
||||
track->db_depth_size, bpe, track->db_offset,
|
||||
radeon_bo_size(track->db_bo));
|
||||
return -EINVAL;
|
||||
}
|
||||
ib[track->db_depth_size_idx] = S_028000_SLICE_TILE_MAX(tmp - 1) | (track->db_depth_size & 0x3FF);
|
||||
} else {
|
||||
size = radeon_bo_size(track->db_bo);
|
||||
/* pitch in pixels */
|
||||
pitch = (G_028000_PITCH_TILE_MAX(track->db_depth_size) + 1) * 8;
|
||||
slice_tile_max = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1;
|
||||
slice_tile_max *= 64;
|
||||
height = slice_tile_max / pitch;
|
||||
if (height > 8192)
|
||||
height = 8192;
|
||||
base_offset = track->db_bo_mc + track->db_offset;
|
||||
array_mode = G_028010_ARRAY_MODE(track->db_depth_info);
|
||||
array_check.array_mode = array_mode;
|
||||
array_check.group_size = track->group_size;
|
||||
array_check.nbanks = track->nbanks;
|
||||
array_check.npipes = track->npipes;
|
||||
array_check.nsamples = track->nsamples;
|
||||
array_check.blocksize = bpe;
|
||||
if (r600_get_array_mode_alignment(&array_check,
|
||||
&pitch_align, &height_align, &depth_align, &base_align)) {
|
||||
dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__,
|
||||
G_028010_ARRAY_MODE(track->db_depth_info),
|
||||
track->db_depth_info);
|
||||
return -EINVAL;
|
||||
}
|
||||
switch (array_mode) {
|
||||
case V_028010_ARRAY_1D_TILED_THIN1:
|
||||
/* don't break userspace */
|
||||
height &= ~0x7;
|
||||
break;
|
||||
case V_028010_ARRAY_2D_TILED_THIN1:
|
||||
break;
|
||||
default:
|
||||
dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__,
|
||||
G_028010_ARRAY_MODE(track->db_depth_info),
|
||||
track->db_depth_info);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!IS_ALIGNED(pitch, pitch_align)) {
|
||||
dev_warn(p->dev, "%s:%d db pitch (%d, 0x%x, %d) invalid\n",
|
||||
__func__, __LINE__, pitch, pitch_align, array_mode);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!IS_ALIGNED(height, height_align)) {
|
||||
dev_warn(p->dev, "%s:%d db height (%d, 0x%x, %d) invalid\n",
|
||||
__func__, __LINE__, height, height_align, array_mode);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!IS_ALIGNED(base_offset, base_align)) {
|
||||
dev_warn(p->dev, "%s offset[%d] 0x%llx, 0x%llx, %d not aligned\n", __func__, i,
|
||||
base_offset, base_align, array_mode);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ntiles = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1;
|
||||
nviews = G_028004_SLICE_MAX(track->db_depth_view) + 1;
|
||||
tmp = ntiles * bpe * 64 * nviews;
|
||||
if ((tmp + track->db_offset) > radeon_bo_size(track->db_bo)) {
|
||||
dev_warn(p->dev, "z/stencil buffer (%d) too small (0x%08X %d %d %d -> %u have %lu)\n",
|
||||
array_mode,
|
||||
track->db_depth_size, ntiles, nviews, bpe, tmp + track->db_offset,
|
||||
radeon_bo_size(track->db_bo));
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
track->db_dirty = false;
|
||||
/* Check depth buffer */
|
||||
if (track->db_dirty && (G_028800_STENCIL_ENABLE(track->db_depth_control) ||
|
||||
G_028800_Z_ENABLE(track->db_depth_control))) {
|
||||
r = r600_cs_track_validate_db(p);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1244,6 +1384,21 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
|
||||
track->db_dirty = true;
|
||||
break;
|
||||
case DB_HTILE_DATA_BASE:
|
||||
r = r600_cs_packet_next_reloc(p, &reloc);
|
||||
if (r) {
|
||||
dev_warn(p->dev, "bad SET_CONTEXT_REG "
|
||||
"0x%04X\n", reg);
|
||||
return -EINVAL;
|
||||
}
|
||||
track->htile_offset = radeon_get_ib_value(p, idx) << 8;
|
||||
ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
|
||||
track->htile_bo = reloc->robj;
|
||||
track->db_dirty = true;
|
||||
break;
|
||||
case DB_HTILE_SURFACE:
|
||||
track->htile_surface = radeon_get_ib_value(p, idx);
|
||||
track->db_dirty = true;
|
||||
break;
|
||||
case SQ_PGM_START_FS:
|
||||
case SQ_PGM_START_ES:
|
||||
case SQ_PGM_START_VS:
|
||||
|
@ -195,6 +195,14 @@
|
||||
#define PREZ_MUST_WAIT_FOR_POSTZ_DONE (1 << 31)
|
||||
#define DB_DEPTH_BASE 0x2800C
|
||||
#define DB_HTILE_DATA_BASE 0x28014
|
||||
#define DB_HTILE_SURFACE 0x28D24
|
||||
#define S_028D24_HTILE_WIDTH(x) (((x) & 0x1) << 0)
|
||||
#define G_028D24_HTILE_WIDTH(x) (((x) >> 0) & 0x1)
|
||||
#define C_028D24_HTILE_WIDTH 0xFFFFFFFE
|
||||
#define S_028D24_HTILE_HEIGHT(x) (((x) & 0x1) << 1)
|
||||
#define G_028D24_HTILE_HEIGHT(x) (((x) >> 1) & 0x1)
|
||||
#define C_028D24_HTILE_HEIGHT 0xFFFFFFFD
|
||||
#define G_028D24_LINEAR(x) (((x) >> 2) & 0x1)
|
||||
#define DB_WATERMARKS 0x9838
|
||||
#define DEPTH_FREE(x) ((x) << 0)
|
||||
#define DEPTH_FLUSH(x) ((x) << 5)
|
||||
|
@ -233,7 +233,17 @@ int radeon_bo_pin_restricted(struct radeon_bo *bo, u32 domain, u64 max_offset,
|
||||
bo->pin_count++;
|
||||
if (gpu_addr)
|
||||
*gpu_addr = radeon_bo_gpu_offset(bo);
|
||||
WARN_ON_ONCE(max_offset != 0);
|
||||
|
||||
if (max_offset != 0) {
|
||||
u64 domain_start;
|
||||
|
||||
if (domain == RADEON_GEM_DOMAIN_VRAM)
|
||||
domain_start = bo->rdev->mc.vram_start;
|
||||
else
|
||||
domain_start = bo->rdev->mc.gtt_start;
|
||||
WARN_ON_ONCE((*gpu_addr - domain_start) > max_offset);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
radeon_ttm_placement_from_domain(bo, domain);
|
||||
|
@ -509,7 +509,6 @@ cayman 0x9400
|
||||
0x00028AA8 IA_MULTI_VGT_PARAM
|
||||
0x00028AB4 VGT_REUSE_OFF
|
||||
0x00028AB8 VGT_VTX_CNT_EN
|
||||
0x00028ABC DB_HTILE_SURFACE
|
||||
0x00028AC0 DB_SRESULTS_COMPARE_STATE0
|
||||
0x00028AC4 DB_SRESULTS_COMPARE_STATE1
|
||||
0x00028AC8 DB_PRELOAD_CONTROL
|
||||
|
@ -519,7 +519,6 @@ evergreen 0x9400
|
||||
0x00028AA4 VGT_INSTANCE_STEP_RATE_1
|
||||
0x00028AB4 VGT_REUSE_OFF
|
||||
0x00028AB8 VGT_VTX_CNT_EN
|
||||
0x00028ABC DB_HTILE_SURFACE
|
||||
0x00028AC0 DB_SRESULTS_COMPARE_STATE0
|
||||
0x00028AC4 DB_SRESULTS_COMPARE_STATE1
|
||||
0x00028AC8 DB_PRELOAD_CONTROL
|
||||
|
@ -713,7 +713,6 @@ r600 0x9400
|
||||
0x0000A710 TD_VS_SAMPLER17_BORDER_RED
|
||||
0x00009508 TA_CNTL_AUX
|
||||
0x0002802C DB_DEPTH_CLEAR
|
||||
0x00028D24 DB_HTILE_SURFACE
|
||||
0x00028D34 DB_PREFETCH_LIMIT
|
||||
0x00028D30 DB_PRELOAD_CONTROL
|
||||
0x00028D0C DB_RENDER_CONTROL
|
||||
|
Loading…
Reference in New Issue
Block a user