Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e2be2cd8 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge branch 'drm-fixes-3.6' of git://people.freedesktop.org/~agd5f/linux into drm-fixes

Alex writes:

"This is the current set of radeon fixes for 3.6.  Nothing too major.

Highlights:
- fix vbios fetch on pure uefi systems
- fix vbios fetch on thunderbolt systems
- MSAA fixes
- lockup timeout fix
- modesetting fix"

* 'drm-fixes-3.6' of git://people.freedesktop.org/~agd5f/linux:
  drm/radeon/ss: use num_crtc rather than hardcoded 6
  Revert "drm/radeon: fix bo creation retry path"
  drm/radeon: split ATRM support out from the ATPX handler (v3)
  drm/radeon: convert radeon vfct code to use acpi_get_table_with_size
  ACPI: export symbol acpi_get_table_with_size
  drm/radeon: implement ACPI VFCT vbios fetch (v3)
  drm/radeon/kms: extend the Fujitsu D3003-S2 board connector quirk to cover later silicon stepping
  drm/radeon: fix checking of MSAA renderbuffers on r600-r700
  drm/radeon: allow CMASK and FMASK in the CS checker on r600-r700
  drm/radeon: init lockup timeout on ring init
  drm/radeon: avoid turning off spread spectrum for used pll
parents d9875690 53176706
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -387,6 +387,7 @@ acpi_get_table_with_size(char *signature,

	return (AE_NOT_FOUND);
}
ACPI_EXPORT_SYMBOL(acpi_get_table_with_size)

acpi_status
acpi_get_table(char *signature,
+21 −4
Original line number Diff line number Diff line
@@ -444,11 +444,28 @@ union atom_enable_ss {
static void atombios_crtc_program_ss(struct radeon_device *rdev,
				     int enable,
				     int pll_id,
				     int crtc_id,
				     struct radeon_atom_ss *ss)
{
	unsigned i;
	int index = GetIndexIntoMasterTable(COMMAND, EnableSpreadSpectrumOnPPLL);
	union atom_enable_ss args;

	if (!enable) {
		for (i = 0; i < rdev->num_crtc; i++) {
			if (rdev->mode_info.crtcs[i] &&
			    rdev->mode_info.crtcs[i]->enabled &&
			    i != crtc_id &&
			    pll_id == rdev->mode_info.crtcs[i]->pll_id) {
				/* one other crtc is using this pll don't turn
				 * off spread spectrum as it might turn off
				 * display on active crtc
				 */
				return;
			}
		}
	}

	memset(&args, 0, sizeof(args));

	if (ASIC_IS_DCE5(rdev)) {
@@ -1028,7 +1045,7 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode
		radeon_compute_pll_legacy(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
					  &ref_div, &post_div);

	atombios_crtc_program_ss(rdev, ATOM_DISABLE, radeon_crtc->pll_id, &ss);
	atombios_crtc_program_ss(rdev, ATOM_DISABLE, radeon_crtc->pll_id, radeon_crtc->crtc_id, &ss);

	atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id,
				  encoder_mode, radeon_encoder->encoder_id, mode->clock,
@@ -1051,7 +1068,7 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode
			ss.step = step_size;
		}

		atombios_crtc_program_ss(rdev, ATOM_ENABLE, radeon_crtc->pll_id, &ss);
		atombios_crtc_program_ss(rdev, ATOM_ENABLE, radeon_crtc->pll_id, radeon_crtc->crtc_id, &ss);
	}
}

@@ -1572,11 +1589,11 @@ void radeon_atom_disp_eng_pll_init(struct radeon_device *rdev)
								   ASIC_INTERNAL_SS_ON_DCPLL,
								   rdev->clock.default_dispclk);
		if (ss_enabled)
			atombios_crtc_program_ss(rdev, ATOM_DISABLE, ATOM_DCPLL, &ss);
			atombios_crtc_program_ss(rdev, ATOM_DISABLE, ATOM_DCPLL, -1, &ss);
		/* XXX: DCE5, make sure voltage, dispclk is high enough */
		atombios_crtc_set_disp_eng_pll(rdev, rdev->clock.default_dispclk);
		if (ss_enabled)
			atombios_crtc_program_ss(rdev, ATOM_ENABLE, ATOM_DCPLL, &ss);
			atombios_crtc_program_ss(rdev, ATOM_ENABLE, ATOM_DCPLL, -1, &ss);
	}

}
+88 −17
Original line number Diff line number Diff line
@@ -47,13 +47,17 @@ struct r600_cs_track {
	u32			npipes;
	/* value we track */
	u32			sq_config;
	u32			log_nsamples;
	u32			nsamples;
	u32			cb_color_base_last[8];
	struct radeon_bo	*cb_color_bo[8];
	u64			cb_color_bo_mc[8];
	u32			cb_color_bo_offset[8];
	struct radeon_bo	*cb_color_frag_bo[8]; /* unused */
	struct radeon_bo	*cb_color_tile_bo[8]; /* unused */
	u64			cb_color_bo_offset[8];
	struct radeon_bo	*cb_color_frag_bo[8];
	u64			cb_color_frag_offset[8];
	struct radeon_bo	*cb_color_tile_bo[8];
	u64			cb_color_tile_offset[8];
	u32			cb_color_mask[8];
	u32			cb_color_info[8];
	u32			cb_color_view[8];
	u32			cb_color_size_idx[8]; /* unused */
@@ -349,10 +353,6 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
	unsigned array_mode;
	u32 format;

	if (G_0280A0_TILE_MODE(track->cb_color_info[i])) {
		dev_warn(p->dev, "FMASK or CMASK buffer are not supported by this kernel\n");
		return -EINVAL;
	}
	size = radeon_bo_size(track->cb_color_bo[i]) - track->cb_color_bo_offset[i];
	format = G_0280A0_FORMAT(track->cb_color_info[i]);
	if (!r600_fmt_is_valid_color(format)) {
@@ -420,7 +420,8 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
	}

	/* check offset */
	tmp = r600_fmt_get_nblocksy(format, height) * r600_fmt_get_nblocksx(format, pitch) * r600_fmt_get_blocksize(format);
	tmp = r600_fmt_get_nblocksy(format, height) * r600_fmt_get_nblocksx(format, pitch) *
	      r600_fmt_get_blocksize(format) * track->nsamples;
	switch (array_mode) {
	default:
	case V_0280A0_ARRAY_LINEAR_GENERAL:
@@ -441,7 +442,7 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
			 * broken userspace.
			 */
		} else {
			dev_warn(p->dev, "%s offset[%d] %d %d %d %lu too big (%d %d) (%d %d %d)\n",
			dev_warn(p->dev, "%s offset[%d] %d %llu %d %lu too big (%d %d) (%d %d %d)\n",
				 __func__, i, array_mode,
				 track->cb_color_bo_offset[i], tmp,
				 radeon_bo_size(track->cb_color_bo[i]),
@@ -458,6 +459,51 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
	tmp = S_028060_PITCH_TILE_MAX((pitch / 8) - 1) |
		S_028060_SLICE_TILE_MAX(slice_tile_max - 1);
	ib[track->cb_color_size_idx[i]] = tmp;

	/* FMASK/CMASK */
	switch (G_0280A0_TILE_MODE(track->cb_color_info[i])) {
	case V_0280A0_TILE_DISABLE:
		break;
	case V_0280A0_FRAG_ENABLE:
		if (track->nsamples > 1) {
			uint32_t tile_max = G_028100_FMASK_TILE_MAX(track->cb_color_mask[i]);
			/* the tile size is 8x8, but the size is in units of bits.
			 * for bytes, do just * 8. */
			uint32_t bytes = track->nsamples * track->log_nsamples * 8 * (tile_max + 1);

			if (bytes + track->cb_color_frag_offset[i] >
			    radeon_bo_size(track->cb_color_frag_bo[i])) {
				dev_warn(p->dev, "%s FMASK_TILE_MAX too large "
					 "(tile_max=%u, bytes=%u, offset=%llu, bo_size=%lu)\n",
					 __func__, tile_max, bytes,
					 track->cb_color_frag_offset[i],
					 radeon_bo_size(track->cb_color_frag_bo[i]));
				return -EINVAL;
			}
		}
		/* fall through */
	case V_0280A0_CLEAR_ENABLE:
	{
		uint32_t block_max = G_028100_CMASK_BLOCK_MAX(track->cb_color_mask[i]);
		/* One block = 128x128 pixels, one 8x8 tile has 4 bits..
		 * (128*128) / (8*8) / 2 = 128 bytes per block. */
		uint32_t bytes = (block_max + 1) * 128;

		if (bytes + track->cb_color_tile_offset[i] >
		    radeon_bo_size(track->cb_color_tile_bo[i])) {
			dev_warn(p->dev, "%s CMASK_BLOCK_MAX too large "
				 "(block_max=%u, bytes=%u, offset=%llu, bo_size=%lu)\n",
				 __func__, block_max, bytes,
				 track->cb_color_tile_offset[i],
				 radeon_bo_size(track->cb_color_tile_bo[i]));
			return -EINVAL;
		}
		break;
	}
	default:
		dev_warn(p->dev, "%s invalid tile mode\n", __func__);
		return -EINVAL;
	}
	return 0;
}

@@ -566,7 +612,7 @@ static int r600_cs_track_validate_db(struct radeon_cs_parser *p)

		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;
		tmp = ntiles * bpe * 64 * nviews * track->nsamples;
		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,
@@ -1231,6 +1277,7 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
		break;
	case R_028C04_PA_SC_AA_CONFIG:
		tmp = G_028C04_MSAA_NUM_SAMPLES(radeon_get_ib_value(p, idx));
		track->log_nsamples = tmp;
		track->nsamples = 1 << tmp;
		track->cb_dirty = true;
		break;
@@ -1312,16 +1359,21 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
				dev_err(p->dev, "Broken old userspace ? no cb_color0_base supplied before trying to write 0x%08X\n", reg);
				return -EINVAL;
			}
			ib[idx] = track->cb_color_base_last[tmp];
			track->cb_color_frag_bo[tmp] = track->cb_color_bo[tmp];
			track->cb_color_frag_offset[tmp] = track->cb_color_bo_offset[tmp];
			ib[idx] = track->cb_color_base_last[tmp];
		} else {
			r = r600_cs_packet_next_reloc(p, &reloc);
			if (r) {
				dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg);
				return -EINVAL;
			}
			ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
			track->cb_color_frag_bo[tmp] = reloc->robj;
			track->cb_color_frag_offset[tmp] = (u64)ib[idx] << 8;
			ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
		}
		if (G_0280A0_TILE_MODE(track->cb_color_info[tmp])) {
			track->cb_dirty = true;
		}
		break;
	case R_0280C0_CB_COLOR0_TILE:
@@ -1338,16 +1390,35 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
				dev_err(p->dev, "Broken old userspace ? no cb_color0_base supplied before trying to write 0x%08X\n", reg);
				return -EINVAL;
			}
			ib[idx] = track->cb_color_base_last[tmp];
			track->cb_color_tile_bo[tmp] = track->cb_color_bo[tmp];
			track->cb_color_tile_offset[tmp] = track->cb_color_bo_offset[tmp];
			ib[idx] = track->cb_color_base_last[tmp];
		} else {
			r = r600_cs_packet_next_reloc(p, &reloc);
			if (r) {
				dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg);
				return -EINVAL;
			}
			ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
			track->cb_color_tile_bo[tmp] = reloc->robj;
			track->cb_color_tile_offset[tmp] = (u64)ib[idx] << 8;
			ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
		}
		if (G_0280A0_TILE_MODE(track->cb_color_info[tmp])) {
			track->cb_dirty = true;
		}
		break;
	case R_028100_CB_COLOR0_MASK:
	case R_028104_CB_COLOR1_MASK:
	case R_028108_CB_COLOR2_MASK:
	case R_02810C_CB_COLOR3_MASK:
	case R_028110_CB_COLOR4_MASK:
	case R_028114_CB_COLOR5_MASK:
	case R_028118_CB_COLOR6_MASK:
	case R_02811C_CB_COLOR7_MASK:
		tmp = (reg - R_028100_CB_COLOR0_MASK) / 4;
		track->cb_color_mask[tmp] = ib[idx];
		if (G_0280A0_TILE_MODE(track->cb_color_info[tmp])) {
			track->cb_dirty = true;
		}
		break;
	case CB_COLOR0_BASE:
@@ -1492,7 +1563,7 @@ unsigned r600_mip_minify(unsigned size, unsigned level)
}

static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned llevel,
			      unsigned w0, unsigned h0, unsigned d0, unsigned format,
			      unsigned w0, unsigned h0, unsigned d0, unsigned nsamples, unsigned format,
			      unsigned block_align, unsigned height_align, unsigned base_align,
			      unsigned *l0_size, unsigned *mipmap_size)
{
@@ -1520,7 +1591,7 @@ static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned llevel,

		depth = r600_mip_minify(d0, i);

		size = nbx * nby * blocksize;
		size = nbx * nby * blocksize * nsamples;
		if (nfaces)
			size *= nfaces;
		else
@@ -1672,7 +1743,7 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx,

		nfaces = larray - barray + 1;
	}
	r600_texture_size(nfaces, blevel, llevel, w0, h0, d0, format,
	r600_texture_size(nfaces, blevel, llevel, w0, h0, d0, array_check.nsamples, format,
			  pitch_align, height_align, base_align,
			  &l0_size, &mipmap_size);
	/* using get ib will give us the offset into the texture bo */
+17 −0
Original line number Diff line number Diff line
@@ -92,6 +92,20 @@
#define R_028094_CB_COLOR5_VIEW                      0x028094
#define R_028098_CB_COLOR6_VIEW                      0x028098
#define R_02809C_CB_COLOR7_VIEW                      0x02809C
#define R_028100_CB_COLOR0_MASK                      0x028100
#define   S_028100_CMASK_BLOCK_MAX(x)                  (((x) & 0xFFF) << 0)
#define   G_028100_CMASK_BLOCK_MAX(x)                  (((x) >> 0) & 0xFFF)
#define   C_028100_CMASK_BLOCK_MAX                     0xFFFFF000
#define   S_028100_FMASK_TILE_MAX(x)                   (((x) & 0xFFFFF) << 12)
#define   G_028100_FMASK_TILE_MAX(x)                   (((x) >> 12) & 0xFFFFF)
#define   C_028100_FMASK_TILE_MAX                      0x00000FFF
#define R_028104_CB_COLOR1_MASK                      0x028104
#define R_028108_CB_COLOR2_MASK                      0x028108
#define R_02810C_CB_COLOR3_MASK                      0x02810C
#define R_028110_CB_COLOR4_MASK                      0x028110
#define R_028114_CB_COLOR5_MASK                      0x028114
#define R_028118_CB_COLOR6_MASK                      0x028118
#define R_02811C_CB_COLOR7_MASK                      0x02811C
#define CB_COLOR0_INFO                                  0x280a0
#	define CB_FORMAT(x)				((x) << 2)
#       define CB_ARRAY_MODE(x)                         ((x) << 8)
@@ -1400,6 +1414,9 @@
#define   S_0280A0_TILE_MODE(x)                        (((x) & 0x3) << 18)
#define   G_0280A0_TILE_MODE(x)                        (((x) >> 18) & 0x3)
#define   C_0280A0_TILE_MODE                           0xFFF3FFFF
#define     V_0280A0_TILE_DISABLE			0
#define     V_0280A0_CLEAR_ENABLE			1
#define     V_0280A0_FRAG_ENABLE			2
#define   S_0280A0_BLEND_CLAMP(x)                      (((x) & 0x1) << 20)
#define   G_0280A0_BLEND_CLAMP(x)                      (((x) >> 20) & 0x1)
#define   C_0280A0_BLEND_CLAMP                         0xFFEFFFFF
+0 −15
Original line number Diff line number Diff line
@@ -142,21 +142,6 @@ struct radeon_device;
/*
 * BIOS.
 */
#define ATRM_BIOS_PAGE 4096

#if defined(CONFIG_VGA_SWITCHEROO)
bool radeon_atrm_supported(struct pci_dev *pdev);
int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len);
#else
static inline bool radeon_atrm_supported(struct pci_dev *pdev)
{
	return false;
}

static inline int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len){
	return -EINVAL;
}
#endif
bool radeon_get_bios(struct radeon_device *rdev);

/*
Loading